Skip to content

Commit

Permalink
LG-3930: Date Picker extend popover props (#2179)
Browse files Browse the repository at this point in the history
* wip adding popover props

* rename

* add documentaion

* add more to tests

* changeset

* testing

* update change to minor

* pass the correct props

* remove comment
  • Loading branch information
shaneeza authored Jan 25, 2024
1 parent e7d206e commit e0b4080
Show file tree
Hide file tree
Showing 10 changed files with 141 additions and 7 deletions.
5 changes: 5 additions & 0 deletions .changeset/stale-dryers-unite.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@leafygreen-ui/date-picker': minor
---

Extends [Popover props](https://www.mongodb.design/component/popover/documentation/) but omits the following props: `usePortal`, `refEl`, `children`, `className`, `onClick`, and `active`. [LG-3930](https://jira.mongodb.org/browse/LG-3930)
4 changes: 4 additions & 0 deletions packages/date-picker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ const [date, setDate] = useState<Date>();
| `autoComplete` | `'off'` \| `'on'` \| `'bday'` | Whether the input should autofill | `off` |
| `darkMode` | `boolean` | Render the component in dark mode. | `false` |

## Popover Props

Date Picker extends [Popover props](https://www.mongodb.design/component/popover/documentation/) but omits the following props: `usePortal`, `refEl`, `children`, `className`, `onClick`, and `active`.

## 🔎 Glossary

### Date format
Expand Down
62 changes: 62 additions & 0 deletions packages/date-picker/src/DatePicker/DatePicker.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,14 @@ describe('packages/date-picker', () => {
expect(menuContainerEl).toBeInTheDocument();
});

test('appends to the end of the DOM', async () => {
const { findMenuElements, container } = renderDatePicker({
initialOpen: true,
});
const { menuContainerEl } = await findMenuElements();
expect(container).not.toContain(menuContainerEl);
});

test('menu is initially closed when rendered with `initialOpen` and `disabled`', async () => {
const { findMenuElements } = renderDatePicker({
initialOpen: true,
Expand Down Expand Up @@ -3574,12 +3582,51 @@ describe('packages/date-picker', () => {
});
});

describe('fires Popover callbacks', () => {
test('opening the calendar fires the `onEnter*` callbacks', async () => {
const onEnter = jest.fn();
const onEntering = jest.fn();
const onEntered = jest.fn();

const { inputContainer } = renderDatePicker({
onEnter,
onEntering,
onEntered,
});
userEvent.click(inputContainer);

expect(onEnter).toHaveBeenCalled();
expect(onEntering).toHaveBeenCalled();
await waitFor(() => expect(onEntered).toHaveBeenCalled());
});

test('closing the calendar fires the `onExit*` callbacks', async () => {
const onExit = jest.fn();
const onExiting = jest.fn();
const onExited = jest.fn();
const { calendarButton } = renderDatePicker({
onExit,
onExiting,
onExited,
initialOpen: true,
});
userEvent.click(calendarButton);

expect(onExit).toHaveBeenCalled();
expect(onExiting).toHaveBeenCalled();
await waitFor(() => expect(onExited).toHaveBeenCalled());
});
});

// eslint-disable-next-line jest/no-disabled-tests
test.skip('Types behave as expected', () => {
<>
{/* @ts-expect-error - needs label/aria-label/aria-labelledby */}
<DatePicker />

{/* @ts-expect-error - does not accept usePortal prop */}
<DatePicker usePortal />

<DatePicker label="Pick a date" />
<DatePicker aria-label="Pick a date" />
<DatePicker aria-labelledby="Pick a date" />
Expand All @@ -3602,6 +3649,21 @@ describe('packages/date-picker', () => {
initialOpen={false}
autoComplete="off"
darkMode={false}
portalClassName=""
scrollContainer={{} as HTMLElement}
portalContainer={{} as HTMLElement}
align="bottom"
justify="start"
spacing={10}
adjustOnMutation={true}
popoverZIndex={1}
onEnter={() => {}}
onEntering={() => {}}
onEntered={() => {}}
onExit={() => {}}
onExiting={() => {}}
onExited={() => {}}
contentClassName=""
/>
</>;
});
Expand Down
11 changes: 11 additions & 0 deletions packages/date-picker/src/DatePicker/DatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,15 @@ DatePicker.propTypes = {
initialOpen: PropTypes.bool,
autoComplete: PropTypes.oneOf(Object.values(AutoComplete)),
darkMode: PropTypes.bool,
// Popover Props
popoverZIndex: PropTypes.number,
portalContainer:
typeof window !== 'undefined'
? PropTypes.instanceOf(Element)
: PropTypes.any,
scrollContainer:
typeof window !== 'undefined'
? PropTypes.instanceOf(Element)
: PropTypes.any,
portalClassName: PropTypes.string,
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,14 @@ import {
useForwardedRef,
usePrevious,
} from '@leafygreen-ui/hooks';
import { keyMap } from '@leafygreen-ui/lib';
import { keyMap, pickAndOmit } from '@leafygreen-ui/lib';

import { useSharedDatePickerContext } from '../../shared/context';
import {
ModifiedPopoverPropkeys,
modifiedPopoverPropNames,
SharedDatePickerContextProps,
useSharedDatePickerContext,
} from '../../shared/context';
import { useDatePickerContext } from '../DatePickerContext';
import { DatePickerInput } from '../DatePickerInput';
import { DatePickerMenu } from '../DatePickerMenu';
Expand All @@ -25,10 +30,15 @@ export const DatePickerContent = forwardRef<
HTMLDivElement,
DatePickerContentProps
>(({ ...rest }: DatePickerContentProps, fwdRef) => {
const { min, max, isOpen, menuId, disabled, isSelectOpen } =
const { min, max, isOpen, menuId, disabled, isSelectOpen, ...sharedProps } =
useSharedDatePickerContext();
const { value, closeMenu, handleValidation } = useDatePickerContext();

const [popoverProps] = pickAndOmit<
Partial<SharedDatePickerContextProps>,
ModifiedPopoverPropkeys
>({ ...sharedProps }, modifiedPopoverPropNames);

const prevValue = usePrevious(value);
const prevMin = usePrevious(min);
const prevMax = usePrevious(max);
Expand Down Expand Up @@ -114,6 +124,7 @@ export const DatePickerContent = forwardRef<
id={menuId}
refEl={formFieldRef}
onKeyDown={handleDatePickerKeyDown}
{...popoverProps}
/>
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import { DatePickerMenuProps } from './DatePickerMenu.types';
import { DatePickerMenuHeader } from './DatePickerMenuHeader';

export const DatePickerMenu = forwardRef<HTMLDivElement, DatePickerMenuProps>(
({ onKeyDown, ...rest }: DatePickerMenuProps, fwdRef) => {
({ onKeyDown, onExited, ...rest }: DatePickerMenuProps, fwdRef) => {
const { min, max, isInRange, isOpen, setIsDirty, timeZone } =
useSharedDatePickerContext();
const {
Expand Down Expand Up @@ -182,6 +182,7 @@ export const DatePickerMenu = forwardRef<HTMLDivElement, DatePickerMenuProps>(
*/
const handleMenuTransitionExited: ExitHandler<HTMLDivElement> = () => {
if (!isOpen) {
onExited?.();
closeMenu();
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import { AriaLabelPropsWithLabel } from '@leafygreen-ui/a11y';
import { DateType } from '@leafygreen-ui/date-utils';

import { BaseDatePickerProps, DatePickerState } from '../types';
import { ModifiedPopoverProps } from '../types/BaseDatePickerProps.types';

import { ModifiedPopoverPropkeys } from './SharedDatePickerContext.utils';
import { UseDatePickerErrorNotificationsReturnObject } from './useDatePickerErrorNotifications';

export interface StateNotification {
Expand All @@ -13,7 +15,7 @@ export interface StateNotification {
}
type AriaLabelKeys = keyof AriaLabelPropsWithLabel;

/** The props expected to pass int the provider */
/** The props expected to pass into the provider */
export type SharedDatePickerProviderProps = Omit<
BaseDatePickerProps,
AriaLabelKeys
Expand All @@ -25,14 +27,17 @@ export type SharedDatePickerProviderProps = Omit<

type AriaLabelKeysWithoutLabel = Exclude<AriaLabelKeys, 'label'>;

type OptionalModifiedPopoverProps = Partial<ModifiedPopoverProps>;

/**
* The values in context
*/
export interface SharedDatePickerContextProps
extends Omit<
Required<SharedDatePickerProviderProps>,
'state' | AriaLabelKeysWithoutLabel
'state' | AriaLabelKeysWithoutLabel | ModifiedPopoverPropkeys
>,
OptionalModifiedPopoverProps,
UseDatePickerErrorNotificationsReturnObject {
/** The earliest date accepted */
min: Date;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,40 @@ import { BaseFontSize, Size } from '@leafygreen-ui/tokens';

import { MAX_DATE, MIN_DATE } from '../constants';
import { AutoComplete, BaseDatePickerProps, DatePickerState } from '../types';
import { ModifiedPopoverProps } from '../types/BaseDatePickerProps.types';
import { getFormatParts } from '../utils';

import {
SharedDatePickerContextProps,
SharedDatePickerProviderProps,
} from './SharedDatePickerContext.types';

export type ModifiedPopoverPropkeys = keyof ModifiedPopoverProps;

export type ContextPropKeys = keyof SharedDatePickerProviderProps &
keyof BaseDatePickerProps;

/**
* Prop names that are extended from popoverProps
* */
export const modifiedPopoverPropNames: Array<ModifiedPopoverPropkeys> = [
'scrollContainer',
'portalContainer',
'portalClassName',
'align',
'justify',
'spacing',
'adjustOnMutation',
'popoverZIndex',
'onEnter',
'onEntering',
'onEntered',
'onExit',
'onExiting',
'onExited',
'contentClassName',
];

/**
* Prop names that are in both DatePickerProps and SharedDatePickerProviderProps
* */
Expand All @@ -43,6 +67,7 @@ export const contextPropNames: Array<ContextPropKeys> = [
'state',
'autoComplete',
'darkMode',
...modifiedPopoverPropNames,
];

/** The default context value */
Expand Down
2 changes: 2 additions & 0 deletions packages/date-picker/src/shared/context/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ export {
type ContextPropKeys,
contextPropNames,
defaultSharedDatePickerContext,
type ModifiedPopoverPropkeys,
modifiedPopoverPropNames,
} from './SharedDatePickerContext.utils';
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import { AriaLabelPropsWithLabel } from '@leafygreen-ui/a11y';
import { LocaleString } from '@leafygreen-ui/date-utils';
import { DarkModeProps } from '@leafygreen-ui/lib';
import { PopoverProps } from '@leafygreen-ui/popover';
import { BaseFontSize, Size } from '@leafygreen-ui/tokens';

import { AutoComplete, DatePickerState } from './types';

export type ModifiedPopoverProps = Omit<
PopoverProps,
'usePortal' | 'refEl' | 'children' | 'className' | 'active' | 'onClick'
>;

export type BaseDatePickerProps = {
/**
* A description for the date picker.
Expand Down Expand Up @@ -85,4 +92,5 @@ export type BaseDatePickerProps = {
*/
autoComplete?: AutoComplete;
} & DarkModeProps &
AriaLabelPropsWithLabel;
AriaLabelPropsWithLabel &
ModifiedPopoverProps;

0 comments on commit e0b4080

Please sign in to comment.