Skip to content

Commit

Permalink
Merge branch 'main' into speshkar/ENG-120721/addRole-datepicker-span
Browse files Browse the repository at this point in the history
  • Loading branch information
sravichandran-eightfold authored Jan 14, 2025
2 parents 920c515 + cf3ffeb commit ff126ed
Show file tree
Hide file tree
Showing 17 changed files with 152 additions and 4 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

### [2.52.20](https://github.com/EightfoldAI/octuple/compare/v2.52.19...v2.52.20) (2025-01-09)

### [2.52.19](https://github.com/EightfoldAI/octuple/compare/v2.52.18...v2.52.19) (2025-01-09)

### Bug Fixes

- added aria-label to the date range picker ([#927](https://github.com/EightfoldAI/octuple/issues/927)) ([64519fb](https://github.com/EightfoldAI/octuple/commits/64519fb8c65ea1035c6003822c88f3b44492ed2c))
- added keyboard accesibility to the easy cropper component ([#932](https://github.com/EightfoldAI/octuple/issues/932)) ([0a8b1ff](https://github.com/EightfoldAI/octuple/commits/0a8b1ffc761e28dbfac8f143a70ecc409269f845))
- dropdown: fixed dropdown container focus issue ([#914](https://github.com/EightfoldAI/octuple/issues/914)) ([92a9407](https://github.com/EightfoldAI/octuple/commits/92a940763e9293a6e9b13059f5e7eed7e4638f25))
- panelHeader: Added prop to the close button ([#917](https://github.com/EightfoldAI/octuple/issues/917)) ([906ee0a](https://github.com/EightfoldAI/octuple/commits/906ee0a5dd2491f760d495bc477767a73b70f9a7))
- scroller is interrupting with the mouse events even when it is not visible ([#920](https://github.com/EightfoldAI/octuple/issues/920)) ([35efd65](https://github.com/EightfoldAI/octuple/commits/35efd656095e824014acbbde61e15cb127d4288f))
- tabs: added inset box shadow on focus visible ([#916](https://github.com/EightfoldAI/octuple/issues/916)) ([41039f5](https://github.com/EightfoldAI/octuple/commits/41039f5fefcff744d467bc648fe350661bad8eec))
- two state button loader background color ([#921](https://github.com/EightfoldAI/octuple/issues/921)) ([f0b09c2](https://github.com/EightfoldAI/octuple/commits/f0b09c2c6f0ec694923767775d13a99e2c226dea))

### [2.52.18](https://github.com/EightfoldAI/octuple/compare/v2.52.17...v2.52.18) (2024-11-13)

### Bug Fixes
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@eightfold.ai/octuple",
"version": "2.52.18",
"version": "2.52.20",
"license": "MIT",
"sideEffects": [
"**/*.css"
Expand Down
2 changes: 2 additions & 0 deletions src/components/CheckBox/CheckBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export const CheckBox: FC<CheckboxProps> = React.forwardRef(
value,
variant = SelectorVariant.Default,
'data-test-id': dataTestId,
...rest
},
ref: Ref<HTMLInputElement>
) => {
Expand Down Expand Up @@ -208,6 +209,7 @@ export const CheckBox: FC<CheckboxProps> = React.forwardRef(
value={value}
readOnly
role={toggle ? 'switch' : 'checkbox'}
{...rest}
/>
<label htmlFor={checkBoxId.current} className={labelClassNames}>
{labelPosition == LabelPosition.Start && (
Expand Down
2 changes: 1 addition & 1 deletion src/components/CheckBox/CheckBoxGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export const CheckBoxGroup: FC<CheckboxGroupProps> = React.forwardRef(
<div
className={checkboxGroupClassNames}
style={style}
role="group"
role={items?.length > 1 ? 'group' : undefined}
aria-label={ariaLabel}
id={id}
ref={ref}
Expand Down
23 changes: 23 additions & 0 deletions src/components/DateTimePicker/DatePicker/DatePicker.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,10 @@ const Range_Status_Story: ComponentStory<typeof RangePicker> = (args) => {
);
};

const Range_Picker_With_Aria_Labels_Story: ComponentStory<
typeof RangePicker
> = (args) => <DatePicker.RangePicker {...args} />;

export const Single_Picker = Single_Picker_Story.bind({});
export const Single_Picker_TrapFocus = Single_Picker_TrapFocus_Story.bind({});
export const Single_Picker_Readonly = Single_Picker_Readonly_Story.bind({});
Expand Down Expand Up @@ -588,6 +592,8 @@ export const Single_Borderless = Single_Borderless_Story.bind({});
export const Range_Borderless = Range_Borderless_Story.bind({});
export const Single_Status = Single_Status_Story.bind({});
export const Range_Status = Range_Status_Story.bind({});
export const Range_Picker_With_Aria_Labels =
Range_Picker_With_Aria_Labels_Story.bind({});

// Storybook 6.5 using Webpack >= 5.76.0 automatically alphabetizes exports,
// this line ensures they are exported in the desired order.
Expand Down Expand Up @@ -616,6 +622,7 @@ export const __namedExportsOrder = [
'Range_Borderless',
'Single_Status',
'Range_Status',
'Range_Picker_With_Aria_Labels',
];

const pickerArgs: Object = {
Expand Down Expand Up @@ -748,3 +755,19 @@ Range_Status.args = {
...pickerArgs,
showToday: false,
};

// Add argTypes specifically for RangePicker stories
Range_Picker.argTypes = {
startDateInputAriaLabel: {
control: { type: 'text' },
description: 'Aria label for the start date input',
defaultValue: 'Start date',
},
endDateInputAriaLabel: {
control: { type: 'text' },
description: 'Aria label for the end date input',
defaultValue: 'End date',
},
};

Range_Picker_With_Aria_Labels.argTypes = Range_Picker.argTypes;
6 changes: 6 additions & 0 deletions src/components/DateTimePicker/Internal/OcRangePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ type OmitType<DateType> = Omit<OcRangePickerBaseProps<DateType>, 'picker'> &

type MergedOcRangePickerProps<DateType> = {
picker?: OcPickerMode;
startDateInputAriaLabel?: string;
endDateInputAriaLabel?: string;
} & OmitType<DateType>;

function InnerRangePicker<DateType>(props: OcRangePickerProps<DateType>) {
Expand Down Expand Up @@ -186,6 +188,8 @@ function InnerRangePicker<DateType>(props: OcRangePickerProps<DateType>) {
todayActive,
todayText,
value,
startDateInputAriaLabel = '',
endDateInputAriaLabel = '',
} = props as MergedOcRangePickerProps<DateType>;

const needConfirmButton: boolean =
Expand Down Expand Up @@ -1291,6 +1295,7 @@ function InnerRangePicker<DateType>(props: OcRangePickerProps<DateType>) {
}
disabled={mergedDisabled[0]}
id={id}
aria-label={startDateInputAriaLabel}
readOnly={
mergedReadonly[0] ||
(!mergedReadonly && inputReadOnly) ||
Expand Down Expand Up @@ -1334,6 +1339,7 @@ function InnerRangePicker<DateType>(props: OcRangePickerProps<DateType>) {
>
<input
disabled={mergedDisabled[1]}
aria-label={endDateInputAriaLabel}
readOnly={
mergedReadonly[1] ||
(!mergedReadonly && inputReadOnly) ||
Expand Down
1 change: 0 additions & 1 deletion src/components/Dropdown/Dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,6 @@ export const Dropdown: FC<DropdownProps> = React.memo(
ref={refs.setFloating}
style={dropdownStyles}
className={dropdownClasses}
tabIndex={0}
onClick={
closeOnDropdownClick ? toggle(false, showDropdown) : null
}
Expand Down
5 changes: 5 additions & 0 deletions src/components/Inputs/Input.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ export interface InputIconButtonProps {
* Leverage this to programatically disable the focus for the button as needed.
*/
tabIndex?: number;
/**
* Whether or not to apply the aria-hidden attribute to the icon button.
* @default false
*/
ariaHidden?: boolean;
}

export interface ReadOnlyProps {
Expand Down
1 change: 1 addition & 0 deletions src/components/Inputs/TextInput/TextInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,7 @@ export const TextInput: FC<TextInputProps> = React.forwardRef(
tabIndex={iconButtonProps.tabIndex}
transparent
variant={ButtonVariant.SystemUI}
aria-hidden={iconButtonProps.ariaHidden}
/>
);

Expand Down
4 changes: 4 additions & 0 deletions src/components/Panel/Panel.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,10 @@ export interface PanelHeaderProps extends OcBaseProps<HTMLDivElement> {
* @default IconName.mdiClose
*/
closeIcon?: IconName;
/**
* Close button extra props
*/
closeButtonProps?: CloseButtonProps;
/**
* Configure how contextual props are consumed
*/
Expand Down
2 changes: 2 additions & 0 deletions src/components/Panel/PanelHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const PanelHeader: FC<PanelHeaderProps> = React.forwardRef(
actionButtonOneProps,
actionButtonTwoProps,
actionDefaultButtonProps,
closeButtonProps,
closeButtonAriaLabelText: defaultCloseButtonAriaLabelText,
closeIcon = IconName.mdiClose,
configContextProps = {
Expand Down Expand Up @@ -137,6 +138,7 @@ export const PanelHeader: FC<PanelHeaderProps> = React.forwardRef(
themeContainerId={themeContainerId}
transparent
variant={ButtonVariant.SystemUI}
{...closeButtonProps}
/>
)}
</div>
Expand Down
2 changes: 2 additions & 0 deletions src/components/RadioButton/RadioButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export const RadioButton: FC<RadioButtonProps> = React.forwardRef(
value = '',
variant = SelectorVariant.Default,
'data-test-id': dataTestId,
...rest
},
ref: Ref<HTMLInputElement>
) => {
Expand Down Expand Up @@ -195,6 +196,7 @@ export const RadioButton: FC<RadioButtonProps> = React.forwardRef(
value={value}
onChange={!allowDisabledFocus ? toggleChecked : null}
readOnly
{...rest}
/>
<label htmlFor={radioButtonId.current} className={labelClassNames}>
{labelPosition == LabelPosition.Start && (
Expand Down
2 changes: 1 addition & 1 deletion src/components/RadioButton/RadioGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export const RadioGroup: FC<RadioGroupProps> = React.forwardRef(
return (
<RadioGroupProvider onChange={onChange} value={value}>
<div
role="group"
role={items.length > 1 ? 'group' : undefined}
className={radioGroupClasses}
style={style}
ref={ref}
Expand Down
1 change: 1 addition & 0 deletions src/components/Select/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,7 @@ export const Select: FC<SelectProps> = React.forwardRef(
// the input itself provides the focus and action.
tabIndex: -1,
role: 'presentation',
ariaHidden: true,
iconProps: {
path: dropdownVisible
? IconName.mdiChevronUp
Expand Down
1 change: 1 addition & 0 deletions src/components/Tabs/tabs.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
// Hides the browser default keyboard focus-visible styles.
// Use the ConfigProvider instead.
&:focus-visible {
box-shadow: inset var(--focus-visible-box-shadow);
outline: none;
}

Expand Down
44 changes: 44 additions & 0 deletions src/components/Upload/Cropper/EasyCrop.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import React, {
useImperativeHandle,
useRef,
useState,
useLayoutEffect,
} from 'react';
import { OcThemeName } from '../../ConfigProvider';
import ThemeContext from '../../ConfigProvider/ThemeContext';
Expand Down Expand Up @@ -104,6 +105,49 @@ const EasyCrop = forwardRef<EasyCropHandle, EasyCropProps>((props, ref) => {
[rotateVal]
);

const handleKeyDown = useCallback(
(event: KeyboardEvent) => {
const step = 5;
setCrop((prev) => {
let newX = prev.x;
let newY = prev.y;

switch (event.key) {
case 'ArrowLeft':
newX = Math.max(prev.x - step, -cropSize.width / 2);
break;
case 'ArrowRight':
newX = Math.min(prev.x + step, cropSize.width / 2);
break;
case 'ArrowUp':
newY = Math.max(prev.y - step, -cropSize.height / 2);
break;
case 'ArrowDown':
newY = Math.min(prev.y + step, cropSize.height / 2);
break;
default:
return prev;
}

event.preventDefault();
return { x: newX, y: newY };
});
},
[cropSize]
);

// Add event listener for keyboard events
useLayoutEffect(() => {
const cropperElement = document.getElementsByClassName(
'reactEasyCrop_Container'
)?.[0];
cropperElement?.setAttribute('tabindex', '0'); // to make it focusable
cropperElement?.addEventListener('keydown', handleKeyDown);
return () => {
cropperElement?.removeEventListener('keydown', handleKeyDown);
};
}, [handleKeyDown]);

return (
<>
<EasyCropper
Expand Down
44 changes: 44 additions & 0 deletions src/components/Upload/Upload.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,39 @@ const Basic_Deferred_API_Story: ComponentStory<typeof Upload> = (args) => {
);
};

const Cropper_Story: ComponentStory<typeof Cropper> = (args) => {
const [image, setImage] = useState<string>('');

const handleImageUpload = (file: OcFile) => {
const reader = new FileReader();
reader.onload = () => {
if (typeof reader.result === 'string') {
setImage(reader.result);
}
};
reader.readAsDataURL(file);
};

return (
<Cropper
{...args}
onModalOk={(file) => console.log('Cropped file:', file)}
onUploadFail={(error) => console.error('Upload failed:', error)}
>
<Upload
action="https://run.mocky.io/v3/0ef2249d-ccd9-4032-be61-e853a549ef61"
beforeUpload={handleImageUpload}
>
<Button
text="Select file"
variant={ButtonVariant.Primary}
iconProps={{ path: IconName.mdiUpload }}
/>
</Upload>
</Cropper>
);
};

export const Basic = Basic_Story.bind({});
export const Basic_With_Upload_List = Basic_With_Upload_List_Story.bind({});
export const Drag_and_Drop_Single_Small = Drag_and_Drop_Single_Small_Story.bind(
Expand All @@ -740,6 +773,7 @@ export const Drag_and_Drop_Multiple_Large =
export const Image_List = Image_List_Story.bind({});
export const Image_Editor = Image_Editor_Story.bind({});
export const Basic_Deferred_API = Basic_Deferred_API_Story.bind({});
export const Basic_With_Cropper = Cropper_Story.bind({});

// Storybook 6.5 using Webpack >= 5.76.0 automatically alphabetizes exports,
// this line ensures they are exported in the desired order.
Expand All @@ -756,6 +790,7 @@ export const __namedExportsOrder = [
'Image_List',
'Image_Editor',
'Basic_Deferred_API',
'Basic_With_Cropper',
];

const uploadArgs: Object = {
Expand Down Expand Up @@ -818,3 +853,12 @@ Basic_Deferred_API.args = {
...uploadArgs,
fullWidth: false,
};

Basic_With_Cropper.args = {
aspect: 1,
rotate: true,
zoom: true,
shape: 'round',
theme: 'blue',
themeContainerId: 'cropper-theme-container',
};

0 comments on commit ff126ed

Please sign in to comment.