diff --git a/.changeset/fifty-turkeys-battle.md b/.changeset/fifty-turkeys-battle.md new file mode 100644 index 0000000000..b7b55b36dd --- /dev/null +++ b/.changeset/fifty-turkeys-battle.md @@ -0,0 +1,5 @@ +--- +'@leafygreen-ui/date-picker': patch +--- + +Modify `DatePickerMenu.stories.tsx` to exclude the current date, as it caused daily chromatic changes. \ No newline at end of file diff --git a/.changeset/gorgeous-rabbits-notice.md b/.changeset/gorgeous-rabbits-notice.md new file mode 100644 index 0000000000..e8d83f4b86 --- /dev/null +++ b/.changeset/gorgeous-rabbits-notice.md @@ -0,0 +1,5 @@ +--- +'@leafygreen-ui/date-picker': patch +--- + +Applies a CSS transition duration of 100ms to enhance the hover and focus styles on calendar cells. \ No newline at end of file diff --git a/.changeset/popular-hats-travel.md b/.changeset/popular-hats-travel.md deleted file mode 100644 index ce62779bce..0000000000 --- a/.changeset/popular-hats-travel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@leafygreen-ui/popover': patch ---- - -Adds `@types/react-transition-group` as a dependency of `Popover`. This ensures that any components extending `PopoverProps` are typed correctly. diff --git a/.changeset/stale-dryers-unite.md b/.changeset/stale-dryers-unite.md new file mode 100644 index 0000000000..ea34eaea07 --- /dev/null +++ b/.changeset/stale-dryers-unite.md @@ -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) diff --git a/.changeset/strange-pumpkins-invent.md b/.changeset/strange-pumpkins-invent.md new file mode 100644 index 0000000000..273a311be8 --- /dev/null +++ b/.changeset/strange-pumpkins-invent.md @@ -0,0 +1,5 @@ +--- +'@leafygreen-ui/marketing-modal': patch +--- + +Sets the default `closeIconColor` to correctly be 'default' (`CloseIconColor.Default`) diff --git a/.changeset/tricky-games-worry.md b/.changeset/tricky-games-worry.md new file mode 100644 index 0000000000..1eb020c656 --- /dev/null +++ b/.changeset/tricky-games-worry.md @@ -0,0 +1,5 @@ +--- +'@leafygreen-ui/modal': patch +--- + +Sets the `CloseIconColor` enum to be readonly (`as const`). Improves TypeScript Intellisense/autocomplete diff --git a/.changeset/yellow-items-marry.md b/.changeset/yellow-items-marry.md new file mode 100644 index 0000000000..9a5b41f706 --- /dev/null +++ b/.changeset/yellow-items-marry.md @@ -0,0 +1,6 @@ +--- +'@leafygreen-ui/combobox': minor +--- + +Exports `ComboboxOptionProps` & `ComboboxGroupProps`. +Internal refactor of `type` file organization. diff --git a/packages/combobox/src/Combobox.story.tsx b/packages/combobox/src/Combobox.story.tsx index 9c7244679a..beedc55839 100644 --- a/packages/combobox/src/Combobox.story.tsx +++ b/packages/combobox/src/Combobox.story.tsx @@ -17,7 +17,7 @@ import { SearchState, State, TruncationLocation, -} from './Combobox.types'; +} from './types'; import { Combobox, ComboboxOption, ComboboxProps } from '.'; const wrapperStyle = css` diff --git a/packages/combobox/src/Combobox/Combobox.spec.tsx b/packages/combobox/src/Combobox/Combobox.spec.tsx index c6102e1f83..9f83660757 100644 --- a/packages/combobox/src/Combobox/Combobox.spec.tsx +++ b/packages/combobox/src/Combobox/Combobox.spec.tsx @@ -17,7 +17,7 @@ import isUndefined from 'lodash/isUndefined'; import Button from '@leafygreen-ui/button'; import { keyMap } from '@leafygreen-ui/lib'; -import { OptionObject } from '../Combobox.types'; +import { OptionObject } from '../ComboboxOption/ComboboxOption.types'; import { defaultOptions, getComboboxJSX, diff --git a/packages/combobox/src/Combobox/Combobox.styles.ts b/packages/combobox/src/Combobox/Combobox.styles.ts index d99759e9d1..081d602f59 100644 --- a/packages/combobox/src/Combobox/Combobox.styles.ts +++ b/packages/combobox/src/Combobox/Combobox.styles.ts @@ -11,13 +11,13 @@ import { typeScales, } from '@leafygreen-ui/tokens'; -import { ComboboxSize as Size, Overflow } from '../Combobox.types'; import { chipClassName, chipWrapperPaddingY, fontSize, lineHeight, } from '../ComboboxChip/ComboboxChip.styles'; +import { ComboboxSize as Size, Overflow } from '../types'; /** * Util to get the chip height diff --git a/packages/combobox/src/Combobox/Combobox.tsx b/packages/combobox/src/Combobox/Combobox.tsx index 6dbeebb182..94f3c2bb2a 100644 --- a/packages/combobox/src/Combobox/Combobox.tsx +++ b/packages/combobox/src/Combobox/Combobox.tsx @@ -36,24 +36,23 @@ import LeafyGreenProvider, { import { consoleOnce, isComponentType, keyMap } from '@leafygreen-ui/lib'; import { Description, Label } from '@leafygreen-ui/typography'; +import { ComboboxChip } from '../ComboboxChip'; +import { ComboboxContext } from '../ComboboxContext'; +import { InternalComboboxGroup } from '../ComboboxGroup'; +import { ComboboxMenu } from '../ComboboxMenu'; +import { OptionObject } from '../ComboboxOption'; +import { InternalComboboxOption } from '../ComboboxOption'; import { ComboboxElement, - ComboboxProps, ComboboxSize, getNullSelection, onChangeType, - OptionObject, Overflow, SearchState, SelectValueType, State, TruncationLocation, -} from '../Combobox.types'; -import { ComboboxChip } from '../ComboboxChip'; -import { ComboboxContext } from '../ComboboxContext'; -import { InternalComboboxGroup } from '../ComboboxGroup'; -import { ComboboxMenu } from '../ComboboxMenu'; -import { InternalComboboxOption } from '../ComboboxOption'; +} from '../types'; import { checkScrollPosition, flattenChildren, @@ -91,6 +90,7 @@ import { labelDescriptionLargeStyles, multiselectInputElementStyle, } from './Combobox.styles'; +import { ComboboxProps } from './Combobox.types'; /** * Combobox is a combination of a Select and TextInput, diff --git a/packages/combobox/src/Combobox.types.ts b/packages/combobox/src/Combobox/Combobox.types.ts similarity index 51% rename from packages/combobox/src/Combobox.types.ts rename to packages/combobox/src/Combobox/Combobox.types.ts index 4884ccacba..44f4afdfb6 100644 --- a/packages/combobox/src/Combobox.types.ts +++ b/packages/combobox/src/Combobox/Combobox.types.ts @@ -1,90 +1,17 @@ -import { ComponentPropsWithoutRef, ReactElement, ReactNode } from 'react'; +import { ReactNode } from 'react'; -import { type ChipProps, TruncationLocation } from '@leafygreen-ui/chip'; +import { type ChipProps } from '@leafygreen-ui/chip'; import { Either, HTMLElementProps } from '@leafygreen-ui/lib'; import { PortalControlProps } from '@leafygreen-ui/popover'; -export { TruncationLocation }; - -/** - * Prop Enums & Types - */ - -export const ComboboxElement = { - Input: 'Input', - ClearButton: 'ClearButton', - FirstChip: 'FirstChip', - LastChip: 'LastChip', - MiddleChip: 'MiddleChip', - Combobox: 'Combobox', - Menu: 'Menu', -} as const; -export type ComboboxElement = - (typeof ComboboxElement)[keyof typeof ComboboxElement]; - -/** - * Prop types - */ - -export const ComboboxSize = { - XSmall: 'xsmall', - Small: 'small', - Default: 'default', - Large: 'large', -} as const; -export type ComboboxSize = (typeof ComboboxSize)[keyof typeof ComboboxSize]; - -export const Overflow = { - /** - * Combobox will be set to a fixed width, and will expand its height based on the number of Chips selected - */ - expandY: 'expand-y', - /** - * Combobox will be set to a fixed height and width (default 100% of container). Chips will be scrollable left-right - */ - scrollX: 'scroll-x', - /** - * @deprecated - */ - expandX: 'expand-x', -} as const; -export type Overflow = (typeof Overflow)[keyof typeof Overflow]; - -export const State = { - none: 'none', - error: 'error', -} as const; -export type State = (typeof State)[keyof typeof State]; - -export const SearchState = { - unset: 'unset', - error: 'error', - loading: 'loading', -} as const; -export type SearchState = (typeof SearchState)[keyof typeof SearchState]; - -/** - * Generic Typing - */ - -export type SelectValueType = M extends true - ? Array - : string | null; - -export type onChangeType = M extends true - ? (value: SelectValueType) => void - : (value: SelectValueType) => void; - -// Returns the correct empty state for multiselcect / single select -export function getNullSelection( - multiselect: M, -): SelectValueType { - if (multiselect) { - return [] as Array as SelectValueType; - } else { - return null as SelectValueType; - } -} +import { + ComboboxSize, + onChangeType, + Overflow, + SearchState, + SelectValueType, + State, +} from '../types'; /** * Combobox Props @@ -234,112 +161,3 @@ export type ComboboxProps = Either< BaseComboboxProps & ComboboxMultiselectProps, 'label' | 'aria-label' >; - -/** - * Combobox Option Props - */ - -type ListItemProps = Omit, 'onClick' | 'value'>; - -interface SharedComboboxOptionProps { - /** - * The internal value of the option. Used as the identifier in Combobox `initialValue`, value and filteredOptions. - * When undefined, this is set to `_.kebabCase(displayName)` - */ - value?: string; - - /** - * The display value of the option. Used as the rendered string within the menu and chips. - * When undefined, this is set to `value` - */ - displayName?: string; - - /** - * The icon to display to the left of the option in the menu. - */ - glyph?: ReactElement; - - /** - * Defines whether the option is disabled. - * Node: disabled options are still rendered in the menu, but not selectable. - */ - disabled?: boolean; - - /** - * Styling Prop - */ - className?: string; - - /** - * Optional descriptive text under the displayName. - */ - description?: string; - - /** - * Callback fired when an option is clicked. - */ - onClick?: ( - event: React.SyntheticEvent, - value: string, - ) => void; -} - -type RequiredComboboxOptionProps = Required< - Pick ->; - -type BaseComboboxOptionProps = ListItemProps & SharedComboboxOptionProps; - -export type ComboboxOptionProps = Either< - BaseComboboxOptionProps, - 'value' | 'displayName' ->; - -export interface OptionObject - extends Pick, - RequiredComboboxOptionProps { - isDisabled: boolean; - hasGlyph?: boolean; -} - -export interface InternalComboboxOptionProps - extends ListItemProps, - Omit, - RequiredComboboxOptionProps { - isSelected: boolean; - isFocused: boolean; - setSelected: () => void; - index: number; -} - -/** - * Combobox Group Props - */ - -export interface ComboboxGroupProps { - /** - * Label for the group of options - */ - label: string; - - /** - * Options in the group. Must be one or more `ComboboxOption` components - */ - children: React.ReactNode; - - /** - * Styling prop - */ - className?: string; -} - -/** - * Combobox Chip - */ - -export interface ComboboxChipProps { - displayName: string; - isFocused: boolean; - onRemove: () => void; - onFocus: () => void; -} diff --git a/packages/combobox/src/Combobox/index.ts b/packages/combobox/src/Combobox/index.ts index 661776cd10..a4d068dd9e 100644 --- a/packages/combobox/src/Combobox/index.ts +++ b/packages/combobox/src/Combobox/index.ts @@ -1 +1,6 @@ export { Combobox } from './Combobox'; +export { + type BaseComboboxProps, + type ComboboxMultiselectProps, + type ComboboxProps, +} from './Combobox.types'; diff --git a/packages/combobox/src/ComboboxChip/ComboboxChip.styles.ts b/packages/combobox/src/ComboboxChip/ComboboxChip.styles.ts index ecac2276c0..0aae5bbade 100644 --- a/packages/combobox/src/ComboboxChip/ComboboxChip.styles.ts +++ b/packages/combobox/src/ComboboxChip/ComboboxChip.styles.ts @@ -3,7 +3,7 @@ import { css } from '@leafygreen-ui/emotion'; import { createUniqueClassName } from '@leafygreen-ui/lib'; import { typeScales } from '@leafygreen-ui/tokens'; -import { ComboboxSize } from '../Combobox.types'; +import { ComboboxSize } from '../types'; export const chipClassName = createUniqueClassName('combobox-chip'); diff --git a/packages/combobox/src/ComboboxChip/ComboboxChip.tsx b/packages/combobox/src/ComboboxChip/ComboboxChip.tsx index 698aca284a..0c5a52828b 100644 --- a/packages/combobox/src/ComboboxChip/ComboboxChip.tsx +++ b/packages/combobox/src/ComboboxChip/ComboboxChip.tsx @@ -5,14 +5,11 @@ import { cx } from '@leafygreen-ui/emotion'; import { useForwardedRef } from '@leafygreen-ui/hooks'; import { keyMap } from '@leafygreen-ui/lib'; -import { - ComboboxChipProps, - Overflow, - TruncationLocation, -} from '../Combobox.types'; import { ComboboxContext } from '../ComboboxContext'; +import { Overflow, TruncationLocation } from '../types'; import { chipClassName, chipSizeStyles } from './ComboboxChip.styles'; +import { ComboboxChipProps } from './ComboboxChip.types'; export const ComboboxChip = React.forwardRef< HTMLSpanElement, diff --git a/packages/combobox/src/ComboboxChip/ComboboxChip.types.ts b/packages/combobox/src/ComboboxChip/ComboboxChip.types.ts new file mode 100644 index 0000000000..41a093433d --- /dev/null +++ b/packages/combobox/src/ComboboxChip/ComboboxChip.types.ts @@ -0,0 +1,6 @@ +export interface ComboboxChipProps { + displayName: string; + isFocused: boolean; + onRemove: () => void; + onFocus: () => void; +} diff --git a/packages/combobox/src/ComboboxContext/ComboboxContext.tsx b/packages/combobox/src/ComboboxContext/ComboboxContext.tsx index 4ce684fc88..c4c95cab12 100644 --- a/packages/combobox/src/ComboboxContext/ComboboxContext.tsx +++ b/packages/combobox/src/ComboboxContext/ComboboxContext.tsx @@ -6,7 +6,7 @@ import { SearchState, State, TruncationLocation, -} from '../Combobox.types'; +} from '../types'; export interface ComboboxData { multiselect: boolean; diff --git a/packages/combobox/src/ComboboxContext/index.ts b/packages/combobox/src/ComboboxContext/index.ts index 540bd78bdd..4fe9dde10c 100644 --- a/packages/combobox/src/ComboboxContext/index.ts +++ b/packages/combobox/src/ComboboxContext/index.ts @@ -1 +1 @@ -export { ComboboxContext } from './ComboboxContext'; +export { ComboboxContext, defaultContext } from './ComboboxContext'; diff --git a/packages/combobox/src/ComboboxGroup/ComboboxGroup.tsx b/packages/combobox/src/ComboboxGroup/ComboboxGroup.tsx index 38f96d4aac..bfb264e1bc 100644 --- a/packages/combobox/src/ComboboxGroup/ComboboxGroup.tsx +++ b/packages/combobox/src/ComboboxGroup/ComboboxGroup.tsx @@ -5,13 +5,12 @@ import { cx } from '@leafygreen-ui/emotion'; import { useIdAllocator } from '@leafygreen-ui/hooks'; import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; -import { ComboboxGroupProps } from '../Combobox.types'; - import { comboboxGroupLabel, comboboxGroupLabelThemeStyle, comboboxGroupStyle, } from './ComboboxGroup.styles'; +import { ComboboxGroupProps } from './ComboboxGroup.types'; /** * @internal diff --git a/packages/combobox/src/ComboboxGroup/ComboboxGroup.types.ts b/packages/combobox/src/ComboboxGroup/ComboboxGroup.types.ts new file mode 100644 index 0000000000..90f27e5c85 --- /dev/null +++ b/packages/combobox/src/ComboboxGroup/ComboboxGroup.types.ts @@ -0,0 +1,20 @@ +/** + * Combobox Group Props + */ + +export interface ComboboxGroupProps { + /** + * Label for the group of options + */ + label: string; + + /** + * Options in the group. Must be one or more `ComboboxOption` components + */ + children: React.ReactNode; + + /** + * Styling prop + */ + className?: string; +} diff --git a/packages/combobox/src/ComboboxGroup/index.ts b/packages/combobox/src/ComboboxGroup/index.ts index 7c814d2caa..544293821c 100644 --- a/packages/combobox/src/ComboboxGroup/index.ts +++ b/packages/combobox/src/ComboboxGroup/index.ts @@ -1 +1,2 @@ export { ComboboxGroup, InternalComboboxGroup } from './ComboboxGroup'; +export { type ComboboxGroupProps } from './ComboboxGroup.types'; diff --git a/packages/combobox/src/ComboboxMenu/ComboboxMenu.tsx b/packages/combobox/src/ComboboxMenu/ComboboxMenu.tsx index 8ccc8738a1..24c926335a 100644 --- a/packages/combobox/src/ComboboxMenu/ComboboxMenu.tsx +++ b/packages/combobox/src/ComboboxMenu/ComboboxMenu.tsx @@ -9,7 +9,7 @@ import { palette } from '@leafygreen-ui/palette'; import Popover, { PortalControlProps } from '@leafygreen-ui/popover'; import { Error } from '@leafygreen-ui/typography'; -import { ComboboxProps } from '../Combobox.types'; +import { ComboboxProps } from '../Combobox'; import { ComboboxContext } from '../ComboboxContext'; import { diff --git a/packages/combobox/src/ComboboxMenu/Menu.styles.ts b/packages/combobox/src/ComboboxMenu/Menu.styles.ts index 15696e35d8..fbf52bada0 100644 --- a/packages/combobox/src/ComboboxMenu/Menu.styles.ts +++ b/packages/combobox/src/ComboboxMenu/Menu.styles.ts @@ -5,8 +5,8 @@ import { Theme } from '@leafygreen-ui/lib'; import { palette } from '@leafygreen-ui/palette'; import { fontFamilies, spacing } from '@leafygreen-ui/tokens'; -import { ComboboxSize as Size } from '../Combobox.types'; import { fontSize, lineHeight } from '../ComboboxChip/ComboboxChip.styles'; +import { ComboboxSize as Size } from '../types'; export const menuItemPadding: Record = { [Size.XSmall]: { x: 12, y: 8 }, diff --git a/packages/combobox/src/ComboboxOption/ComboboxOption.stories.tsx b/packages/combobox/src/ComboboxOption/ComboboxOption.stories.tsx index 53699c8eb1..24917f8720 100644 --- a/packages/combobox/src/ComboboxOption/ComboboxOption.stories.tsx +++ b/packages/combobox/src/ComboboxOption/ComboboxOption.stories.tsx @@ -5,8 +5,7 @@ import Icon from '@leafygreen-ui/icon'; import LeafyGreenProvider from '@leafygreen-ui/leafygreen-provider'; import { StoryMetaType, StoryType } from '@leafygreen-ui/lib'; -import { ComboboxContext } from '../ComboboxContext'; -import { defaultContext } from '../ComboboxContext/ComboboxContext'; +import { ComboboxContext, defaultContext } from '../ComboboxContext'; import { InternalComboboxOption } from './ComboboxOption'; diff --git a/packages/combobox/src/ComboboxOption/ComboboxOption.styles.ts b/packages/combobox/src/ComboboxOption/ComboboxOption.styles.ts index 8f84a98bf2..f8257fe2b0 100644 --- a/packages/combobox/src/ComboboxOption/ComboboxOption.styles.ts +++ b/packages/combobox/src/ComboboxOption/ComboboxOption.styles.ts @@ -4,12 +4,12 @@ import { Theme } from '@leafygreen-ui/lib'; import { palette } from '@leafygreen-ui/palette'; import { fontWeights, spacing } from '@leafygreen-ui/tokens'; -import { ComboboxSize } from '../Combobox.types'; import { fontSize, lineHeight } from '../ComboboxChip/ComboboxChip.styles'; import { getMenuItemHeight, menuItemPadding, } from '../ComboboxMenu/Menu.styles'; +import { ComboboxSize } from '../types'; /** * Styles diff --git a/packages/combobox/src/ComboboxOption/ComboboxOption.tsx b/packages/combobox/src/ComboboxOption/ComboboxOption.tsx index bed81fde7f..0370171c0e 100644 --- a/packages/combobox/src/ComboboxOption/ComboboxOption.tsx +++ b/packages/combobox/src/ComboboxOption/ComboboxOption.tsx @@ -6,12 +6,8 @@ import { useForwardedRef, useIdAllocator } from '@leafygreen-ui/hooks'; import { InputOption, InputOptionContent } from '@leafygreen-ui/input-option'; import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; -import { - ComboboxOptionProps, - ComboboxSize, - InternalComboboxOptionProps, -} from '../Combobox.types'; import { ComboboxContext } from '../ComboboxContext'; +import { ComboboxSize } from '../types'; import { wrapJSX } from '../utils'; import { @@ -20,6 +16,10 @@ import { multiselectIconLargePosition, multiselectIconPosition, } from './ComboboxOption.styles'; +import { + ComboboxOptionProps, + InternalComboboxOptionProps, +} from './ComboboxOption.types'; import { getGlyphs } from './getGlyphs'; /** diff --git a/packages/combobox/src/ComboboxOption/ComboboxOption.types.ts b/packages/combobox/src/ComboboxOption/ComboboxOption.types.ts new file mode 100644 index 0000000000..dce2c02dc3 --- /dev/null +++ b/packages/combobox/src/ComboboxOption/ComboboxOption.types.ts @@ -0,0 +1,80 @@ +import { ComponentPropsWithoutRef, ReactElement } from 'react'; + +import { Either } from '@leafygreen-ui/lib'; + +/** + * Combobox Option Props + */ + +type ListItemProps = Omit, 'onClick' | 'value'>; + +interface SharedComboboxOptionProps { + /** + * The internal value of the option. Used as the identifier in Combobox `initialValue`, value and filteredOptions. + * When undefined, this is set to `_.kebabCase(displayName)` + */ + value?: string; + + /** + * The display value of the option. Used as the rendered string within the menu and chips. + * When undefined, this is set to `value` + */ + displayName?: string; + + /** + * The icon to display to the left of the option in the menu. + */ + glyph?: ReactElement; + + /** + * Defines whether the option is disabled. + * Node: disabled options are still rendered in the menu, but not selectable. + */ + disabled?: boolean; + + /** + * Styling Prop + */ + className?: string; + + /** + * Optional descriptive text under the displayName. + */ + description?: string; + + /** + * Callback fired when an option is clicked. + */ + onClick?: ( + event: React.SyntheticEvent, + value: string, + ) => void; +} + +type RequiredComboboxOptionProps = Required< + Pick +>; + +type BaseComboboxOptionProps = ListItemProps & SharedComboboxOptionProps; + +export type ComboboxOptionProps = Either< + BaseComboboxOptionProps, + 'value' | 'displayName' +>; + +export interface OptionObject + extends Pick, + RequiredComboboxOptionProps { + isDisabled: boolean; + hasGlyph?: boolean; +} + +export interface InternalComboboxOptionProps + extends ListItemProps, + Omit, + RequiredComboboxOptionProps { + isSelected: boolean; + isFocused: boolean; + setSelected: () => void; + index: number; +} diff --git a/packages/combobox/src/ComboboxOption/getGlyphs.tsx b/packages/combobox/src/ComboboxOption/getGlyphs.tsx index d2ed10495e..a76bdab32b 100644 --- a/packages/combobox/src/ComboboxOption/getGlyphs.tsx +++ b/packages/combobox/src/ComboboxOption/getGlyphs.tsx @@ -5,7 +5,7 @@ import { cx } from '@leafygreen-ui/emotion'; import Icon, { isComponentGlyph } from '@leafygreen-ui/icon'; import { Theme } from '@leafygreen-ui/lib'; -import { ComboboxSize } from '../Combobox.types'; +import { ComboboxSize } from '../types'; import { checkBoxBaseStyles, diff --git a/packages/combobox/src/ComboboxOption/index.ts b/packages/combobox/src/ComboboxOption/index.ts index a789486e3d..d495dcda82 100644 --- a/packages/combobox/src/ComboboxOption/index.ts +++ b/packages/combobox/src/ComboboxOption/index.ts @@ -1 +1,5 @@ export { ComboboxOption, InternalComboboxOption } from './ComboboxOption'; +export { + type ComboboxOptionProps, + type OptionObject, +} from './ComboboxOption.types'; diff --git a/packages/combobox/src/index.ts b/packages/combobox/src/index.ts index 5c8f6613d2..077a402a0e 100644 --- a/packages/combobox/src/index.ts +++ b/packages/combobox/src/index.ts @@ -1,4 +1,3 @@ -export { Combobox } from './Combobox'; -export { type ComboboxProps } from './Combobox.types'; -export { ComboboxGroup } from './ComboboxGroup'; -export { ComboboxOption } from './ComboboxOption'; +export { Combobox, type ComboboxProps } from './Combobox'; +export { ComboboxGroup, type ComboboxGroupProps } from './ComboboxGroup'; +export { ComboboxOption, type ComboboxOptionProps } from './ComboboxOption'; diff --git a/packages/combobox/src/types/Combobox.types.ts b/packages/combobox/src/types/Combobox.types.ts new file mode 100644 index 0000000000..bd7011a8a1 --- /dev/null +++ b/packages/combobox/src/types/Combobox.types.ts @@ -0,0 +1,92 @@ +/** + * Identifier for individual component elements within the Combobox + */ +export const ComboboxElement = { + Input: 'Input', + ClearButton: 'ClearButton', + FirstChip: 'FirstChip', + LastChip: 'LastChip', + MiddleChip: 'MiddleChip', + Combobox: 'Combobox', + Menu: 'Menu', +} as const; +export type ComboboxElement = + (typeof ComboboxElement)[keyof typeof ComboboxElement]; + +/** + * The rendered size of the Combobox + */ +export const ComboboxSize = { + XSmall: 'xsmall', + Small: 'small', + Default: 'default', + Large: 'large', +} as const; +export type ComboboxSize = (typeof ComboboxSize)[keyof typeof ComboboxSize]; + +/** + * Defines the behavior of the Combobox when there are more selected chips than will fit in the input + */ +export const Overflow = { + /** + * Combobox will be set to a fixed width, and will expand its height based on the number of Chips selected + */ + expandY: 'expand-y', + /** + * Combobox will be set to a fixed height and width (default 100% of container). Chips will be scrollable left-right + */ + scrollX: 'scroll-x', + /** + * @deprecated + */ + expandX: 'expand-x', +} as const; +export type Overflow = (typeof Overflow)[keyof typeof Overflow]; + +/** The error state of the Combobox */ +export const State = { + none: 'none', + error: 'error', +} as const; +export type State = (typeof State)[keyof typeof State]; + +/** The search state of the Combobox */ +export const SearchState = { + unset: 'unset', + error: 'error', + loading: 'loading', +} as const; +export type SearchState = (typeof SearchState)[keyof typeof SearchState]; + +/** + * The type expected in the `value` or `initialValue` prop. + * Also the type passed as an argument to `onChange`. + * + * Type varies depending on the value of `multiselect` + */ +export type SelectValueType = M extends true + ? Array + : string | null; + +/** + * Callback event fired when the value changes + * + * Type varies depending on the value of `multiselect` + */ +// TODO: onChange signature should match the native event handler signature +export type onChangeType = M extends true + ? (value: SelectValueType) => void + : (value: SelectValueType) => void; + +/** + * Returns the correct empty state for multiselect / single select + */ +export function getNullSelection( + multiselect: M, +): SelectValueType { + if (multiselect) { + return [] as Array as SelectValueType; + } else { + return null as SelectValueType; + } +} diff --git a/packages/combobox/src/types/index.ts b/packages/combobox/src/types/index.ts new file mode 100644 index 0000000000..f94d725102 --- /dev/null +++ b/packages/combobox/src/types/index.ts @@ -0,0 +1,11 @@ +export { + ComboboxElement, + ComboboxSize, + getNullSelection, + onChangeType, + Overflow, + SearchState, + SelectValueType, + State, +} from './Combobox.types'; +export { TruncationLocation } from '@leafygreen-ui/chip'; diff --git a/packages/combobox/src/utils/ComboboxTestUtils.tsx b/packages/combobox/src/utils/ComboboxTestUtils.tsx index f9fcb67382..04678f14bf 100644 --- a/packages/combobox/src/utils/ComboboxTestUtils.tsx +++ b/packages/combobox/src/utils/ComboboxTestUtils.tsx @@ -15,11 +15,8 @@ import isNull from 'lodash/isNull'; import LeafyGreenProvider from '@leafygreen-ui/leafygreen-provider'; -import { - BaseComboboxProps, - ComboboxMultiselectProps, - OptionObject, -} from '../Combobox.types'; +import { BaseComboboxProps, ComboboxMultiselectProps } from '../Combobox'; +import { OptionObject } from '../ComboboxOption'; import { Combobox, ComboboxGroup, ComboboxOption } from '..'; export interface NestedObject { diff --git a/packages/combobox/src/utils/OptionObjectUtils.ts b/packages/combobox/src/utils/OptionObjectUtils.ts index bc1a013f62..0178622245 100644 --- a/packages/combobox/src/utils/OptionObjectUtils.ts +++ b/packages/combobox/src/utils/OptionObjectUtils.ts @@ -1,4 +1,4 @@ -import { OptionObject } from '../Combobox.types'; +import { OptionObject } from '../ComboboxOption'; /** * * @param value diff --git a/packages/combobox/src/utils/flattenChildren.tsx b/packages/combobox/src/utils/flattenChildren.tsx index 006db98338..8ea52d592a 100644 --- a/packages/combobox/src/utils/flattenChildren.tsx +++ b/packages/combobox/src/utils/flattenChildren.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { isComponentType } from '@leafygreen-ui/lib'; -import { OptionObject } from '../Combobox.types'; +import { OptionObject } from '../ComboboxOption'; import { getNameAndValue } from './getNameAndValue'; diff --git a/packages/combobox/src/utils/getNameAndValue.ts b/packages/combobox/src/utils/getNameAndValue.ts index d7888c9e15..7e239fbbf5 100644 --- a/packages/combobox/src/utils/getNameAndValue.ts +++ b/packages/combobox/src/utils/getNameAndValue.ts @@ -1,6 +1,6 @@ import kebabCase from 'lodash/kebabCase'; -import { ComboboxOptionProps } from '../Combobox.types'; +import { ComboboxOptionProps } from '../ComboboxOption'; /** * diff --git a/packages/date-picker/README.md b/packages/date-picker/README.md index 23e4a1de37..152a16480d 100644 --- a/packages/date-picker/README.md +++ b/packages/date-picker/README.md @@ -59,6 +59,10 @@ const [date, setDate] = useState(); | `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 diff --git a/packages/date-picker/src/DatePicker/DatePicker.spec.tsx b/packages/date-picker/src/DatePicker/DatePicker.spec.tsx index 7cd1afade7..6f53096cd1 100644 --- a/packages/date-picker/src/DatePicker/DatePicker.spec.tsx +++ b/packages/date-picker/src/DatePicker/DatePicker.spec.tsx @@ -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, @@ -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 */} + {/* @ts-expect-error - does not accept usePortal prop */} + + @@ -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="" /> ; }); diff --git a/packages/date-picker/src/DatePicker/DatePicker.tsx b/packages/date-picker/src/DatePicker/DatePicker.tsx index 43da9e94b0..e17b4b1ad6 100644 --- a/packages/date-picker/src/DatePicker/DatePicker.tsx +++ b/packages/date-picker/src/DatePicker/DatePicker.tsx @@ -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, }; diff --git a/packages/date-picker/src/DatePicker/DatePickerContent/DatePickerContent.tsx b/packages/date-picker/src/DatePicker/DatePickerContent/DatePickerContent.tsx index ae36cd5ecb..9ca8d1f725 100644 --- a/packages/date-picker/src/DatePicker/DatePickerContent/DatePickerContent.tsx +++ b/packages/date-picker/src/DatePicker/DatePickerContent/DatePickerContent.tsx @@ -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'; @@ -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, + ModifiedPopoverPropkeys + >({ ...sharedProps }, modifiedPopoverPropNames); + const prevValue = usePrevious(value); const prevMin = usePrevious(min); const prevMax = usePrevious(max); @@ -114,6 +124,7 @@ export const DatePickerContent = forwardRef< id={menuId} refEl={formFieldRef} onKeyDown={handleDatePickerKeyDown} + {...popoverProps} /> ); diff --git a/packages/date-picker/src/DatePicker/DatePickerMenu/DatePickerMenu.stories.tsx b/packages/date-picker/src/DatePicker/DatePickerMenu/DatePickerMenu.stories.tsx index 04dfec8fa6..b17a0eddec 100644 --- a/packages/date-picker/src/DatePicker/DatePickerMenu/DatePickerMenu.stories.tsx +++ b/packages/date-picker/src/DatePicker/DatePickerMenu/DatePickerMenu.stories.tsx @@ -78,41 +78,12 @@ export default meta; type DatePickerMenuStoryType = StoryObj; -export const Basic: DatePickerMenuStoryType = { - render: args => { - MockDate.reset(); - const [value, setValue] = useState(null); - - const date = new Date(Date.now()); - const props = omit(args, [...contextPropNames, 'isOpen']); - const refEl = useRef(null); - return ( - -
- - Today:{' '} - {new Intl.DateTimeFormat('en-GB', { - dateStyle: 'full', - }).format(date)} - - -
-
- ); - }, -}; - -Basic.parameters = { - chromatic: { disableSnapshot: true }, -}; - export const WithValue: DatePickerMenuStoryType = { render: args => { MockDate.reset(); const props = omit(args, [...contextPropNames, 'isOpen']); const refEl = useRef(null); - const date = new Date(Date.now()); const withValueDate = new Date(2023, Month.September, 10); return ( {}} >
- - Today:{' '} - {new Intl.DateTimeFormat('en-GB', { - dateStyle: 'full', - }).format(date)} - -

Value:{' '} {new Intl.DateTimeFormat('en-GB', { @@ -156,15 +120,14 @@ export const MockedToday: DatePickerMenuStoryType = { const props = omit(args, [...contextPropNames, 'isOpen']); const refEl = useRef(null); - const date = new Date(Date.now()); return (
- Today:{' '} + Mocked Today:{' '} {new Intl.DateTimeFormat('en-GB', { dateStyle: 'full', - }).format(date)} + }).format(mockToday)}
@@ -188,8 +151,8 @@ type DatePickerMenuInteractionTestType = Omit & * Chromatic Interaction tests */ -export const InitialFocusToday: DatePickerMenuInteractionTestType = { - ...Basic, +export const InitialFocusMockedToday: DatePickerMenuInteractionTestType = { + ...MockedToday, play: async ctx => { const { findByRole } = within(ctx.canvasElement.parentElement!); await findByRole('listbox'); @@ -208,7 +171,7 @@ export const InitialFocusValue: DatePickerMenuInteractionTestType = { export const LeftArrowKey: DatePickerMenuInteractionTestType = { ...WithValue, play: async ctx => { - await InitialFocusToday.play(ctx); + await InitialFocusMockedToday.play(ctx); userEvent.keyboard('{arrowleft}'); }, }; @@ -216,7 +179,7 @@ export const LeftArrowKey: DatePickerMenuInteractionTestType = { export const RightArrowKey: DatePickerMenuInteractionTestType = { ...WithValue, play: async ctx => { - await InitialFocusToday.play(ctx); + await InitialFocusMockedToday.play(ctx); userEvent.keyboard('{arrowright}'); }, }; @@ -224,7 +187,7 @@ export const RightArrowKey: DatePickerMenuInteractionTestType = { export const UpArrowKey: DatePickerMenuInteractionTestType = { ...WithValue, play: async ctx => { - await InitialFocusToday.play(ctx); + await InitialFocusMockedToday.play(ctx); userEvent.keyboard('{arrowup}'); }, }; @@ -232,7 +195,7 @@ export const UpArrowKey: DatePickerMenuInteractionTestType = { export const DownArrowKey: DatePickerMenuInteractionTestType = { ...WithValue, play: async ctx => { - await InitialFocusToday.play(ctx); + await InitialFocusMockedToday.play(ctx); userEvent.keyboard('{arrowdown}'); }, }; @@ -240,7 +203,7 @@ export const DownArrowKey: DatePickerMenuInteractionTestType = { export const UpToPrevMonth: DatePickerMenuInteractionTestType = { ...WithValue, play: async ctx => { - await InitialFocusToday.play(ctx); + await InitialFocusMockedToday.play(ctx); userEvent.keyboard('{arrowup}{arrowup}'); }, }; @@ -248,7 +211,7 @@ export const UpToPrevMonth: DatePickerMenuInteractionTestType = { export const DownToNextMonth: DatePickerMenuInteractionTestType = { ...WithValue, play: async ctx => { - await InitialFocusToday.play(ctx); + await InitialFocusMockedToday.play(ctx); userEvent.keyboard('{arrowdown}{arrowdown}{arrowdown}'); }, }; diff --git a/packages/date-picker/src/DatePicker/DatePickerMenu/DatePickerMenu.tsx b/packages/date-picker/src/DatePicker/DatePickerMenu/DatePickerMenu.tsx index 4537871f66..6ec51d5109 100644 --- a/packages/date-picker/src/DatePicker/DatePickerMenu/DatePickerMenu.tsx +++ b/packages/date-picker/src/DatePicker/DatePickerMenu/DatePickerMenu.tsx @@ -42,7 +42,7 @@ import { DatePickerMenuProps } from './DatePickerMenu.types'; import { DatePickerMenuHeader } from './DatePickerMenuHeader'; export const DatePickerMenu = forwardRef( - ({ onKeyDown, ...rest }: DatePickerMenuProps, fwdRef) => { + ({ onKeyDown, onExited, ...rest }: DatePickerMenuProps, fwdRef) => { const { min, max, isInRange, isOpen, setIsDirty, timeZone } = useSharedDatePickerContext(); const { @@ -182,6 +182,7 @@ export const DatePickerMenu = forwardRef( */ const handleMenuTransitionExited: ExitHandler = () => { if (!isOpen) { + onExited?.(); closeMenu(); } }; diff --git a/packages/date-picker/src/shared/components/Calendar/CalendarCell/CalendarCell.styles.ts b/packages/date-picker/src/shared/components/Calendar/CalendarCell/CalendarCell.styles.ts index f2c7b4c50c..39d86c289f 100644 --- a/packages/date-picker/src/shared/components/Calendar/CalendarCell/CalendarCell.styles.ts +++ b/packages/date-picker/src/shared/components/Calendar/CalendarCell/CalendarCell.styles.ts @@ -5,6 +5,7 @@ import { fontFamilies, fontWeights, spacing, + transitionDuration, typeScales, } from '@leafygreen-ui/tokens'; @@ -32,6 +33,7 @@ export const calendarCellStyles = css` text-align: center; padding: 0; z-index: 0; + transition: color ${transitionDuration.faster}ms ease-in-out; `; type ThemedStateStyles = Record>; @@ -308,6 +310,8 @@ export const indicatorBaseStyles = css` z-index: 1; border-radius: 100%; outline-offset: -1px; + transition: box-shadow ${transitionDuration.faster}ms ease-in-out, + background-color ${transitionDuration.faster}ms ease-in-out; `; export const cellTextStyles = css` diff --git a/packages/date-picker/src/shared/context/SharedDatePickerContext.types.ts b/packages/date-picker/src/shared/context/SharedDatePickerContext.types.ts index 0581d08379..9908f0594d 100644 --- a/packages/date-picker/src/shared/context/SharedDatePickerContext.types.ts +++ b/packages/date-picker/src/shared/context/SharedDatePickerContext.types.ts @@ -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 { @@ -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 @@ -25,14 +27,17 @@ export type SharedDatePickerProviderProps = Omit< type AriaLabelKeysWithoutLabel = Exclude; +type OptionalModifiedPopoverProps = Partial; + /** * The values in context */ export interface SharedDatePickerContextProps extends Omit< Required, - 'state' | AriaLabelKeysWithoutLabel + 'state' | AriaLabelKeysWithoutLabel | ModifiedPopoverPropkeys >, + OptionalModifiedPopoverProps, UseDatePickerErrorNotificationsReturnObject { /** The earliest date accepted */ min: Date; diff --git a/packages/date-picker/src/shared/context/SharedDatePickerContext.utils.ts b/packages/date-picker/src/shared/context/SharedDatePickerContext.utils.ts index e7d4981ae5..25952c1a0d 100644 --- a/packages/date-picker/src/shared/context/SharedDatePickerContext.utils.ts +++ b/packages/date-picker/src/shared/context/SharedDatePickerContext.utils.ts @@ -13,6 +13,7 @@ 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 { @@ -20,9 +21,32 @@ import { 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 = [ + 'scrollContainer', + 'portalContainer', + 'portalClassName', + 'align', + 'justify', + 'spacing', + 'adjustOnMutation', + 'popoverZIndex', + 'onEnter', + 'onEntering', + 'onEntered', + 'onExit', + 'onExiting', + 'onExited', + 'contentClassName', +]; + /** * Prop names that are in both DatePickerProps and SharedDatePickerProviderProps * */ @@ -43,6 +67,7 @@ export const contextPropNames: Array = [ 'state', 'autoComplete', 'darkMode', + ...modifiedPopoverPropNames, ]; /** The default context value */ diff --git a/packages/date-picker/src/shared/context/index.ts b/packages/date-picker/src/shared/context/index.ts index e05fe34680..ddd2e2af47 100644 --- a/packages/date-picker/src/shared/context/index.ts +++ b/packages/date-picker/src/shared/context/index.ts @@ -11,4 +11,6 @@ export { type ContextPropKeys, contextPropNames, defaultSharedDatePickerContext, + type ModifiedPopoverPropkeys, + modifiedPopoverPropNames, } from './SharedDatePickerContext.utils'; diff --git a/packages/date-picker/src/shared/types/BaseDatePickerProps.types.ts b/packages/date-picker/src/shared/types/BaseDatePickerProps.types.ts index db4064906e..adf2a821fb 100644 --- a/packages/date-picker/src/shared/types/BaseDatePickerProps.types.ts +++ b/packages/date-picker/src/shared/types/BaseDatePickerProps.types.ts @@ -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. @@ -85,4 +92,5 @@ export type BaseDatePickerProps = { */ autoComplete?: AutoComplete; } & DarkModeProps & - AriaLabelPropsWithLabel; + AriaLabelPropsWithLabel & + ModifiedPopoverProps; diff --git a/packages/marketing-modal/src/MarketingModal/MarketingModal.tsx b/packages/marketing-modal/src/MarketingModal/MarketingModal.tsx index ad58a21b28..3aaf6b2bde 100644 --- a/packages/marketing-modal/src/MarketingModal/MarketingModal.tsx +++ b/packages/marketing-modal/src/MarketingModal/MarketingModal.tsx @@ -38,7 +38,7 @@ const MarketingModal = ({ linkText, darkMode: darkModeProp, graphicStyle = GraphicStyle.Center, - closeIconColor = CloseIconColor.Dark, + closeIconColor = CloseIconColor.Default, blobPosition = BlobPosition.TopLeft, showBlob = false, disclaimer, diff --git a/packages/modal/src/Modal/Modal.types.ts b/packages/modal/src/Modal/Modal.types.ts index fd322b7e5d..0deeeff6f2 100644 --- a/packages/modal/src/Modal/Modal.types.ts +++ b/packages/modal/src/Modal/Modal.types.ts @@ -6,7 +6,7 @@ export const CloseIconColor = { Default: 'default', Dark: 'dark', Light: 'light', -}; +} as const; export type CloseIconColor = (typeof CloseIconColor)[keyof typeof CloseIconColor]; diff --git a/packages/popover/CHANGELOG.md b/packages/popover/CHANGELOG.md index d8263e8b3d..99d0dfdccd 100644 --- a/packages/popover/CHANGELOG.md +++ b/packages/popover/CHANGELOG.md @@ -1,5 +1,11 @@ # @leafygreen-ui/popover +## 11.2.2 + +### Patch Changes + +- 0e49ec9c: Adds `@types/react-transition-group` as a dependency of `Popover`. This ensures that any components extending `PopoverProps` are typed correctly. + ## 11.2.1 ### Patch Changes diff --git a/packages/popover/package.json b/packages/popover/package.json index 7c6e13d839..e8b67fbb70 100644 --- a/packages/popover/package.json +++ b/packages/popover/package.json @@ -1,6 +1,6 @@ { "name": "@leafygreen-ui/popover", - "version": "11.2.1", + "version": "11.2.2", "description": "LeafyGreen UI Kit Popover", "main": "./dist/index.js", "module": "./dist/esm/index.js", diff --git a/packages/table/CHANGELOG.md b/packages/table/CHANGELOG.md index 0b3c460da5..725d63b3d2 100644 --- a/packages/table/CHANGELOG.md +++ b/packages/table/CHANGELOG.md @@ -1,5 +1,11 @@ # @leafygreen-ui/table +## 12.3.0 + +### Minor Changes + +- 91372fff: useLeafygreenTable now exposes an `scrollToIndex` method for virtualized tables. + ## 12.2.0 ### Minor Changes diff --git a/packages/table/README.md b/packages/table/README.md index 910a3444c1..acd08d289c 100644 --- a/packages/table/README.md +++ b/packages/table/README.md @@ -188,7 +188,7 @@ Setting this prop will indicate that the Table component is being used with the #### `useVirtualScrolling` -`react-virtual`'s `useVirtual` hook will be called if this option is set. When this option is set, the object returned by `useLeafygreenTable` will include `virtualRows` and `totalSize`. Refer to our [Storybook deployment](https://mongodb.github.io/leafygreen-ui) to find examples. +`react-virtual`'s `useVirtual` hook will be called if this option is set. When this option is set, the object returned by `useLeafygreenTable` will include `virtualRows`, `totalSize` and `scrollToIndex`. Refer to our [Storybook deployment](https://mongodb.github.io/leafygreen-ui) to find examples. > Note that the number of virtual rows rendered depends on the height passed to the `Table` component. For a reasonably performant use of virtual scrolling, ensure that there is a height set on the component to reduce the number of virtual rows rendered. diff --git a/packages/table/package.json b/packages/table/package.json index 1d8055648c..db2b142fbc 100644 --- a/packages/table/package.json +++ b/packages/table/package.json @@ -1,6 +1,6 @@ { "name": "@leafygreen-ui/table", - "version": "12.2.0", + "version": "12.3.0", "description": "leafyGreen UI Kit Table", "main": "./dist/index.js", "module": "./dist/esm/index.js", diff --git a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx index 7070e7f751..1f5ac239d4 100644 --- a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx +++ b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx @@ -83,6 +83,7 @@ function useLeafyGreenTable({ ...(useVirtualScrolling && { virtualRows: _rowVirtualizer.virtualItems, totalSize: _rowVirtualizer.totalSize, + scrollToIndex: _rowVirtualizer.scrollToIndex, }), hasSelectableRows, } as LeafyGreenTable; diff --git a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.types.ts b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.types.ts index f8cef2f587..3e429635c4 100644 --- a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.types.ts +++ b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.types.ts @@ -54,7 +54,7 @@ export interface LeafyGreenTableOptions< /** LeafyGreen extension of `useReactTable` {@link Table}*/ export interface LeafyGreenTable extends Table>, - Pick { + Pick { virtualRows?: Array; hasSelectableRows: boolean; }