Skip to content

Commit

Permalink
Merge branch 'main' into downshift-actions
Browse files Browse the repository at this point in the history
  • Loading branch information
tay1orjones authored Aug 9, 2024
2 parents 248dd68 + 6a32844 commit 59b44dd
Show file tree
Hide file tree
Showing 25 changed files with 425 additions and 114 deletions.
7 changes: 5 additions & 2 deletions e2e/components/ComboBox/ComboBox-test.avt.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ test.describe('@avt ComboBox', () => {
await expect(combobox).toBeFocused();
await page.keyboard.press('Enter');
await expect(menu).toBeVisible();
await page.keyboard.press('ArrowDown');
// Navigation inside the menu
// move to first option
await expect(optionOne).toHaveClass(
Expand Down Expand Up @@ -122,15 +123,17 @@ test.describe('@avt ComboBox', () => {
await page.keyboard.press('Enter');
await page.keyboard.press('ArrowDown');
await page.keyboard.press('Enter');
await expect(combobox).toHaveValue('Option 1');
await expect(combobox).toHaveValue(
'An example option that is really long to show what should be done to handle long text'
);
await page.keyboard.press('Escape');

// should open and select option 2
await page.keyboard.press('Enter');
await page.keyboard.press('ArrowDown');
await page.keyboard.press('ArrowDown');
await page.keyboard.press('Enter');
await expect(combobox).toHaveValue('Option 2');
await expect(combobox).toHaveValue('Option 1');
await page.keyboard.press('Escape');
});
});
2 changes: 1 addition & 1 deletion e2e/components/DatePicker/DatePicker-test.avt.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ test.describe('@avt DatePicker', () => {
await page.keyboard.press('Enter');
await page.keyboard.press('Enter');
await expect(
page.locator('input#date-picker-input-id-finish')
page.locator('input#date-picker-input-id-start')
).toBeFocused();
await expect(page.locator('div.flatpickr-calendar')).not.toHaveClass(
/open/
Expand Down
1 change: 1 addition & 0 deletions e2e/components/FluidComboBox/FluidComboBox-test.avt.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ test.describe('@avt FluidComboBox', () => {
await expect(combobox).toBeFocused();
await page.keyboard.press('Enter');
await expect(menu).toBeVisible();
await page.keyboard.press('ArrowDown');
// Navigation inside the menu
// move to first option
await expect(optionOne).toHaveClass(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ test.describe('@avt FluidDatePicker', () => {
await page.keyboard.press('ArrowDown');
await page.keyboard.press('Enter');
await expect(
page.locator('input#date-picker-input-id-finish')
page.locator('input#date-picker-input-id-start')
).toBeFocused();
await expect(page.locator('div.flatpickr-calendar')).not.toHaveClass(
/open/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ test.describe('@avt FluidMultiSelect', () => {
await expect(toggleButton).toBeFocused();
await page.keyboard.press('Space');
await expect(menu).toBeVisible();
await page.keyboard.press('ArrowDown');
// Navigation inside the menu
// Focus on first element by default
await expect(
Expand Down Expand Up @@ -175,6 +176,7 @@ test.describe('@avt FluidMultiSelect', () => {
await expect(toggleButton).toBeFocused();
await page.keyboard.press('Space');
await expect(menu).toBeVisible();
await page.keyboard.press('ArrowDown');
// Navigation inside the menu
// Focus on first element by default
await expect(
Expand Down
3 changes: 2 additions & 1 deletion e2e/components/MultiSelect/MultiSelect-test.avt.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,11 @@ test.describe('@avt MultiSelect', () => {
page.getByRole('option', {
name: 'An example option that is really long to show what should be done to handle long text',
})
).toHaveClass(
).not.toHaveClass(
'cds--list-box__menu-item cds--list-box__menu-item--highlighted'
);
// select first option (should select with enter and space)
await page.keyboard.press('ArrowDown');
await page.keyboard.press('Enter');
await expect(
page.getByRole('option', {
Expand Down
10 changes: 5 additions & 5 deletions e2e/components/Toggle/Toggle-test.avt.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,11 @@ test.describe('@avt Toggle', () => {
theme: 'white',
},
});
const toggleSwitch = page.getByRole('switch');
await page.keyboard.press('Tab');
await expect(page.getByRole('switch')).toBeVisible();
await page.keyboard.press('Space');
page.getByText('Off');
await page.keyboard.press('Space');
page.getByText('On');
await expect(toggleSwitch).toBeVisible();
await expect(toggleSwitch).toHaveAttribute('aria-checked', 'true');
await page.keyboard.press('Enter');
await expect(toggleSwitch).toHaveAttribute('aria-checked', 'false');
});
});
4 changes: 2 additions & 2 deletions packages/react/src/components/ComboBox/ComboBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ const ComboBox = forwardRef(
case FunctionToggleMenu:
case ToggleButtonClick:
if (changes.isOpen && !changes.selectedItem) {
return { ...changes, highlightedIndex: 0 };
return { ...changes };
}
return changes;

Expand Down Expand Up @@ -594,7 +594,7 @@ const ComboBox = forwardRef(

const inputClasses = cx(`${prefix}--text-input`, {
[`${prefix}--text-input--empty`]: !inputValue,
[`${prefix}--combo-box--input--focus`]: isFocused && !isFluid,
[`${prefix}--combo-box--input--focus`]: isFocused,
});

// needs to be Capitalized for react to render it correctly
Expand Down
3 changes: 2 additions & 1 deletion packages/react/src/components/DataTable/TableSelectRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
*/

import PropTypes from 'prop-types';
import React, { useId } from 'react';
import React from 'react';
import classNames from 'classnames';
import InlineCheckbox from '../InlineCheckbox';
import RadioButton from '../RadioButton';
import { useId } from '../../internal/useId';
import { usePrefix } from '../../internal/usePrefix';
import deprecate from '../../prop-types/deprecate';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ const TableToolbarSearch = ({

const expanded = controlled ? expandedProp : expandedState;
const [value, setValue] = useState(defaultValue || '');
const uniqueId = useId();
const uniqueId = useId('table-toolbar-search');
const [focusTarget, setFocusTarget] = useState<RefObject<HTMLElement> | null>(
null
);
Expand Down Expand Up @@ -213,11 +213,7 @@ const TableToolbarSearch = ({
disabled={disabled}
className={searchClasses}
value={value}
id={
typeof id !== 'undefined'
? id
: `table-toolbar-search-${uniqueId.toString()}`
}
id={typeof id !== 'undefined' ? id : uniqueId}
labelText={labelText || t('carbon.table.toolbar.search.label')}
placeholder={placeholder || t('carbon.table.toolbar.search.placeholder')}
onChange={onChange}
Expand Down
102 changes: 80 additions & 22 deletions packages/react/src/components/DatePicker/DatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -443,11 +443,17 @@ const DatePicker = React.forwardRef(function DatePicker(

const lastStartValue = useRef('');

interface CalendarCloseEvent {
selectedDates: Date[];
dateStr: string;
instance: object; //This is `Intance` of flatpicker
}
const [calendarCloseEvent, setCalendarCloseEvent] =
useState<CalendarCloseEvent | null>(null);

// fix datepicker deleting the selectedDate when the calendar closes
const onCalendarClose = (selectedDates, dateStr) => {
endInputField?.current?.focus();
calendarRef?.current?.calendarContainer?.classList.remove('open');
setTimeout(() => {
const handleCalendarClose = useCallback(
(selectedDates, dateStr, instance) => {
if (
lastStartValue.current &&
selectedDates[0] &&
Expand All @@ -461,21 +467,29 @@ const DatePicker = React.forwardRef(function DatePicker(
);
}
if (onClose) {
onClose(
calendarRef.current.selectedDates,
dateStr,
calendarRef.current
);
onClose(selectedDates, dateStr, instance);
}
});
},
[onClose]
);
const onCalendarClose = (selectedDates, dateStr, instance, e) => {
if (e && e.type === 'clickOutside') {
return;
}
setCalendarCloseEvent({ selectedDates, dateStr, instance });
};
useEffect(() => {
if (calendarCloseEvent) {
const { selectedDates, dateStr, instance } = calendarCloseEvent;
handleCalendarClose(selectedDates, dateStr, instance);
setCalendarCloseEvent(null);
}
}, [calendarCloseEvent, handleCalendarClose]);

const endInputField = useRef<HTMLTextAreaElement>(null);
const calendarRef: any | undefined = useRef(null);
const savedOnChange = useSavedCallback(onChange);
const savedOnClose = useSavedCallback(
datePickerType === 'range' ? onCalendarClose : onClose
);

const savedOnOpen = useSavedCallback(onOpen);

const datePickerClasses = cx(`${prefix}--date-picker`, {
Expand Down Expand Up @@ -610,6 +624,7 @@ const DatePicker = React.forwardRef(function DatePicker(
const { current: end } = endInputField;
const flatpickerconfig: any = {
inline: inline ?? false,
onClose: onCalendarClose,
disableMobile: true,
defaultDate: value,
closeOnSelect: closeOnSelect,
Expand Down Expand Up @@ -653,7 +668,7 @@ const DatePicker = React.forwardRef(function DatePicker(
savedOnChange(...args);
}
},
onClose: savedOnClose,

onReady: onHook,
onMonthChange: onHook,
onYearChange: onHook,
Expand Down Expand Up @@ -772,14 +787,7 @@ const DatePicker = React.forwardRef(function DatePicker(
}
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
savedOnChange,
savedOnClose,
savedOnOpen,
readOnly,
closeOnSelect,
hasInput,
]);
}, [savedOnChange, savedOnOpen, readOnly, closeOnSelect, hasInput]);

// this hook allows consumers to access the flatpickr calendar
// instance for cases where functions like open() or close()
Expand Down Expand Up @@ -831,6 +839,56 @@ const DatePicker = React.forwardRef(function DatePicker(
calendarRef.current.set('inline', inline);
}
}, [inline]);
useEffect(() => {
//when value prop is set to empty, this clears the faltpicker's calendar instance and text input
if (value === '') {
calendarRef.current?.clear();
if (startInputField.current) {
startInputField.current.value = '';
}

if (endInputField.current) {
endInputField.current.value = '';
}
}
}, [value]);

useEffect(() => {
let isMouseDown = false;

const handleMouseDown = (event) => {
if (
calendarRef.current &&
calendarRef.current.isOpen &&
!calendarRef.current.calendarContainer.contains(event.target) &&
!startInputField.current.contains(event.target) &&
!endInputField.current?.contains(event.target)
) {
isMouseDown = true;
// Close the calendar immediately on mousedown
closeCalendar(event);
}
};

const closeCalendar = (event) => {
calendarRef.current.close();
// Remove focus from endDate calendar input
if (document.activeElement instanceof HTMLElement) {
document.activeElement.blur();
}
onCalendarClose(
calendarRef.current.selectedDates,
'',
calendarRef.current,
{ type: 'clickOutside' }
);
};
document.addEventListener('mousedown', handleMouseDown, true);

return () => {
document.removeEventListener('mousedown', handleMouseDown, true);
};
}, [calendarRef, startInputField, endInputField, onCalendarClose]);

useEffect(() => {
if (calendarRef?.current?.set) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,20 @@ import { match, keys } from '../../../internal/keyboard';
*/
export default (config) => (fp) => {
const { inputFrom, inputTo, lastStartValue } = config;
/**
* Handles `click` outside to close calendar
*/
const handleClickOutside = (event) => {
if (
!fp.isOpen ||
fp.calendarContainer.contains(event.target) ||
event.target === inputFrom ||
event.target === inputTo
) {
return;
}
fp.close();
};
/**
* Handles `keydown` event.
*/
Expand Down Expand Up @@ -127,6 +141,7 @@ export default (config) => (fp) => {
inputTo.removeEventListener('blur', handleBlur, true);
}
inputFrom.removeEventListener('keydown', handleKeydown, true);
document.removeEventListener('click', handleClickOutside, true);
};

/**
Expand All @@ -140,6 +155,7 @@ export default (config) => (fp) => {
inputTo.addEventListener('keydown', handleKeydown, true);
inputTo.addEventListener('blur', handleBlur, true);
}
document.addEventListener('click', handleClickOutside, true);
};

/**
Expand Down
Loading

0 comments on commit 59b44dd

Please sign in to comment.