Skip to content

Commit

Permalink
LG-3312: Fix Combobox Props (#1859)
Browse files Browse the repository at this point in the history
* retype comboprops

* fix types

* fix ts error
  • Loading branch information
bruugey authored Jul 26, 2023
1 parent 038f621 commit 2603d7a
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 149 deletions.
5 changes: 5 additions & 0 deletions .changeset/strong-horses-confess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@leafygreen-ui/combobox': patch
---

Component props now properly inherit from `PopoverProps` interface
248 changes: 113 additions & 135 deletions packages/combobox/src/Combobox.types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ComponentPropsWithoutRef, ReactElement, ReactNode } from 'react';

import { Either, HTMLElementProps } from '@leafygreen-ui/lib';
import { PortalControlProps } from '@leafygreen-ui/popover';

/**
* Prop Enums & Types
Expand Down Expand Up @@ -132,141 +133,118 @@ export interface ComboboxMultiselectProps<M extends boolean> {
overflow?: M extends true ? Overflow : undefined;
}

export interface BaseComboboxProps
extends Omit<HTMLElementProps<'div'>, 'onChange'> {
/**
* Defines the Combobox Options by passing children. Must be `ComboboxOption` or `ComboboxGroup`
*/
children?: ReactNode;

/**
* An accessible label for the input, rendered in a <label> to the DOM
*/
label?: string;

/**
* An accessible label for the input, used only for screen-readers
*/
'aria-label'?: string;

/**
* A description for the input
*/
description?: string;

/**
* A placeholder for the input element. Uses the native `placeholder` attribute.
*/
placeholder?: string;

/**
* Disables all interaction with the component
*/
disabled?: boolean;

/**
* Defines the visual size of the component
*/
size?: ComboboxSize;

/**
* Toggles Dark Mode
*/
darkMode?: boolean;

/**
* The error state of the component. Defines whether the error message is displayed.
*/
state?: State;

/**
* The message shown below the input when state is `error`
*/
errorMessage?: string;

/**
* The state of search results. Toggles search messages within the menu.
*/
searchState?: SearchState;

/**
* A message shown within the menu when there are no options passed in as children, or `filteredOptions` is an empty array
*/
searchEmptyMessage?: string;

/**
* A message shown within the menu when searchState is `error`
*/
searchErrorMessage?: string;

/**
* A message shown within the menu when searchState is `loading`
*/
searchLoadingMessage?: string;

/**
* A callback called when the search input changes.
* Receives a single argument that is the current input value.
* Use this callback to set `searchState` and/or `filteredOptions` appropriately
*/
onFilter?: (value: string) => void;

/**
* Defines whether the Clear button appears to the right of the input.
*/
clearable?: boolean;

