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

DateRange: make onCancel and onSubmit events optional (web) #3812

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion docs/examples/daterange/implementation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ export default function Example() {
<Popover
anchor={anchorRef.current}
idealDirection="down"
onDismiss={() => {}}
onDismiss={() => {
setShowComponent(false);
}}
positionRelativeToAnchor={false}
size="flexible"
>
Expand Down
2 changes: 2 additions & 0 deletions docs/pages/web/daterange.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,8 @@ Use \`dateValue\`, \`onDateChange\`, \`onDateError\`, \`onSubmit\` and \`onCance
Follow the implementation in the example to implement a controlled DateRange correctly.

When there’s not a date range selected, the call-to-action is disabled to prevent user errors.

\`onSubmit\` and \`onCancel\` are optional props. When not used, make sure DateRange is accessible implementing Popover's onDismiss correctly, as shown in the example. Otherwise, DateRange might not be able to be dismissed if the user performs no changes in the data.
`}
title="Controlled component"
>
Expand Down
26 changes: 26 additions & 0 deletions packages/gestalt-datepicker/src/DateRange.jsdom.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -258,4 +258,30 @@ describe('DateRange', () => {
await userEvent.click(secondaryEndDateButton);
expect(screen.getByDisplayValue('10 / 09 / 2024')).toBeInTheDocument();
});

it('renders apply and cancel buttons', () => {
render(
<DateRange
dateValue={{ startDate: new Date(), endDate: new Date() }}
onCancel={() => {}}
onDateChange={() => {}}
onDateError={{ startDate: () => {}, endDate: () => {} }}
onSubmit={() => {}}
/>,
);
expect(screen.getByRole('button', { name: /cancel/i })).toBeVisible();
expect(screen.getByRole('button', { name: /apply/i })).toBeVisible();
});

