Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(Timepicker-compat): clearIcon not working in freeform #31324

Merged
merged 5 commits into from
May 27, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🕵 fluentuiv9 Open the Visual Regressions report to inspect the affected screenshots

Avatar Converged 1 screenshots
Image Name Diff(in Pixels) Image Type
Avatar Converged.badgeMask.normal.chromium.png 2 Changed
Card Converged - Selectable 8 screenshots
Image Name Diff(in Pixels) Image Type
Card Converged - Selectable.appearance focusable + selectable.click.chromium.png 0 Added
Card Converged - Selectable.appearance focusable + selectable.hover.chromium.png 0 Added
Card Converged - Selectable.appearance focusable + selectable.normal.chromium.png 0 Added
Card Converged - Selectable.appearance focusable + selectable.selected.chromium.png 0 Added
Card Converged - Selectable.appearance selectable - Filled.click.chromium.png 0 Added
Card Converged - Selectable.appearance selectable - Filled.hover.chromium.png 0 Added
Card Converged - Selectable.appearance selectable - Filled.normal.chromium.png 0 Added
Card Converged - Selectable.appearance selectable - Filled.selected.chromium.png 0 Added

"type": "patch",
"comment": "fix: clear icon not working with freeform",
"packageName": "@fluentui/react-timepicker-compat",
"email": "yuanboxue@microsoft.com",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const mount = (element: JSX.Element) => {
mountBase(<FluentProvider theme={teamsLightTheme}>{element}</FluentProvider>);
};

const Default = ({ freeform }: Pick<TimePickerProps, 'freeform'>) => {
const Default = ({ freeform, clearable }: Pick<TimePickerProps, 'freeform' | 'clearable'>) => {
const [selectedTimeText, setSelectedTimeText] = React.useState<string | undefined>(undefined);
const onTimeChange: TimePickerProps['onTimeChange'] = (_ev, data) => {
setSelectedTimeText(data.selectedTimeText);
Expand All @@ -18,6 +18,7 @@ const Default = ({ freeform }: Pick<TimePickerProps, 'freeform'>) => {
<div>
<TimePicker
freeform={freeform}
clearable={clearable}
startHour={10}
endHour={20}
increment={60}
Expand All @@ -29,7 +30,7 @@ const Default = ({ freeform }: Pick<TimePickerProps, 'freeform'>) => {
);
};

const Controlled = ({ freeform }: Pick<TimePickerProps, 'freeform'>) => {
const Controlled = ({ freeform, clearable }: Pick<TimePickerProps, 'freeform' | 'clearable'>) => {
const [selectedTime, setSelectedTime] = React.useState<Date | null>(null);
const [selectedTimeText, setSelectedTimeText] = React.useState<string | undefined>(undefined);
const [value, setValue] = React.useState<string>('');
Expand All @@ -47,6 +48,7 @@ const Controlled = ({ freeform }: Pick<TimePickerProps, 'freeform'>) => {
<div>
<TimePicker
freeform={freeform}
clearable={clearable}
startHour={10}
endHour={20}
increment={60}
Expand All @@ -63,6 +65,7 @@ const Controlled = ({ freeform }: Pick<TimePickerProps, 'freeform'>) => {

const inputSelector = '[role="combobox"]';
const optionSelector = (index: number) => `[role="option"]:nth-of-type(${index + 1})`;
const clearIconSelector = '.fui-Combobox__clearIcon';

describe('TimePicker', () => {
[
Expand Down Expand Up @@ -143,6 +146,22 @@ describe('TimePicker', () => {
cy.get('#selected-time-text').should('have.text', '10:30');
});
});

describe('clearable', () => {
it(`${name} should clear input on clear icon click`, () => {
mount(<Example clearable />);
cy.get(inputSelector).click().realPress('Enter').get(inputSelector).should('have.value', '10:00');
cy.get(clearIconSelector).click().get(inputSelector).should('have.value', '');
cy.get('#selected-time-text').should('have.text', '');
});

it(`freeform ${name} should clear input on clear icon click`, () => {
mount(<Example clearable freeform />);
cy.get(inputSelector).click().type('14{enter}').get(inputSelector).should('have.value', '14:00');
cy.get(clearIconSelector).click().get(inputSelector).should('have.value', '');
cy.get('#selected-time-text').should('have.text', '');
});
});
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,13 @@ export const useTimePicker_unstable = (props: TimePickerProps, ref: React.Ref<HT
return selectedOption ? [selectedOption.key] : [];
}, [options, selectedTime]);

const clearIconRef = React.useRef<HTMLSpanElement>(null);
const handleOptionSelect: ComboboxProps['onOptionSelect'] = useEventCallback((e, data) => {
if (freeform && data.optionValue === undefined) {
if (
freeform &&
data.optionValue === undefined &&
!(rest.clearable && e.type === 'click' && e.currentTarget === clearIconRef.current)
) {
// Combobox clears selection when input value not matching any option; but we allow this case in freeform TimePicker.
return;
}
Expand Down Expand Up @@ -117,8 +122,15 @@ export const useTimePicker_unstable = (props: TimePickerProps, ref: React.Ref<HT
[dateEndAnchor, dateStartAnchor, hourCycle, showSeconds],
);

const mergedClearIconRef = useMergedRefs(baseState.clearIcon?.ref, clearIconRef);
const state: TimePickerState = {
...baseState,
clearIcon: baseState.clearIcon
? {
...baseState.clearIcon,
ref: mergedClearIconRef,
}
: undefined,
freeform,
parseTimeStringToDate: parseTimeStringToDateInProps ?? defaultParseTimeStringToDate,
submittedText,
Expand Down