@leafygreen-ui/combobox 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/dist/Chip.d.ts.map +1 -1
  3. package/dist/Combobox.d.ts +7 -1
  4. package/dist/Combobox.d.ts.map +1 -1
  5. package/dist/Combobox.styles.d.ts +6 -3
  6. package/dist/Combobox.styles.d.ts.map +1 -1
  7. package/dist/Combobox.types.d.ts +27 -1
  8. package/dist/Combobox.types.d.ts.map +1 -1
  9. package/dist/ComboboxContext.d.ts +1 -1
  10. package/dist/ComboboxContext.d.ts.map +1 -1
  11. package/dist/ComboboxOption.d.ts.map +1 -1
  12. package/dist/ComboboxTestUtils.d.ts +1 -2
  13. package/dist/ComboboxTestUtils.d.ts.map +1 -1
  14. package/dist/esm/index.js +1 -1
  15. package/dist/esm/index.js.map +1 -1
  16. package/dist/index.js +1 -1
  17. package/dist/index.js.map +1 -1
  18. package/dist/utils/OptionObjectUtils.d.ts +5 -0
  19. package/dist/utils/OptionObjectUtils.d.ts.map +1 -0
  20. package/dist/utils/flattenChildren.d.ts +11 -0
  21. package/dist/utils/flattenChildren.d.ts.map +1 -0
  22. package/dist/utils/getNameAndValue.d.ts +14 -0
  23. package/dist/utils/getNameAndValue.d.ts.map +1 -0
  24. package/dist/utils/index.d.ts +5 -0
  25. package/dist/utils/index.d.ts.map +1 -0
  26. package/dist/utils/wrapJSX.d.ts +14 -0
  27. package/dist/utils/wrapJSX.d.ts.map +1 -0
  28. package/package.json +9 -9
  29. package/src/Chip.tsx +13 -3
  30. package/src/Combobox.spec.tsx +321 -242
  31. package/src/Combobox.story.tsx +98 -3
  32. package/src/Combobox.styles.ts +82 -22
  33. package/src/Combobox.tsx +446 -266
  34. package/src/Combobox.types.ts +36 -1
  35. package/src/ComboboxContext.tsx +2 -2
  36. package/src/ComboboxOption.tsx +34 -8
  37. package/src/ComboboxTestUtils.tsx +20 -3
  38. package/src/utils/ComboboxUtils.spec.tsx +227 -0
  39. package/src/utils/OptionObjectUtils.ts +26 -0
  40. package/src/utils/flattenChildren.tsx +47 -0
  41. package/src/utils/getNameAndValue.ts +23 -0
  42. package/src/utils/index.ts +8 -0
  43. package/src/utils/wrapJSX.tsx +54 -0
  44. package/tsconfig.tsbuildinfo +1 -1
  45. package/dist/util.d.ts +0 -53
  46. package/dist/util.d.ts.map +0 -1
  47. package/src/util.tsx +0 -133
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/ComboboxContext.tsx","../src/ComboboxOption.tsx","../src/Combobox.styles.ts","../src/util.tsx","../src/Chip.tsx","../src/ComboboxGroup.tsx","../src/Combobox.tsx","../src/Combobox.types.ts"],"sourcesContent":["import { createContext } from 'react';\nimport { ComboboxSize, TrunctationLocation } from './Combobox.types';\n\ninterface ComboboxData {\n multiselect: boolean;\n darkMode: boolean;\n size: keyof typeof ComboboxSize;\n withIcons: boolean;\n disabled: boolean;\n chipTruncationLocation?: TrunctationLocation;\n chipCharacterLimit?: number;\n inputValue?: string;\n}\n\nexport const ComboboxContext = createContext<ComboboxData>({\n multiselect: false,\n darkMode: false,\n size: 'default',\n withIcons: false,\n disabled: false,\n});\n","import { css, cx } from '@leafygreen-ui/emotion';\nimport React, { useCallback, useContext, useMemo } from 'react';\nimport { uiColors } from '@leafygreen-ui/palette';\nimport { isComponentType } from '@leafygreen-ui/lib';\nimport { useForwardedRef, useIdAllocator } from '@leafygreen-ui/hooks';\nimport Checkbox from '@leafygreen-ui/checkbox';\nimport Icon, { isComponentGlyph } from '@leafygreen-ui/icon';\nimport {\n ComboboxOptionProps,\n InternalComboboxOptionProps,\n} from './Combobox.types';\nimport { ComboboxContext } from './ComboboxContext';\nimport { wrapJSX } from './util';\n\n/**\n * Styles\n */\n\nconst comboboxOptionStyle = () => css`\n position: relative;\n display: flex;\n align-items: center;\n justify-content: space-between;\n list-style: none;\n color: inherit;\n cursor: pointer;\n overflow: hidden;\n font-size: var(--lg-combobox-item-font-size);\n line-height: var(--lg-combobox-item-line-height);\n padding: var(--lg-combobox-item-padding-y) var(--lg-combobox-item-padding-x);\n\n &:before {\n content: '';\n position: absolute;\n left: 0;\n width: 3px;\n height: var(--lg-combobox-item-wedge-height);\n background-color: transparent;\n border-radius: 0 2px 2px 0;\n transform: scaleY(0.3);\n transition: 150ms ease-in-out;\n transition-property: transform, background-color;\n }\n\n &:hover {\n outline: none;\n background-color: var(--lg-combobox-item-hover-color);\n }\n\n &[aria-selected='true'] {\n outline: none;\n background-color: var(--lg-combobox-item-active-color);\n\n &:before {\n background-color: var(--lg-combobox-item-wedge-color);\n transform: scaleY(1);\n }\n }\n`;\n\nconst flexSpan = css`\n display: inline-flex;\n gap: 8px;\n justify-content: start;\n align-items: inherit;\n`;\n\nconst disallowPointer = css`\n pointer-events: none;\n`;\n\nconst displayNameStyle = (isSelected: boolean) => css`\n font-weight: ${isSelected ? 'bold' : 'normal'};\n`;\n/**\n * Component\n */\n\nconst InternalComboboxOption = React.forwardRef<\n HTMLLIElement,\n InternalComboboxOptionProps\n>(\n (\n {\n displayName,\n glyph,\n isSelected,\n isFocused,\n setSelected,\n className,\n }: InternalComboboxOptionProps,\n forwardedRef,\n ) => {\n const { multiselect, darkMode, withIcons, inputValue } =\n useContext(ComboboxContext);\n const optionTextId = useIdAllocator({ prefix: 'combobox-option-text' });\n const optionRef = useForwardedRef(forwardedRef, null);\n\n const handleOptionClick = useCallback(\n (e: React.SyntheticEvent) => {\n e.stopPropagation();\n\n // If user clicked on the option, or the checkbox\n // Ignore extra click events on the checkbox wrapper\n if (\n e.target === optionRef.current ||\n (e.target as Element).tagName === 'INPUT'\n ) {\n setSelected();\n }\n },\n [optionRef, setSelected],\n );\n\n const renderedIcon = useMemo(() => {\n if (glyph) {\n if (isComponentGlyph(glyph) || isComponentType(glyph, 'Icon')) {\n return glyph;\n }\n console.error(\n '`ComboboxOption` instance did not render icon because it is not a known glyph element.',\n glyph,\n );\n }\n }, [glyph]);\n\n const renderedChildren = useMemo(() => {\n // Multiselect\n if (multiselect) {\n const checkbox = (\n <Checkbox\n // Using empty label due to this bug: https://jira.mongodb.org/browse/PD-1681\n label=\"\"\n aria-labelledby={optionTextId}\n checked={isSelected}\n tabIndex={-1}\n animate={false}\n />\n );\n\n return (\n <>\n <span className={cx(flexSpan, disallowPointer)}>\n {withIcons ? renderedIcon : checkbox}\n <span id={optionTextId} className={displayNameStyle(isSelected)}>\n {wrapJSX(displayName, inputValue, 'strong')}\n </span>\n </span>\n {withIcons && checkbox}\n </>\n );\n }\n\n // Single select\n return (\n <>\n <span className={cx(flexSpan, disallowPointer)}>\n {renderedIcon}\n <span className={displayNameStyle(isSelected)}>\n {wrapJSX(displayName, inputValue, 'strong')}\n </span>\n </span>\n {isSelected && (\n <Icon\n glyph=\"Checkmark\"\n color={darkMode ? uiColors.blue.light1 : uiColors.blue.base}\n />\n )}\n </>\n );\n }, [\n multiselect,\n renderedIcon,\n isSelected,\n displayName,\n inputValue,\n darkMode,\n optionTextId,\n withIcons,\n ]);\n\n return (\n <li\n ref={optionRef}\n role=\"option\"\n aria-selected={isFocused}\n aria-label={displayName}\n tabIndex={-1}\n className={cx(comboboxOptionStyle(), className)}\n onClick={handleOptionClick}\n onKeyPress={handleOptionClick}\n >\n {renderedChildren}\n </li>\n );\n },\n);\nInternalComboboxOption.displayName = 'ComboboxOption';\n\nexport { InternalComboboxOption };\nexport default function ComboboxOption(_: ComboboxOptionProps): JSX.Element {\n throw Error('`ComboboxOption` must be a child of a `Combobox` instance');\n}\nComboboxOption.displayName = 'ComboboxOption';\n","/**\n * Styles\n */\n\nimport { css, cx, keyframes } from '@leafygreen-ui/emotion';\nimport { createUniqueClassName } from '@leafygreen-ui/lib';\nimport { uiColors } from '@leafygreen-ui/palette';\nimport { fontFamilies } from '@leafygreen-ui/tokens';\nimport { isArray } from 'lodash';\nimport { ComboboxSize, Overflow, State } from './Combobox.types';\n\nconst minWidth = 24;\n\nexport const chipClassName = createUniqueClassName('combobox-chip');\n\nexport const comboboxParentStyle = ({\n darkMode,\n size,\n overflow,\n}: {\n darkMode: boolean;\n size: ComboboxSize;\n overflow: Overflow;\n}) => {\n const modeStyle = (darkMode: boolean) => {\n if (darkMode) {\n return css``;\n } else {\n return css`\n --lg-combobox-color-error: ${uiColors.red.base};\n --lg-combobox-text-color: ${uiColors.gray.dark3};\n --lg-combobox-text-color-disabled: ${uiColors.gray.dark1};\n\n --lg-combobox-background-color: ${uiColors.gray.light3};\n --lg-combobox-background-color-focus: ${uiColors.white};\n --lg-combobox-background-color-disabled: ${uiColors.gray.light2};\n\n --lg-combobox-border-color: ${uiColors.gray.base};\n --lg-combobox-border-color-disabled: ${uiColors.gray.light1};\n --lg-combobox-border-color-error: ${uiColors.red.base};\n\n --lg-combobox-shadow: 0px 1px 2px rgba(6, 22, 33, 0.3);\n --lg-combobox-shadow-focus: 0px 4px 4px rgba(6, 22, 33, 0.3);\n `;\n }\n };\n\n const sizeStyle = (size: ComboboxSize) => {\n switch (size) {\n case 'default':\n return css`\n --lg-combobox-padding-y: 5px;\n --lg-combobox-padding-x: 7px;\n --lg-combobox-height: 24px;\n --lg-combobox-font-size: 14px;\n --lg-combobox-line-height: 20px;\n --lg-combobox-border-radius: 3px;\n --lg-combobox-icon-height: 16px;\n `;\n }\n };\n\n return cx(\n modeStyle(darkMode),\n sizeStyle(size),\n css`\n --lg-combobox-width: ${overflow === 'expand-x' ? 'unset' : '100%'};\n --lg-combobox-padding: var(--lg-combobox-padding-y)\n var(--lg-combobox-padding-x) var(--lg-combobox-padding-y)\n ${overflow === 'scroll-x' ? '0' : 'var(--lg-combobox-padding-x)'};\n width: var(--lg-combobox-width);\n // TODO: Clean this up 🤮\n min-width: calc(\n ${minWidth}px + var(--lg-combobox-padding-x) * 2 + 2px +\n var(--lg-combobox-icon-height)\n );\n `,\n );\n};\n\nexport const comboboxStyle = css`\n display: flex;\n flex-wrap: nowrap;\n align-items: center;\n padding: var(--lg-combobox-padding);\n color: var(--lg-combobox-text-color);\n background-color: var(--lg-combobox-background-color);\n box-shadow: var(--lg-combobox-shadow);\n border: 1px solid var(--lg-combobox-border-color);\n border-radius: var(--lg-combobox-border-radius);\n width: var(--lg-combobox-width);\n cursor: text;\n transition: 150ms ease-in-out;\n transition-property: background-color, box-shadow;\n\n &:focus-within {\n background-color: var(--lg-combobox-background-color-focus);\n box-shadow: var(--lg-combobox-shadow-focus);\n }\n\n &[data-disabled='true'] {\n color: var(--lg-combobox-text-color-disabled);\n background-color: var(--lg-combobox-background-color-disabled);\n border-color: var(--lg-combobox-border-color-disabled);\n box-shadow: unset;\n cursor: not-allowed;\n }\n\n &[data-state='error'] {\n border-color: var(--lg-combobox-border-color-error);\n }\n`;\n\nexport const interactionRingStyle = css`\n width: var(--lg-combobox-width);\n`;\n\nexport const interactionRingColor = ({\n state,\n darkMode,\n}: {\n state: State;\n darkMode: boolean;\n}) => {\n if (darkMode) {\n return {\n hovered: state === 'error' ? uiColors.red.dark2 : undefined,\n };\n } else {\n return {\n hovered: state === 'error' ? uiColors.red.light3 : undefined,\n };\n }\n};\n\nexport const inputWrapperStyle = ({\n overflow,\n isOpen,\n selection,\n value,\n}: {\n overflow: Overflow;\n isOpen: boolean;\n selection: string | Array<string> | null;\n value?: string;\n}) => {\n const isMultiselect = isArray(selection) && selection.length > 0;\n const inputLength = value?.length ?? 0;\n\n const baseWrapperStyle = css`\n flex-grow: 1;\n width: var(--lg-combobox-width);\n\n --lg-combobox-input-width: ${isMultiselect ? `${inputLength}ch` : '100%'};\n `;\n\n switch (overflow) {\n case 'scroll-x': {\n return css`\n ${baseWrapperStyle}\n display: block;\n height: var(--lg-combobox-height);\n white-space: nowrap;\n overflow-x: scroll;\n padding-left: var(--lg-combobox-padding-x);\n scroll-behavior: smooth;\n scrollbar-width: none;\n /*\n * Immediate transition in, slow transition out. \n * '-in' transition is handled by \\`scroll-behavior\\` \n */\n --lg-combobox-input-transition: width ease-in-out\n ${isOpen ? '0' : '100ms'};\n\n &::-webkit-scrollbar {\n display: none;\n }\n\n & > .${chipClassName} {\n margin-inline: 2px;\n\n &:first-child {\n margin-inline-start: 0;\n }\n\n &:last-child {\n margin-inline-end: 0;\n }\n }\n `;\n }\n\n case 'expand-x': {\n return css`\n ${baseWrapperStyle}\n display: flex;\n gap: 4px;\n flex-wrap: nowrap;\n white-space: nowrap;\n height: var(--lg-combobox-height);\n --lg-combobox-input-transition: none;\n `;\n }\n\n // TODO - look into animating input element height on wrap\n case 'expand-y': {\n return css`\n ${baseWrapperStyle}\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n overflow-x: visible;\n min-height: var(--lg-combobox-height);\n `;\n }\n }\n};\n\nexport const inputElementStyle = css`\n border: none;\n cursor: inherit;\n background-color: inherit;\n box-sizing: content-box;\n padding: 0;\n margin: 0;\n text-overflow: ellipsis;\n line-height: var(--lg-combobox-line-height);\n height: var(--lg-combobox-height);\n width: var(--lg-combobox-input-width, 0);\n transition: var(--lg-combobox-input-transition);\n\n &:focus {\n outline: none;\n }\n`;\n\nexport const clearButton = css`\n // Add a negative margin so the button takes up the same space as the regular icons\n margin-block: calc(var(--lg-combobox-icon-height) / 2 - 100%);\n`;\n\nexport const errorMessageStyle = css`\n font-size: var(--lg-combobox-font-size);\n line-height: var(--lg-combobox-line-height);\n color: var(--lg-combobox-color-error);\n padding-top: var(--lg-combobox-padding-y);\n`;\n\nexport const endIcon = css`\n margin-inline-end: calc(var(--lg-combobox-padding-x) / 2);\n`;\n\nconst loadingIconAnimation = keyframes`\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n`;\nexport const loadingIconStyle = css`\n animation: ${loadingIconAnimation} 1.5s linear infinite;\n`;\n\n/**\n * Menu styles\n */\nexport const menuWrapperStyle = ({\n darkMode,\n size,\n width = 384,\n}: {\n darkMode: boolean;\n size: ComboboxSize;\n width?: number;\n}) => {\n let menuModeStyle, menuSizeStyle;\n\n if (darkMode) {\n menuModeStyle = css``;\n } else {\n menuModeStyle = css`\n --lg-combobox-menu-color: ${uiColors.gray.dark3};\n --lg-combobox-menu-message-color: ${uiColors.gray.dark1};\n --lg-combobox-menu-background-color: ${uiColors.white};\n --lg-combobox-menu-shadow: 0px 3px 7px rgba(0, 0, 0, 0.25);\n --lg-combobox-item-hover-color: ${uiColors.gray.light2};\n --lg-combobox-item-active-color: ${uiColors.blue.light3};\n --lg-combobox-item-wedge-color: ${uiColors.blue.base};\n `;\n }\n\n switch (size) {\n case 'default':\n menuSizeStyle = css`\n --lg-combobox-menu-border-radius: 4px;\n --lg-combobox-item-height: 36px;\n --lg-combobox-item-padding-y: 8px;\n --lg-combobox-item-padding-x: 12px;\n --lg-combobox-item-font-size: 14px;\n --lg-combobox-item-line-height: 21px;\n --lg-combobox-item-wedge-height: 22px;\n `;\n }\n\n return cx(\n menuModeStyle,\n menuSizeStyle,\n css`\n width: ${width}px;\n border-radius: var(--lg-combobox-menu-border-radius);\n\n & > * {\n border-radius: inherit;\n }\n `,\n );\n};\n\nexport const menuStyle = ({ maxHeight }: { maxHeight: number }) => css`\n position: relative;\n width: 100%;\n margin: 0;\n padding: 0;\n font-family: ${fontFamilies.default};\n color: var(--lg-combobox-menu-color);\n background-color: var(--lg-combobox-menu-background-color);\n box-shadow: var(--lg-combobox-menu-shadow);\n border-radius: inherit;\n overflow: auto;\n min-height: var(--lg-combobox-item-height);\n max-height: ${maxHeight}px;\n scroll-behavior: smooth;\n`;\n\nexport const menuList = css`\n position: relative;\n margin: 0;\n padding: 0;\n`;\n\nexport const menuMessage = css`\n display: inline-flex;\n align-items: center;\n gap: 8px;\n font-size: var(--lg-combobox-item-font-size);\n color: var(--lg-combobox-menu-message-color);\n padding: var(--lg-combobox-item-padding-y) var(--lg-combobox-item-padding-x);\n\n & > svg {\n width: 1em;\n height: 1em;\n }\n`;\n","import { isComponentType, keyMap as _keyMap } from '@leafygreen-ui/lib';\nimport kebabCase from 'lodash/kebabCase';\nimport React, { ReactChild } from 'react';\nimport { ComboboxOptionProps } from './Combobox.types';\n\n// TODO - remove this when lib/keyMap supports Backspace & Delete\nexport const keyMap = {\n ..._keyMap,\n Backspace: 8,\n Delete: 46,\n} as const;\n\n/**\n *\n * Wraps every instance of `wrap` found in `str` in the provided `element`.\n *\n * E.g. `wrapJSX('Apple', 'ap', 'em') => <em>Ap</em>ple`\n *\n * @param str\n * @param wrap\n * @param element\n * @returns `JSX.Element`\n */\nexport const wrapJSX = (\n str: string,\n wrap?: string,\n element?: keyof HTMLElementTagNameMap,\n): JSX.Element => {\n if (wrap && element) {\n const regex = new RegExp(wrap, 'gi');\n const matches = str.matchAll(regex);\n\n if (matches) {\n const outArray = str.split('') as Array<ReactChild>;\n\n /**\n * For every match, splice it into the \"string\",\n * wrapped in the React element\n */\n // Consider adding --downlevelIteration TS flag so we don't need Array.from\n for (const match of Array.from(matches)) {\n const matchIndex = match.index ?? -1;\n const matchContent = match[0];\n const matchLength = matchContent.length;\n const key = matchIndex + matchContent + matchLength;\n\n // We create a replacement array that's\n // the same length as the match we're deleting,\n // in order to keep the matchIndexes aligned\n // with the indexes of the output array\n const replacement = new Array<ReactChild>(matchLength).fill('');\n replacement[0] = React.createElement(element, { key }, matchContent);\n\n outArray.splice(matchIndex, matchLength, ...replacement);\n }\n\n return <>{outArray}</>;\n }\n\n return <>{str}</>;\n }\n\n return <>{str}</>;\n};\n\n/**\n *\n * Returns an object with properties `value` & `displayName`\n * based on the props provided\n *\n * @property value: string\n * @property displayName: string\n */\nexport const getNameAndValue = ({\n value: valProp,\n displayName: nameProp,\n}: ComboboxOptionProps): {\n value: string;\n displayName: string;\n} => {\n return {\n value: valProp ?? kebabCase(nameProp),\n displayName: nameProp ?? valProp ?? '', // TODO consider adding a prop to customize displayName => startCase(valProp),\n };\n};\n\nexport interface OptionObject {\n value: string;\n displayName: string;\n hasGlyph?: boolean;\n}\n\n/**\n *\n * Flattens multiple nested ComboboxOptions into a 1D array\n *\n * @param _children\n * @returns `Array<OptionObject>`\n */\nexport const flattenChildren = (\n _children: React.ReactNode,\n): Array<OptionObject> => {\n // TS doesn't like .reduce\n // @ts-expect-error\n return React.Children.toArray(_children).reduce(\n // @ts-expect-error\n (\n acc: Array<OptionObject>,\n child: React.ReactNode,\n ): Array<OptionObject> | undefined => {\n if (isComponentType(child, 'ComboboxOption')) {\n const { value, displayName } = getNameAndValue(child.props);\n const { glyph } = child.props;\n\n return [\n ...acc,\n {\n value,\n displayName,\n hasGlyph: !!glyph,\n },\n ];\n } else if (isComponentType(child, 'ComboboxGroup')) {\n const { children } = child.props;\n\n if (children) {\n return [...acc, ...flattenChildren(children)];\n }\n }\n },\n [] as Array<OptionObject>,\n );\n};\n","import React, { useContext, useEffect, useMemo, useRef } from 'react';\nimport { ChipProps, ComboboxSize } from './Combobox.types';\nimport Icon from '@leafygreen-ui/icon';\nimport { ComboboxContext } from './ComboboxContext';\nimport { css, cx } from '@leafygreen-ui/emotion';\nimport { uiColors } from '@leafygreen-ui/palette';\nimport InlineDefinition from '@leafygreen-ui/inline-definition';\nimport { keyMap } from './util';\nimport { chipClassName } from './Combobox.styles';\n\nconst chipWrapperStyle = ({\n darkMode,\n size,\n}: {\n darkMode: boolean;\n size: ComboboxSize;\n}) => {\n let chipModeStyle, chipSizeStyle;\n\n if (darkMode) {\n chipModeStyle = css``;\n } else {\n chipModeStyle = css`\n --lg-combobox-chip-text-color: ${uiColors.gray.dark3};\n --lg-combobox-chip-icon-color: ${uiColors.gray.dark2};\n --lg-combobox-chip-background-color: ${uiColors.gray.light2};\n --lg-combobox-chip-hover-color: ${uiColors.gray.light1};\n --lg-combobox-chip-focus-color: ${uiColors.blue.light2};\n `;\n }\n\n switch (size) {\n case 'default':\n chipSizeStyle = css`\n --lg-combobox-chip-height: 24px;\n --lg-combobox-chip-border-radius: 4px;\n --lg-combobox-chip-font-size: 14px;\n --lg-combobox-chip-line-height: 20px;\n --lg-combobox-chip-padding-x: 6px;\n `;\n break;\n }\n\n return cx(\n chipModeStyle,\n chipSizeStyle,\n css`\n display: inline-flex;\n align-items: center;\n overflow: hidden;\n white-space: nowrap;\n height: var(--lg-combobox-chip-height);\n font-size: var(--lg-combobox-chip-font-size);\n line-height: var(--lg-combobox-chip-line-height);\n border-radius: var(--lg-combobox-chip-border-radius);\n color: var(--lg-combobox-chip-text-color);\n background-color: var(--lg-combobox-chip-background-color);\n\n // TODO - refine these styles\n /* &:focus, */\n &:focus-within {\n background-color: var(--lg-combobox-chip-focus-color);\n }\n `,\n );\n};\n\nconst chipText = css`\n padding-inline: var(--lg-combobox-chip-padding-x);\n`;\n\nconst chipButton = css`\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n outline: none;\n border: none;\n background-color: transparent;\n color: var(--lg-combobox-chip-icon-color);\n cursor: pointer;\n transition: background-color 100ms ease-in-out;\n\n &:before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n width: 1px;\n background-color: var(--lg-combobox-chip-hover-color);\n }\n\n &:hover {\n background-color: var(--lg-combobox-chip-hover-color);\n }\n`;\n\nexport const Chip = React.forwardRef<HTMLSpanElement, ChipProps>(\n ({ displayName, isFocused, onRemove, onFocus }: ChipProps, forwardedRef) => {\n const {\n darkMode,\n size,\n disabled,\n chipTruncationLocation = 'end',\n chipCharacterLimit = 12,\n } = useContext(ComboboxContext);\n\n const isTruncated =\n !!chipCharacterLimit &&\n !!chipTruncationLocation &&\n chipTruncationLocation !== 'none' &&\n displayName.length > chipCharacterLimit;\n\n const buttonRef = useRef<HTMLButtonElement>(null);\n\n const truncatedName = useMemo(() => {\n if (isTruncated) {\n const ellipsis = '…';\n const chars = chipCharacterLimit - 3; // ellipsis dots included in the char limit\n\n switch (chipTruncationLocation) {\n case 'start': {\n const end = displayName\n .substring(displayName.length - chars)\n .trim();\n return ellipsis + end;\n }\n\n case 'middle': {\n const start = displayName.substring(0, chars / 2).trim();\n const end = displayName\n .substring(displayName.length - chars / 2)\n .trim();\n return start + ellipsis + end;\n }\n\n case 'end': {\n const start = displayName.substring(0, chars).trim();\n return start + ellipsis;\n }\n\n default: {\n return displayName;\n }\n }\n }\n\n return false;\n }, [chipCharacterLimit, chipTruncationLocation, displayName, isTruncated]);\n\n useEffect(() => {\n if (isFocused && !disabled) {\n buttonRef?.current?.focus();\n }\n }, [disabled, forwardedRef, isFocused]);\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (\n !disabled &&\n (e.keyCode === keyMap.Delete ||\n e.keyCode === keyMap.Backspace ||\n e.keyCode === keyMap.Enter ||\n e.keyCode === keyMap.Space)\n ) {\n onRemove();\n }\n };\n\n const handleChipClick = (e: React.MouseEvent) => {\n // Did not click button\n if (!buttonRef.current?.contains(e.target as Node)) {\n onFocus();\n }\n };\n\n const handleButtonClick = () => {\n if (!disabled) {\n onRemove();\n }\n };\n\n return (\n // eslint-disable-next-line jsx-a11y/click-events-have-key-events\n <span\n role=\"option\"\n aria-selected={isFocused}\n data-testid=\"lg-combobox-chip\"\n ref={forwardedRef}\n className={cx(chipClassName, chipWrapperStyle({ darkMode, size }))}\n onClick={handleChipClick}\n tabIndex={-1}\n >\n <span className={chipText}>\n {truncatedName ? (\n <InlineDefinition definition={displayName} align=\"bottom\">\n {truncatedName}\n </InlineDefinition>\n ) : (\n displayName\n )}\n </span>\n <button\n aria-label={`Deselect ${displayName}`}\n aria-disabled={disabled}\n disabled={disabled}\n ref={buttonRef}\n className={chipButton}\n onClick={handleButtonClick}\n onKeyDown={handleKeyDown}\n >\n <Icon glyph=\"X\" />\n </button>\n </span>\n );\n },\n);\nChip.displayName = 'Chip';\n","import { css, cx } from '@leafygreen-ui/emotion';\nimport { useIdAllocator } from '@leafygreen-ui/hooks';\nimport { uiColors } from '@leafygreen-ui/palette';\nimport React, { useContext } from 'react';\nimport { ComboboxGroupProps } from './Combobox.types';\nimport { ComboboxContext } from './ComboboxContext';\n\nconst comboboxGroupStyle = (darkMode: boolean) => css`\n --lg-combobox-group-label-color: ${darkMode\n ? uiColors.gray.light1\n : uiColors.gray.dark1};\n --lg-combobox-group-border-color: ${darkMode\n ? uiColors.gray.dark1\n : uiColors.gray.light1};\n padding-top: 8px;\n border-bottom: 1px solid var(--lg-combobox-group-border-color);\n`;\n\nconst comboboxGroupLabel = css`\n cursor: default;\n width: 100%;\n padding: 0 12px 2px;\n outline: none;\n overflow-wrap: anywhere;\n font-size: 12px;\n line-height: 16px;\n font-weight: bold;\n text-transform: uppercase;\n letter-spacing: 0.4px;\n color: var(--lg-combobox-group-label-color);\n`;\n\nexport function InternalComboboxGroup({\n label,\n className,\n children,\n}: ComboboxGroupProps): JSX.Element {\n const { darkMode } = useContext(ComboboxContext);\n\n const groupId = useIdAllocator({ prefix: 'combobox-group' });\n const childCount = React.Children.count(children);\n\n return childCount > 0 ? (\n <div className={cx(comboboxGroupStyle(darkMode), className)}>\n <div className={comboboxGroupLabel} id={groupId}>\n {label}\n </div>\n <div role=\"group\" aria-labelledby={groupId}>\n {children}\n </div>\n </div>\n ) : (\n <></>\n );\n}\n\nComboboxGroup.displayName = 'ComboboxGroup';\n\nexport default function ComboboxGroup(_: ComboboxGroupProps): JSX.Element {\n throw Error('`ComboboxGroup` must be a child of a `Combobox` instance');\n}\n","import React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { clone, isArray, isEqual, isNull, isString, isUndefined } from 'lodash';\nimport { Description, Label } from '@leafygreen-ui/typography';\nimport Popover from '@leafygreen-ui/popover';\nimport {\n useDynamicRefs,\n useEventListener,\n useIdAllocator,\n usePrevious,\n useViewportSize,\n} from '@leafygreen-ui/hooks';\nimport InteractionRing from '@leafygreen-ui/interaction-ring';\nimport Icon from '@leafygreen-ui/icon';\nimport IconButton from '@leafygreen-ui/icon-button';\nimport { cx } from '@leafygreen-ui/emotion';\nimport { uiColors } from '@leafygreen-ui/palette';\nimport { consoleOnce, isComponentType } from '@leafygreen-ui/lib';\nimport {\n ComboboxProps,\n getNullSelection,\n onChangeType,\n SelectValueType,\n} from './Combobox.types';\nimport { ComboboxContext } from './ComboboxContext';\nimport { InternalComboboxOption } from './ComboboxOption';\nimport { Chip } from './Chip';\nimport {\n clearButton,\n comboboxParentStyle,\n comboboxStyle,\n endIcon,\n errorMessageStyle,\n inputElementStyle,\n inputWrapperStyle,\n interactionRingColor,\n interactionRingStyle,\n loadingIconStyle,\n menuList,\n menuMessage,\n menuStyle,\n menuWrapperStyle,\n} from './Combobox.styles';\nimport { InternalComboboxGroup } from './ComboboxGroup';\nimport { flattenChildren, getNameAndValue, OptionObject, keyMap } from './util';\n\n/**\n * Component\n */\nexport default function Combobox<M extends boolean>({\n children,\n label,\n description,\n placeholder = 'Select',\n 'aria-label': ariaLabel,\n disabled = false,\n size = 'default',\n darkMode = false,\n state = 'none',\n errorMessage,\n searchState = 'unset',\n searchEmptyMessage = 'No results found',\n searchErrorMessage = 'Could not get results!',\n searchLoadingMessage = 'Loading results...',\n filteredOptions,\n onFilter,\n clearable = true,\n onClear,\n overflow = 'expand-y',\n multiselect = false as M,\n initialValue,\n onChange,\n value,\n chipTruncationLocation,\n chipCharacterLimit = 12,\n className,\n usePortal = true,\n portalClassName,\n portalContainer,\n scrollContainer,\n popoverZIndex,\n ...rest\n}: ComboboxProps<M>) {\n const getOptionRef = useDynamicRefs<HTMLLIElement>({ prefix: 'option' });\n const getChipRef = useDynamicRefs<HTMLSpanElement>({ prefix: 'chip' });\n\n const inputId = useIdAllocator({ prefix: 'combobox-input' });\n const labelId = useIdAllocator({ prefix: 'combobox-label' });\n const menuId = useIdAllocator({ prefix: 'combobox-menu' });\n\n const comboboxRef = useRef<HTMLDivElement>(null);\n const clearButtonRef = useRef<HTMLButtonElement>(null);\n const inputWrapperRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n\n const [isOpen, setOpen] = useState(false);\n const prevOpenState = usePrevious(isOpen);\n const [focusedOption, setFocusedOption] = useState<string | null>(null);\n const [selection, setSelection] = useState<SelectValueType<M> | null>(null);\n const prevSelection = usePrevious(selection);\n const [inputValue, setInputValue] = useState<string>('');\n const prevValue = usePrevious(inputValue);\n const [focusedChip, setFocusedChip] = useState<string | null>(null);\n\n const doesSelectionExist =\n !isNull(selection) &&\n ((isArray(selection) && selection.length > 0) || isString(selection));\n\n // Tells typescript that selection is multiselect\n const isMultiselect = useCallback(\n <T extends string>(val?: Array<T> | T | null): val is Array<T> => {\n if (multiselect && (typeof val == 'string' || typeof val == 'number')) {\n consoleOnce.error(\n `Error in Combobox: multiselect is set to \\`true\\`, but recieved a ${typeof val} value: \"${val}\"`,\n );\n } else if (!multiselect && isArray(val)) {\n consoleOnce.error(\n 'Error in Combobox: multiselect is set to `false`, but recieved an Array value',\n );\n }\n\n return multiselect && isArray(val);\n },\n [multiselect],\n );\n\n // Force focus of input box\n const setInputFocus = useCallback(\n (cursorPos?: number) => {\n if (!disabled && inputRef && inputRef.current) {\n inputRef.current.focus();\n if (!isUndefined(cursorPos)) {\n inputRef.current.setSelectionRange(cursorPos, cursorPos);\n }\n }\n },\n [disabled],\n );\n\n // Update selection differently in mulit & single select\n const updateSelection = useCallback(\n (value: string | null) => {\n if (isMultiselect(selection)) {\n const newSelection: SelectValueType<M> = clone(selection);\n\n if (isNull(value)) {\n newSelection.length = 0;\n } else {\n if (selection.includes(value)) {\n // remove from array\n newSelection.splice(newSelection.indexOf(value), 1);\n } else {\n // add to array\n newSelection.push(value);\n // clear text\n setInputValue('');\n }\n }\n setSelection(newSelection);\n (onChange as onChangeType<true>)?.(\n newSelection as SelectValueType<true>,\n );\n } else {\n const newSelection: SelectValueType<M> = value as SelectValueType<M>;\n setSelection(newSelection);\n (onChange as onChangeType<false>)?.(\n newSelection as SelectValueType<false>,\n );\n }\n },\n [isMultiselect, onChange, selection],\n );\n\n // Scrolls the combobox to the far right\n // Used when `overflow == 'scroll-x'`\n const scrollToEnd = () => {\n if (inputWrapperRef && inputWrapperRef.current) {\n // TODO - consider converting to .scrollTo(). This is not yet wuppoted in IE or jsdom\n inputWrapperRef.current.scrollLeft = inputWrapperRef.current.scrollWidth;\n }\n };\n\n const placeholderValue =\n multiselect && isArray(selection) && selection.length > 0\n ? undefined\n : placeholder;\n\n const allOptions = useMemo(() => flattenChildren(children), [children]);\n\n const getDisplayNameForValue = useCallback(\n (value: string | null): string => {\n return value\n ? allOptions.find(opt => opt.value === value)?.displayName ?? value\n : '';\n },\n [allOptions],\n );\n\n // Computes whether the option is visible based on the current input\n const isOptionVisible = useCallback(\n (option: string | OptionObject): boolean => {\n const value = typeof option === 'string' ? option : option.value;\n\n // If filtered options are provided\n if (filteredOptions && filteredOptions.length > 0) {\n return filteredOptions.includes(value);\n }\n\n // otherwise, we do our own filtering\n const displayName =\n typeof option === 'string'\n ? getDisplayNameForValue(value)\n : option.displayName;\n return displayName.toLowerCase().includes(inputValue.toLowerCase());\n },\n [filteredOptions, getDisplayNameForValue, inputValue],\n );\n\n const visibleOptions = useMemo(\n () => allOptions.filter(isOptionVisible),\n [allOptions, isOptionVisible],\n );\n\n const isValueValid = useCallback(\n (value: string | null): boolean => {\n return value ? !!allOptions.find(opt => opt.value === value) : false;\n },\n [allOptions],\n );\n\n const getIndexOfValue = useCallback(\n (value: string | null): number => {\n return visibleOptions\n ? visibleOptions.findIndex(option => option.value === value)\n : -1;\n },\n [visibleOptions],\n );\n\n const getValueAtIndex = useCallback(\n (index: number): string | undefined => {\n if (visibleOptions && visibleOptions.length >= index) {\n const option = visibleOptions[index];\n return option ? option.value : undefined;\n }\n },\n [visibleOptions],\n );\n\n const getActiveChipIndex = useCallback(\n () =>\n isMultiselect(selection)\n ? selection.findIndex(value =>\n getChipRef(value)?.current?.contains(document.activeElement),\n )\n : -1,\n [getChipRef, isMultiselect, selection],\n );\n\n /**\n *\n * Focus Management\n *\n */\n\n const getFocusedElementName = useCallback(() => {\n const isFocusOn = {\n Input: inputRef.current?.contains(document.activeElement),\n ClearButton: clearButtonRef.current?.contains(document.activeElement),\n Chip:\n isMultiselect(selection) &&\n selection.some(value =>\n getChipRef(value)?.current?.contains(document.activeElement),\n ),\n };\n const getActiveChipIndex = () =>\n isMultiselect(selection)\n ? selection.findIndex(value =>\n getChipRef(value)?.current?.contains(document.activeElement),\n )\n : -1;\n\n if (isMultiselect(selection) && isFocusOn.Chip) {\n if (getActiveChipIndex() === 0) {\n return 'FirstChip';\n } else if (getActiveChipIndex() === selection.length - 1) {\n return 'LastChip';\n }\n\n return 'MiddleChip';\n } else if (isFocusOn.Input) {\n return 'Input';\n } else if (isFocusOn.ClearButton) {\n return 'ClearButton';\n } else if (comboboxRef.current?.contains(document.activeElement)) {\n return 'Combobox';\n }\n }, [getChipRef, isMultiselect, selection]);\n\n type Direction = 'next' | 'prev' | 'first' | 'last';\n const updateFocusedOption = useCallback(\n (direction: Direction) => {\n const optionsCount = visibleOptions?.length ?? 0;\n const lastIndex = optionsCount - 1 > 0 ? optionsCount - 1 : 0;\n const indexOfFocus = getIndexOfValue(focusedOption);\n\n // Remove focus from chip\n if (direction && isOpen) {\n setFocusedChip(null);\n setInputFocus();\n }\n\n switch (direction) {\n case 'next': {\n const newValue =\n indexOfFocus + 1 < optionsCount\n ? getValueAtIndex(indexOfFocus + 1)\n : getValueAtIndex(0);\n\n setFocusedOption(newValue ?? null);\n break;\n }\n\n case 'prev': {\n const newValue =\n indexOfFocus - 1 >= 0\n ? getValueAtIndex(indexOfFocus - 1)\n : getValueAtIndex(lastIndex);\n\n setFocusedOption(newValue ?? null);\n break;\n }\n\n case 'last': {\n const newValue = getValueAtIndex(lastIndex);\n setFocusedOption(newValue ?? null);\n break;\n }\n\n case 'first':\n default: {\n const newValue = getValueAtIndex(0);\n setFocusedOption(newValue ?? null);\n }\n }\n },\n [\n focusedOption,\n getIndexOfValue,\n getValueAtIndex,\n isOpen,\n setInputFocus,\n visibleOptions?.length,\n ],\n );\n\n const updateFocusedChip = useCallback(\n (direction: Direction | null, relativeToIndex?: number) => {\n if (isMultiselect(selection)) {\n switch (direction) {\n case 'next': {\n const referenceChipIndex = relativeToIndex ?? getActiveChipIndex();\n const nextChipIndex =\n referenceChipIndex + 1 < selection.length\n ? referenceChipIndex + 1\n : selection.length - 1;\n const nextChipValue = selection[nextChipIndex];\n setFocusedChip(nextChipValue);\n break;\n }\n\n case 'prev': {\n const referenceChipIndex = relativeToIndex ?? getActiveChipIndex();\n const prevChipIndex =\n referenceChipIndex > 0\n ? referenceChipIndex - 1\n : referenceChipIndex < 0\n ? selection.length - 1\n : 0;\n const prevChipValue = selection[prevChipIndex];\n setFocusedChip(prevChipValue);\n break;\n }\n\n case 'first': {\n const firstChipValue = selection[0];\n setFocusedChip(firstChipValue);\n break;\n }\n\n case 'last': {\n const lastChipValue = selection[selection.length - 1];\n setFocusedChip(lastChipValue);\n break;\n }\n\n default:\n setFocusedChip(null);\n break;\n }\n }\n },\n [getActiveChipIndex, isMultiselect, selection],\n );\n\n const handleArrowKey = useCallback(\n (direction: 'left' | 'right', event: React.KeyboardEvent<Element>) => {\n // Remove focus from menu\n if (direction) setFocusedOption(null);\n\n const focusedElementName = getFocusedElementName();\n\n switch (direction) {\n case 'right':\n switch (focusedElementName) {\n case 'Input': {\n // If cursor is at the end of the input\n if (\n inputRef.current?.selectionEnd ===\n inputRef.current?.value.length\n ) {\n clearButtonRef.current?.focus();\n }\n break;\n }\n\n case 'LastChip': {\n // if focus is on last chip, go to input\n event.preventDefault();\n setInputFocus(0);\n updateFocusedChip(null);\n break;\n }\n\n case 'FirstChip':\n case 'MiddleChip': {\n updateFocusedChip('next');\n break;\n }\n\n case 'ClearButton':\n default:\n break;\n }\n break;\n\n case 'left':\n switch (focusedElementName) {\n case 'ClearButton': {\n event.preventDefault();\n setInputFocus(inputRef?.current?.value.length);\n break;\n }\n\n case 'Input':\n case 'MiddleChip':\n case 'LastChip': {\n if (isMultiselect(selection)) {\n // Break if cursor is not at the start of the input\n if (\n focusedElementName === 'Input' &&\n inputRef.current?.selectionStart !== 0\n ) {\n break;\n }\n\n updateFocusedChip('prev');\n }\n break;\n }\n\n case 'FirstChip':\n default:\n break;\n }\n break;\n default:\n updateFocusedChip(null);\n break;\n }\n },\n [\n getFocusedElementName,\n isMultiselect,\n selection,\n setInputFocus,\n updateFocusedChip,\n ],\n );\n\n // Update the focused option when the inputValue changes\n useEffect(() => {\n if (inputValue !== prevValue) {\n updateFocusedOption('first');\n }\n }, [inputValue, isOpen, prevValue, updateFocusedOption]);\n\n // When the focused option chenges, update the menu scroll if necessary\n useEffect(() => {\n if (focusedOption) {\n const focusedElementRef = getOptionRef(focusedOption);\n\n if (focusedElementRef && focusedElementRef.current && menuRef.current) {\n const { offsetTop: optionTop } = focusedElementRef.current;\n const { scrollTop: menuScroll, offsetHeight: menuHeight } =\n menuRef.current;\n\n if (optionTop > menuHeight || optionTop < menuScroll) {\n menuRef.current.scrollTop = optionTop;\n }\n }\n }\n }, [focusedOption, getOptionRef]);\n\n /**\n *\n * Rendering\n *\n */\n const renderInternalOptions = useCallback(\n (_children: React.ReactNode) => {\n return React.Children.map(_children, child => {\n if (isComponentType(child, 'ComboboxOption')) {\n const { value, displayName } = getNameAndValue(child.props);\n\n if (isOptionVisible(value)) {\n const { className, glyph } = child.props;\n const index = allOptions.findIndex(opt => opt.value === value);\n\n const isFocused = focusedOption === value;\n const isSelected = isMultiselect(selection)\n ? selection.includes(value)\n : selection === value;\n\n const setSelected = () => {\n setFocusedOption(value);\n updateSelection(value);\n setInputFocus();\n\n if (value === selection) {\n closeMenu();\n }\n };\n\n const optionRef = getOptionRef(value);\n\n return (\n <InternalComboboxOption\n value={value}\n displayName={displayName}\n isFocused={isFocused}\n isSelected={isSelected}\n setSelected={setSelected}\n glyph={glyph}\n className={className}\n index={index}\n ref={optionRef}\n />\n );\n }\n } else if (isComponentType(child, 'ComboboxGroup')) {\n const nestedChildren = renderInternalOptions(child.props.children);\n\n if (nestedChildren && nestedChildren?.length > 0) {\n return (\n <InternalComboboxGroup\n label={child.props.label}\n className={child.props.className}\n >\n {renderInternalOptions(nestedChildren)}\n </InternalComboboxGroup>\n );\n }\n }\n });\n },\n [\n allOptions,\n focusedOption,\n getOptionRef,\n isMultiselect,\n isOptionVisible,\n selection,\n setInputFocus,\n updateSelection,\n ],\n );\n\n const renderedOptions = useMemo(\n () => renderInternalOptions(children),\n [children, renderInternalOptions],\n );\n\n const renderedChips = useMemo(() => {\n if (isMultiselect(selection)) {\n return selection.filter(isValueValid).map((value, index) => {\n const displayName = getDisplayNameForValue(value);\n\n const onRemove = () => {\n updateFocusedChip('next', index);\n updateSelection(value);\n };\n\n const isFocused = focusedChip === value;\n const chipRef = getChipRef(value);\n\n const onFocus = () => {\n setFocusedChip(value);\n };\n\n return (\n <Chip\n key={value}\n displayName={displayName}\n isFocused={isFocused}\n onRemove={onRemove}\n onFocus={onFocus}\n ref={chipRef}\n />\n );\n });\n }\n }, [\n isMultiselect,\n selection,\n isValueValid,\n getDisplayNameForValue,\n focusedChip,\n getChipRef,\n updateFocusedChip,\n updateSelection,\n ]);\n\n const renderedInputIcons = useMemo(() => {\n const handleClearButtonClick = (\n e: React.MouseEvent<HTMLButtonElement, MouseEvent>,\n ) => {\n if (!disabled) {\n updateSelection(null);\n onClear?.(e);\n onFilter?.('');\n if (!isOpen) {\n openMenu();\n }\n }\n };\n\n return (\n <>\n {clearable && doesSelectionExist && (\n <IconButton\n aria-label=\"Clear selection\"\n aria-disabled={disabled}\n disabled={disabled}\n ref={clearButtonRef}\n onClick={handleClearButtonClick}\n onFocus={handleClearButtonFocus}\n className={clearButton}\n >\n <Icon glyph=\"XWithCircle\" />\n </IconButton>\n )}\n {state === 'error' ? (\n <Icon glyph=\"Warning\" color={uiColors.red.base} className={endIcon} />\n ) : (\n <Icon glyph=\"CaretDown\" className={endIcon} />\n )}\n </>\n );\n }, [\n clearable,\n doesSelectionExist,\n disabled,\n state,\n updateSelection,\n onClear,\n onFilter,\n isOpen,\n ]);\n\n // Do any of the options have an icon?\n const withIcons = useMemo(\n () => allOptions.some(opt => opt.hasGlyph),\n [allOptions],\n );\n\n /**\n *\n * Selection Management\n *\n */\n\n const onCloseMenu = useCallback(() => {\n if (!isMultiselect(selection) && selection === prevSelection) {\n const exactMatchedOption = visibleOptions.find(\n option =>\n option.displayName === inputValue || option.value === inputValue,\n );\n\n // check if inputValue is matches a valid option\n // Set the selection to that value if the component is not controlled\n if (exactMatchedOption && !value) {\n setSelection(exactMatchedOption.value as SelectValueType<M>);\n } else {\n // Revert the value to the previous selection\n const displayName =\n getDisplayNameForValue(selection as SelectValueType<false>) ?? '';\n setInputValue(displayName);\n }\n }\n }, [\n getDisplayNameForValue,\n inputValue,\n isMultiselect,\n prevSelection,\n selection,\n value,\n visibleOptions,\n ]);\n\n const onSelect = useCallback(() => {\n if (doesSelectionExist) {\n if (isMultiselect(selection)) {\n // Scroll the wrapper to the end. No effect if not `overflow=\"scroll-x\"`\n scrollToEnd();\n } else if (!isMultiselect(selection)) {\n // Update the text input\n const displayName =\n getDisplayNameForValue(selection as SelectValueType<false>) ?? '';\n setInputValue(displayName);\n closeMenu();\n }\n } else {\n setInputValue('');\n }\n }, [doesSelectionExist, getDisplayNameForValue, isMultiselect, selection]);\n\n // Set initialValue\n useEffect(() => {\n if (initialValue) {\n if (isArray(initialValue)) {\n // Ensure the values we set are real options\n const filteredValue =\n initialValue.filter(value => isValueValid(value)) ?? [];\n setSelection(filteredValue as SelectValueType<M>);\n } else {\n if (isValueValid(initialValue as string)) {\n setSelection(initialValue);\n }\n }\n } else {\n setSelection(getNullSelection(multiselect));\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // When controlled value changes, update the selection\n useEffect(() => {\n if (!isUndefined(value) && value !== prevValue) {\n if (isNull(value)) {\n setSelection(null);\n } else if (isMultiselect(value)) {\n // Ensure the value(s) passed in are valid options\n const newSelection = value.filter(isValueValid) as SelectValueType<M>;\n setSelection(newSelection);\n } else {\n setSelection(\n isValueValid(value as SelectValueType<false>) ? value : null,\n );\n }\n }\n }, [isMultiselect, isValueValid, prevValue, value]);\n\n // onSelect\n // Side effects to run when the selection changes\n useEffect(() => {\n if (!isEqual(selection, prevSelection)) {\n onSelect();\n }\n }, [onSelect, prevSelection, selection]);\n\n // when the menu closes, update the value if needed\n useEffect(() => {\n if (!isOpen && prevOpenState !== isOpen) {\n onCloseMenu();\n }\n }, [isOpen, prevOpenState, onCloseMenu]);\n\n /**\n *\n * Menu management\n *\n */\n const closeMenu = () => setOpen(false);\n const openMenu = () => setOpen(true);\n\n const [menuWidth, setMenuWidth] = useState(0);\n useEffect(() => {\n setMenuWidth(comboboxRef.current?.clientWidth ?? 0);\n }, [comboboxRef, isOpen, focusedOption, selection]);\n const handleTransitionEnd = () => {\n setMenuWidth(comboboxRef.current?.clientWidth ?? 0);\n };\n\n const renderedMenuContents = useMemo((): JSX.Element => {\n switch (searchState) {\n case 'loading': {\n return (\n <span className={menuMessage}>\n <Icon\n glyph=\"Refresh\"\n color={uiColors.blue.base}\n className={loadingIconStyle}\n />\n {searchLoadingMessage}\n </span>\n );\n }\n\n case 'error': {\n return (\n <span className={menuMessage}>\n <Icon glyph=\"Warning\" color={uiColors.red.base} />\n {searchErrorMessage}\n </span>\n );\n }\n\n case 'unset':\n default: {\n if (renderedOptions && renderedOptions.length > 0) {\n return <ul className={menuList}>{renderedOptions}</ul>;\n }\n\n return <span className={menuMessage}>{searchEmptyMessage}</span>;\n }\n }\n }, [\n renderedOptions,\n searchEmptyMessage,\n searchErrorMessage,\n searchLoadingMessage,\n searchState,\n ]);\n\n const viewportSize = useViewportSize();\n\n // Set the max height of the menu\n const maxHeight = useMemo(() => {\n // TODO - consolidate this hook with Select/ListMenu\n const maxMenuHeight = 274;\n const menuMargin = 8;\n\n if (viewportSize && comboboxRef.current && menuRef.current) {\n const { top: triggerTop, bottom: triggerBottom } =\n comboboxRef.current.getBoundingClientRect();\n\n // Find out how much space is available above or below the trigger\n const safeSpace = Math.max(\n viewportSize.height - triggerBottom,\n triggerTop,\n );\n\n // if there's more than enough space, set to maxMenuHeight\n // otherwise fill the space available\n return Math.min(maxMenuHeight, safeSpace - menuMargin);\n }\n\n return maxMenuHeight;\n }, [viewportSize, comboboxRef, menuRef]);\n\n // Scroll the menu when the focus changes\n useEffect(() => {\n // get the focused option\n }, [focusedOption]);\n\n /**\n *\n * Event Handlers\n *\n */\n\n // Prevent combobox from gaining focus by default\n const handleInputWrapperMousedown = (e: React.MouseEvent) => {\n if (disabled) {\n e.preventDefault();\n }\n };\n\n // Set focus to the input element on click\n const handleInputWrapperClick = (e: React.MouseEvent) => {\n if (e.target !== inputRef.current) {\n let cursorPos = 0;\n\n if (inputRef.current) {\n const mouseX = e.nativeEvent.offsetX;\n const inputRight =\n inputRef.current.offsetLeft + inputRef.current.clientWidth;\n cursorPos = mouseX > inputRight ? inputValue.length : 0;\n }\n\n setInputFocus(cursorPos);\n }\n };\n\n // Fired when the wrapper gains focus\n const handleInputWrapperFocus = () => {\n scrollToEnd();\n openMenu();\n };\n\n // Fired onChange\n const handleInputChange = ({\n target: { value },\n }: React.ChangeEvent<HTMLInputElement>) => {\n setInputValue(value);\n // fire any filter function passed in\n onFilter?.(value);\n };\n\n const handleClearButtonFocus = () => {\n setFocusedOption(null);\n };\n\n const handleKeyDown = (event: React.KeyboardEvent) => {\n const isFocusInMenu = menuRef.current?.contains(document.activeElement);\n const isFocusOnCombobox = comboboxRef.current?.contains(\n document.activeElement,\n );\n\n const isFocusInComponent = isFocusOnCombobox || isFocusInMenu;\n\n if (isFocusInComponent) {\n // No support for modifiers yet\n // TODO - Handle support for multiple chip selection\n if (event.ctrlKey || event.shiftKey || event.altKey) {\n return;\n }\n\n const focusedElement = getFocusedElementName();\n\n switch (event.keyCode) {\n case keyMap.Tab: {\n switch (focusedElement) {\n case 'Input': {\n if (!doesSelectionExist) {\n closeMenu();\n updateFocusedOption('first');\n updateFocusedChip(null);\n }\n // else use default behavior\n break;\n }\n\n case 'LastChip': {\n // use default behavior\n updateFocusedChip(null);\n break;\n }\n\n case 'FirstChip':\n case 'MiddleChip': {\n // use default behavior\n break;\n }\n\n case 'ClearButton':\n default:\n break;\n }\n\n break;\n }\n\n case keyMap.Escape: {\n closeMenu();\n updateFocusedOption('first');\n break;\n }\n\n case keyMap.Enter: {\n if (\n // Focused on input element\n document.activeElement === inputRef.current &&\n isOpen &&\n !isNull(focusedOption)\n ) {\n updateSelection(focusedOption);\n } else if (\n // Focused on clear button\n document.activeElement === clearButtonRef.current\n ) {\n updateSelection(null);\n setInputFocus();\n }\n break;\n }\n\n case keyMap.Backspace: {\n // Backspace key focuses last chip\n // Delete key does not\n if (\n isMultiselect(selection) &&\n inputRef.current?.selectionStart === 0\n ) {\n updateFocusedChip('last');\n } else {\n openMenu();\n }\n break;\n }\n\n case keyMap.ArrowDown: {\n if (isOpen) {\n // Prevent the page from scrolling\n event.preventDefault();\n }\n openMenu();\n updateFocusedOption('next');\n break;\n }\n\n case keyMap.ArrowUp: {\n if (isOpen) {\n // Prevent the page from scrolling\n event.preventDefault();\n }\n updateFocusedOption('prev');\n break;\n }\n\n case keyMap.ArrowRight: {\n handleArrowKey('right', event);\n break;\n }\n\n case keyMap.ArrowLeft: {\n handleArrowKey('left', event);\n break;\n }\n\n default: {\n if (!isOpen) {\n openMenu();\n }\n }\n }\n }\n };\n\n /**\n *\n * Global Event Handler\n *\n */\n // Global backdrop click handler\n const handleBackdropClick = ({ target }: MouseEvent) => {\n const isChildFocused =\n menuRef.current?.contains(target as Node) ||\n comboboxRef.current?.contains(target as Node) ||\n false;\n\n if (!isChildFocused) {\n setOpen(false);\n }\n };\n\n useEventListener('mousedown', handleBackdropClick);\n\n const popoverProps = {\n popoverZIndex,\n ...(usePortal\n ? {\n usePortal,\n portalClassName,\n portalContainer,\n scrollContainer,\n }\n : { usePortal }),\n } as const;\n\n return (\n <ComboboxContext.Provider\n value={{\n multiselect,\n darkMode,\n size,\n withIcons,\n disabled,\n chipTruncationLocation,\n chipCharacterLimit,\n inputValue,\n }}\n >\n <div\n className={cx(\n comboboxParentStyle({ darkMode, size, overflow }),\n className,\n )}\n {...rest}\n >\n <div>\n {label && (\n <Label id={labelId} htmlFor={inputId}>\n {label}\n </Label>\n )}\n {description && <Description>{description}</Description>}\n </div>\n\n <InteractionRing\n className={interactionRingStyle}\n disabled={disabled}\n color={interactionRingColor({ state, darkMode })}\n >\n {/* Disable eslint: onClick sets focus. Key events would already have focus */}\n {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */}\n <div\n ref={comboboxRef}\n role=\"combobox\"\n aria-expanded={isOpen}\n aria-controls={menuId}\n aria-owns={menuId}\n tabIndex={-1}\n className={comboboxStyle}\n onMouseDown={handleInputWrapperMousedown}\n onClick={handleInputWrapperClick}\n onFocus={handleInputWrapperFocus}\n onKeyDown={handleKeyDown}\n onTransitionEnd={handleTransitionEnd}\n data-disabled={disabled}\n data-state={state}\n >\n <div\n ref={inputWrapperRef}\n className={inputWrapperStyle({\n overflow,\n isOpen,\n selection,\n value: inputValue,\n })}\n >\n {renderedChips}\n <input\n aria-label={ariaLabel ?? label}\n aria-autocomplete=\"list\"\n aria-controls={menuId}\n aria-labelledby={labelId}\n ref={inputRef}\n id={inputId}\n className={inputElementStyle}\n placeholder={placeholderValue}\n disabled={disabled ?? undefined}\n onChange={handleInputChange}\n value={inputValue}\n autoComplete=\"off\"\n />\n </div>\n {renderedInputIcons}\n </div>\n </InteractionRing>\n\n {state === 'error' && errorMessage && (\n <div className={errorMessageStyle}>{errorMessage}</div>\n )}\n\n {/******* /\n * Menu *\n / *******/}\n <Popover\n active={isOpen && !disabled}\n spacing={4}\n align=\"bottom\"\n justify=\"middle\"\n refEl={comboboxRef}\n adjustOnMutation={true}\n className={menuWrapperStyle({ darkMode, size, width: menuWidth })}\n {...popoverProps}\n >\n <div\n id={menuId}\n role=\"listbox\"\n aria-labelledby={labelId}\n aria-expanded={isOpen}\n ref={menuRef}\n className={menuStyle({ maxHeight })}\n onMouseDownCapture={e => e.preventDefault()}\n >\n {renderedMenuContents}\n </div>\n </Popover>\n </div>\n </ComboboxContext.Provider>\n );\n}\n","import { ReactElement, ReactNode } from 'react';\nimport { Either } from '@leafygreen-ui/lib';\n\n/**\n * Prop Enums & Types\n */\n\nexport const ComboboxSize = {\n default: 'default',\n} as const;\nexport type ComboboxSize = typeof ComboboxSize[keyof typeof ComboboxSize];\n\nexport const TrunctationLocation = {\n start: 'start',\n middle: 'middle',\n end: 'end',\n none: 'none',\n} as const;\nexport type TrunctationLocation =\n typeof TrunctationLocation[keyof typeof TrunctationLocation];\n\nexport const Overflow = {\n expandY: 'expand-y',\n expandX: 'expand-x',\n scrollX: 'scroll-x',\n} as const;\nexport type Overflow = typeof Overflow[keyof typeof Overflow];\n\nexport const State = {\n error: 'error',\n none: 'none',\n} as const;\nexport type State = typeof State[keyof typeof State];\n\nexport const SearchState = {\n unset: 'unset',\n error: 'error',\n loading: 'loading',\n} as const;\nexport type SearchState = typeof SearchState[keyof typeof SearchState];\n\n/**\n * Generic Typing\n */\n\nexport type SelectValueType<M extends boolean> = M extends true\n ? Array<string>\n : string | null;\n\nexport type onChangeType<M extends boolean> = M extends true\n ? (value: SelectValueType<true>) => void\n : (value: SelectValueType<false>) => void;\n\n// Returns the correct empty state for multiselcect / single select\nexport function getNullSelection<M extends boolean>(\n multiselect: M,\n): SelectValueType<M> {\n if (multiselect) {\n return [] as Array<string> as SelectValueType<M>;\n } else {\n return null as SelectValueType<M>;\n }\n}\n\n/**\n * Combobox Props\n */\n\nexport interface ComboboxMultiselectProps<M extends boolean> {\n /**\n * Defines whether a user can select multiple options, or only a single option.\n * When using TypeScript, `multiselect` affects the valid values of `initialValue`, `value`, and `onChange`\n */\n multiselect?: M;\n /**\n * The initial selection.\n * Must be a string (or array of strings) that matches the `value` prop of a `ComboboxOption`.\n * Changing the `initialValue` after initial render will not change the selection.\n */\n initialValue?: SelectValueType<M>;\n /**\n * A callback called when the selection changes.\n * Callback recieves a single argument that is the new selection, either string, or string array\n */\n onChange?: onChangeType<M>;\n /**\n * The controlled value of the Combobox.\n * Must be a string (or array of strings) that matches the `value` prop of a `ComboboxOption`.\n * Changing `value` after initial render _will_ affect the selection.\n * `value` will always take precedence over `initialValue` if both are provided.\n */\n value?: SelectValueType<M>;\n\n /**\n * Defines the overflow behavior of a multiselect combobox.\n *\n * `expand-y`: Combobox has fixed width, and additional selections will cause the element to grow in the block direction.\n *\n * `expand-x`: Combobox has fixed height, and additional selections will cause the elemenet to grow in the inline direction.\n *\n * `scroll-x`: Combobox has fixed height and width, and additional selections will cause the element to be scrollable in the x (horizontal) direction.\n */\n overflow?: M extends true ? Overflow : undefined;\n}\n\nexport interface BaseComboboxProps {\n /**\n * Defines the Combobox Options by passing children. Must be `ComboboxOption` or `ComboboxGroup`\n */\n children?: ReactNode;\n\n /**\n * An accessible label for the input, rendered in a <label> to the DOM\n */\n label?: string;\n\n /**\n * An accessible label for the input, used only for screen-readers\n */\n 'aria-label'?: string;\n\n /**\n * A description for the input\n */\n description?: string;\n\n /**\n * A placeholder for the input element. Uses the native `placeholder` attribute.\n */\n placeholder?: string;\n\n /**\n * Disables all interaction with the component\n */\n disabled?: boolean;\n\n /**\n * Defines the visual size of the component\n */\n size?: ComboboxSize;\n\n /**\n * Toggles Dark Mode\n */\n darkMode?: boolean;\n\n /**\n * The error state of the component. Defines whether the error message is displayed.\n */\n state?: State;\n\n /**\n * The message shown below the input when state is `error`\n */\n errorMessage?: string;\n\n /**\n * The state of search results. Toggles search messages within the menu.\n */\n searchState?: SearchState;\n\n /**\n * A message shown within the menu when there are no options passed in as children, or `filteredOptions` is an empty array\n */\n searchEmptyMessage?: string;\n\n /**\n * A message shown within the menu when searchState is `error`\n */\n searchErrorMessage?: string;\n\n /**\n * A message shown within the menu when searchState is `loading`\n */\n searchLoadingMessage?: string;\n\n /**\n * A callback called when the search input changes.\n * Recieves a single argument that is the current input value.\n * Use this callback to set `searchState` and/or `filteredOptions` appropriately\n */\n onFilter?: (value: string) => void;\n\n /**\n * Defines whether the Clear button appears to the right of the input.\n */\n clearable?: boolean;\n\n /**\n * A callback fired when the Clear button is pressed.\n * Fired _after_ `onChange`, and _before_ `onFilter`\n */\n onClear?: (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;\n\n /**\n * An array used to define which options are displayed.\n * Do not remove options from the JSX children, as this will affect the selected options\n */\n filteredOptions?: Array<string>;\n\n /**\n * Defines where the ellipses appear in a Chip when the length exceeds the `chipCharacterLimit`\n */\n chipTruncationLocation?: TrunctationLocation;\n\n /**\n * Defined the character limit of a multiselect Chip before they start truncating.\n * Note: the three ellipses dots are included in the character limit.\n */\n chipCharacterLimit?: number;\n\n /**\n * Styling prop\n */\n className?: string;\n\n /**\n * Specifies that the popover content should be rendered at the end of the DOM,\n * rather than in the DOM tree.\n *\n * default: `true`\n */\n usePortal?: boolean;\n\n /**\n * When usePortal is `true`, specifies a class name to apply to the root element of the portal.\n */\n portalClassName?: undefined;\n\n /**\n * 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.\n */\n portalContainer?: null;\n\n /**\n * When usePortal is `true`, specifies the scrollable element to position relative to.\n */\n scrollContainer?: null;\n\n /**\n * Number that controls the z-index of the popover element directly.\n */\n popoverZIndex?: number;\n}\n\nexport type ComboboxProps<M extends boolean> = Either<\n BaseComboboxProps & ComboboxMultiselectProps<M>,\n 'label' | 'aria-label'\n>;\n\n/**\n * Combobox Option Props\n */\ninterface BaseComboboxOptionProps {\n /**\n * The internal value of the option. Used as the identifier in Combobox `initialValue`, value and filteredOptions.\n * When undefined, this is set to `_.kebabCase(displayName)`\n */\n value?: string;\n\n /**\n * The display value of the option. Used as the rendered string within the menu and chips.\n * When undefined, this is set to `value`\n */\n displayName?: string;\n\n /**\n * The icon to display to the left of the option in the menu.\n */\n glyph?: ReactElement;\n\n /**\n * Styling Prop\n */\n className?: string;\n}\n\nexport type ComboboxOptionProps = Either<\n BaseComboboxOptionProps,\n 'value' | 'displayName'\n>;\n\nexport interface InternalComboboxOptionProps {\n value: string;\n displayName: string;\n isSelected: boolean;\n isFocused: boolean;\n setSelected: () => void;\n glyph?: ReactElement;\n className?: string;\n index: number;\n}\n\n/**\n * Combobox Group Props\n */\n\nexport interface ComboboxGroupProps {\n /**\n * Label for the group of options\n */\n label: string;\n\n /**\n * Options in the group. Must be one or more `ComboboxOption` components\n */\n children: React.ReactNode;\n\n /**\n * Styling prop\n */\n className?: string;\n}\n\n/**\n * Combobox Chip\n */\n\nexport interface ChipProps {\n displayName: string;\n isFocused: boolean;\n onRemove: () => void;\n onFocus: () => void;\n}\n"],"names":["_templateObject","_templateObject2","_templateObject3","_templateObject4","_templateObject5","_templateObject6","_templateObject7","_templateObject8","_templateObject9","_templateObject10","_templateObject11","_templateObject12","_templateObject13","_templateObject14","_templateObject15","_templateObject16","_templateObject17","_templateObject18","_templateObject19","_templateObject20","_templateObject21","_templateObject22","_templateObject23","ComboboxContext","createContext","multiselect","darkMode","size","withIcons","disabled","keyMap","_objectSpread","_keyMap","Backspace","Delete","wrapJSX","str","wrap","element","regex","RegExp","matches","matchAll","outArray","split","_i","_Array$from","Array","from","length","_match$index","match","matchIndex","index","matchContent","matchLength","key","replacement","fill","React","createElement","splice","apply","concat","_toConsumableArray","___EmotionJSX","jsx","Fragment","getNameAndValue","_ref","_ref2","valProp","value","nameProp","displayName","kebabCase","flattenChildren","_children","Children","toArray","reduce","acc","child","isComponentType","_getNameAndValue","props","glyph","hasGlyph","children","flexSpan","css","_taggedTemplateLiteral","disallowPointer","displayNameStyle","isSelected","InternalComboboxOption","forwardRef","forwardedRef","isFocused","setSelected","className","_useContext","useContext","inputValue","optionTextId","useIdAllocator","prefix","optionRef","useForwardedRef","handleOptionClick","useCallback","e","stopPropagation","target","current","tagName","renderedIcon","useMemo","isComponentGlyph","console","error","renderedChildren","checkbox","Checkbox","label","checked","tabIndex","animate","cx","id","Icon","color","uiColors","blue","light1","base","ref","role","onClick","onKeyPress","ComboboxOption","_","Error","chipClassName","createUniqueClassName","comboboxParentStyle","overflow","red","gray","dark3","dark1","light3","white","light2","modeStyle","sizeStyle","comboboxStyle","interactionRingStyle","interactionRingColor","state","hovered","dark2","undefined","inputWrapperStyle","_ref3","_value$length","isOpen","selection","isMultiselect","isArray","inputLength","baseWrapperStyle","inputElementStyle","clearButton","errorMessageStyle","endIcon","loadingIconAnimation","keyframes","loadingIconStyle","menuWrapperStyle","_ref4","menuModeStyle","menuSizeStyle","_ref4$width","width","menuStyle","_ref5","maxHeight","fontFamilies","default","menuList","menuMessage","chipWrapperStyle","chipModeStyle","chipSizeStyle","chipText","chipButton","Chip","onRemove","onFocus","_useContext$chipTrunc","chipTruncationLocation","_useContext$chipChara","chipCharacterLimit","isTruncated","buttonRef","useRef","truncatedName","chars","substring","trim","useEffect","_buttonRef$current","focus","_buttonRef$current2","contains","InlineDefinition","definition","align","onKeyDown","keyCode","Enter","Space","comboboxGroupStyle","comboboxGroupLabel","InternalComboboxGroup","groupId","count","ComboboxGroup","_excluded","description","_ref$placeholder","placeholder","ariaLabel","_ref$disabled","_ref$size","_ref$darkMode","_ref$state","errorMessage","_ref$searchState","searchState","_ref$searchEmptyMessa","searchEmptyMessage","_ref$searchErrorMessa","searchErrorMessage","_ref$searchLoadingMes","searchLoadingMessage","filteredOptions","onFilter","_ref$clearable","clearable","onClear","_ref$overflow","_ref$multiselect","initialValue","onChange","_ref$chipCharacterLim","_ref$usePortal","usePortal","portalClassName","portalContainer","scrollContainer","popoverZIndex","rest","_objectWithoutProperties","getOptionRef","useDynamicRefs","getChipRef","inputId","labelId","menuId","comboboxRef","clearButtonRef","inputWrapperRef","inputRef","menuRef","_useState2","_slicedToArray","useState","setOpen","prevOpenState","usePrevious","_useState4","focusedOption","setFocusedOption","_useState6","setSelection","prevSelection","_useState8","setInputValue","prevValue","_useState10","focusedChip","setFocusedChip","doesSelectionExist","isNull","isString","val","consoleOnce","_typeof","setInputFocus","cursorPos","isUndefined","setSelectionRange","updateSelection","newSelection","clone","includes","indexOf","push","_newSelection","scrollToEnd","scrollLeft","scrollWidth","placeholderValue","allOptions","getDisplayNameForValue","_allOptions$find$disp","_allOptions$find","find","opt","isOptionVisible","option","toLowerCase","visibleOptions","filter","isValueValid","getIndexOfValue","findIndex","getValueAtIndex","getActiveChipIndex","_getChipRef","_getChipRef$current","document","activeElement","getFocusedElementName","_inputRef$current","_clearButtonRef$curre","_comboboxRef$current","isFocusOn","some","_getChipRef2","_getChipRef2$current","_getChipRef3","_getChipRef3$current","updateFocusedOption","direction","_visibleOptions$lengt","optionsCount","lastIndex","indexOfFocus","newValue","_newValue","_newValue2","_newValue3","updateFocusedChip","relativeToIndex","referenceChipIndex","nextChipIndex","nextChipValue","_referenceChipIndex","prevChipIndex","prevChipValue","firstChipValue","lastChipValue","handleArrowKey","event","focusedElementName","_inputRef$current2","_inputRef$current3","_clearButtonRef$curre2","selectionEnd","preventDefault","_inputRef$current4","_inputRef$current5","selectionStart","focusedElementRef","optionTop","offsetTop","_menuRef$current","menuScroll","scrollTop","offsetHeight","renderInternalOptions","map","_value","_child$props","_className","closeMenu","nestedChildren","renderedOptions","renderedChips","chipRef","renderedInputIcons","IconButton","openMenu","handleClearButtonFocus","onCloseMenu","exactMatchedOption","_getDisplayNameForVal","onSelect","_getDisplayNameForVal2","_initialValue$filter","filteredValue","getNullSelection","isEqual","_useState12","menuWidth","setMenuWidth","_comboboxRef$current$","_comboboxRef$current2","clientWidth","renderedMenuContents","viewportSize","useViewportSize","_comboboxRef$current$3","getBoundingClientRect","triggerTop","top","triggerBottom","bottom","safeSpace","Math","max","height","min","useEventListener","_menuRef$current3","_comboboxRef$current5","popoverProps","Provider","_extends","Label","htmlFor","Description","InteractionRing","onMouseDown","nativeEvent","offsetX","offsetLeft","_menuRef$current2","_comboboxRef$current4","isFocusInMenu","ctrlKey","shiftKey","altKey","focusedElement","Tab","Escape","_inputRef$current6","ArrowDown","ArrowUp","ArrowRight","ArrowLeft","onTransitionEnd","_comboboxRef$current$2","_comboboxRef$current3","autoComplete","Popover","active","spacing","justify","refEl","adjustOnMutation","onMouseDownCapture"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/Combobox.types.ts","../src/ComboboxContext.tsx","../src/ComboboxOption.tsx","../src/Combobox.styles.ts","../src/utils/wrapJSX.tsx","../src/utils/getNameAndValue.ts","../src/utils/OptionObjectUtils.ts","../src/utils/flattenChildren.tsx","../src/Chip.tsx","../src/ComboboxGroup.tsx","../src/Combobox.tsx"],"sourcesContent":["import { ReactElement, ReactNode } from 'react';\nimport { Either } from '@leafygreen-ui/lib';\n\n/**\n * Prop Enums & Types\n */\n\nexport const ComboboxElement = {\n Input: 'Input',\n ClearButton: 'ClearButton',\n FirstChip: 'FirstChip',\n LastChip: 'LastChip',\n MiddleChip: 'MiddleChip',\n Combobox: 'Combobox',\n Menu: 'Menu',\n} as const;\nexport type ComboboxElement =\n typeof ComboboxElement[keyof typeof ComboboxElement];\n\n/**\n * Prop types\n */\n\nexport const ComboboxSize = {\n // TODO: add XSmall & Small variants after the refresh\n // XSmall: 'xsmall',\n // Small: 'small',\n Default: 'default',\n Large: 'large',\n} as const;\nexport type ComboboxSize = typeof ComboboxSize[keyof typeof ComboboxSize];\n\nexport const TrunctationLocation = {\n start: 'start',\n middle: 'middle',\n end: 'end',\n none: 'none',\n} as const;\nexport type TrunctationLocation =\n typeof TrunctationLocation[keyof typeof TrunctationLocation];\n\nexport const Overflow = {\n expandY: 'expand-y',\n expandX: 'expand-x',\n scrollX: 'scroll-x',\n} as const;\nexport type Overflow = typeof Overflow[keyof typeof Overflow];\n\nexport const State = {\n error: 'error',\n none: 'none',\n} as const;\nexport type State = typeof State[keyof typeof State];\n\nexport const SearchState = {\n unset: 'unset',\n error: 'error',\n loading: 'loading',\n} as const;\nexport type SearchState = typeof SearchState[keyof typeof SearchState];\n\n/**\n * Generic Typing\n */\n\nexport type SelectValueType<M extends boolean> = M extends true\n ? Array<string>\n : string | null;\n\nexport type onChangeType<M extends boolean> = M extends true\n ? (value: SelectValueType<true>) => void\n : (value: SelectValueType<false>) => void;\n\n// Returns the correct empty state for multiselcect / single select\nexport function getNullSelection<M extends boolean>(\n multiselect: M,\n): SelectValueType<M> {\n if (multiselect) {\n return [] as Array<string> as SelectValueType<M>;\n } else {\n return null as SelectValueType<M>;\n }\n}\n\n/**\n * Combobox Props\n */\n\nexport interface ComboboxMultiselectProps<M extends boolean> {\n /**\n * Defines whether a user can select multiple options, or only a single option.\n * When using TypeScript, `multiselect` affects the valid values of `initialValue`, `value`, and `onChange`\n */\n multiselect?: M;\n /**\n * The initial selection.\n * Must be a string (or array of strings) that matches the `value` prop of a `ComboboxOption`.\n * Changing the `initialValue` after initial render will not change the selection.\n */\n initialValue?: SelectValueType<M>;\n /**\n * A callback called when the selection changes.\n * Callback recieves a single argument that is the new selection, either string, or string array\n */\n onChange?: onChangeType<M>;\n /**\n * The controlled value of the Combobox.\n * Must be a string (or array of strings) that matches the `value` prop of a `ComboboxOption`.\n * Changing `value` after initial render _will_ affect the selection.\n * `value` will always take precedence over `initialValue` if both are provided.\n */\n value?: SelectValueType<M>;\n\n /**\n * Defines the overflow behavior of a multiselect combobox.\n *\n * `expand-y`: Combobox has fixed width, and additional selections will cause the element to grow in the block direction.\n *\n * `expand-x`: Combobox has fixed height, and additional selections will cause the elemenet to grow in the inline direction.\n *\n * `scroll-x`: Combobox has fixed height and width, and additional selections will cause the element to be scrollable in the x (horizontal) direction.\n */\n overflow?: M extends true ? Overflow : undefined;\n}\n\nexport interface BaseComboboxProps {\n /**\n * Defines the Combobox Options by passing children. Must be `ComboboxOption` or `ComboboxGroup`\n */\n children?: ReactNode;\n\n /**\n * An accessible label for the input, rendered in a <label> to the DOM\n */\n label?: string;\n\n /**\n * An accessible label for the input, used only for screen-readers\n */\n 'aria-label'?: string;\n\n /**\n * A description for the input\n */\n description?: string;\n\n /**\n * A placeholder for the input element. Uses the native `placeholder` attribute.\n */\n placeholder?: string;\n\n /**\n * Disables all interaction with the component\n */\n disabled?: boolean;\n\n /**\n * Defines the visual size of the component\n */\n size?: ComboboxSize;\n\n /**\n * Toggles Dark Mode\n */\n darkMode?: boolean;\n\n /**\n * The error state of the component. Defines whether the error message is displayed.\n */\n state?: State;\n\n /**\n * The message shown below the input when state is `error`\n */\n errorMessage?: string;\n\n /**\n * The state of search results. Toggles search messages within the menu.\n */\n searchState?: SearchState;\n\n /**\n * A message shown within the menu when there are no options passed in as children, or `filteredOptions` is an empty array\n */\n searchEmptyMessage?: string;\n\n /**\n * A message shown within the menu when searchState is `error`\n */\n searchErrorMessage?: string;\n\n /**\n * A message shown within the menu when searchState is `loading`\n */\n searchLoadingMessage?: string;\n\n /**\n * A callback called when the search input changes.\n * Recieves a single argument that is the current input value.\n * Use this callback to set `searchState` and/or `filteredOptions` appropriately\n */\n onFilter?: (value: string) => void;\n\n /**\n * Defines whether the Clear button appears to the right of the input.\n */\n clearable?: boolean;\n\n /**\n * A callback fired when the Clear button is pressed.\n * Fired _after_ `onChange`, and _before_ `onFilter`\n */\n onClear?: (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;\n\n /**\n * An array used to define which options are displayed.\n * Do not remove options from the JSX children, as this will affect the selected options\n */\n filteredOptions?: Array<string>;\n\n /**\n * Defines where the ellipses appear in a Chip when the length exceeds the `chipCharacterLimit`\n */\n chipTruncationLocation?: TrunctationLocation;\n\n /**\n * Defined the character limit of a multiselect Chip before they start truncating.\n * Note: the three ellipses dots are included in the character limit.\n */\n chipCharacterLimit?: number;\n\n /**\n * Styling prop\n */\n className?: string;\n\n /**\n * Specifies that the popover content should be rendered at the end of the DOM,\n * rather than in the DOM tree.\n *\n * default: `true`\n */\n usePortal?: boolean;\n\n /**\n * When usePortal is `true`, specifies a class name to apply to the root element of the portal.\n */\n portalClassName?: undefined;\n\n /**\n * 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.\n */\n portalContainer?: null;\n\n /**\n * When usePortal is `true`, specifies the scrollable element to position relative to.\n */\n scrollContainer?: null;\n\n /**\n * Number that controls the z-index of the popover element directly.\n */\n popoverZIndex?: number;\n}\n\nexport type ComboboxProps<M extends boolean> = Either<\n BaseComboboxProps & ComboboxMultiselectProps<M>,\n 'label' | 'aria-label'\n>;\n\n/**\n * Combobox Option Props\n */\n\ninterface BaseComboboxOptionProps {\n /**\n * The internal value of the option. Used as the identifier in Combobox `initialValue`, value and filteredOptions.\n * When undefined, this is set to `_.kebabCase(displayName)`\n */\n value?: string;\n\n /**\n * The display value of the option. Used as the rendered string within the menu and chips.\n * When undefined, this is set to `value`\n */\n displayName?: string;\n\n /**\n * The icon to display to the left of the option in the menu.\n */\n glyph?: ReactElement;\n\n /**\n * Defines whether the option is disabled.\n * Node: disabled options are still rendered in the menu, but not selectable.\n */\n disabled?: boolean;\n\n /**\n * Styling Prop\n */\n className?: string;\n}\n\nexport type ComboboxOptionProps = Either<\n BaseComboboxOptionProps,\n 'value' | 'displayName'\n>;\n\nexport interface OptionObject {\n value: string;\n displayName: string;\n isDisabled: boolean;\n hasGlyph?: boolean;\n}\n\nexport interface InternalComboboxOptionProps {\n value: string;\n displayName: string;\n isSelected: boolean;\n isFocused: boolean;\n setSelected: () => void;\n disabled?: boolean;\n glyph?: ReactElement;\n className?: string;\n index: number;\n}\n\n/**\n * Combobox Group Props\n */\n\nexport interface ComboboxGroupProps {\n /**\n * Label for the group of options\n */\n label: string;\n\n /**\n * Options in the group. Must be one or more `ComboboxOption` components\n */\n children: React.ReactNode;\n\n /**\n * Styling prop\n */\n className?: string;\n}\n\n/**\n * Combobox Chip\n */\n\nexport interface ChipProps {\n displayName: string;\n isFocused: boolean;\n onRemove: () => void;\n onFocus: () => void;\n}\n","import { createContext } from 'react';\nimport { ComboboxSize, TrunctationLocation } from './Combobox.types';\n\ninterface ComboboxData {\n multiselect: boolean;\n darkMode: boolean;\n size: ComboboxSize;\n withIcons: boolean;\n disabled: boolean;\n chipTruncationLocation?: TrunctationLocation;\n chipCharacterLimit?: number;\n inputValue?: string;\n}\n\nexport const ComboboxContext = createContext<ComboboxData>({\n multiselect: false,\n darkMode: false,\n size: ComboboxSize.Default,\n withIcons: false,\n disabled: false,\n});\n","import { css, cx } from '@leafygreen-ui/emotion';\nimport React, { useCallback, useContext, useMemo } from 'react';\nimport { uiColors } from '@leafygreen-ui/palette';\nimport { isComponentType } from '@leafygreen-ui/lib';\nimport { useForwardedRef, useIdAllocator } from '@leafygreen-ui/hooks';\nimport Checkbox from '@leafygreen-ui/checkbox';\nimport Icon, { isComponentGlyph } from '@leafygreen-ui/icon';\nimport {\n ComboboxOptionProps,\n InternalComboboxOptionProps,\n} from './Combobox.types';\nimport { ComboboxContext } from './ComboboxContext';\nimport { wrapJSX } from './utils';\nimport { fontFamilies } from '@leafygreen-ui/tokens';\n\n/**\n * Styles\n */\n\nconst comboboxOptionStyle = css`\n position: relative;\n display: flex;\n align-items: center;\n justify-content: space-between;\n list-style: none;\n color: inherit;\n cursor: pointer;\n overflow: hidden;\n font-family: ${fontFamilies.legacy};\n font-size: var(--lg-combobox-item-font-size);\n line-height: var(--lg-combobox-item-line-height);\n padding: var(--lg-combobox-item-padding-y) var(--lg-combobox-item-padding-x);\n\n // Left wedge\n &:before {\n content: '';\n position: absolute;\n left: 0;\n width: 3px;\n height: var(--lg-combobox-item-wedge-height);\n background-color: transparent;\n border-radius: 0 2px 2px 0;\n transform: scaleY(0.3);\n transition: 150ms ease-in-out;\n transition-property: transform, background-color;\n }\n\n &:hover {\n outline: none;\n background-color: var(--lg-combobox-item-hover-color);\n }\n\n &[aria-selected='true'] {\n outline: none;\n background-color: var(--lg-combobox-item-active-color);\n\n &:before {\n background-color: var(--lg-combobox-item-wedge-color);\n transform: scaleY(1);\n }\n }\n`;\n\nconst comboboxOptionDisabledStyle = css`\n cursor: not-allowed;\n color: ${uiColors.gray.base};\n\n &:hover {\n background-color: inherit;\n }\n`;\n\nconst flexSpan = css`\n display: inline-flex;\n gap: 8px;\n justify-content: start;\n align-items: inherit;\n overflow-wrap: anywhere;\n`;\n\nconst disallowPointer = css`\n pointer-events: none;\n`;\n\nconst displayNameStyle = (isSelected: boolean) => css`\n font-weight: ${isSelected ? 'bold' : 'normal'};\n`;\n\n/**\n * Component\n */\nconst InternalComboboxOption = React.forwardRef<\n HTMLLIElement,\n InternalComboboxOptionProps\n>(\n (\n {\n displayName,\n glyph,\n isSelected,\n isFocused,\n disabled,\n setSelected,\n className,\n }: InternalComboboxOptionProps,\n forwardedRef,\n ) => {\n const { multiselect, darkMode, withIcons, inputValue } =\n useContext(ComboboxContext);\n const optionTextId = useIdAllocator({ prefix: 'combobox-option-text' });\n const optionRef = useForwardedRef(forwardedRef, null);\n\n const handleOptionClick = useCallback(\n (e: React.SyntheticEvent) => {\n // stopPropagation will not stop the keyDown event (only click)\n // since the option is never `focused`, only `aria-selected`\n // the keyDown event does not actually fire on the option element\n e.stopPropagation();\n\n // If user clicked on the option, or the checkbox\n // Ignore extra click events on the checkbox wrapper\n if (\n !disabled &&\n (e.target === optionRef.current ||\n (e.target as Element).tagName === 'INPUT')\n ) {\n setSelected();\n }\n },\n [disabled, optionRef, setSelected],\n );\n\n const renderedIcon = useMemo(() => {\n if (glyph) {\n if (isComponentGlyph(glyph) || isComponentType(glyph, 'Icon')) {\n return glyph;\n }\n console.error(\n '`ComboboxOption` instance did not render icon because it is not a known glyph element.',\n glyph,\n );\n }\n }, [glyph]);\n\n const renderedChildren = useMemo(() => {\n // Multiselect\n if (multiselect) {\n const checkbox = (\n <Checkbox\n // Using empty label due to this bug: https://jira.mongodb.org/browse/PD-1681\n label=\"\"\n aria-labelledby={optionTextId}\n checked={isSelected}\n tabIndex={-1}\n animate={false}\n disabled={disabled}\n />\n );\n\n return (\n <>\n <span className={cx(flexSpan, disallowPointer)}>\n {withIcons ? renderedIcon : checkbox}\n <span id={optionTextId} className={displayNameStyle(isSelected)}>\n {wrapJSX(displayName, inputValue, 'strong')}\n </span>\n </span>\n {withIcons && checkbox}\n </>\n );\n }\n\n // Single select\n return (\n <>\n <span className={cx(flexSpan, disallowPointer)}>\n {renderedIcon}\n <span className={displayNameStyle(isSelected)}>\n {wrapJSX(displayName, inputValue, 'strong')}\n </span>\n </span>\n {isSelected && (\n <Icon\n glyph=\"Checkmark\"\n color={darkMode ? uiColors.blue.light1 : uiColors.blue.base}\n />\n )}\n </>\n );\n }, [\n multiselect,\n renderedIcon,\n isSelected,\n displayName,\n inputValue,\n darkMode,\n optionTextId,\n disabled,\n withIcons,\n ]);\n\n return (\n <li\n ref={optionRef}\n role=\"option\"\n aria-selected={isFocused}\n aria-label={displayName}\n tabIndex={-1}\n className={cx(\n comboboxOptionStyle,\n {\n [comboboxOptionDisabledStyle]: disabled,\n },\n className,\n )}\n onClick={handleOptionClick}\n onKeyDown={handleOptionClick}\n >\n {renderedChildren}\n </li>\n );\n },\n);\nInternalComboboxOption.displayName = 'ComboboxOption';\n\nexport { InternalComboboxOption };\nexport default function ComboboxOption(_: ComboboxOptionProps): JSX.Element {\n throw Error('`ComboboxOption` must be a child of a `Combobox` instance');\n}\nComboboxOption.displayName = 'ComboboxOption';\n","/**\n * Styles\n */\n\nimport { css, cx, keyframes } from '@leafygreen-ui/emotion';\nimport { createUniqueClassName } from '@leafygreen-ui/lib';\nimport { uiColors } from '@leafygreen-ui/palette';\nimport { fontFamilies, typeScales } from '@leafygreen-ui/tokens';\nimport { isArray } from 'lodash';\nimport { ComboboxSize, Overflow, State } from './Combobox.types';\n\n/**\n * Width of the widest character (in px)\n */\nconst maxCharWidth: Record<ComboboxSize, number> = {\n [ComboboxSize.Default]: typeScales.body1.fontSize,\n [ComboboxSize.Large]: typeScales.body2.fontSize,\n};\n\nexport const chipClassName = createUniqueClassName('combobox-chip');\n\n// TODO: Remove this during refresh update\nexport const _tempLabelDescriptionOverrideStyle = css`\n font-family: ${fontFamilies.legacy};\n font-size: var(--lg-combobox-font-size);\n line-height: var(--lg-combobox-line-height);\n`;\n\nexport const comboboxParentStyle = ({\n darkMode,\n size,\n overflow,\n}: {\n darkMode: boolean;\n size: ComboboxSize;\n overflow: Overflow;\n}) => {\n const modeStyle = (darkMode: boolean) => {\n if (darkMode) {\n return css``;\n } else {\n return css`\n --lg-combobox-color-error: ${uiColors.red.base};\n --lg-combobox-text-color: ${uiColors.gray.dark3};\n --lg-combobox-text-color-disabled: ${uiColors.gray.dark1};\n\n --lg-combobox-background-color: ${uiColors.gray.light3};\n --lg-combobox-background-color-focus: ${uiColors.white};\n --lg-combobox-background-color-disabled: ${uiColors.gray.light2};\n\n --lg-combobox-border-color: ${uiColors.gray.base};\n --lg-combobox-border-color-disabled: ${uiColors.gray.light1};\n --lg-combobox-border-color-error: ${uiColors.red.base};\n\n --lg-combobox-shadow: 0px 1px 2px rgba(6, 22, 33, 0.3);\n --lg-combobox-shadow-focus: 0px 4px 4px rgba(6, 22, 33, 0.3);\n `;\n }\n };\n\n const sizeStyle = (size: ComboboxSize) => {\n switch (size) {\n case ComboboxSize.Default:\n return css`\n --lg-combobox-padding-y: 5px;\n --lg-combobox-padding-x: 7px;\n --lg-combobox-height: calc(\n 36px - 2px - 2 * var(--lg-combobox-padding-y)\n );\n --lg-combobox-font-size: ${typeScales.body1.fontSize +\n 1}px; // TODO: update this for redesign\n --lg-combobox-line-height: ${typeScales.body1.lineHeight + 1}px;\n `;\n case ComboboxSize.Large:\n return css`\n --lg-combobox-padding-y: 9px;\n --lg-combobox-padding-x: 11px;\n --lg-combobox-height: calc(\n 48px - 2px - 2 * var(--lg-combobox-padding-y)\n );\n --lg-combobox-font-size: ${typeScales.body2.fontSize}px;\n --lg-combobox-line-height: ${typeScales.body2.lineHeight}px;\n `;\n }\n };\n\n return cx(\n modeStyle(darkMode),\n sizeStyle(size),\n css`\n --lg-combobox-icon-height: 16px;\n --lg-combobox-border-radius: 3px;\n --lg-combobox-width: ${overflow === 'expand-x' ? 'unset' : '100%'};\n --lg-combobox-padding: var(--lg-combobox-padding-y)\n var(--lg-combobox-padding-x) var(--lg-combobox-padding-y)\n ${overflow === 'scroll-x' ? '0' : 'var(--lg-combobox-padding-x)'};\n width: var(--lg-combobox-width);\n // TODO: Clean this up 🤮\n min-width: calc(\n ${maxCharWidth[size]}px + var(--lg-combobox-padding-x) * 2 + 2px +\n var(--lg-combobox-icon-height)\n );\n `,\n );\n};\n\nexport const comboboxStyle = css`\n display: flex;\n flex-wrap: nowrap;\n align-items: center;\n padding: var(--lg-combobox-padding);\n color: var(--lg-combobox-text-color);\n background-color: var(--lg-combobox-background-color);\n box-shadow: var(--lg-combobox-shadow);\n border: 1px solid var(--lg-combobox-border-color);\n border-radius: var(--lg-combobox-border-radius);\n width: var(--lg-combobox-width);\n cursor: text;\n transition: 150ms ease-in-out;\n transition-property: background-color, box-shadow, border-color;\n\n &[data-disabled='true'] {\n color: var(--lg-combobox-text-color-disabled);\n background-color: var(--lg-combobox-background-color-disabled);\n border-color: var(--lg-combobox-border-color-disabled);\n box-shadow: unset;\n cursor: not-allowed;\n }\n\n &[data-state='error'] {\n border-color: var(--lg-combobox-border-color-error);\n }\n`;\n\nexport const comboboxFocusStyle = css`\n &:focus-within {\n border-color: transparent;\n background-color: var(--lg-combobox-background-color-focus);\n // TODO: Remove for UI refresh & Darkmode\n box-shadow: 0 0 0 3px ${uiColors.focus}, var(--lg-combobox-shadow-focus);\n }\n`;\n\nexport const interactionRingColor = ({\n state,\n darkMode,\n}: {\n state: State;\n darkMode: boolean;\n}) => {\n if (darkMode) {\n return {\n hovered: state === 'error' ? uiColors.red.dark2 : undefined,\n };\n } else {\n return {\n hovered: state === 'error' ? uiColors.red.light3 : undefined,\n };\n }\n};\n\nexport const inputWrapperStyle = ({\n overflow,\n isOpen,\n selection,\n size,\n value,\n}: {\n overflow: Overflow;\n isOpen: boolean;\n selection: string | Array<string> | null;\n size: ComboboxSize;\n value?: string;\n}) => {\n const isMultiselect = isArray(selection) && selection.length > 0;\n const inputLength = value?.length ?? 0;\n\n const baseWrapperStyle = css`\n flex-grow: 1;\n width: var(--lg-combobox-width);\n\n --lg-combobox-input-width: ${isMultiselect\n ? `${inputLength * maxCharWidth[size]}px`\n : '100%'};\n --lg-combobox-input-min-width: ${maxCharWidth[size]}px;\n `;\n\n switch (overflow) {\n case 'scroll-x': {\n return css`\n ${baseWrapperStyle}\n display: block;\n height: var(--lg-combobox-height);\n white-space: nowrap;\n overflow-x: scroll;\n padding-left: var(--lg-combobox-padding-x);\n scroll-behavior: smooth;\n scrollbar-width: none;\n /*\n * Immediate transition in, slow transition out. \n * '-in' transition is handled by \\`scroll-behavior\\` \n */\n --lg-combobox-input-transition: width ease-in-out\n ${isOpen ? '0' : '100ms'};\n\n &::-webkit-scrollbar {\n display: none;\n }\n\n & > .${chipClassName} {\n margin-inline: 2px;\n\n &:first-child {\n margin-inline-start: 0;\n }\n\n &:last-child {\n margin-inline-end: 0;\n }\n }\n `;\n }\n\n case 'expand-x': {\n return css`\n ${baseWrapperStyle}\n display: flex;\n gap: 4px;\n flex-wrap: nowrap;\n white-space: nowrap;\n height: var(--lg-combobox-height);\n --lg-combobox-input-transition: none;\n `;\n }\n\n // TODO - look into animating input element height on wrap\n case 'expand-y': {\n return css`\n ${baseWrapperStyle}\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n overflow-x: visible;\n min-height: var(--lg-combobox-height);\n `;\n }\n }\n};\n\nexport const inputElementStyle = css`\n border: none;\n cursor: inherit;\n background-color: inherit;\n box-sizing: content-box;\n padding: 0;\n margin: 0;\n text-overflow: ellipsis;\n font-size: var(--lg-combobox-font-size);\n line-height: var(--lg-combobox-line-height);\n height: var(--lg-combobox-height);\n width: var(--lg-combobox-input-width, 0);\n min-width: var(--lg-combobox-input-min-width);\n transition: var(--lg-combobox-input-transition);\n\n &:focus {\n outline: none;\n }\n`;\n\nexport const clearButtonStyle = css`\n // Add a negative margin so the button takes up the same space as the regular icons\n margin-block: calc(var(--lg-combobox-icon-height) / 2 - 100%);\n`;\n\n// Temporary styles to override redesigned icon-button\n// TODO: Remove for UI refresh\nexport const clearButtonFocusOverrideStyles = css`\n &:focus {\n box-shadow: unset;\n &::before {\n background-color: ${uiColors.blue.light2};\n }\n }\n`;\n\nexport const errorMessageStyle = css`\n font-size: var(--lg-combobox-font-size);\n line-height: var(--lg-combobox-line-height);\n color: var(--lg-combobox-color-error);\n padding-top: var(--lg-combobox-padding-y);\n`;\n\nexport const endIcon = css`\n margin-inline-end: calc(var(--lg-combobox-padding-x) / 2);\n`;\n\nconst loadingIconAnimation = keyframes`\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n`;\nexport const loadingIconStyle = css`\n animation: ${loadingIconAnimation} 1.5s linear infinite;\n`;\n\n/**\n * Menu styles\n */\nexport const menuWrapperStyle = ({\n darkMode,\n size,\n width = 384,\n}: {\n darkMode: boolean;\n size: ComboboxSize;\n width?: number;\n}) => {\n let menuModeStyle, menuSizeStyle;\n\n if (darkMode) {\n menuModeStyle = css``;\n } else {\n menuModeStyle = css`\n --lg-combobox-menu-color: ${uiColors.gray.dark3};\n --lg-combobox-menu-message-color: ${uiColors.gray.dark1};\n --lg-combobox-menu-background-color: ${uiColors.white};\n --lg-combobox-menu-shadow: 0px 3px 7px rgba(0, 0, 0, 0.25);\n --lg-combobox-item-hover-color: ${uiColors.gray.light2};\n --lg-combobox-item-active-color: ${uiColors.blue.light3};\n --lg-combobox-item-wedge-color: ${uiColors.blue.base};\n `;\n }\n\n switch (size) {\n case ComboboxSize.Default:\n menuSizeStyle = css`\n --lg-combobox-menu-border-radius: 4px;\n --lg-combobox-item-height: 36px;\n --lg-combobox-item-padding-y: 8px;\n --lg-combobox-item-padding-x: 12px;\n --lg-combobox-item-font-size: ${typeScales.body1.fontSize +\n 1}px; // TODO: update this\n --lg-combobox-item-line-height: ${typeScales.body1.lineHeight +\n 1}px; // TODO: update this\n --lg-combobox-item-wedge-height: 22px;\n `;\n break;\n case ComboboxSize.Large:\n menuSizeStyle = css`\n --lg-combobox-menu-border-radius: 4px;\n --lg-combobox-item-height: 36px;\n --lg-combobox-item-padding-y: 8px;\n --lg-combobox-item-padding-x: 12px;\n --lg-combobox-item-font-size: ${typeScales.body2.fontSize +\n 1}px; // TODO: update this\n --lg-combobox-item-line-height: ${typeScales.body2.lineHeight +\n 1}px; // TODO: update this\n --lg-combobox-item-wedge-height: 22px;\n `;\n break;\n }\n\n return cx(\n menuModeStyle,\n menuSizeStyle,\n css`\n width: ${width}px;\n border-radius: var(--lg-combobox-menu-border-radius);\n\n & > * {\n border-radius: inherit;\n }\n `,\n );\n};\n\nexport const menuStyle = ({ maxHeight }: { maxHeight: number }) => css`\n position: relative;\n width: 100%;\n margin: 0;\n padding: 0;\n font-family: ${fontFamilies.default};\n color: var(--lg-combobox-menu-color);\n background-color: var(--lg-combobox-menu-background-color);\n box-shadow: var(--lg-combobox-menu-shadow);\n border-radius: inherit;\n overflow: auto;\n min-height: var(--lg-combobox-item-height);\n max-height: ${maxHeight}px;\n scroll-behavior: smooth;\n`;\n\nexport const menuList = css`\n position: relative;\n margin: 0;\n padding: 0;\n`;\n\nexport const menuMessage = css`\n display: inline-flex;\n align-items: center;\n gap: 8px;\n font-size: var(--lg-combobox-item-font-size);\n color: var(--lg-combobox-menu-message-color);\n padding: var(--lg-combobox-item-padding-y) var(--lg-combobox-item-padding-x);\n\n & > svg {\n width: 1em;\n height: 1em;\n }\n`;\n","import React, { ReactChild } from 'react';\n\n/**\n *\n * Wraps every instance of `wrap` found in `str` in the provided `element`.\n *\n * E.g. `wrapJSX('Apple', 'ap', 'em') => <em>Ap</em>ple`\n *\n * @param str\n * @param wrap\n * @param element\n * @returns `JSX.Element`\n */\nexport const wrapJSX = (\n str: string,\n wrap?: string,\n element?: keyof HTMLElementTagNameMap,\n): JSX.Element => {\n if (wrap && element) {\n const regex = new RegExp(wrap, 'gi');\n const matches = str.matchAll(regex);\n\n if (matches) {\n const outArray = str.split('') as Array<ReactChild>;\n\n /**\n * For every match, splice it into the \"string\",\n * wrapped in the React element\n */\n // Consider adding --downlevelIteration TS flag so we don't need Array.from\n for (const match of Array.from(matches)) {\n const matchIndex = match.index ?? -1;\n const matchContent = match[0];\n const matchLength = matchContent.length;\n const key = matchIndex + matchContent + matchLength;\n\n // We create a replacement array that's\n // the same length as the match we're deleting,\n // in order to keep the matchIndexes aligned\n // with the indexes of the output array\n const replacement = new Array<ReactChild>(matchLength).fill('');\n replacement[0] = React.createElement(element, { key }, matchContent);\n\n outArray.splice(matchIndex, matchLength, ...replacement);\n }\n\n return <>{outArray}</>;\n }\n\n return <>{str}</>;\n }\n\n return <>{str}</>;\n};\n","import kebabCase from 'lodash/kebabCase';\nimport { ComboboxOptionProps } from '../Combobox.types';\n\n/**\n *\n * Returns an object with properties `value` & `displayName`\n * based on the props provided\n *\n * @property value: string\n * @property displayName: string\n */\nexport const getNameAndValue = ({\n value: valProp,\n displayName: nameProp,\n}: ComboboxOptionProps): {\n value: string;\n displayName: string;\n} => {\n return {\n value: valProp ?? kebabCase(nameProp),\n displayName: nameProp ?? valProp ?? '', // TODO consider adding a prop to customize displayName => startCase(valProp),\n };\n};\n","import { OptionObject } from '../Combobox.types';\n\nexport const getOptionObjectFromValue = (\n value: string | null,\n options: Array<OptionObject>,\n): OptionObject | undefined => {\n if (value) return options.find(opt => opt.value === value);\n};\n\nexport const getDisplayNameForValue = (\n value: string | null,\n options: Array<OptionObject>,\n): string => {\n return value\n ? getOptionObjectFromValue(value, options)?.displayName ?? value\n : '';\n};\n\nexport const getValueForDisplayName = (\n displayName: string | null,\n options: Array<OptionObject>,\n): string => {\n return displayName\n ? options.find(opt => opt.displayName === displayName)?.value ?? displayName\n : '';\n};\n","import React from 'react';\nimport { isComponentType, keyMap as _keyMap } from '@leafygreen-ui/lib';\nimport { OptionObject } from '../Combobox.types';\nimport { getNameAndValue } from './getNameAndValue';\n\n/**\n *\n * Flattens multiple nested ComboboxOptions into a 1D array\n *\n * @param _children\n * @returns `Array<OptionObject>`\n */\nexport const flattenChildren = (\n _children: React.ReactNode,\n): Array<OptionObject> => {\n // TS doesn't like .reduce\n // @ts-expect-error\n return React.Children.toArray(_children).reduce(\n // @ts-expect-error\n (\n acc: Array<OptionObject>,\n child: React.ReactNode,\n ): Array<OptionObject> | undefined => {\n if (isComponentType(child, 'ComboboxOption')) {\n const { value, displayName } = getNameAndValue(child.props);\n const { glyph, disabled } = child.props;\n\n return [\n ...acc,\n {\n value,\n displayName,\n isDisabled: !!disabled,\n hasGlyph: !!glyph,\n },\n ];\n } else if (isComponentType(child, 'ComboboxGroup')) {\n const { children } = child.props;\n\n if (children) {\n return [...acc, ...flattenChildren(children)];\n }\n }\n },\n [] as Array<OptionObject>,\n );\n};\n","import React, { useContext, useEffect, useMemo, useRef } from 'react';\nimport { ChipProps, ComboboxSize } from './Combobox.types';\nimport Icon from '@leafygreen-ui/icon';\nimport { ComboboxContext } from './ComboboxContext';\nimport { css, cx } from '@leafygreen-ui/emotion';\nimport { uiColors } from '@leafygreen-ui/palette';\nimport InlineDefinition from '@leafygreen-ui/inline-definition';\nimport { keyMap } from '@leafygreen-ui/lib';\nimport { chipClassName } from './Combobox.styles';\nimport { typeScales } from '@leafygreen-ui/tokens';\n\nconst chipWrapperStyle = ({\n darkMode,\n size,\n}: {\n darkMode: boolean;\n size: ComboboxSize;\n}) => {\n let chipModeStyle, chipSizeStyle;\n\n if (darkMode) {\n chipModeStyle = css``;\n } else {\n chipModeStyle = css`\n --lg-combobox-chip-text-color: ${uiColors.gray.dark3};\n --lg-combobox-chip-icon-color: ${uiColors.gray.dark2};\n --lg-combobox-chip-background-color: ${uiColors.gray.light2};\n --lg-combobox-chip-hover-color: ${uiColors.gray.light1};\n --lg-combobox-chip-focus-color: ${uiColors.blue.light2};\n `;\n }\n\n switch (size) {\n case ComboboxSize.Default:\n chipSizeStyle = css`\n --lg-combobox-chip-height: 24px;\n --lg-combobox-chip-border-radius: 4px;\n --lg-combobox-chip-font-size: 14px;\n --lg-combobox-chip-line-height: 20px;\n --lg-combobox-chip-padding-x: 6px;\n `;\n break;\n case ComboboxSize.Large:\n chipSizeStyle = css`\n --lg-combobox-chip-height: 28px;\n --lg-combobox-chip-border-radius: 4px;\n --lg-combobox-chip-font-size: ${typeScales.body2.fontSize}px;\n --lg-combobox-chip-line-height: ${typeScales.body2.lineHeight}px;\n --lg-combobox-chip-padding-x: 6px;\n `;\n break;\n }\n\n return cx(\n chipModeStyle,\n chipSizeStyle,\n css`\n display: inline-flex;\n align-items: center;\n overflow: hidden;\n white-space: nowrap;\n height: var(--lg-combobox-chip-height);\n font-size: var(--lg-combobox-chip-font-size);\n line-height: var(--lg-combobox-chip-line-height);\n border-radius: var(--lg-combobox-chip-border-radius);\n color: var(--lg-combobox-chip-text-color);\n background-color: var(--lg-combobox-chip-background-color);\n\n // TODO - refine these styles\n /* &:focus, */\n &:focus-within {\n background-color: var(--lg-combobox-chip-focus-color);\n }\n `,\n );\n};\n\nconst chipText = css`\n padding-inline: var(--lg-combobox-chip-padding-x);\n`;\n\nconst chipButton = css`\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n outline: none;\n border: none;\n background-color: transparent;\n color: var(--lg-combobox-chip-icon-color);\n cursor: pointer;\n transition: background-color 100ms ease-in-out;\n\n &:before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n width: 1px;\n background-color: var(--lg-combobox-chip-hover-color);\n }\n\n &:hover {\n background-color: var(--lg-combobox-chip-hover-color);\n }\n`;\n\nexport const Chip = React.forwardRef<HTMLSpanElement, ChipProps>(\n ({ displayName, isFocused, onRemove, onFocus }: ChipProps, forwardedRef) => {\n const {\n darkMode,\n size,\n disabled,\n chipTruncationLocation = 'end',\n chipCharacterLimit = 12,\n } = useContext(ComboboxContext);\n\n const isTruncated =\n !!chipCharacterLimit &&\n !!chipTruncationLocation &&\n chipTruncationLocation !== 'none' &&\n displayName.length > chipCharacterLimit;\n\n const buttonRef = useRef<HTMLButtonElement>(null);\n\n const truncatedName = useMemo(() => {\n if (isTruncated) {\n const ellipsis = '…';\n const chars = chipCharacterLimit - 3; // ellipsis dots included in the char limit\n\n switch (chipTruncationLocation) {\n case 'start': {\n const end = displayName\n .substring(displayName.length - chars)\n .trim();\n return ellipsis + end;\n }\n\n case 'middle': {\n const start = displayName.substring(0, chars / 2).trim();\n const end = displayName\n .substring(displayName.length - chars / 2)\n .trim();\n return start + ellipsis + end;\n }\n\n case 'end': {\n const start = displayName.substring(0, chars).trim();\n return start + ellipsis;\n }\n\n default: {\n return displayName;\n }\n }\n }\n\n return false;\n }, [chipCharacterLimit, chipTruncationLocation, displayName, isTruncated]);\n\n useEffect(() => {\n if (isFocused && !disabled) {\n buttonRef?.current?.focus();\n }\n }, [disabled, forwardedRef, isFocused]);\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (\n !disabled &&\n (e.keyCode === keyMap.Delete ||\n e.keyCode === keyMap.Backspace ||\n e.keyCode === keyMap.Enter ||\n e.keyCode === keyMap.Space)\n ) {\n onRemove();\n }\n };\n\n const handleChipClick = (e: React.MouseEvent) => {\n // Did not click button\n if (!buttonRef.current?.contains(e.target as Node)) {\n onFocus();\n }\n };\n\n const handleButtonClick = () => {\n if (!disabled) {\n onRemove();\n }\n };\n\n return (\n // eslint-disable-next-line jsx-a11y/click-events-have-key-events\n <span\n role=\"option\"\n aria-selected={isFocused}\n data-testid=\"lg-combobox-chip\"\n ref={forwardedRef}\n className={cx(chipClassName, chipWrapperStyle({ darkMode, size }))}\n onClick={handleChipClick}\n onKeyDown={handleKeyDown}\n tabIndex={-1}\n >\n <span className={chipText}>\n {truncatedName ? (\n <InlineDefinition definition={displayName} align=\"bottom\">\n {truncatedName}\n </InlineDefinition>\n ) : (\n displayName\n )}\n </span>\n <button\n aria-label={`Deselect ${displayName}`}\n aria-disabled={disabled}\n disabled={disabled}\n ref={buttonRef}\n className={chipButton}\n onClick={handleButtonClick}\n >\n <Icon glyph=\"X\" />\n </button>\n </span>\n );\n },\n);\nChip.displayName = 'Chip';\n","import { css, cx } from '@leafygreen-ui/emotion';\nimport { useIdAllocator } from '@leafygreen-ui/hooks';\nimport { uiColors } from '@leafygreen-ui/palette';\nimport React, { useContext } from 'react';\nimport { ComboboxGroupProps } from './Combobox.types';\nimport { ComboboxContext } from './ComboboxContext';\n\nconst comboboxGroupStyle = (darkMode: boolean) => css`\n --lg-combobox-group-label-color: ${darkMode\n ? uiColors.gray.light1\n : uiColors.gray.dark1};\n --lg-combobox-group-border-color: ${darkMode\n ? uiColors.gray.dark1\n : uiColors.gray.light1};\n padding-top: 8px;\n border-bottom: 1px solid var(--lg-combobox-group-border-color);\n`;\n\nconst comboboxGroupLabel = css`\n cursor: default;\n width: 100%;\n padding: 0 12px 2px;\n outline: none;\n overflow-wrap: anywhere;\n font-size: 12px;\n line-height: 16px;\n font-weight: bold;\n text-transform: uppercase;\n letter-spacing: 0.4px;\n color: var(--lg-combobox-group-label-color);\n`;\n\nexport function InternalComboboxGroup({\n label,\n className,\n children,\n}: ComboboxGroupProps): JSX.Element {\n const { darkMode } = useContext(ComboboxContext);\n\n const groupId = useIdAllocator({ prefix: 'combobox-group' });\n const childCount = React.Children.count(children);\n\n return childCount > 0 ? (\n <div className={cx(comboboxGroupStyle(darkMode), className)}>\n <div className={comboboxGroupLabel} id={groupId}>\n {label}\n </div>\n <div role=\"group\" aria-labelledby={groupId}>\n {children}\n </div>\n </div>\n ) : (\n <></>\n );\n}\n\nComboboxGroup.displayName = 'ComboboxGroup';\n\nexport default function ComboboxGroup(_: ComboboxGroupProps): JSX.Element {\n throw Error('`ComboboxGroup` must be a child of a `Combobox` instance');\n}\n","import React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { clone, isArray, isEqual, isNull, isString, isUndefined } from 'lodash';\nimport { Description, Label } from '@leafygreen-ui/typography';\nimport Popover from '@leafygreen-ui/popover';\nimport {\n useAvailableSpace,\n useDynamicRefs,\n useEventListener,\n useIdAllocator,\n usePrevious,\n} from '@leafygreen-ui/hooks';\nimport Icon from '@leafygreen-ui/icon';\nimport IconButton from '@leafygreen-ui/icon-button';\nimport { cx } from '@leafygreen-ui/emotion';\nimport { uiColors } from '@leafygreen-ui/palette';\nimport { consoleOnce, isComponentType, keyMap } from '@leafygreen-ui/lib';\nimport {\n ComboboxProps,\n getNullSelection,\n onChangeType,\n SelectValueType,\n OptionObject,\n ComboboxElement,\n ComboboxSize,\n} from './Combobox.types';\nimport { ComboboxContext } from './ComboboxContext';\nimport { InternalComboboxOption } from './ComboboxOption';\nimport { Chip } from './Chip';\nimport {\n clearButtonStyle,\n clearButtonFocusOverrideStyles,\n comboboxFocusStyle,\n comboboxParentStyle,\n comboboxStyle,\n endIcon,\n errorMessageStyle,\n inputElementStyle,\n inputWrapperStyle,\n loadingIconStyle,\n menuList,\n menuMessage,\n menuStyle,\n menuWrapperStyle,\n _tempLabelDescriptionOverrideStyle,\n} from './Combobox.styles';\nimport { InternalComboboxGroup } from './ComboboxGroup';\nimport {\n flattenChildren,\n getOptionObjectFromValue,\n getDisplayNameForValue,\n getValueForDisplayName,\n getNameAndValue,\n} from './utils';\n\n/**\n * Combobox is a combination of a Select and TextInput,\n * allowing the user to either type a value directly or select a value from the list.\n * Can be configured to select a single or multiple options.\n */\nexport default function Combobox<M extends boolean>({\n children,\n label,\n description,\n placeholder = 'Select',\n 'aria-label': ariaLabel,\n disabled = false,\n size = ComboboxSize.Default,\n darkMode = false,\n state = 'none',\n errorMessage,\n searchState = 'unset',\n searchEmptyMessage = 'No results found',\n searchErrorMessage = 'Could not get results!',\n searchLoadingMessage = 'Loading results...',\n filteredOptions,\n onFilter,\n clearable = true,\n onClear,\n overflow = 'expand-y',\n multiselect = false as M,\n initialValue,\n onChange,\n value,\n chipTruncationLocation,\n chipCharacterLimit = 12,\n className,\n usePortal = true,\n portalClassName,\n portalContainer,\n scrollContainer,\n popoverZIndex,\n ...rest\n}: ComboboxProps<M>) {\n const getOptionRef = useDynamicRefs<HTMLLIElement>({ prefix: 'option' });\n const getChipRef = useDynamicRefs<HTMLSpanElement>({ prefix: 'chip' });\n\n const inputId = useIdAllocator({ prefix: 'combobox-input' });\n const labelId = useIdAllocator({ prefix: 'combobox-label' });\n const menuId = useIdAllocator({ prefix: 'combobox-menu' });\n\n const comboboxRef = useRef<HTMLDivElement>(null);\n const clearButtonRef = useRef<HTMLButtonElement>(null);\n const inputWrapperRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n\n const [isOpen, setOpen] = useState(false);\n const wasOpen = usePrevious(isOpen);\n const [highlightedOption, sethighlightedOption] = useState<string | null>(\n null,\n );\n const [selection, setSelection] = useState<SelectValueType<M> | null>(null);\n const prevSelection = usePrevious(selection);\n const [inputValue, setInputValue] = useState<string>('');\n const prevValue = usePrevious(inputValue);\n const [focusedChip, setFocusedChip] = useState<string | null>(null);\n\n const doesSelectionExist =\n !isNull(selection) &&\n ((isArray(selection) && selection.length > 0) || isString(selection));\n\n const placeholderValue =\n multiselect && isArray(selection) && selection.length > 0\n ? undefined\n : placeholder;\n\n const closeMenu = () => setOpen(false);\n const openMenu = () => setOpen(true);\n\n /**\n * Array of all of the options objects\n */\n const allOptions: Array<OptionObject> = useMemo(\n () => flattenChildren(children),\n [children],\n );\n\n /**\n * Utility function that tells Typescript whether selection is multiselect\n */\n const isMultiselect = useCallback(\n <T extends string>(val?: Array<T> | T | null): val is Array<T> => {\n if (multiselect && (typeof val == 'string' || typeof val == 'number')) {\n consoleOnce.error(\n `Error in Combobox: multiselect is set to \\`true\\`, but recieved a ${typeof val} value: \"${val}\"`,\n );\n } else if (!multiselect && isArray(val)) {\n consoleOnce.error(\n 'Error in Combobox: multiselect is set to `false`, but recieved an Array value',\n );\n }\n\n return multiselect && isArray(val);\n },\n [multiselect],\n );\n\n /**\n * Forces focus of input box\n * @param cursorPos index the cursor should be set to\n */\n const setInputFocus = useCallback(\n (cursorPos?: number) => {\n if (!disabled && inputRef && inputRef.current) {\n inputRef.current.focus();\n if (!isUndefined(cursorPos)) {\n inputRef.current.setSelectionRange(cursorPos, cursorPos);\n }\n }\n },\n [disabled],\n );\n\n /**\n * Update selection.\n * This behaves differently in multi. vs single select.\n * @param value option value the selection should be set to\n */\n const updateSelection = useCallback(\n (value: string | null) => {\n if (isMultiselect(selection)) {\n const newSelection: SelectValueType<M> = clone(selection);\n\n if (isNull(value)) {\n newSelection.length = 0;\n } else {\n if (selection.includes(value)) {\n // remove from array\n newSelection.splice(newSelection.indexOf(value), 1);\n } else {\n // add to array\n newSelection.push(value);\n // clear text\n setInputValue('');\n }\n }\n setSelection(newSelection);\n (onChange as onChangeType<true>)?.(\n newSelection as SelectValueType<true>,\n );\n } else {\n const newSelection: SelectValueType<M> = value as SelectValueType<M>;\n setSelection(newSelection);\n (onChange as onChangeType<false>)?.(\n newSelection as SelectValueType<false>,\n );\n }\n },\n [isMultiselect, onChange, selection],\n );\n\n /**\n * Returns whether a given value is included in, or equal to, the current selection\n * @param value the option value to check\n */\n const isValueCurrentSelection = useCallback(\n (value: string): boolean => {\n return isMultiselect(selection)\n ? selection.includes(value)\n : value === selection;\n },\n [isMultiselect, selection],\n );\n\n /**\n * Returns whether given text is included in, or equal to, the current selection.\n * Similar to `isValueCurrentSelection`, but assumes the text argument is the `displayName` for the selection\n * @param text the text to check\n */\n const isTextCurrentSelection = useCallback(\n (text: string): boolean => {\n const value = getValueForDisplayName(text, allOptions);\n return isValueCurrentSelection(value);\n },\n [allOptions, isValueCurrentSelection],\n );\n\n /**\n * Returns whether the provided option is disabled\n * @param option the option value or OptionObject to check\n */\n const isOptionDisabled = (option: string | OptionObject): boolean => {\n if (typeof option === 'string') {\n const optionObj = getOptionObjectFromValue(option, allOptions);\n return !!optionObj?.isDisabled;\n } else {\n return !!option.isDisabled;\n }\n };\n\n /**\n * Computes whether the option is visible based on the current input\n * @param option the option value or OptionObject to compute\n */\n const shouldOptionBeVisible = useCallback(\n (option: string | OptionObject): boolean => {\n const value = typeof option === 'string' ? option : option.value;\n\n // If filtered options are provided\n if (filteredOptions && filteredOptions.length > 0) {\n return filteredOptions.includes(value);\n }\n\n // If the text input value is the current selection\n // (or included in the selection)\n // then all options should be visible\n if (isTextCurrentSelection(inputValue)) {\n return true;\n }\n\n // otherwise, we do our own filtering\n const displayName =\n typeof option === 'string'\n ? getDisplayNameForValue(value, allOptions)\n : option.displayName;\n\n const isValueInDisplayName = displayName\n .toLowerCase()\n .includes(inputValue.toLowerCase());\n\n return isValueInDisplayName;\n },\n [filteredOptions, isTextCurrentSelection, inputValue, allOptions],\n );\n\n /**\n * The array of visible options objects\n */\n const visibleOptions: Array<OptionObject> = useMemo(\n () => allOptions.filter(shouldOptionBeVisible),\n [allOptions, shouldOptionBeVisible],\n );\n\n /**\n * Returns whether the given value is in the options array\n * @param value the value to check\n */\n const isValueValid = useCallback(\n (value: string | null): boolean => {\n return value ? !!allOptions.find(opt => opt.value === value) : false;\n },\n [allOptions],\n );\n\n /**\n * Returns the index of a given value in the array of visible (filtered) options\n * @param value the option value to get the index of\n */\n const getIndexOfValue = useCallback(\n (value: string | null): number => {\n return visibleOptions\n ? visibleOptions.findIndex(option => option.value === value)\n : -1;\n },\n [visibleOptions],\n );\n\n /**\n * Returns the option value of a given index in the array of visible (filtered) options\n * @param index the option index to get the value of\n */\n const getValueAtIndex = useCallback(\n (index: number): string | undefined => {\n if (visibleOptions && visibleOptions.length >= index) {\n const option = visibleOptions[index];\n return option ? option.value : undefined;\n }\n },\n [visibleOptions],\n );\n\n /**\n * Returns the index of the active chip in the selection array\n */\n const getActiveChipIndex = useCallback(\n () =>\n isMultiselect(selection)\n ? selection.findIndex(value =>\n getChipRef(value)?.current?.contains(document.activeElement),\n )\n : -1,\n [getChipRef, isMultiselect, selection],\n );\n\n /**\n *\n * Focus Management\n *\n */\n\n const [focusedElementName, trackFocusedElement] = useState<\n ComboboxElement | undefined\n >();\n\n type Direction = 'next' | 'prev' | 'first' | 'last';\n\n /**\n * Updates the highlighted menu option based on the provided direction\n * @param direction the direction to move the focus. `'next' | 'prev' | 'first' | 'last'`\n */\n const updateHighlightedOption = useCallback(\n (direction: Direction) => {\n const optionsCount = visibleOptions?.length ?? 0;\n const lastIndex = optionsCount - 1 > 0 ? optionsCount - 1 : 0;\n const indexOfHighlight = getIndexOfValue(highlightedOption);\n\n // Remove focus from chip\n if (direction && isOpen) {\n setFocusedChip(null);\n setInputFocus();\n }\n\n switch (direction) {\n case 'next': {\n const newValue =\n indexOfHighlight + 1 < optionsCount\n ? getValueAtIndex(indexOfHighlight + 1)\n : getValueAtIndex(0);\n\n sethighlightedOption(newValue ?? null);\n break;\n }\n\n case 'prev': {\n const newValue =\n indexOfHighlight - 1 >= 0\n ? getValueAtIndex(indexOfHighlight - 1)\n : getValueAtIndex(lastIndex);\n\n sethighlightedOption(newValue ?? null);\n break;\n }\n\n case 'last': {\n const newValue = getValueAtIndex(lastIndex);\n sethighlightedOption(newValue ?? null);\n break;\n }\n\n case 'first':\n default: {\n const newValue = getValueAtIndex(0);\n sethighlightedOption(newValue ?? null);\n }\n }\n },\n [\n highlightedOption,\n getIndexOfValue,\n getValueAtIndex,\n isOpen,\n setInputFocus,\n visibleOptions?.length,\n ],\n );\n\n /**\n * Updates the focused chip based on the provided direction\n * @param direction the direction to move the focus. `'next' | 'prev' | 'first' | 'last'`\n * @param relativeToIndex the chip index to move focus relative to\n */\n const updateFocusedChip = useCallback(\n (direction: Direction | null, relativeToIndex?: number) => {\n if (isMultiselect(selection)) {\n switch (direction) {\n case 'next': {\n const referenceChipIndex = relativeToIndex ?? getActiveChipIndex();\n const nextChipIndex =\n referenceChipIndex + 1 < selection.length\n ? referenceChipIndex + 1\n : selection.length - 1;\n const nextChipValue = selection[nextChipIndex];\n setFocusedChip(nextChipValue);\n break;\n }\n\n case 'prev': {\n const referenceChipIndex = relativeToIndex ?? getActiveChipIndex();\n const prevChipIndex =\n referenceChipIndex > 0\n ? referenceChipIndex - 1\n : referenceChipIndex < 0\n ? selection.length - 1\n : 0;\n const prevChipValue = selection[prevChipIndex];\n setFocusedChip(prevChipValue);\n break;\n }\n\n case 'first': {\n const firstChipValue = selection[0];\n setFocusedChip(firstChipValue);\n break;\n }\n\n case 'last': {\n const lastChipValue = selection[selection.length - 1];\n setFocusedChip(lastChipValue);\n break;\n }\n\n default:\n setFocusedChip(null);\n break;\n }\n }\n },\n [getActiveChipIndex, isMultiselect, selection],\n );\n\n /**\n * Handles an arrow key press\n */\n const handleArrowKey = useCallback(\n (direction: 'left' | 'right', event: React.KeyboardEvent<Element>) => {\n // Remove focus from menu\n if (direction) sethighlightedOption(null);\n\n switch (direction) {\n case 'right':\n switch (focusedElementName) {\n case ComboboxElement.Input: {\n // If cursor is at the end of the input\n if (\n inputRef.current?.selectionEnd ===\n inputRef.current?.value.length\n ) {\n clearButtonRef.current?.focus();\n }\n break;\n }\n\n case ComboboxElement.FirstChip:\n case ComboboxElement.MiddleChip:\n case ComboboxElement.LastChip: {\n if (\n focusedElementName === ComboboxElement.LastChip ||\n // the first chip is also the last chip (i.e. only one)\n selection?.length === 1\n ) {\n // if focus is on last chip, go to input\n setInputFocus(0);\n updateFocusedChip(null);\n event.preventDefault();\n break;\n }\n // First/middle chips\n updateFocusedChip('next');\n break;\n }\n\n case ComboboxElement.ClearButton:\n default:\n break;\n }\n break;\n\n case 'left':\n switch (focusedElementName) {\n case ComboboxElement.ClearButton: {\n event.preventDefault();\n setInputFocus(inputRef?.current?.value.length);\n break;\n }\n\n case ComboboxElement.Input:\n case ComboboxElement.MiddleChip:\n case ComboboxElement.LastChip: {\n if (isMultiselect(selection)) {\n // Break if cursor is not at the start of the input\n if (\n focusedElementName === ComboboxElement.Input &&\n inputRef.current?.selectionStart !== 0\n ) {\n break;\n }\n\n updateFocusedChip('prev');\n }\n break;\n }\n\n case ComboboxElement.FirstChip:\n default:\n break;\n }\n break;\n default:\n updateFocusedChip(null);\n break;\n }\n },\n [\n focusedElementName,\n isMultiselect,\n selection,\n setInputFocus,\n updateFocusedChip,\n ],\n );\n\n // When the input value changes (or when the menu opens)\n // Update the focused option\n useEffect(() => {\n if (inputValue !== prevValue) {\n updateHighlightedOption('first');\n }\n }, [inputValue, isOpen, prevValue, updateHighlightedOption]);\n\n // When the focused option changes, update the menu scroll if necessary\n useEffect(() => {\n if (highlightedOption) {\n const focusedElementRef = getOptionRef(highlightedOption);\n\n if (focusedElementRef && focusedElementRef.current && menuRef.current) {\n const { offsetTop: optionTop } = focusedElementRef.current;\n const { scrollTop: menuScroll, offsetHeight: menuHeight } =\n menuRef.current;\n\n if (optionTop > menuHeight || optionTop < menuScroll) {\n menuRef.current.scrollTop = optionTop;\n }\n }\n }\n }, [highlightedOption, getOptionRef]);\n\n /**\n * Rendering\n */\n\n /**\n * Callback to render the children as <InternalComboboxOption> elements\n */\n const renderInternalOptions = useCallback(\n (_children: React.ReactNode) => {\n return React.Children.map(_children, child => {\n if (isComponentType(child, 'ComboboxOption')) {\n const { value, displayName } = getNameAndValue(child.props);\n\n if (shouldOptionBeVisible(value)) {\n const { className, glyph, disabled } = child.props;\n const index = allOptions.findIndex(opt => opt.value === value);\n\n const isFocused = highlightedOption === value;\n const isSelected = isMultiselect(selection)\n ? selection.includes(value)\n : selection === value;\n\n const setSelected = () => {\n sethighlightedOption(value);\n updateSelection(value);\n setInputFocus();\n\n if (value === selection) {\n closeMenu();\n }\n };\n\n const optionRef = getOptionRef(value);\n\n return (\n <InternalComboboxOption\n value={value}\n displayName={displayName}\n isFocused={isFocused}\n isSelected={isSelected}\n disabled={disabled}\n setSelected={setSelected}\n glyph={glyph}\n className={className}\n index={index}\n ref={optionRef}\n />\n );\n }\n } else if (isComponentType(child, 'ComboboxGroup')) {\n const nestedChildren = renderInternalOptions(child.props.children);\n\n if (nestedChildren && nestedChildren?.length > 0) {\n return (\n <InternalComboboxGroup\n label={child.props.label}\n className={child.props.className}\n >\n {renderInternalOptions(nestedChildren)}\n </InternalComboboxGroup>\n );\n }\n }\n });\n },\n [\n allOptions,\n highlightedOption,\n getOptionRef,\n isMultiselect,\n shouldOptionBeVisible,\n selection,\n setInputFocus,\n updateSelection,\n ],\n );\n\n /**\n * The rendered JSX elements for the options\n */\n const renderedOptionsJSX = useMemo(\n () => renderInternalOptions(children),\n [children, renderInternalOptions],\n );\n\n /**\n * The rendered JSX for the selection Chips\n */\n const renderedChips = useMemo(() => {\n if (isMultiselect(selection)) {\n return selection.filter(isValueValid).map((value, index) => {\n const displayName = getDisplayNameForValue(value, allOptions);\n const isFocused = focusedChip === value;\n const chipRef = getChipRef(value);\n const isLastChip = index >= selection.length - 1;\n\n const onRemove = () => {\n if (isLastChip) {\n // Focus the input if this is the last chip in the set\n setInputFocus();\n updateFocusedChip(null);\n } else {\n updateFocusedChip('next', index);\n }\n updateSelection(value);\n };\n\n const onFocus = () => {\n setFocusedChip(value);\n };\n\n return (\n <Chip\n key={value}\n displayName={displayName}\n isFocused={isFocused}\n onRemove={onRemove}\n onFocus={onFocus}\n ref={chipRef}\n />\n );\n });\n }\n }, [\n isMultiselect,\n selection,\n isValueValid,\n allOptions,\n focusedChip,\n getChipRef,\n updateSelection,\n setInputFocus,\n updateFocusedChip,\n ]);\n\n /**\n * The rendered JSX for the input icons (clear, warn & caret)\n */\n const renderedInputIcons = useMemo(() => {\n const handleClearButtonClick = (\n e: React.MouseEvent<HTMLButtonElement, MouseEvent>,\n ) => {\n if (!disabled) {\n updateSelection(null);\n onClear?.(e);\n onFilter?.('');\n if (!isOpen) {\n openMenu();\n }\n }\n };\n\n return (\n <>\n {clearable && doesSelectionExist && (\n <IconButton\n aria-label=\"Clear selection\"\n aria-disabled={disabled}\n disabled={disabled}\n ref={clearButtonRef}\n onClick={handleClearButtonClick}\n onFocus={handleClearButtonFocus}\n className={cx(clearButtonStyle, clearButtonFocusOverrideStyles)}\n >\n <Icon glyph=\"XWithCircle\" />\n </IconButton>\n )}\n {state === 'error' ? (\n <Icon glyph=\"Warning\" color={uiColors.red.base} className={endIcon} />\n ) : (\n <Icon glyph=\"CaretDown\" className={endIcon} />\n )}\n </>\n );\n }, [\n clearable,\n doesSelectionExist,\n disabled,\n state,\n updateSelection,\n onClear,\n onFilter,\n isOpen,\n ]);\n\n /**\n * Flag to determine whether the rendered options have icons\n */\n const withIcons = useMemo(\n () => allOptions.some(opt => opt.hasGlyph),\n [allOptions],\n );\n\n /**\n *\n * Selection Management\n *\n */\n\n const onCloseMenu = useCallback(() => {\n // Single select, and no change to selection\n if (!isMultiselect(selection) && selection === prevSelection) {\n const exactMatchedOption = visibleOptions.find(\n option =>\n option.displayName === inputValue || option.value === inputValue,\n );\n\n // check if inputValue is matches a valid option\n // Set the selection to that value if the component is not controlled\n if (exactMatchedOption && !value) {\n setSelection(exactMatchedOption.value as SelectValueType<M>);\n } else {\n // Revert the value to the previous selection\n const displayName =\n getDisplayNameForValue(\n selection as SelectValueType<false>,\n allOptions,\n ) ?? '';\n setInputValue(displayName);\n }\n }\n }, [\n allOptions,\n inputValue,\n isMultiselect,\n prevSelection,\n selection,\n value,\n visibleOptions,\n ]);\n\n const onSelect = useCallback(() => {\n if (doesSelectionExist) {\n if (isMultiselect(selection)) {\n // Scroll the wrapper to the end. No effect if not `overflow=\"scroll-x\"`\n scrollInputToEnd();\n } else if (!isMultiselect(selection)) {\n // Update the text input\n const displayName =\n getDisplayNameForValue(\n selection as SelectValueType<false>,\n allOptions,\n ) ?? '';\n setInputValue(displayName);\n closeMenu();\n }\n } else {\n setInputValue('');\n }\n }, [doesSelectionExist, allOptions, isMultiselect, selection]);\n\n // Set the initialValue\n useEffect(() => {\n if (initialValue) {\n if (isArray(initialValue)) {\n // Ensure the values we set are real options\n const filteredValue =\n initialValue.filter(value => isValueValid(value)) ?? [];\n setSelection(filteredValue as SelectValueType<M>);\n } else {\n if (isValueValid(initialValue as string)) {\n setSelection(initialValue);\n }\n }\n } else {\n setSelection(getNullSelection(multiselect));\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // When controlled value changes, update the selection\n useEffect(() => {\n if (!isUndefined(value) && value !== prevValue) {\n if (isNull(value)) {\n setSelection(null);\n } else if (isMultiselect(value)) {\n // Ensure the value(s) passed in are valid options\n const newSelection = value.filter(isValueValid) as SelectValueType<M>;\n setSelection(newSelection);\n } else {\n setSelection(\n isValueValid(value as SelectValueType<false>) ? value : null,\n );\n }\n }\n }, [isMultiselect, isValueValid, prevValue, value]);\n\n // onSelect\n // Side effects to run when the selection changes\n useEffect(() => {\n if (!isEqual(selection, prevSelection)) {\n onSelect();\n }\n }, [onSelect, prevSelection, selection]);\n\n // when the menu closes, update the value if needed\n useEffect(() => {\n if (!isOpen && wasOpen) {\n onCloseMenu();\n }\n }, [isOpen, wasOpen, onCloseMenu]);\n\n /**\n *\n * Menu management\n *\n */\n\n const [menuWidth, setMenuWidth] = useState(0);\n\n // When the menu opens, or the selection changes, or the focused option changes\n // update the menu width\n useEffect(() => {\n setMenuWidth(comboboxRef.current?.clientWidth ?? 0);\n }, [comboboxRef, isOpen, highlightedOption, selection]);\n\n // Handler fired when the manu has finished transitioning in/out\n const handleTransitionEnd = () => {\n setMenuWidth(comboboxRef.current?.clientWidth ?? 0);\n };\n\n /**\n * The rendered menu JSX contents\n * Includes error, empty, search and default states\n */\n const renderedMenuContents = useMemo((): JSX.Element => {\n switch (searchState) {\n case 'loading': {\n return (\n <span className={menuMessage}>\n <Icon\n glyph=\"Refresh\"\n color={uiColors.blue.base}\n className={loadingIconStyle}\n />\n {searchLoadingMessage}\n </span>\n );\n }\n\n case 'error': {\n return (\n <span className={menuMessage}>\n <Icon glyph=\"Warning\" color={uiColors.red.base} />\n {searchErrorMessage}\n </span>\n );\n }\n\n case 'unset':\n default: {\n if (renderedOptionsJSX && renderedOptionsJSX.length > 0) {\n return <ul className={menuList}>{renderedOptionsJSX}</ul>;\n }\n\n return <span className={menuMessage}>{searchEmptyMessage}</span>;\n }\n }\n }, [\n renderedOptionsJSX,\n searchEmptyMessage,\n searchErrorMessage,\n searchLoadingMessage,\n searchState,\n ]);\n\n /** The max height of the menu element */\n const maxHeight = Math.min(256, useAvailableSpace(comboboxRef));\n\n /**\n *\n * Event Handlers\n *\n */\n\n // Prevent combobox from gaining focus by default\n const handleInputWrapperMousedown = (e: React.MouseEvent) => {\n if (disabled) {\n e.preventDefault();\n }\n };\n\n // Set focus to the input element on click\n const handleComboboxClick = (e: React.MouseEvent) => {\n // If we clicked the wrapper, not the input itself.\n // (Focus is set automatically if the click is on the input)\n if (e.target !== inputRef.current) {\n let cursorPos = 0;\n\n if (inputRef.current) {\n const mouseX = e.nativeEvent.offsetX;\n const inputRight =\n inputRef.current.offsetLeft + inputRef.current.clientWidth;\n cursorPos = mouseX > inputRight ? inputValue.length : 0;\n }\n\n setInputFocus(cursorPos);\n }\n };\n\n // Fired whenever the wrapper gains focus,\n // and any time the focus within changes\n const handleComboboxFocus = (e: React.FocusEvent) => {\n scrollInputToEnd();\n openMenu();\n trackFocusedElement(getNameFromElement(e.target));\n };\n\n // Fired onChange\n const handleInputChange = ({\n target: { value },\n }: React.ChangeEvent<HTMLInputElement>) => {\n setInputValue(value);\n // fire any filter function passed in\n onFilter?.(value);\n };\n\n const handleClearButtonFocus = () => {\n sethighlightedOption(null);\n };\n\n const handleKeyDown = (event: React.KeyboardEvent) => {\n const isFocusInMenu = menuRef.current?.contains(document.activeElement);\n const isFocusOnCombobox = comboboxRef.current?.contains(\n document.activeElement,\n );\n\n const isFocusInComponent = isFocusOnCombobox || isFocusInMenu;\n\n // Only run if the focus is in the component\n if (isFocusInComponent) {\n // No support for modifiers yet\n // TODO - Handle support for multiple chip selection\n if (event.ctrlKey || event.shiftKey || event.altKey) {\n return;\n }\n\n switch (event.keyCode) {\n case keyMap.Tab: {\n switch (focusedElementName) {\n case 'Input': {\n if (!doesSelectionExist) {\n closeMenu();\n updateHighlightedOption('first');\n updateFocusedChip(null);\n }\n // else use default behavior\n break;\n }\n\n case 'LastChip': {\n // use default behavior\n updateFocusedChip(null);\n break;\n }\n\n case 'FirstChip':\n case 'MiddleChip': {\n // use default behavior\n break;\n }\n\n case 'ClearButton':\n default:\n break;\n }\n\n break;\n }\n\n case keyMap.Escape: {\n closeMenu();\n updateHighlightedOption('first');\n break;\n }\n\n case keyMap.Enter: {\n // Select the highlighed option iff\n // the menu is open\n // we're focused on input element,\n // and the highlighted option is not disabled\n if (\n isOpen &&\n focusedElementName === ComboboxElement.Input &&\n !isNull(highlightedOption) &&\n !isOptionDisabled(highlightedOption)\n ) {\n updateSelection(highlightedOption);\n } else if (\n // Focused on clear button\n focusedElementName === ComboboxElement.ClearButton\n ) {\n updateSelection(null);\n setInputFocus();\n }\n break;\n }\n\n case keyMap.Backspace: {\n // Backspace key focuses last chip if the input is focused\n // Note: Chip removal behavior is handled in `onRemove` defined in `renderChips`\n if (isMultiselect(selection)) {\n if (\n focusedElementName === 'Input' &&\n inputRef.current?.selectionStart === 0\n ) {\n updateFocusedChip('last');\n }\n }\n // Open the menu regardless\n openMenu();\n break;\n }\n\n case keyMap.ArrowDown: {\n if (isOpen) {\n // Prevent the page from scrolling\n event.preventDefault();\n // only change option if the menu is already open\n updateHighlightedOption('next');\n } else {\n openMenu();\n }\n break;\n }\n\n case keyMap.ArrowUp: {\n if (isOpen) {\n // Prevent the page from scrolling\n event.preventDefault();\n // only change option if the menu is already open\n updateHighlightedOption('prev');\n } else {\n openMenu();\n }\n break;\n }\n\n case keyMap.ArrowRight: {\n handleArrowKey('right', event);\n break;\n }\n\n case keyMap.ArrowLeft: {\n handleArrowKey('left', event);\n break;\n }\n\n default: {\n if (!isOpen) {\n openMenu();\n }\n }\n }\n }\n };\n\n /**\n *\n * Global Event Handler\n *\n */\n\n /**\n * We add two event handlers to the document to handle the backdrop click behavior.\n * Intended behavior is to close the menu, and keep focus on the Combobox.\n * No other click event handlers should fire on backdrop click\n *\n * 1. Mousedown event fires\n * 2. We prevent `mousedown`'s default behavior, to prevent focus from being applied to the body (or other target)\n * 3. Click event fires\n * 4. We handle this event on _capture_, and stop propagation before the `click` event propagates all the way to any other element.\n * This ensures that even if we click on a button, that handler is not fired\n * 5. Then we call `closeMenu`, setting `isOpen = false`, and rerender the component\n */\n useEventListener(\n 'mousedown',\n (mousedown: MouseEvent) => {\n if (!doesComponentContainEventTarget(mousedown)) {\n mousedown.preventDefault(); // Prevent focus from being applied to body\n mousedown.stopPropagation(); // Stop any other mousedown events from firing\n }\n },\n {\n enabled: isOpen,\n },\n );\n useEventListener(\n 'click',\n (click: MouseEvent) => {\n if (!doesComponentContainEventTarget(click)) {\n click.stopPropagation(); // Stop any other click events from firing\n closeMenu();\n }\n },\n {\n options: { capture: true },\n enabled: isOpen,\n },\n );\n\n const popoverProps = {\n popoverZIndex,\n ...(usePortal\n ? {\n usePortal,\n portalClassName,\n portalContainer,\n scrollContainer,\n }\n : { usePortal }),\n } as const;\n\n return (\n <ComboboxContext.Provider\n value={{\n multiselect,\n darkMode,\n size,\n withIcons,\n disabled,\n chipTruncationLocation,\n chipCharacterLimit,\n inputValue,\n }}\n >\n <div\n className={cx(\n comboboxParentStyle({ darkMode, size, overflow }),\n className,\n )}\n {...rest}\n >\n <div>\n {label && (\n <Label\n id={labelId}\n htmlFor={inputId}\n className={_tempLabelDescriptionOverrideStyle}\n >\n {label}\n </Label>\n )}\n {description && (\n <Description className={_tempLabelDescriptionOverrideStyle}>\n {description}\n </Description>\n )}\n </div>\n\n {/* Disable eslint: onClick sets focus. Key events would already have focus */}\n {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */}\n <div\n ref={comboboxRef}\n role=\"combobox\"\n aria-expanded={isOpen}\n aria-controls={menuId}\n aria-owns={menuId}\n tabIndex={-1}\n className={cx(comboboxStyle, {\n [comboboxFocusStyle]: focusedElementName === ComboboxElement.Input,\n })}\n onMouseDown={handleInputWrapperMousedown}\n onClick={handleComboboxClick}\n onFocus={handleComboboxFocus}\n onKeyDown={handleKeyDown}\n onTransitionEnd={handleTransitionEnd}\n data-disabled={disabled}\n data-state={state}\n >\n <div\n ref={inputWrapperRef}\n className={inputWrapperStyle({\n overflow,\n isOpen,\n selection,\n size,\n value: inputValue,\n })}\n >\n {renderedChips}\n <input\n aria-label={ariaLabel ?? label}\n aria-autocomplete=\"list\"\n aria-controls={menuId}\n aria-labelledby={labelId}\n ref={inputRef}\n id={inputId}\n className={inputElementStyle}\n placeholder={placeholderValue}\n disabled={disabled ?? undefined}\n onChange={handleInputChange}\n value={inputValue}\n autoComplete=\"off\"\n />\n </div>\n {renderedInputIcons}\n </div>\n\n {state === 'error' && errorMessage && (\n <div className={errorMessageStyle}>{errorMessage}</div>\n )}\n\n {/******* /\n * Menu *\n / *******/}\n <Popover\n active={isOpen && !disabled}\n spacing={4}\n align=\"bottom\"\n justify=\"middle\"\n refEl={comboboxRef}\n adjustOnMutation={true}\n className={menuWrapperStyle({ darkMode, size, width: menuWidth })}\n {...popoverProps}\n >\n <div\n id={menuId}\n role=\"listbox\"\n aria-labelledby={labelId}\n aria-expanded={isOpen}\n ref={menuRef}\n className={menuStyle({ maxHeight })}\n onMouseDownCapture={e => e.preventDefault()}\n >\n {renderedMenuContents}\n </div>\n </Popover>\n </div>\n </ComboboxContext.Provider>\n );\n\n // Closure-dependant utils\n\n /**\n * Returns whether the event target is a Combobox element\n */\n function doesComponentContainEventTarget({ target }: MouseEvent): boolean {\n return (\n menuRef.current?.contains(target as Node) ||\n comboboxRef.current?.contains(target as Node) ||\n false\n );\n }\n\n /**\n * Scrolls the combobox to the far right.\n * Used when `overflow == 'scroll-x'`.\n * Has no effect otherwise\n */\n function scrollInputToEnd() {\n if (inputWrapperRef && inputWrapperRef.current) {\n // TODO - consider converting to .scrollTo(). This is not yet suppoted in IE or jsdom\n inputWrapperRef.current.scrollLeft = inputWrapperRef.current.scrollWidth;\n }\n }\n\n /**\n * Returns the provided element as a ComboboxElement string\n */\n function getNameFromElement(\n element?: Element | null,\n ): ComboboxElement | undefined {\n if (!element) return;\n if (inputRef.current?.contains(element)) return ComboboxElement.Input;\n if (clearButtonRef.current?.contains(element))\n return ComboboxElement.ClearButton;\n\n const activeChipIndex = isMultiselect(selection)\n ? selection.findIndex(value =>\n getChipRef(value)?.current?.contains(element),\n )\n : -1;\n\n if (isMultiselect(selection)) {\n if (activeChipIndex === 0) return ComboboxElement.FirstChip;\n if (activeChipIndex === selection.length - 1)\n return ComboboxElement.LastChip;\n if (activeChipIndex > 0) return ComboboxElement.MiddleChip;\n }\n\n if (menuRef.current?.contains(element)) return ComboboxElement.Menu;\n if (comboboxRef.current?.contains(element)) return ComboboxElement.Combobox;\n }\n}\n/**\n * Why'd you have to go and make things so complicated?\n * - Avril; and also me to myself about this component\n */\n"],"names":["ComboboxElement","ComboboxSize","_templateObject","_templateObject2","_templateObject3","_templateObject4","_templateObject5","_maxCharWidth","_templateObject6","_templateObject7","_templateObject8","_templateObject9","_templateObject10","_templateObject11","_templateObject12","_templateObject13","_templateObject14","_templateObject15","_templateObject16","_templateObject17","_templateObject18","_templateObject19","_templateObject20","_templateObject21","_templateObject22","_templateObject23","_templateObject24","_templateObject25","_templateObject26","_templateObject27","ComboboxContext","createContext","multiselect","darkMode","size","withIcons","disabled","wrapJSX","str","wrap","element","regex","RegExp","matches","matchAll","outArray","split","_i","_Array$from","Array","from","length","_match$index","match","matchIndex","index","matchContent","matchLength","key","replacement","fill","React","createElement","splice","apply","concat","_toConsumableArray","___EmotionJSX","jsx","Fragment","getNameAndValue","_ref","_ref2","valProp","value","nameProp","displayName","kebabCase","getOptionObjectFromValue","options","find","opt","getDisplayNameForValue","_getOptionObjectFromV","_getOptionObjectFromV2","flattenChildren","_children","Children","toArray","reduce","acc","child","isComponentType","_getNameAndValue","props","_child$props","glyph","isDisabled","hasGlyph","children","comboboxOptionStyle","css","_taggedTemplateLiteral","fontFamilies","legacy","comboboxOptionDisabledStyle","uiColors","gray","base","flexSpan","disallowPointer","displayNameStyle","isSelected","InternalComboboxOption","forwardRef","forwardedRef","isFocused","setSelected","className","_useContext","useContext","inputValue","optionTextId","useIdAllocator","prefix","optionRef","useForwardedRef","handleOptionClick","useCallback","e","stopPropagation","target","current","tagName","renderedIcon","useMemo","isComponentGlyph","console","error","renderedChildren","checkbox","Checkbox","label","checked","tabIndex","animate","cx","id","Icon","color","blue","light1","ref","role","_defineProperty","onClick","onKeyDown","ComboboxOption","_","Error","maxCharWidth","typeScales","body1","fontSize","body2","chipClassName","createUniqueClassName","_tempLabelDescriptionOverrideStyle","comboboxParentStyle","overflow","red","dark3","dark1","light3","white","light2","modeStyle","lineHeight","sizeStyle","comboboxStyle","comboboxFocusStyle","focus","inputWrapperStyle","_ref3","_value$length","isOpen","selection","isMultiselect","isArray","inputLength","baseWrapperStyle","inputElementStyle","clearButtonStyle","clearButtonFocusOverrideStyles","errorMessageStyle","endIcon","loadingIconAnimation","keyframes","loadingIconStyle","menuWrapperStyle","_ref4","menuModeStyle","menuSizeStyle","_ref4$width","width","menuStyle","_ref5","maxHeight","default","menuList","menuMessage","chipWrapperStyle","chipModeStyle","chipSizeStyle","dark2","chipText","chipButton","Chip","onRemove","onFocus","_useContext$chipTrunc","chipTruncationLocation","_useContext$chipChara","chipCharacterLimit","isTruncated","buttonRef","useRef","truncatedName","chars","substring","trim","useEffect","_buttonRef$current","_buttonRef$current2","contains","keyCode","keyMap","Delete","Backspace","Enter","Space","InlineDefinition","definition","align","comboboxGroupStyle","comboboxGroupLabel","InternalComboboxGroup","groupId","count","ComboboxGroup","_excluded","description","_ref$placeholder","placeholder","ariaLabel","_ref$disabled","_ref$size","_ref$darkMode","_ref$state","state","errorMessage","_ref$searchState","searchState","_ref$searchEmptyMessa","searchEmptyMessage","_ref$searchErrorMessa","searchErrorMessage","_ref$searchLoadingMes","searchLoadingMessage","filteredOptions","onFilter","_ref$clearable","clearable","onClear","_ref$overflow","_ref$multiselect","initialValue","onChange","_ref$chipCharacterLim","_ref$usePortal","usePortal","portalClassName","portalContainer","scrollContainer","popoverZIndex","rest","_objectWithoutProperties","getOptionRef","useDynamicRefs","getChipRef","inputId","labelId","menuId","comboboxRef","clearButtonRef","inputWrapperRef","inputRef","menuRef","_useState2","_slicedToArray","useState","setOpen","wasOpen","usePrevious","_useState4","highlightedOption","sethighlightedOption","_useState6","setSelection","prevSelection","_useState8","setInputValue","prevValue","_useState10","focusedChip","setFocusedChip","doesSelectionExist","isNull","isString","placeholderValue","undefined","closeMenu","openMenu","allOptions","val","consoleOnce","_typeof","setInputFocus","cursorPos","isUndefined","setSelectionRange","updateSelection","newSelection","clone","includes","indexOf","push","_newSelection","isValueCurrentSelection","isTextCurrentSelection","text","_options$find$value","_options$find","shouldOptionBeVisible","option","toLowerCase","visibleOptions","filter","isValueValid","getIndexOfValue","findIndex","getValueAtIndex","getActiveChipIndex","_getChipRef","_getChipRef$current","document","activeElement","_useState12","focusedElementName","trackFocusedElement","updateHighlightedOption","direction","_visibleOptions$lengt","optionsCount","lastIndex","indexOfHighlight","newValue","_newValue","_newValue2","_newValue3","updateFocusedChip","relativeToIndex","referenceChipIndex","nextChipIndex","nextChipValue","_referenceChipIndex","prevChipIndex","prevChipValue","firstChipValue","lastChipValue","handleArrowKey","event","_inputRef$current","_inputRef$current2","_clearButtonRef$curre","selectionEnd","preventDefault","_inputRef$current3","_inputRef$current4","selectionStart","focusedElementRef","optionTop","offsetTop","_menuRef$current","menuScroll","scrollTop","offsetHeight","renderInternalOptions","map","_value","_className","_disabled","nestedChildren","renderedOptionsJSX","renderedChips","chipRef","isLastChip","renderedInputIcons","IconButton","handleClearButtonFocus","some","onCloseMenu","exactMatchedOption","_getDisplayNameForVal","onSelect","scrollInputToEnd","_getDisplayNameForVal2","_initialValue$filter","filteredValue","getNullSelection","isEqual","_useState14","menuWidth","setMenuWidth","_comboboxRef$current$","_comboboxRef$current","clientWidth","renderedMenuContents","Math","min","useAvailableSpace","useEventListener","mousedown","doesComponentContainEventTarget","enabled","click","capture","popoverProps","_objectSpread","Provider","_extends","Label","htmlFor","Description","onMouseDown","nativeEvent","offsetX","offsetLeft","_inputRef$current6","_clearButtonRef$curre2","_menuRef$current4","_comboboxRef$current5","activeChipIndex","_getChipRef2","_getChipRef2$current","getNameFromElement","_menuRef$current2","_comboboxRef$current3","isFocusInMenu","ctrlKey","shiftKey","altKey","Tab","Escape","optionObj","isOptionDisabled","_inputRef$current5","ArrowDown","ArrowUp","ArrowRight","ArrowLeft","onTransitionEnd","_comboboxRef$current$2","_comboboxRef$current2","autoComplete","Popover","active","spacing","justify","refEl","adjustOnMutation","onMouseDownCapture","_menuRef$current3","_comboboxRef$current4","scrollLeft","scrollWidth"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { OptionObject } from '../Combobox.types';
2
+ export declare const getOptionObjectFromValue: (value: string | null, options: Array<OptionObject>) => OptionObject | undefined;
3
+ export declare const getDisplayNameForValue: (value: string | null, options: Array<OptionObject>) => string;
4
+ export declare const getValueForDisplayName: (displayName: string | null, options: Array<OptionObject>) => string;
5
+ //# sourceMappingURL=OptionObjectUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OptionObjectUtils.d.ts","sourceRoot":"","sources":["../../src/utils/OptionObjectUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,eAAO,MAAM,wBAAwB,UAC5B,MAAM,GAAG,IAAI,WACX,MAAM,YAAY,CAAC,KAC3B,YAAY,GAAG,SAEjB,CAAC;AAEF,eAAO,MAAM,sBAAsB,UAC1B,MAAM,GAAG,IAAI,WACX,MAAM,YAAY,CAAC,KAC3B,MAIF,CAAC;AAEF,eAAO,MAAM,sBAAsB,gBACpB,MAAM,GAAG,IAAI,WACjB,MAAM,YAAY,CAAC,KAC3B,MAIF,CAAC"}
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import { OptionObject } from '../Combobox.types';
3
+ /**
4
+ *
5
+ * Flattens multiple nested ComboboxOptions into a 1D array
6
+ *
7
+ * @param _children
8
+ * @returns `Array<OptionObject>`
9
+ */
10
+ export declare const flattenChildren: (_children: React.ReactNode) => Array<OptionObject>;
11
+ //# sourceMappingURL=flattenChildren.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flattenChildren.d.ts","sourceRoot":"","sources":["../../src/utils/flattenChildren.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjD;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,cACf,MAAM,SAAS,KACzB,MAAM,YAAY,CAgCpB,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { ComboboxOptionProps } from '../Combobox.types';
2
+ /**
3
+ *
4
+ * Returns an object with properties `value` & `displayName`
5
+ * based on the props provided
6
+ *
7
+ * @property value: string
8
+ * @property displayName: string
9
+ */
10
+ export declare const getNameAndValue: ({ value: valProp, displayName: nameProp, }: ComboboxOptionProps) => {
11
+ value: string;
12
+ displayName: string;
13
+ };
14
+ //# sourceMappingURL=getNameAndValue.d.ts.map