/**
* A callback fired when the Clear button is pressed.
* Fired _after_ `onChange`, and _before_ `onFilter`
*/
onClear?: (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;

/**
* An array used to define which options are displayed.
* Do not remove options from the JSX children, as this will affect the selected options
*/
filteredOptions?: Array<string>;

/**
* Defines where the ellipses appear in a Chip when the length exceeds the `chipCharacterLimit`
*/
chipTruncationLocation?: TruncationLocation;

/**
* Defined the character limit of a multiselect Chip before they start truncating.
* Note: the three ellipses dots are included in the character limit.
*/
chipCharacterLimit?: number;

/**
* Specifies that the popover content should be rendered at the end of the DOM,
* rather than in the DOM tree.
*
* default: `true`
*/
usePortal?: boolean;

/**
* When usePortal is `true`, specifies a class name to apply to the root element of the portal.
*/
portalClassName?: undefined;

/**
* When usePortal is `true`, specifies an element to portal within. The default behavior is to generate a div at the end of the document to render within.
*/
portalContainer?: null;

/**
* When usePortal is `true`, specifies the scrollable element to position relative to.
*/
scrollContainer?: null;

/**
* Number that controls the z-index of the popover element directly.
*/
popoverZIndex?: number;
}
export type BaseComboboxProps = Omit<HTMLElementProps<'div'>, 'onChange'> &
PortalControlProps & {
/**
* Defines the Combobox Options by passing children. Must be `ComboboxOption` or `ComboboxGroup`
*/
children?: ReactNode;

/**
* An accessible label for the input, rendered in a <label> to the DOM
*/
label?: string;

/**
* An accessible label for the input, used only for screen-readers
*/
'aria-label'?: string;

/**
* A description for the input
*/
description?: string;

/**
* A placeholder for the input element. Uses the native `placeholder` attribute.
*/
placeholder?: string;

/**
* Disables all interaction with the component
*/
disabled?: boolean;

/**
* Defines the visual size of the component
*/
size?: ComboboxSize;

/**
* Toggles Dark Mode
*/
darkMode?: boolean;

/**
* The error state of the component. Defines whether the error message is displayed.
*/
state?: State;

/**
* The message shown below the input when state is `error`
*/
errorMessage?: string;

/**
* The state of search results. Toggles search messages within the menu.
*/
searchState?: SearchState;

/**
* A message shown within the menu when there are no options passed in as children, or `filteredOptions` is an empty array
*/
searchEmptyMessage?: string;

/**
* A message shown within the menu when searchState is `error`
*/
searchErrorMessage?: string;

/**
* A message shown within the menu when searchState is `loading`
*/
searchLoadingMessage?: string;

/**
* A callback called when the search input changes.
* Receives a single argument that is the current input value.
* Use this callback to set `searchState` and/or `filteredOptions` appropriately
*/
onFilter?: (value: string) => void;

/**
* Defines whether the Clear button appears to the right of the input.
*/
clearable?: boolean;

/**
* A callback fired when the Clear button is pressed.
* Fired _after_ `onChange`, and _before_ `onFilter`
*/
onClear?: (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;

/**
* An array used to define which options are displayed.
* Do not remove options from the JSX children, as this will affect the selected options
*/
filteredOptions?: Array<string>;

/**
* Defines where the ellipses appear in a Chip when the length exceeds the `chipCharacterLimit`
*/
chipTruncationLocation?: TruncationLocation;

/**
* Defined the character limit of a multiselect Chip before they start truncating.
* Note: the three ellipses dots are included in the character limit.
*/
chipCharacterLimit?: number;

/**
* Number that controls the z-index of the popover element directly.
*/
popoverZIndex?: number;
};

export type ComboboxProps<M extends boolean> = Either<
BaseComboboxProps & ComboboxMultiselectProps<M>,
Expand Down
21 changes: 9 additions & 12 deletions packages/combobox/src/ComboboxMenu/ComboboxMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useAvailableSpace, useForwardedRef } from '@leafygreen-ui/hooks';
import Icon from '@leafygreen-ui/icon';
import { useDarkMode } from '@leafygreen-ui/leafygreen-provider';
import { palette } from '@leafygreen-ui/palette';
import Popover from '@leafygreen-ui/popover';
import Popover, { PortalControlProps } from '@leafygreen-ui/popover';
import { Error } from '@leafygreen-ui/typography';

import { ComboboxProps } from '../Combobox.types';
Expand All @@ -30,17 +30,14 @@ type ComboboxMenuProps = {
id: string;
labelId: string;
menuWidth: number;
} & Pick<
ComboboxProps<any>,
| 'searchLoadingMessage'
| 'searchErrorMessage'
| 'searchEmptyMessage'
| 'usePortal'
| 'portalClassName'
| 'portalContainer'
| 'scrollContainer'
| 'popoverZIndex'
>;
} & PortalControlProps &
Pick<
ComboboxProps<any>,
| 'searchLoadingMessage'
| 'searchErrorMessage'
| 'searchEmptyMessage'
| 'popoverZIndex'
>;

export const ComboboxMenu = React.forwardRef<HTMLDivElement, ComboboxMenuProps>(
(
Expand Down
8 changes: 6 additions & 2 deletions packages/combobox/src/utils/ComboboxTestUtils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,12 @@ export function renderCombobox<T extends Select>(
* @param newProps
* @returns
*/
const rerenderCombobox = (newProps: renderComboboxProps) =>
renderResult.rerender(getComboboxJSX({ ...props, ...newProps }));
const rerenderCombobox = (newProps: renderComboboxProps) => {
const rerenderProps = { ...props, ...newProps };
return renderResult.rerender(
getComboboxJSX(rerenderProps as renderComboboxProps),
);
};

/**
* @returns all chip elements
Expand Down

0 comments on commit 2603d7a

Please sign in to comment.