it('not renders apply and cancel buttons if event handlers are not present', () => {
render(
<DateRange
dateValue={{ startDate: new Date(), endDate: new Date() }}
onDateChange={() => {}}
onDateError={{ startDate: () => {}, endDate: () => {} }}
/>,
);
expect(screen.queryByRole('button', { name: /cancel/i })).toBeNull();
expect(screen.queryByRole('button', { name: /apply/i })).toBeNull();
});
});
58 changes: 30 additions & 28 deletions packages/gestalt-datepicker/src/DateRange.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,16 @@ type Props = {
/**
* Callback triggered when the user clicks the Cancel button to not persist the selected dates. It should be used to close DateRange. See the [controlled component variant](https://gestalt.pinterest.systems/web/daterange#Controlled-component) to learn more.
*/
onCancel: () => void;
onCancel?: () => void;
/**
* Callback triggered when the end date input loses focus. See the [error messaging variant](https://gestalt.pinterest.systems/web/daterange#Error-messaging) to learn more.
* Callback triggered when the start date or end date input loses focus. See the [error messaging variant](https://gestalt.pinterest.systems/web/daterange#Error-messaging) to learn more.
*/
onDateBlur?: {
startDate: (args: { event: React.FocusEvent<HTMLInputElement>; value: string }) => void;
endDate: (args: { event: React.FocusEvent<HTMLInputElement>; value: string }) => void;
};
/**
* Callback triggered when the end date input loses focus. See the [error messaging variant](https://gestalt.pinterest.systems/web/daterange#Error-messaging) to learn more.
* Callback triggered when the start date or end date secondary input loses focus. See the [error messaging variant](https://gestalt.pinterest.systems/web/daterange#Error-messaging) to learn more.
*/
onSecondaryDateBlur?: {
startDate: (args: { event: React.FocusEvent<HTMLInputElement>; value: string }) => void;
Expand All @@ -62,28 +62,28 @@ type Props = {
endDate: { value: Date | null },
) => void;
/**
* Callback triggered when the start date value entered is invalid. See the [error messaging variant](https://gestalt.pinterest.systems/web/daterange#Error-messaging) to learn more.
* Callback triggered when the start date or end date values entered are invalid. See the [error messaging variant](https://gestalt.pinterest.systems/web/daterange#Error-messaging) to learn more.
*/
onDateError?: {
startDate: (args: { errorMessage: string; value: Date | null }) => void;
endDate: (args: { errorMessage: string; value: Date | null }) => void;
};
/**
* Callback triggered when the start date value entered is invalid. See the [error messaging variant](https://gestalt.pinterest.systems/web/daterange#Error-messaging) to learn more.
* Callback triggered when the secondary start date or secondary end date values entered are invalid. See the [error messaging variant](https://gestalt.pinterest.systems/web/daterange#Error-messaging) to learn more.
*/
onSecondaryDateError?: {
startDate: (args: { errorMessage: string; value: Date | null }) => void;
endDate: (args: { errorMessage: string; value: Date | null }) => void;
};
/**
* Callback triggered when the user focus on the input of the start date DateField. See the [error messaging variant](https://gestalt.pinterest.systems/web/daterange#Error-messaging) to learn more.
* Callback triggered when the user focus on the start date or end date input DateFields. See the [error messaging variant](https://gestalt.pinterest.systems/web/daterange#Error-messaging) to learn more.
*/
onDateFocus?: {
startDate: (args: { event: React.FocusEvent<HTMLInputElement>; value: string }) => void;
endDate: (args: { event: React.FocusEvent<HTMLInputElement>; value: string }) => void;
};
/**
* Callback triggered when the user focus on the input of the start date DateField. See the [error messaging variant](https://gestalt.pinterest.systems/web/daterange#Error-messaging) to learn more.
* Callback triggered when the user focus on the start date or end date secondary input DateFields. See the [error messaging variant](https://gestalt.pinterest.systems/web/daterange#Error-messaging) to learn more.
*/
onSecondaryDateFocus?: {
startDate: (args: { event: React.FocusEvent<HTMLInputElement>; value: string }) => void;
Expand All @@ -92,7 +92,7 @@ type Props = {
/**
* Callback triggered when the user clicks the Apply button to persist the selected dates. It should be used to persist the dates selected and close the DateRange. See the [controlled component variant](https://gestalt.pinterest.systems/web/daterange#Controlled-component) to learn more.
*/
onSubmit: () => void;
onSubmit?: () => void;
/**
* An optional RadioGroup to provide preestablished date range options. See the [with RadioGroup variant](https://gestalt.pinterest.systems/web/daterange#With-RadioGroup) to learn more.
*/
Expand All @@ -106,11 +106,11 @@ type Props = {
*/
secondaryDateValue?: { startDate: Date | null; endDate: Date | null };
/**
* Customize your error message for the cases the user enters invalid start dates. See the [error messaging variant](https://gestalt.pinterest.systems/web/daterange#Error-messaging) to learn more.
* Customize your error message for the cases the user enters invalid dates. See the [error messaging variant](https://gestalt.pinterest.systems/web/daterange#Error-messaging) to learn more.
*/
dateErrorMessage?: { startDate: string | null; endDate: string | null };
/**
* Customize your error message for the cases the user enters invalid start dates. See the [error messaging variant](https://gestalt.pinterest.systems/web/daterange#Error-messaging) to learn more.
* Customize your error message for the cases the user enters invalid dates. See the [error messaging variant](https://gestalt.pinterest.systems/web/daterange#Error-messaging) to learn more.
*/
secondaryDateErrorMessage?: { startDate: string | null; endDate: string | null };
};
Expand Down Expand Up @@ -364,25 +364,27 @@ function DateRange({
}
/>
</Box>
<Flex.Item alignSelf={isMobile ? 'center' : 'end'}>
<Box marginBottom={4} marginEnd={4}>
<ButtonGroup>
<Button color="gray" onClick={() => onCancel()} text={cancelText} />
{onSubmit && onCancel ? (
<Flex.Item alignSelf={isMobile ? 'center' : 'end'}>
<Box marginBottom={4} marginEnd={4}>
<ButtonGroup>
<Button color="gray" onClick={() => onCancel()} text={cancelText} />

<Button
color="red"
disabled={
!!dateErrorMessage?.startDate ||
!!dateErrorMessage?.endDate ||
!dateValue.startDate ||
!dateValue.endDate
}
onClick={() => onSubmit()}
text={applyText}
/>
</ButtonGroup>
</Box>
</Flex.Item>
<Button
color="red"
disabled={
!!dateErrorMessage?.startDate ||
!!dateErrorMessage?.endDate ||
!dateValue.startDate ||
!dateValue.endDate
}
onClick={() => onSubmit()}
text={applyText}
/>
</ButtonGroup>
</Box>
</Flex.Item>
) : null}
</Flex>
</Box>
</Flex>
Expand Down
Loading