@artsy/palette 46.4.0 → 46.5.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.
- package/dist/cjs/elements/AutocompleteInput/AutocompleteInput.js +3 -1
- package/dist/cjs/elements/AutocompleteInput/AutocompleteInput.js.map +1 -1
- package/dist/cjs/elements/BaseTabs/BaseTab.d.ts +2 -2
- package/dist/cjs/elements/Dropdown/Dropdown.d.ts +17 -3
- package/dist/cjs/elements/Dropdown/Dropdown.js +124 -174
- package/dist/cjs/elements/Dropdown/Dropdown.js.map +1 -1
- package/dist/cjs/elements/MultiSelect/MultiSelect.js +4 -2
- package/dist/cjs/elements/MultiSelect/MultiSelect.js.map +1 -1
- package/dist/cjs/elements/Pointer/Pointer.d.ts +21 -14
- package/dist/cjs/elements/Pointer/Pointer.js +65 -135
- package/dist/cjs/elements/Pointer/Pointer.js.map +1 -1
- package/dist/cjs/elements/Popover/Popover.js +12 -11
- package/dist/cjs/elements/Popover/Popover.js.map +1 -1
- package/dist/cjs/elements/SelectInput/SelectInput.js +3 -1
- package/dist/cjs/elements/SelectInput/SelectInput.js.map +1 -1
- package/dist/cjs/elements/Sup/Sup.d.ts +1 -1
- package/dist/cjs/elements/Tooltip/Tooltip.js +16 -17
- package/dist/cjs/elements/Tooltip/Tooltip.js.map +1 -1
- package/dist/cjs/utils/usePosition.d.ts +70 -37
- package/dist/cjs/utils/usePosition.js +110 -349
- package/dist/cjs/utils/usePosition.js.map +1 -1
- package/dist/esm/elements/AutocompleteInput/AutocompleteInput.js +3 -1
- package/dist/esm/elements/AutocompleteInput/AutocompleteInput.js.map +1 -1
- package/dist/esm/elements/Dropdown/Dropdown.js +124 -173
- package/dist/esm/elements/Dropdown/Dropdown.js.map +1 -1
- package/dist/esm/elements/MultiSelect/MultiSelect.js +4 -2
- package/dist/esm/elements/MultiSelect/MultiSelect.js.map +1 -1
- package/dist/esm/elements/Pointer/Pointer.js +66 -134
- package/dist/esm/elements/Pointer/Pointer.js.map +1 -1
- package/dist/esm/elements/Popover/Popover.js +13 -12
- package/dist/esm/elements/Popover/Popover.js.map +1 -1
- package/dist/esm/elements/SelectInput/SelectInput.js +3 -1
- package/dist/esm/elements/SelectInput/SelectInput.js.map +1 -1
- package/dist/esm/elements/Tooltip/Tooltip.js +17 -18
- package/dist/esm/elements/Tooltip/Tooltip.js.map +1 -1
- package/dist/esm/utils/usePosition.js +109 -343
- package/dist/esm/utils/usePosition.js.map +1 -1
- package/package.json +3 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AutocompleteInput.js","names":["CloseIcon","SearchIcon","composeRefs","themeGet","React","createRef","useCallback","useEffect","useMemo","useReducer","useRef","styled","useKeyboardListNavigation","useClickOutside","useContainsFocus","usePosition","useMouseActivity","useWidthOf","Box","splitBoxProps","Clickable","LabeledInput","Spinner","VisuallyHidden","AutocompleteInputOption","AutocompleteInputOptionLabel","jsx","_jsx","jsxs","_jsxs","reducer","state","action","type","open","query","payload","AutocompleteInput","clamp","defaultValue","dropdownMaxHeight","dropdownMinWidth","flip","footer","forwardRef","forwardedRef","header","height","id","loading","onChange","onClear","onClose","onKeyDown","onSelect","onSubmit","options","renderOption","option","rest","inputRef","containerRef","headerRef","footerRef","boxProps","inputProps","dispatch","optionsWithRefs","map","ref","resetUI","setTimeout","current","focus","reset","handleSelect","index","text","set","list","waitForInteractive","onEnter","element","i","event","preventDefault","stopPropagation","isDropdownVisible","length","anchorRef","tooltipRef","active","key","offset","position","width","handleFocus","handleMouseDown","handleClick","lastMouseMoveTimestamp","handleMouseEnter","now","performance","cursor","interactive","handleChange","currentTarget","value","handleClearOrSubmit","handleClose","ignoreFocusChangeRef","ignoreFocusChange","onMouseDown","onMouseUp","el","isPointerInteraction","preventScroll","scrollIntoView","block","handleFocusChange","focused","containsFocusRef","onClickOutside","when","handleInputKeydown","blur","handleContainerKeydown","staged","children","role","label","size","onClick","display","alignItems","fill","onFocus","autoComplete","AutocompleteInputDropdownContainer","minWidth","pt","AutocompleteInputDropdown","AutocompleteInputOptions","maxHeight","onMouseEnter","tabIndex","displayName","withConfig","componentId"],"sources":["../../../../src/elements/AutocompleteInput/AutocompleteInput.tsx"],"sourcesContent":["import CloseIcon from \"@artsy/icons/CloseIcon\"\nimport SearchIcon from \"@artsy/icons/SearchIcon\"\nimport composeRefs from \"@seznam/compose-react-refs\"\nimport { themeGet } from \"@styled-system/theme-get\"\nimport React, {\n createRef,\n useCallback,\n useEffect,\n useMemo,\n useReducer,\n useRef,\n} from \"react\"\nimport styled from \"styled-components\"\nimport { ResponsiveValue } from \"styled-system\"\nimport { useKeyboardListNavigation } from \"use-keyboard-list-navigation\"\nimport { useClickOutside, useContainsFocus, usePosition } from \"../../utils\"\nimport { useMouseActivity } from \"../../utils/useMouseActivity\"\nimport { useWidthOf } from \"../../utils/useWidthOf\"\nimport { Box, splitBoxProps } from \"../Box\"\nimport { Clickable } from \"../Clickable\"\nimport { InputProps } from \"../Input\"\nimport { LabeledInput } from \"../LabeledInput\"\nimport { Spinner } from \"../Spinner\"\nimport { VisuallyHidden } from \"../VisuallyHidden\"\nimport { AutocompleteInputOption } from \"./AutocompleteInputOption\"\nimport { AutocompleteInputOptionLabel } from \"./AutocompleteInputOptionLabel\"\n\nexport interface AutocompleteFooterActions {\n /** Call to close dropdown */\n onClose(): void\n}\n\n/** Base option type — can be expanded */\nexport interface AutocompleteInputOptionType {\n text: string\n value: string\n}\n\ninterface State {\n open: boolean\n query: string\n}\n\ntype Action =\n | { type: \"OPEN\" }\n | { type: \"CLOSE\" }\n | { type: \"CLEAR\" }\n | { type: \"CHANGE\"; payload: { query: string } }\n | { type: \"SELECT\"; payload: { query: string } }\n\nconst reducer = (state: State, action: Action): State => {\n switch (action.type) {\n case \"OPEN\":\n return { ...state, open: true }\n case \"CLOSE\":\n return { ...state, open: false }\n case \"CLEAR\":\n return { ...state, query: \"\" }\n case \"CHANGE\":\n return { ...state, query: action.payload.query, open: true }\n case \"SELECT\":\n return { ...state, query: action.payload.query, open: false }\n }\n}\n\nexport interface AutocompleteInputProps<T extends AutocompleteInputOptionType>\n extends Omit<InputProps, \"onSelect\" | \"onSubmit\"> {\n /** Optionally enable clamping (default: `false`) */\n clamp?: boolean\n defaultValue?: string\n dropdownMaxHeight?: ResponsiveValue<string | number>\n dropdownMinWidth?: ResponsiveValue<string | number>\n loading?: boolean\n header?: React.ReactNode\n /** Optionally disable flipping (default: `true`) */\n flip?: boolean\n footer?:\n | React.ReactNode\n | ((dropdownActions: AutocompleteFooterActions) => React.ReactNode)\n /** Ref to the input; workaround generics */\n forwardRef?: React.Ref<HTMLInputElement>\n /** on <enter> when no option is selected */\n onSubmit?(query: string): void\n /** on <click> or <enter> when an option is selected */\n onSelect?(option: T, index: number): void\n /** on <click> of the 'x' (clear) button */\n onClear?(): void\n /** Callback that runs when options are hidden */\n onClose?(): void\n options: T[]\n renderOption?(\n option: T,\n i: number\n ): React.ReactElement<any, string | React.JSXElementConstructor<any>>\n}\n\n/** AutocompleteInput */\nexport const AutocompleteInput = <T extends AutocompleteInputOptionType>({\n clamp = false,\n defaultValue = \"\",\n dropdownMaxHeight = 308, // 308 = roughly 5.5 options\n dropdownMinWidth,\n flip = true,\n footer,\n forwardRef: forwardedRef,\n header,\n height,\n id,\n loading,\n onChange,\n onClear,\n onClose,\n onKeyDown,\n onSelect,\n onSubmit,\n options,\n renderOption = (option) => <AutocompleteInputOptionLabel {...option} />,\n ...rest\n}: AutocompleteInputProps<T>) => {\n const inputRef = useRef<HTMLInputElement | null>(null)\n const containerRef = useRef<HTMLDivElement | null>(null)\n const headerRef = useRef<HTMLDivElement | null>(null)\n const footerRef = useRef<HTMLDivElement | null>(null)\n\n const [boxProps, inputProps] = splitBoxProps(rest)\n\n const [state, dispatch] = useReducer(reducer, {\n open: false,\n query: defaultValue,\n })\n\n const optionsWithRefs = useMemo(() => {\n return options.map((option) => ({\n option,\n ref: createRef<HTMLButtonElement>(),\n }))\n }, [options])\n\n const resetUI = () => {\n setTimeout(() => {\n inputRef.current?.focus()\n reset()\n dispatch({ type: \"CLOSE\" })\n }, 100)\n }\n\n const handleSelect = (option: T, index: number) => {\n dispatch({ type: \"SELECT\", payload: { query: option.text } })\n inputRef.current?.focus()\n onSelect?.(option, index)\n }\n\n const { index, reset, set } = useKeyboardListNavigation({\n ref: containerRef,\n list: options,\n waitForInteractive: true,\n onEnter: ({ element: option, index: i, event }) => {\n event.preventDefault()\n event.stopPropagation()\n handleSelect(option, i)\n resetUI()\n },\n })\n\n const isDropdownVisible = state.open && options.length > 0\n\n // Reset keyboard navigation when options change\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useEffect(reset, [options])\n\n // Reset keyboard navigation when query is empty\n useEffect(() => {\n if (state.query === \"\") reset()\n }, [reset, state.query])\n\n const { anchorRef, tooltipRef } = usePosition({\n active: isDropdownVisible,\n clamp,\n flip,\n key: options.length,\n offset: 0,\n position: \"bottom\",\n })\n\n const { width } = useWidthOf({ ref: anchorRef })\n\n const handleFocus = () => {\n reset()\n dispatch({ type: \"OPEN\" })\n }\n\n const handleMouseDown = (option: T, i: number) => () => {\n handleSelect(option, i)\n resetUI()\n }\n\n const handleClick = () => {\n dispatch({ type: \"OPEN\" })\n }\n\n // Records the latest mouse movement and, inside the `handleMouseEnter` callback,\n // only treat the event as genuine if the mouse has moved very recently.\n // Otherwise, the event is presumed to have been triggered by scrolling and is ignored.\n const { lastMouseMoveTimestamp } = useMouseActivity()\n\n const handleMouseEnter = (i: number) => () => {\n const now = performance.now()\n\n // 50ms mouse move window\n if (now - lastMouseMoveTimestamp.current < 50) {\n set({ cursor: i, interactive: true })\n }\n }\n\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n const {\n currentTarget: { value },\n } = event\n\n dispatch({ type: \"CHANGE\", payload: { query: value } })\n onChange?.(event)\n }\n\n const handleClearOrSubmit = () => {\n if (state.query === \"\") {\n onSubmit?.(state.query)\n return\n }\n\n dispatch({ type: \"CLEAR\" })\n inputRef.current?.focus()\n onClear?.()\n }\n\n const handleClose = useCallback(() => {\n dispatch({ type: \"CLOSE\" })\n reset()\n onClose?.()\n }, [onClose, reset])\n\n const ignoreFocusChangeRef = useRef<boolean>(false)\n const ignoreFocusChange = {\n onMouseDown: () => (ignoreFocusChangeRef.current = true),\n onMouseUp: () => (ignoreFocusChangeRef.current = false),\n }\n\n // Moves focus to different options when keyboard navigating using up/down\n useEffect(() => {\n const el = optionsWithRefs[index]?.ref?.current\n if (!el) return\n\n const isPointerInteraction =\n performance.now() - lastMouseMoveTimestamp.current < 50\n\n if (isPointerInteraction) {\n // Pointer interactions should not cause scroll\n el.focus({ preventScroll: true })\n return\n }\n\n // Keyboard navigation: focus and ensure visibility\n el.focus({ preventScroll: true })\n try {\n el.scrollIntoView({ block: \"nearest\" })\n } catch {}\n }, [index, optionsWithRefs])\n\n const handleFocusChange = useCallback(\n (focused: boolean) => {\n if (ignoreFocusChangeRef.current || focused || !isDropdownVisible) return\n\n handleClose()\n },\n\n [isDropdownVisible, handleClose]\n )\n\n // Handle closing the dropdown when clicking outside of the input\n // or when focus leaves the input completely\n const { ref: containsFocusRef } = useContainsFocus({\n onChange: handleFocusChange,\n })\n\n useClickOutside({\n ref: containsFocusRef,\n onClickOutside: handleClose,\n when: isDropdownVisible,\n type: \"click\",\n })\n\n const handleInputKeydown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n switch (event.key) {\n // Handle <Enter> when nothing is selected\n case \"Enter\":\n if (state.query !== \"\" && index === -1) {\n onSubmit?.(state.query)\n resetUI()\n }\n return\n\n // <Esc> to close dropdown\n case \"Escape\":\n event.preventDefault()\n event.stopPropagation()\n\n dispatch({ type: \"CLOSE\" })\n inputRef.current?.blur()\n\n return\n\n default:\n break\n }\n\n onKeyDown?.(event)\n }\n\n // Moves focus back to input when typing\n const handleContainerKeydown = (\n event: React.KeyboardEvent<HTMLDivElement>\n ) => {\n switch (event.key) {\n case \"Alt\":\n case \"ArrowDown\":\n case \"ArrowUp\":\n case \"Control\":\n case \"Enter\":\n case \"Meta\":\n case \"Shift\":\n case \"Tab\":\n // Ignore\n return\n\n case \"Escape\":\n event.preventDefault()\n event.stopPropagation()\n\n dispatch({ type: \"CLOSE\" })\n inputRef.current?.blur()\n reset()\n\n return\n\n default:\n inputRef.current?.focus()\n }\n }\n\n // Option that is being hovered or keyed into\n const staged = options[index]\n\n return (\n <Box\n ref={composeRefs(containerRef, containsFocusRef) as any}\n onKeyDown={handleContainerKeydown}\n {...boxProps}\n >\n <LabeledInput\n ref={composeRefs(inputRef, anchorRef, forwardedRef) as any}\n role=\"combobox\"\n aria-expanded={isDropdownVisible}\n aria-autocomplete=\"list\"\n {...(id ? { id, \"aria-describedby\": `${id}__assistiveHint` } : {})}\n label={\n loading ? (\n <Box width={18}>\n <Spinner size=\"small\" />\n </Box>\n ) : state.query ? (\n <Clickable\n onClick={handleClearOrSubmit}\n height=\"100%\"\n display=\"flex\"\n alignItems=\"center\"\n aria-label=\"Clear input\"\n >\n <CloseIcon fill=\"mono60\" aria-hidden />\n </Clickable>\n ) : (\n <SearchIcon fill=\"mono60\" aria-hidden />\n )\n }\n value={staged?.text ?? state.query}\n onChange={handleChange}\n onFocus={handleFocus}\n onKeyDown={handleInputKeydown}\n onClick={handleClick}\n autoComplete=\"off\"\n height={height}\n {...inputProps}\n />\n\n {isDropdownVisible && (\n <AutocompleteInputDropdownContainer\n ref={tooltipRef as any}\n role=\"listbox\"\n width={width}\n minWidth={200}\n pt={1} // Gap in place of `offset` for `usePosition`\n >\n <AutocompleteInputDropdown minWidth={dropdownMinWidth}>\n <div ref={headerRef} {...ignoreFocusChange}>\n {header}\n </div>\n\n <AutocompleteInputOptions maxHeight={dropdownMaxHeight}>\n {optionsWithRefs.map(({ option, ref }, i) => {\n return (\n <AutocompleteInputOption\n key={i}\n ref={ref}\n role=\"option\"\n aria-selected={i === index}\n aria-posinset={i + 1}\n aria-setsize={options.length}\n onMouseDown={handleMouseDown(option, i)}\n onMouseEnter={handleMouseEnter(i)}\n tabIndex={-1}\n >\n {renderOption(option, i)}\n </AutocompleteInputOption>\n )\n })}\n </AutocompleteInputOptions>\n\n <div ref={footerRef} {...ignoreFocusChange}>\n {typeof footer === \"function\"\n ? footer({ onClose: handleClose })\n : footer}\n </div>\n </AutocompleteInputDropdown>\n </AutocompleteInputDropdownContainer>\n )}\n\n <VisuallyHidden {...(id ? { id: `${id}__assistiveHint` } : {})}>\n When autocomplete results are available use up and down arrows to review\n and enter to select. Touch device users, explore by touch or with swipe\n gestures.\n </VisuallyHidden>\n\n {isDropdownVisible && (\n <VisuallyHidden role=\"status\" aria-atomic=\"true\" aria-live=\"polite\">\n {options.length === 1\n ? `1 result is available`\n : `${options.length} results are available`}\n </VisuallyHidden>\n )}\n </Box>\n )\n}\n\nconst AutocompleteInputDropdownContainer = styled(Box)`\n z-index: 1;\n`\n\nconst AutocompleteInputDropdown = styled(Box)`\n box-shadow: ${themeGet(\"effects.dropShadow\")};\n`\n\nconst AutocompleteInputOptions = styled(Box)`\n overflow-y: auto;\n -webkit-overflow-scrolling: touch;\n`\n"],"mappings":"AAAA,OAAOA,SAAS,MAAM,wBAAwB;AAC9C,OAAOC,UAAU,MAAM,yBAAyB;AAChD,OAAOC,WAAW,MAAM,4BAA4B;AACpD,SAASC,QAAQ,QAAQ,0BAA0B;AACnD,OAAOC,KAAK,IACVC,SAAS,EACTC,WAAW,EACXC,SAAS,EACTC,OAAO,EACPC,UAAU,EACVC,MAAM,QACD,OAAO;AACd,OAAOC,MAAM,MAAM,mBAAmB;AAEtC,SAASC,yBAAyB,QAAQ,8BAA8B;AACxE,SAASC,eAAe,EAAEC,gBAAgB,EAAEC,WAAW;AACvD,SAASC,gBAAgB;AACzB,SAASC,UAAU;AACnB,SAASC,GAAG,EAAEC,aAAa;AAC3B,SAASC,SAAS;AAElB,SAASC,YAAY;AACrB,SAASC,OAAO;AAChB,SAASC,cAAc;AACvB,SAASC,uBAAuB;AAChC,SAASC,4BAA4B;;AAOrC;AAAA,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAkBA,MAAMC,OAAO,GAAGA,CAACC,KAAY,EAAEC,MAAc,KAAY;EACvD,QAAQA,MAAM,CAACC,IAAI;IACjB,KAAK,MAAM;MACT,OAAO;QAAE,GAAGF,KAAK;QAAEG,IAAI,EAAE;MAAK,CAAC;IACjC,KAAK,OAAO;MACV,OAAO;QAAE,GAAGH,KAAK;QAAEG,IAAI,EAAE;MAAM,CAAC;IAClC,KAAK,OAAO;MACV,OAAO;QAAE,GAAGH,KAAK;QAAEI,KAAK,EAAE;MAAG,CAAC;IAChC,KAAK,QAAQ;MACX,OAAO;QAAE,GAAGJ,KAAK;QAAEI,KAAK,EAAEH,MAAM,CAACI,OAAO,CAACD,KAAK;QAAED,IAAI,EAAE;MAAK,CAAC;IAC9D,KAAK,QAAQ;MACX,OAAO;QAAE,GAAGH,KAAK;QAAEI,KAAK,EAAEH,MAAM,CAACI,OAAO,CAACD,KAAK;QAAED,IAAI,EAAE;MAAM,CAAC;EAAA;AAEnE,CAAC;AAiCD;AACA,OAAO,MAAMG,iBAAiB,GAAGA,CAAwC;EACvEC,KAAK,GAAG,KAAK;EACbC,YAAY,GAAG,EAAE;EACjBC,iBAAiB,GAAG,GAAG;EAAE;EACzBC,gBAAgB;EAChBC,IAAI,GAAG,IAAI;EACXC,MAAM;EACNC,UAAU,EAAEC,YAAY;EACxBC,MAAM;EACNC,MAAM;EACNC,EAAE;EACFC,OAAO;EACPC,QAAQ;EACRC,OAAO;EACPC,OAAO;EACPC,SAAS;EACTC,QAAQ;EACRC,QAAQ;EACRC,OAAO;EACPC,YAAY,GAAIC,MAAM,iBAAK/B,IAAA,CAACF,4BAA4B;IAAA,GAAKiC;EAAM,EAAI;EACvE,GAAGC;AACsB,CAAC,KAAK;EAC/B,MAAMC,QAAQ,GAAGlD,MAAM,CAA0B,IAAI,CAAC;EACtD,MAAMmD,YAAY,GAAGnD,MAAM,CAAwB,IAAI,CAAC;EACxD,MAAMoD,SAAS,GAAGpD,MAAM,CAAwB,IAAI,CAAC;EACrD,MAAMqD,SAAS,GAAGrD,MAAM,CAAwB,IAAI,CAAC;EAErD,MAAM,CAACsD,QAAQ,EAAEC,UAAU,CAAC,GAAG9C,aAAa,CAACwC,IAAI,CAAC;EAElD,MAAM,CAAC5B,KAAK,EAAEmC,QAAQ,CAAC,GAAGzD,UAAU,CAACqB,OAAO,EAAE;IAC5CI,IAAI,EAAE,KAAK;IACXC,KAAK,EAAEI;EACT,CAAC,CAAC;EAEF,MAAM4B,eAAe,GAAG3D,OAAO,CAAC,MAAM;IACpC,OAAOgD,OAAO,CAACY,GAAG,CAAEV,MAAM,KAAM;MAC9BA,MAAM;MACNW,GAAG,eAAEhE,SAAS;IAChB,CAAC,CAAC,CAAC;EACL,CAAC,EAAE,CAACmD,OAAO,CAAC,CAAC;EAEb,MAAMc,OAAO,GAAGA,CAAA,KAAM;IACpBC,UAAU,CAAC,MAAM;MACfX,QAAQ,CAACY,OAAO,EAAEC,KAAK,EAAE;MACzBC,KAAK,EAAE;MACPR,QAAQ,CAAC;QAAEjC,IAAI,EAAE;MAAQ,CAAC,CAAC;IAC7B,CAAC,EAAE,GAAG,CAAC;EACT,CAAC;EAED,MAAM0C,YAAY,GAAGA,CAACjB,MAAS,EAAEkB,KAAa,KAAK;IACjDV,QAAQ,CAAC;MAAEjC,IAAI,EAAE,QAAQ;MAAEG,OAAO,EAAE;QAAED,KAAK,EAAEuB,MAAM,CAACmB;MAAK;IAAE,CAAC,CAAC;IAC7DjB,QAAQ,CAACY,OAAO,EAAEC,KAAK,EAAE;IACzBnB,QAAQ,GAAGI,MAAM,EAAEkB,KAAK,CAAC;EAC3B,CAAC;EAED,MAAM;IAAEA,KAAK;IAAEF,KAAK;IAAEI;EAAI,CAAC,GAAGlE,yBAAyB,CAAC;IACtDyD,GAAG,EAAER,YAAY;IACjBkB,IAAI,EAAEvB,OAAO;IACbwB,kBAAkB,EAAE,IAAI;IACxBC,OAAO,EAAEA,CAAC;MAAEC,OAAO,EAAExB,MAAM;MAAEkB,KAAK,EAAEO,CAAC;MAAEC;IAAM,CAAC,KAAK;MACjDA,KAAK,CAACC,cAAc,EAAE;MACtBD,KAAK,CAACE,eAAe,EAAE;MACvBX,YAAY,CAACjB,MAAM,EAAEyB,CAAC,CAAC;MACvBb,OAAO,EAAE;IACX;EACF,CAAC,CAAC;EAEF,MAAMiB,iBAAiB,GAAGxD,KAAK,CAACG,IAAI,IAAIsB,OAAO,CAACgC,MAAM,GAAG,CAAC;;EAE1D;EACA;EACAjF,SAAS,CAACmE,KAAK,EAAE,CAAClB,OAAO,CAAC,CAAC;;EAE3B;EACAjD,SAAS,CAAC,MAAM;IACd,IAAIwB,KAAK,CAACI,KAAK,KAAK,EAAE,EAAEuC,KAAK,EAAE;EACjC,CAAC,EAAE,CAACA,KAAK,EAAE3C,KAAK,CAACI,KAAK,CAAC,CAAC;EAExB,MAAM;IAAEsD,SAAS;IAAEC;EAAW,CAAC,GAAG3E,WAAW,CAAC;IAC5C4E,MAAM,EAAEJ,iBAAiB;IACzBjD,KAAK;IACLI,IAAI;IACJkD,GAAG,EAAEpC,OAAO,CAACgC,MAAM;IACnBK,MAAM,EAAE,CAAC;IACTC,QAAQ,EAAE;EACZ,CAAC,CAAC;EAEF,MAAM;IAAEC;EAAM,CAAC,GAAG9E,UAAU,CAAC;IAAEoD,GAAG,EAAEoB;EAAU,CAAC,CAAC;EAEhD,MAAMO,WAAW,GAAGA,CAAA,KAAM;IACxBtB,KAAK,EAAE;IACPR,QAAQ,CAAC;MAAEjC,IAAI,EAAE;IAAO,CAAC,CAAC;EAC5B,CAAC;EAED,MAAMgE,eAAe,GAAGA,CAACvC,MAAS,EAAEyB,CAAS,KAAK,MAAM;IACtDR,YAAY,CAACjB,MAAM,EAAEyB,CAAC,CAAC;IACvBb,OAAO,EAAE;EACX,CAAC;EAED,MAAM4B,WAAW,GAAGA,CAAA,KAAM;IACxBhC,QAAQ,CAAC;MAAEjC,IAAI,EAAE;IAAO,CAAC,CAAC;EAC5B,CAAC;;EAED;EACA;EACA;EACA,MAAM;IAAEkE;EAAuB,CAAC,GAAGnF,gBAAgB,EAAE;EAErD,MAAMoF,gBAAgB,GAAIjB,CAAS,IAAK,MAAM;IAC5C,MAAMkB,GAAG,GAAGC,WAAW,CAACD,GAAG,EAAE;;IAE7B;IACA,IAAIA,GAAG,GAAGF,sBAAsB,CAAC3B,OAAO,GAAG,EAAE,EAAE;MAC7CM,GAAG,CAAC;QAAEyB,MAAM,EAAEpB,CAAC;QAAEqB,WAAW,EAAE;MAAK,CAAC,CAAC;IACvC;EACF,CAAC;EAED,MAAMC,YAAY,GAAIrB,KAA0C,IAAK;IACnE,MAAM;MACJsB,aAAa,EAAE;QAAEC;MAAM;IACzB,CAAC,GAAGvB,KAAK;IAETlB,QAAQ,CAAC;MAAEjC,IAAI,EAAE,QAAQ;MAAEG,OAAO,EAAE;QAAED,KAAK,EAAEwE;MAAM;IAAE,CAAC,CAAC;IACvDzD,QAAQ,GAAGkC,KAAK,CAAC;EACnB,CAAC;EAED,MAAMwB,mBAAmB,GAAGA,CAAA,KAAM;IAChC,IAAI7E,KAAK,CAACI,KAAK,KAAK,EAAE,EAAE;MACtBoB,QAAQ,GAAGxB,KAAK,CAACI,KAAK,CAAC;MACvB;IACF;IAEA+B,QAAQ,CAAC;MAAEjC,IAAI,EAAE;IAAQ,CAAC,CAAC;IAC3B2B,QAAQ,CAACY,OAAO,EAAEC,KAAK,EAAE;IACzBtB,OAAO,IAAI;EACb,CAAC;EAED,MAAM0D,WAAW,GAAGvG,WAAW,CAAC,MAAM;IACpC4D,QAAQ,CAAC;MAAEjC,IAAI,EAAE;IAAQ,CAAC,CAAC;IAC3ByC,KAAK,EAAE;IACPtB,OAAO,IAAI;EACb,CAAC,EAAE,CAACA,OAAO,EAAEsB,KAAK,CAAC,CAAC;EAEpB,MAAMoC,oBAAoB,GAAGpG,MAAM,CAAU,KAAK,CAAC;EACnD,MAAMqG,iBAAiB,GAAG;IACxBC,WAAW,EAAEA,CAAA,KAAOF,oBAAoB,CAACtC,OAAO,GAAG,IAAK;IACxDyC,SAAS,EAAEA,CAAA,KAAOH,oBAAoB,CAACtC,OAAO,GAAG;EACnD,CAAC;;EAED;EACAjE,SAAS,CAAC,MAAM;IACd,MAAM2G,EAAE,GAAG/C,eAAe,CAACS,KAAK,CAAC,EAAEP,GAAG,EAAEG,OAAO;IAC/C,IAAI,CAAC0C,EAAE,EAAE;IAET,MAAMC,oBAAoB,GACxBb,WAAW,CAACD,GAAG,EAAE,GAAGF,sBAAsB,CAAC3B,OAAO,GAAG,EAAE;IAEzD,IAAI2C,oBAAoB,EAAE;MACxB;MACAD,EAAE,CAACzC,KAAK,CAAC;QAAE2C,aAAa,EAAE;MAAK,CAAC,CAAC;MACjC;IACF;;IAEA;IACAF,EAAE,CAACzC,KAAK,CAAC;MAAE2C,aAAa,EAAE;IAAK,CAAC,CAAC;IACjC,IAAI;MACFF,EAAE,CAACG,cAAc,CAAC;QAAEC,KAAK,EAAE;MAAU,CAAC,CAAC;IACzC,CAAC,CAAC,MAAM,CAAC;EACX,CAAC,EAAE,CAAC1C,KAAK,EAAET,eAAe,CAAC,CAAC;EAE5B,MAAMoD,iBAAiB,GAAGjH,WAAW,CAClCkH,OAAgB,IAAK;IACpB,IAAIV,oBAAoB,CAACtC,OAAO,IAAIgD,OAAO,IAAI,CAACjC,iBAAiB,EAAE;IAEnEsB,WAAW,EAAE;EACf,CAAC,EAED,CAACtB,iBAAiB,EAAEsB,WAAW,CAAC,CACjC;;EAED;EACA;EACA,MAAM;IAAExC,GAAG,EAAEoD;EAAiB,CAAC,GAAG3G,gBAAgB,CAAC;IACjDoC,QAAQ,EAAEqE;EACZ,CAAC,CAAC;EAEF1G,eAAe,CAAC;IACdwD,GAAG,EAAEoD,gBAAgB;IACrBC,cAAc,EAAEb,WAAW;IAC3Bc,IAAI,EAAEpC,iBAAiB;IACvBtD,IAAI,EAAE;EACR,CAAC,CAAC;EAEF,MAAM2F,kBAAkB,GAAIxC,KAA4C,IAAK;IAC3E,QAAQA,KAAK,CAACQ,GAAG;MACf;MACA,KAAK,OAAO;QACV,IAAI7D,KAAK,CAACI,KAAK,KAAK,EAAE,IAAIyC,KAAK,KAAK,CAAC,CAAC,EAAE;UACtCrB,QAAQ,GAAGxB,KAAK,CAACI,KAAK,CAAC;UACvBmC,OAAO,EAAE;QACX;QACA;;MAEF;MACA,KAAK,QAAQ;QACXc,KAAK,CAACC,cAAc,EAAE;QACtBD,KAAK,CAACE,eAAe,EAAE;QAEvBpB,QAAQ,CAAC;UAAEjC,IAAI,EAAE;QAAQ,CAAC,CAAC;QAC3B2B,QAAQ,CAACY,OAAO,EAAEqD,IAAI,EAAE;QAExB;MAEF;QACE;IAAK;IAGTxE,SAAS,GAAG+B,KAAK,CAAC;EACpB,CAAC;;EAED;EACA,MAAM0C,sBAAsB,GAC1B1C,KAA0C,IACvC;IACH,QAAQA,KAAK,CAACQ,GAAG;MACf,KAAK,KAAK;MACV,KAAK,WAAW;MAChB,KAAK,SAAS;MACd,KAAK,SAAS;MACd,KAAK,OAAO;MACZ,KAAK,MAAM;MACX,KAAK,OAAO;MACZ,KAAK,KAAK;QACR;QACA;MAEF,KAAK,QAAQ;QACXR,KAAK,CAACC,cAAc,EAAE;QACtBD,KAAK,CAACE,eAAe,EAAE;QAEvBpB,QAAQ,CAAC;UAAEjC,IAAI,EAAE;QAAQ,CAAC,CAAC;QAC3B2B,QAAQ,CAACY,OAAO,EAAEqD,IAAI,EAAE;QACxBnD,KAAK,EAAE;QAEP;MAEF;QACEd,QAAQ,CAACY,OAAO,EAAEC,KAAK,EAAE;IAAA;EAE/B,CAAC;;EAED;EACA,MAAMsD,MAAM,GAAGvE,OAAO,CAACoB,KAAK,CAAC;EAE7B,oBACE/C,KAAA,CAACX,GAAG;IACFmD,GAAG,EAAEnE,WAAW,CAAC2D,YAAY,EAAE4D,gBAAgB,CAAS;IACxDpE,SAAS,EAAEyE,sBAAuB;IAAA,GAC9B9D,QAAQ;IAAAgE,QAAA,gBAEZrG,IAAA,CAACN,YAAY;MACXgD,GAAG,EAAEnE,WAAW,CAAC0D,QAAQ,EAAE6B,SAAS,EAAE5C,YAAY,CAAS;MAC3DoF,IAAI,EAAC,UAAU;MACf,iBAAe1C,iBAAkB;MACjC,qBAAkB,MAAM;MAAA,IACnBvC,EAAE,GAAG;QAAEA,EAAE;QAAE,kBAAkB,EAAG,GAAEA,EAAG;MAAiB,CAAC,GAAG,CAAC,CAAC;MACjEkF,KAAK,EACHjF,OAAO,gBACLtB,IAAA,CAACT,GAAG;QAAC6E,KAAK,EAAE,EAAG;QAAAiC,QAAA,eACbrG,IAAA,CAACL,OAAO;UAAC6G,IAAI,EAAC;QAAO;MAAG,EACpB,GACJpG,KAAK,CAACI,KAAK,gBACbR,IAAA,CAACP,SAAS;QACRgH,OAAO,EAAExB,mBAAoB;QAC7B7D,MAAM,EAAC,MAAM;QACbsF,OAAO,EAAC,MAAM;QACdC,UAAU,EAAC,QAAQ;QACnB,cAAW,aAAa;QAAAN,QAAA,eAExBrG,IAAA,CAAC3B,SAAS;UAACuI,IAAI,EAAC,QAAQ;UAAC;QAAW;MAAG,EAC7B,gBAEZ5G,IAAA,CAAC1B,UAAU;QAACsI,IAAI,EAAC,QAAQ;QAAC;MAAW,EAExC;MACD5B,KAAK,EAAEoB,MAAM,EAAElD,IAAI,IAAI9C,KAAK,CAACI,KAAM;MACnCe,QAAQ,EAAEuD,YAAa;MACvB+B,OAAO,EAAExC,WAAY;MACrB3C,SAAS,EAAEuE,kBAAmB;MAC9BQ,OAAO,EAAElC,WAAY;MACrBuC,YAAY,EAAC,KAAK;MAClB1F,MAAM,EAAEA,MAAO;MAAA,GACXkB;IAAU,EACd,EAEDsB,iBAAiB,iBAChB5D,IAAA,CAAC+G,kCAAkC;MACjCrE,GAAG,EAAEqB,UAAkB;MACvBuC,IAAI,EAAC,SAAS;MACdlC,KAAK,EAAEA,KAAM;MACb4C,QAAQ,EAAE,GAAI;MACdC,EAAE,EAAE,CAAE,CAAC;MAAA;MAAAZ,QAAA,eAEPnG,KAAA,CAACgH,yBAAyB;QAACF,QAAQ,EAAElG,gBAAiB;QAAAuF,QAAA,gBACpDrG,IAAA;UAAK0C,GAAG,EAAEP,SAAU;UAAA,GAAKiD,iBAAiB;UAAAiB,QAAA,EACvClF;QAAM,EACH,eAENnB,IAAA,CAACmH,wBAAwB;UAACC,SAAS,EAAEvG,iBAAkB;UAAAwF,QAAA,EACpD7D,eAAe,CAACC,GAAG,CAAC,CAAC;YAAEV,MAAM;YAAEW;UAAI,CAAC,EAAEc,CAAC,KAAK;YAC3C,oBACExD,IAAA,CAACH,uBAAuB;cAEtB6C,GAAG,EAAEA,GAAI;cACT4D,IAAI,EAAC,QAAQ;cACb,iBAAe9C,CAAC,KAAKP,KAAM;cAC3B,iBAAeO,CAAC,GAAG,CAAE;cACrB,gBAAc3B,OAAO,CAACgC,MAAO;cAC7BwB,WAAW,EAAEf,eAAe,CAACvC,MAAM,EAAEyB,CAAC,CAAE;cACxC6D,YAAY,EAAE5C,gBAAgB,CAACjB,CAAC,CAAE;cAClC8D,QAAQ,EAAE,CAAC,CAAE;cAAAjB,QAAA,EAEZvE,YAAY,CAACC,MAAM,EAAEyB,CAAC;YAAC,GAVnBA,CAAC,CAWkB;UAE9B,CAAC;QAAC,EACuB,eAE3BxD,IAAA;UAAK0C,GAAG,EAAEN,SAAU;UAAA,GAAKgD,iBAAiB;UAAAiB,QAAA,EACvC,OAAOrF,MAAM,KAAK,UAAU,GACzBA,MAAM,CAAC;YAAES,OAAO,EAAEyD;UAAY,CAAC,CAAC,GAChClE;QAAM,EACN;MAAA;IACoB,EAE/B,eAEDhB,IAAA,CAACJ,cAAc;MAAA,IAAMyB,EAAE,GAAG;QAAEA,EAAE,EAAG,GAAEA,EAAG;MAAiB,CAAC,GAAG,CAAC,CAAC;MAAAgF,QAAA,EAAG;IAIhE,EAAiB,EAEhBzC,iBAAiB,iBAChB5D,IAAA,CAACJ,cAAc;MAAC0G,IAAI,EAAC,QAAQ;MAAC,eAAY,MAAM;MAAC,aAAU,QAAQ;MAAAD,QAAA,EAChExE,OAAO,CAACgC,MAAM,KAAK,CAAC,GAChB,uBAAsB,GACtB,GAAEhC,OAAO,CAACgC,MAAO;IAAuB,EAEhD;EAAA,EACG;AAEV,CAAC;AAhWYnD,iBAAiB,CAAA6G,WAAA;AAkW9B,MAAMR,kCAAkC,GAAG/H,MAAM,CAACO,GAAG,CAAC,CAAAiI,UAAA;EAAAD,WAAA;EAAAE,WAAA;AAAA,kBAErD;AAED,MAAMP,yBAAyB,GAAGlI,MAAM,CAACO,GAAG,CAAC,CAAAiI,UAAA;EAAAD,WAAA;EAAAE,WAAA;AAAA,yBAC7BjJ,QAAQ,CAAC,oBAAoB,CAAC,CAC7C;AAED,MAAM2I,wBAAwB,GAAGnI,MAAM,CAACO,GAAG,CAAC,CAAAiI,UAAA;EAAAD,WAAA;EAAAE,WAAA;AAAA,yDAG3C"}
|
|
1
|
+
{"version":3,"file":"AutocompleteInput.js","names":["CloseIcon","SearchIcon","composeRefs","themeGet","React","createRef","useCallback","useEffect","useMemo","useReducer","useRef","styled","useKeyboardListNavigation","useClickOutside","useContainsFocus","usePosition","useMouseActivity","useWidthOf","Box","splitBoxProps","Clickable","LabeledInput","Spinner","VisuallyHidden","AutocompleteInputOption","AutocompleteInputOptionLabel","jsx","_jsx","jsxs","_jsxs","reducer","state","action","type","open","query","payload","AutocompleteInput","clamp","defaultValue","dropdownMaxHeight","dropdownMinWidth","flip","footer","forwardRef","forwardedRef","header","height","id","loading","onChange","onClear","onClose","onKeyDown","onSelect","onSubmit","options","renderOption","option","rest","inputRef","containerRef","headerRef","footerRef","boxProps","inputProps","dispatch","optionsWithRefs","map","ref","resetUI","setTimeout","current","focus","reset","handleSelect","index","text","set","list","waitForInteractive","onEnter","element","i","event","preventDefault","stopPropagation","isDropdownVisible","length","anchorRef","tooltipRef","floatingStyles","active","key","offset","position","width","handleFocus","handleMouseDown","handleClick","lastMouseMoveTimestamp","handleMouseEnter","now","performance","cursor","interactive","handleChange","currentTarget","value","handleClearOrSubmit","handleClose","ignoreFocusChangeRef","ignoreFocusChange","onMouseDown","onMouseUp","el","isPointerInteraction","preventScroll","scrollIntoView","block","handleFocusChange","focused","containsFocusRef","onClickOutside","when","handleInputKeydown","blur","handleContainerKeydown","staged","children","role","label","size","onClick","display","alignItems","fill","onFocus","autoComplete","AutocompleteInputDropdownContainer","minWidth","pt","style","AutocompleteInputDropdown","AutocompleteInputOptions","maxHeight","onMouseEnter","tabIndex","displayName","withConfig","componentId"],"sources":["../../../../src/elements/AutocompleteInput/AutocompleteInput.tsx"],"sourcesContent":["import CloseIcon from \"@artsy/icons/CloseIcon\"\nimport SearchIcon from \"@artsy/icons/SearchIcon\"\nimport composeRefs from \"@seznam/compose-react-refs\"\nimport { themeGet } from \"@styled-system/theme-get\"\nimport React, {\n createRef,\n useCallback,\n useEffect,\n useMemo,\n useReducer,\n useRef,\n} from \"react\"\nimport styled from \"styled-components\"\nimport { ResponsiveValue } from \"styled-system\"\nimport { useKeyboardListNavigation } from \"use-keyboard-list-navigation\"\nimport { useClickOutside, useContainsFocus, usePosition } from \"../../utils\"\nimport { useMouseActivity } from \"../../utils/useMouseActivity\"\nimport { useWidthOf } from \"../../utils/useWidthOf\"\nimport { Box, splitBoxProps } from \"../Box\"\nimport { Clickable } from \"../Clickable\"\nimport { InputProps } from \"../Input\"\nimport { LabeledInput } from \"../LabeledInput\"\nimport { Spinner } from \"../Spinner\"\nimport { VisuallyHidden } from \"../VisuallyHidden\"\nimport { AutocompleteInputOption } from \"./AutocompleteInputOption\"\nimport { AutocompleteInputOptionLabel } from \"./AutocompleteInputOptionLabel\"\n\nexport interface AutocompleteFooterActions {\n /** Call to close dropdown */\n onClose(): void\n}\n\n/** Base option type — can be expanded */\nexport interface AutocompleteInputOptionType {\n text: string\n value: string\n}\n\ninterface State {\n open: boolean\n query: string\n}\n\ntype Action =\n | { type: \"OPEN\" }\n | { type: \"CLOSE\" }\n | { type: \"CLEAR\" }\n | { type: \"CHANGE\"; payload: { query: string } }\n | { type: \"SELECT\"; payload: { query: string } }\n\nconst reducer = (state: State, action: Action): State => {\n switch (action.type) {\n case \"OPEN\":\n return { ...state, open: true }\n case \"CLOSE\":\n return { ...state, open: false }\n case \"CLEAR\":\n return { ...state, query: \"\" }\n case \"CHANGE\":\n return { ...state, query: action.payload.query, open: true }\n case \"SELECT\":\n return { ...state, query: action.payload.query, open: false }\n }\n}\n\nexport interface AutocompleteInputProps<T extends AutocompleteInputOptionType>\n extends Omit<InputProps, \"onSelect\" | \"onSubmit\"> {\n /** Optionally enable clamping (default: `false`) */\n clamp?: boolean\n defaultValue?: string\n dropdownMaxHeight?: ResponsiveValue<string | number>\n dropdownMinWidth?: ResponsiveValue<string | number>\n loading?: boolean\n header?: React.ReactNode\n /** Optionally disable flipping (default: `true`) */\n flip?: boolean\n footer?:\n | React.ReactNode\n | ((dropdownActions: AutocompleteFooterActions) => React.ReactNode)\n /** Ref to the input; workaround generics */\n forwardRef?: React.Ref<HTMLInputElement>\n /** on <enter> when no option is selected */\n onSubmit?(query: string): void\n /** on <click> or <enter> when an option is selected */\n onSelect?(option: T, index: number): void\n /** on <click> of the 'x' (clear) button */\n onClear?(): void\n /** Callback that runs when options are hidden */\n onClose?(): void\n options: T[]\n renderOption?(\n option: T,\n i: number\n ): React.ReactElement<any, string | React.JSXElementConstructor<any>>\n}\n\n/** AutocompleteInput */\nexport const AutocompleteInput = <T extends AutocompleteInputOptionType>({\n clamp = false,\n defaultValue = \"\",\n dropdownMaxHeight = 308, // 308 = roughly 5.5 options\n dropdownMinWidth,\n flip = true,\n footer,\n forwardRef: forwardedRef,\n header,\n height,\n id,\n loading,\n onChange,\n onClear,\n onClose,\n onKeyDown,\n onSelect,\n onSubmit,\n options,\n renderOption = (option) => <AutocompleteInputOptionLabel {...option} />,\n ...rest\n}: AutocompleteInputProps<T>) => {\n const inputRef = useRef<HTMLInputElement | null>(null)\n const containerRef = useRef<HTMLDivElement | null>(null)\n const headerRef = useRef<HTMLDivElement | null>(null)\n const footerRef = useRef<HTMLDivElement | null>(null)\n\n const [boxProps, inputProps] = splitBoxProps(rest)\n\n const [state, dispatch] = useReducer(reducer, {\n open: false,\n query: defaultValue,\n })\n\n const optionsWithRefs = useMemo(() => {\n return options.map((option) => ({\n option,\n ref: createRef<HTMLButtonElement>(),\n }))\n }, [options])\n\n const resetUI = () => {\n setTimeout(() => {\n inputRef.current?.focus()\n reset()\n dispatch({ type: \"CLOSE\" })\n }, 100)\n }\n\n const handleSelect = (option: T, index: number) => {\n dispatch({ type: \"SELECT\", payload: { query: option.text } })\n inputRef.current?.focus()\n onSelect?.(option, index)\n }\n\n const { index, reset, set } = useKeyboardListNavigation({\n ref: containerRef,\n list: options,\n waitForInteractive: true,\n onEnter: ({ element: option, index: i, event }) => {\n event.preventDefault()\n event.stopPropagation()\n handleSelect(option, i)\n resetUI()\n },\n })\n\n const isDropdownVisible = state.open && options.length > 0\n\n // Reset keyboard navigation when options change\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useEffect(reset, [options])\n\n // Reset keyboard navigation when query is empty\n useEffect(() => {\n if (state.query === \"\") reset()\n }, [reset, state.query])\n\n const { anchorRef, tooltipRef, floatingStyles } = usePosition({\n active: isDropdownVisible,\n clamp,\n flip,\n key: options.length,\n offset: 0,\n position: \"bottom\",\n })\n\n const { width } = useWidthOf({ ref: anchorRef })\n\n const handleFocus = () => {\n reset()\n dispatch({ type: \"OPEN\" })\n }\n\n const handleMouseDown = (option: T, i: number) => () => {\n handleSelect(option, i)\n resetUI()\n }\n\n const handleClick = () => {\n dispatch({ type: \"OPEN\" })\n }\n\n // Records the latest mouse movement and, inside the `handleMouseEnter` callback,\n // only treat the event as genuine if the mouse has moved very recently.\n // Otherwise, the event is presumed to have been triggered by scrolling and is ignored.\n const { lastMouseMoveTimestamp } = useMouseActivity()\n\n const handleMouseEnter = (i: number) => () => {\n const now = performance.now()\n\n // 50ms mouse move window\n if (now - lastMouseMoveTimestamp.current < 50) {\n set({ cursor: i, interactive: true })\n }\n }\n\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n const {\n currentTarget: { value },\n } = event\n\n dispatch({ type: \"CHANGE\", payload: { query: value } })\n onChange?.(event)\n }\n\n const handleClearOrSubmit = () => {\n if (state.query === \"\") {\n onSubmit?.(state.query)\n return\n }\n\n dispatch({ type: \"CLEAR\" })\n inputRef.current?.focus()\n onClear?.()\n }\n\n const handleClose = useCallback(() => {\n dispatch({ type: \"CLOSE\" })\n reset()\n onClose?.()\n }, [onClose, reset])\n\n const ignoreFocusChangeRef = useRef<boolean>(false)\n const ignoreFocusChange = {\n onMouseDown: () => (ignoreFocusChangeRef.current = true),\n onMouseUp: () => (ignoreFocusChangeRef.current = false),\n }\n\n // Moves focus to different options when keyboard navigating using up/down\n useEffect(() => {\n const el = optionsWithRefs[index]?.ref?.current\n if (!el) return\n\n const isPointerInteraction =\n performance.now() - lastMouseMoveTimestamp.current < 50\n\n if (isPointerInteraction) {\n // Pointer interactions should not cause scroll\n el.focus({ preventScroll: true })\n return\n }\n\n // Keyboard navigation: focus and ensure visibility\n el.focus({ preventScroll: true })\n try {\n el.scrollIntoView({ block: \"nearest\" })\n } catch {}\n }, [index, optionsWithRefs])\n\n const handleFocusChange = useCallback(\n (focused: boolean) => {\n if (ignoreFocusChangeRef.current || focused || !isDropdownVisible) return\n\n handleClose()\n },\n\n [isDropdownVisible, handleClose]\n )\n\n // Handle closing the dropdown when clicking outside of the input\n // or when focus leaves the input completely\n const { ref: containsFocusRef } = useContainsFocus({\n onChange: handleFocusChange,\n })\n\n useClickOutside({\n ref: containsFocusRef,\n onClickOutside: handleClose,\n when: isDropdownVisible,\n type: \"click\",\n })\n\n const handleInputKeydown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n switch (event.key) {\n // Handle <Enter> when nothing is selected\n case \"Enter\":\n if (state.query !== \"\" && index === -1) {\n onSubmit?.(state.query)\n resetUI()\n }\n return\n\n // <Esc> to close dropdown\n case \"Escape\":\n event.preventDefault()\n event.stopPropagation()\n\n dispatch({ type: \"CLOSE\" })\n inputRef.current?.blur()\n\n return\n\n default:\n break\n }\n\n onKeyDown?.(event)\n }\n\n // Moves focus back to input when typing\n const handleContainerKeydown = (\n event: React.KeyboardEvent<HTMLDivElement>\n ) => {\n switch (event.key) {\n case \"Alt\":\n case \"ArrowDown\":\n case \"ArrowUp\":\n case \"Control\":\n case \"Enter\":\n case \"Meta\":\n case \"Shift\":\n case \"Tab\":\n // Ignore\n return\n\n case \"Escape\":\n event.preventDefault()\n event.stopPropagation()\n\n dispatch({ type: \"CLOSE\" })\n inputRef.current?.blur()\n reset()\n\n return\n\n default:\n inputRef.current?.focus()\n }\n }\n\n // Option that is being hovered or keyed into\n const staged = options[index]\n\n return (\n <Box\n ref={composeRefs(containerRef, containsFocusRef) as any}\n onKeyDown={handleContainerKeydown}\n {...boxProps}\n >\n <LabeledInput\n ref={composeRefs(inputRef, anchorRef, forwardedRef) as any}\n role=\"combobox\"\n aria-expanded={isDropdownVisible}\n aria-autocomplete=\"list\"\n {...(id ? { id, \"aria-describedby\": `${id}__assistiveHint` } : {})}\n label={\n loading ? (\n <Box width={18}>\n <Spinner size=\"small\" />\n </Box>\n ) : state.query ? (\n <Clickable\n onClick={handleClearOrSubmit}\n height=\"100%\"\n display=\"flex\"\n alignItems=\"center\"\n aria-label=\"Clear input\"\n >\n <CloseIcon fill=\"mono60\" aria-hidden />\n </Clickable>\n ) : (\n <SearchIcon fill=\"mono60\" aria-hidden />\n )\n }\n value={staged?.text ?? state.query}\n onChange={handleChange}\n onFocus={handleFocus}\n onKeyDown={handleInputKeydown}\n onClick={handleClick}\n autoComplete=\"off\"\n height={height}\n {...inputProps}\n />\n\n {isDropdownVisible && (\n <AutocompleteInputDropdownContainer\n ref={tooltipRef as any}\n role=\"listbox\"\n width={width}\n minWidth={200}\n pt={1} // Gap in place of `offset` for `usePosition`\n style={floatingStyles}\n >\n <AutocompleteInputDropdown minWidth={dropdownMinWidth}>\n <div ref={headerRef} {...ignoreFocusChange}>\n {header}\n </div>\n\n <AutocompleteInputOptions maxHeight={dropdownMaxHeight}>\n {optionsWithRefs.map(({ option, ref }, i) => {\n return (\n <AutocompleteInputOption\n key={i}\n ref={ref}\n role=\"option\"\n aria-selected={i === index}\n aria-posinset={i + 1}\n aria-setsize={options.length}\n onMouseDown={handleMouseDown(option, i)}\n onMouseEnter={handleMouseEnter(i)}\n tabIndex={-1}\n >\n {renderOption(option, i)}\n </AutocompleteInputOption>\n )\n })}\n </AutocompleteInputOptions>\n\n <div ref={footerRef} {...ignoreFocusChange}>\n {typeof footer === \"function\"\n ? footer({ onClose: handleClose })\n : footer}\n </div>\n </AutocompleteInputDropdown>\n </AutocompleteInputDropdownContainer>\n )}\n\n <VisuallyHidden {...(id ? { id: `${id}__assistiveHint` } : {})}>\n When autocomplete results are available use up and down arrows to review\n and enter to select. Touch device users, explore by touch or with swipe\n gestures.\n </VisuallyHidden>\n\n {isDropdownVisible && (\n <VisuallyHidden role=\"status\" aria-atomic=\"true\" aria-live=\"polite\">\n {options.length === 1\n ? `1 result is available`\n : `${options.length} results are available`}\n </VisuallyHidden>\n )}\n </Box>\n )\n}\n\nconst AutocompleteInputDropdownContainer = styled(Box)`\n z-index: 1;\n`\n\nconst AutocompleteInputDropdown = styled(Box)`\n box-shadow: ${themeGet(\"effects.dropShadow\")};\n`\n\nconst AutocompleteInputOptions = styled(Box)`\n overflow-y: auto;\n -webkit-overflow-scrolling: touch;\n`\n"],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
2
|
-
import styled from "styled-components";
|
|
2
|
+
import styled, { css } from "styled-components";
|
|
3
|
+
import { useHover, useClick, useDismiss, useInteractions, safePolygon, useTransitionStatus } from "@floating-ui/react";
|
|
3
4
|
import { calculateMaxHeight, usePosition } from "../../utils";
|
|
4
5
|
import { useDidMount } from "../../utils/useDidMount";
|
|
5
6
|
import { usePortal } from "../../utils/usePortal";
|
|
@@ -23,223 +24,173 @@ export const Dropdown = ({
|
|
|
23
24
|
openDropdownByClick,
|
|
24
25
|
transition: _transition = true,
|
|
25
26
|
flip = true,
|
|
27
|
+
autoPlacement = false,
|
|
26
28
|
returnFocus = true,
|
|
27
29
|
delay = 0,
|
|
30
|
+
safePolygonOptions,
|
|
28
31
|
...rest
|
|
29
32
|
}) => {
|
|
30
33
|
const [visible, setVisible] = useState(false);
|
|
31
34
|
|
|
32
|
-
//
|
|
35
|
+
// Sync with controlled `visible` prop
|
|
33
36
|
useEffect(() => {
|
|
34
37
|
setVisible(_visible);
|
|
35
38
|
}, [_visible]);
|
|
36
|
-
const timeoutRef = useRef(null);
|
|
37
39
|
|
|
38
|
-
//
|
|
39
|
-
//
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
timeoutRef.current = setTimeout(() => {
|
|
49
|
-
if (!visible && activeRef.current) return;
|
|
50
|
-
pointerRef.current = isPointer;
|
|
51
|
-
setVisible(visible);
|
|
52
|
-
}, finalDelay);
|
|
53
|
-
}, [_transition, delay, openDropdownByClick]);
|
|
54
|
-
const onVisible = () => {
|
|
55
|
-
setVisibility({
|
|
56
|
-
visible: true
|
|
57
|
-
});
|
|
58
|
-
};
|
|
59
|
-
const onHide = useCallback(() => {
|
|
60
|
-
setVisibility({
|
|
61
|
-
visible: false
|
|
62
|
-
});
|
|
63
|
-
}, [setVisibility]);
|
|
64
|
-
const onToggleVisibility = () => {
|
|
65
|
-
if (visible) {
|
|
66
|
-
return onHide();
|
|
67
|
-
}
|
|
68
|
-
onVisible();
|
|
69
|
-
};
|
|
40
|
+
// Track whether the current open was triggered by pointer (hover) so we know
|
|
41
|
+
// whether to enable keyboard focus-trapping via FocusOn.
|
|
42
|
+
const pointerRef = useRef(false);
|
|
43
|
+
|
|
44
|
+
// onOpenChange is called by Floating UI interaction hooks (useHover, useClick,
|
|
45
|
+
// useDismiss). The `reason` arg lets us detect pointer vs keyboard opens.
|
|
46
|
+
const onOpenChange = useCallback((open, _event, reason) => {
|
|
47
|
+
pointerRef.current = open && (reason === "hover" || reason === "safe-polygon");
|
|
48
|
+
setVisible(open);
|
|
49
|
+
}, []);
|
|
70
50
|
const {
|
|
71
51
|
anchorRef,
|
|
72
52
|
tooltipRef: panelRef,
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
53
|
+
floatingStyles,
|
|
54
|
+
resolvedPlacement,
|
|
55
|
+
context
|
|
76
56
|
} = usePosition({
|
|
77
57
|
position: placement,
|
|
78
58
|
offset: 0,
|
|
79
59
|
active: visible,
|
|
80
|
-
flip
|
|
81
|
-
|
|
60
|
+
// Avoid running both middleware: autoPlacement supersedes flip.
|
|
61
|
+
flip: autoPlacement ? false : flip,
|
|
62
|
+
autoPlacement,
|
|
63
|
+
padding: offset,
|
|
64
|
+
onOpenChange
|
|
82
65
|
});
|
|
83
|
-
useEffect(() => {
|
|
84
|
-
const handleKeyDown = event => {
|
|
85
|
-
if (event.key === "Escape") {
|
|
86
|
-
onHide();
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
66
|
|
|
90
|
-
|
|
67
|
+
// useHover: opens/closes on pointer enter/leave. Optionally use safePolygon
|
|
68
|
+
// to keep the panel open while the cursor traverses the gap (when safePolygonOptions is set).
|
|
69
|
+
const hover = useHover(context, {
|
|
70
|
+
enabled: !openDropdownByClick,
|
|
71
|
+
delay: {
|
|
72
|
+
open: delay ?? (_transition ? 50 : 1),
|
|
73
|
+
close: _transition ? 150 : 50
|
|
74
|
+
},
|
|
75
|
+
handleClose: safePolygonOptions !== undefined && safePolygonOptions !== null ? safePolygon(safePolygonOptions) : null
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// useClick: toggles for click-mode; open-only (toggle:false) for hover-mode
|
|
79
|
+
// so keyboard users can press Enter/Space on a focused anchor to open it.
|
|
80
|
+
const click = useClick(context, {
|
|
81
|
+
toggle: !!openDropdownByClick
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// useDismiss: closes on Escape key and click outside (replaces manual listeners).
|
|
85
|
+
const dismiss = useDismiss(context);
|
|
86
|
+
const {
|
|
87
|
+
getReferenceProps,
|
|
88
|
+
getFloatingProps
|
|
89
|
+
} = useInteractions([hover, click, dismiss]);
|
|
90
|
+
|
|
91
|
+
// Tab-key close for hover-mode: FocusOn is disabled so focus can leave the
|
|
92
|
+
// panel freely; we watch for that and close when it does.
|
|
93
|
+
useEffect(() => {
|
|
94
|
+
if (!visible || openDropdownByClick) return;
|
|
91
95
|
const handleKeyUp = event => {
|
|
92
96
|
if (!panelRef.current) return;
|
|
93
|
-
if (event.key === "Tab" && !
|
|
94
|
-
|
|
97
|
+
if (event.key === "Tab" && !panelRef.current.contains(document.activeElement)) {
|
|
98
|
+
setVisible(false);
|
|
95
99
|
}
|
|
96
100
|
};
|
|
101
|
+
document.addEventListener("keyup", handleKeyUp);
|
|
102
|
+
return () => document.removeEventListener("keyup", handleKeyUp);
|
|
103
|
+
}, [visible, openDropdownByClick, panelRef]);
|
|
104
|
+
|
|
105
|
+
// Close when a link inside the panel is clicked (click-mode only).
|
|
106
|
+
useEffect(() => {
|
|
107
|
+
if (!openDropdownByClick) return;
|
|
97
108
|
const handleClick = event => {
|
|
98
|
-
if (!panelRef.current
|
|
109
|
+
if (!panelRef.current) return;
|
|
99
110
|
const target = event.target;
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
let element = target;
|
|
103
|
-
|
|
104
|
-
// Find parent link element
|
|
105
|
-
if (!isClosableElement) {
|
|
106
|
-
element = target.closest("a");
|
|
107
|
-
isClosableElement = !!element;
|
|
108
|
-
}
|
|
109
|
-
if (isClosableElement && element && panelRef.current.contains(element)) {
|
|
110
|
-
onHide();
|
|
111
|
-
}
|
|
111
|
+
const link = target.tagName.toLowerCase() === "a" ? target : target.closest("a");
|
|
112
|
+
if (link && panelRef.current.contains(link)) setVisible(false);
|
|
112
113
|
};
|
|
113
|
-
document.addEventListener("keydown", handleKeyDown);
|
|
114
|
-
document.addEventListener("keyup", handleKeyUp);
|
|
115
114
|
document.addEventListener("click", handleClick);
|
|
116
|
-
return () =>
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
};
|
|
121
|
-
}, [panelRef, openDropdownByClick, onHide]);
|
|
122
|
-
const activeRef = useRef(false);
|
|
123
|
-
const handleMouseEnter = () => {
|
|
124
|
-
activeRef.current = true;
|
|
125
|
-
};
|
|
126
|
-
const handleMouseLeave = () => {
|
|
127
|
-
activeRef.current = false;
|
|
128
|
-
onHide();
|
|
129
|
-
};
|
|
130
|
-
const [transition, setTransition] = useState(false);
|
|
115
|
+
return () => document.removeEventListener("click", handleClick);
|
|
116
|
+
}, [openDropdownByClick, panelRef]);
|
|
117
|
+
const onVisible = useCallback(() => setVisible(true), []);
|
|
118
|
+
const onHide = useCallback(() => setVisible(false), []);
|
|
131
119
|
|
|
132
|
-
//
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
case "top":
|
|
142
|
-
case "top-end":
|
|
143
|
-
return `translateY(10px)`;
|
|
144
|
-
case "bottom-start":
|
|
145
|
-
case "bottom":
|
|
146
|
-
case "bottom-end":
|
|
147
|
-
return `translateY(-10px)`;
|
|
148
|
-
case "left-start":
|
|
149
|
-
case "left":
|
|
150
|
-
case "left-end":
|
|
151
|
-
return `translateX(10px)`;
|
|
152
|
-
case "right-start":
|
|
153
|
-
case "right":
|
|
154
|
-
case "right-end":
|
|
155
|
-
return `translateX(-10px)`;
|
|
156
|
-
}
|
|
157
|
-
}, [placement]);
|
|
120
|
+
// Placement-aware transitions via CSS data attributes (per Floating UI docs).
|
|
121
|
+
// CSS reads the current data-placement on every frame, so there's no stale
|
|
122
|
+
// capture when flip changes placement after mount.
|
|
123
|
+
const {
|
|
124
|
+
isMounted,
|
|
125
|
+
status
|
|
126
|
+
} = useTransitionStatus(context, {
|
|
127
|
+
duration: _transition ? 250 : 0
|
|
128
|
+
});
|
|
158
129
|
|
|
159
|
-
//
|
|
130
|
+
// Padding on the panel that fills the gap between anchor and panel so the
|
|
131
|
+
// safePolygon cursor path isn't interrupted.
|
|
160
132
|
const padding = useMemo(() => {
|
|
161
|
-
switch (
|
|
133
|
+
switch (resolvedPlacement) {
|
|
162
134
|
case "top-start":
|
|
163
135
|
case "top":
|
|
164
136
|
case "top-end":
|
|
165
137
|
return {
|
|
166
|
-
|
|
138
|
+
pb: offset
|
|
167
139
|
};
|
|
168
140
|
case "bottom-start":
|
|
169
141
|
case "bottom":
|
|
170
142
|
case "bottom-end":
|
|
171
143
|
return {
|
|
172
|
-
|
|
144
|
+
pt: offset
|
|
173
145
|
};
|
|
174
146
|
case "left-start":
|
|
175
147
|
case "left":
|
|
176
148
|
case "left-end":
|
|
177
149
|
return {
|
|
178
|
-
|
|
150
|
+
pr: offset
|
|
179
151
|
};
|
|
180
152
|
case "right-start":
|
|
181
153
|
case "right":
|
|
182
154
|
case "right-end":
|
|
183
155
|
return {
|
|
184
|
-
|
|
156
|
+
pl: offset
|
|
185
157
|
};
|
|
186
158
|
}
|
|
187
|
-
}, [
|
|
188
|
-
const pointerRef = useRef(false);
|
|
189
|
-
const handlePointerVisible = () => {
|
|
190
|
-
setVisibility({
|
|
191
|
-
visible: true,
|
|
192
|
-
isPointer: true
|
|
193
|
-
});
|
|
194
|
-
};
|
|
195
|
-
const handlePointerHide = () => {
|
|
196
|
-
setVisibility({
|
|
197
|
-
visible: false,
|
|
198
|
-
isPointer: false
|
|
199
|
-
});
|
|
200
|
-
};
|
|
201
|
-
const anchorProps = {
|
|
202
|
-
"aria-expanded": visible,
|
|
203
|
-
"aria-haspopup": true,
|
|
204
|
-
...(openDropdownByClick ? {
|
|
205
|
-
onClick: onToggleVisibility
|
|
206
|
-
} : {
|
|
207
|
-
onMouseEnter: handlePointerVisible,
|
|
208
|
-
onMouseLeave: handlePointerHide,
|
|
209
|
-
onClick: onVisible
|
|
210
|
-
})
|
|
211
|
-
};
|
|
212
|
-
const {
|
|
213
|
-
createPortal
|
|
214
|
-
} = usePortal();
|
|
215
|
-
const isClient = useDidMount();
|
|
159
|
+
}, [resolvedPlacement, offset]);
|
|
216
160
|
const isPointer = !openDropdownByClick && pointerRef.current;
|
|
217
161
|
const focusEnabled = visible && !isPointer;
|
|
218
162
|
const [maxHeight, setMaxHeight] = useState(0);
|
|
219
163
|
useEffect(() => {
|
|
220
|
-
const calculate =
|
|
164
|
+
const calculate = () => {
|
|
221
165
|
if (!anchorRef.current) return;
|
|
222
166
|
const nextMaxHeight = calculateMaxHeight({
|
|
223
167
|
anchorRect: anchorRef.current.getBoundingClientRect(),
|
|
224
|
-
position:
|
|
168
|
+
position: resolvedPlacement,
|
|
225
169
|
offset
|
|
226
170
|
});
|
|
227
171
|
setMaxHeight(nextMaxHeight);
|
|
228
|
-
}
|
|
229
|
-
|
|
172
|
+
};
|
|
173
|
+
const calculateOnViewportChange = debounce(calculate, 100);
|
|
174
|
+
window.addEventListener("resize", calculateOnViewportChange, {
|
|
230
175
|
passive: true
|
|
231
176
|
});
|
|
232
|
-
window.addEventListener("scroll",
|
|
177
|
+
window.addEventListener("scroll", calculateOnViewportChange, {
|
|
233
178
|
passive: true
|
|
234
179
|
});
|
|
235
180
|
calculate();
|
|
236
181
|
return () => {
|
|
237
|
-
window.removeEventListener("resize",
|
|
238
|
-
window.removeEventListener("scroll",
|
|
182
|
+
window.removeEventListener("resize", calculateOnViewportChange);
|
|
183
|
+
window.removeEventListener("scroll", calculateOnViewportChange);
|
|
239
184
|
};
|
|
240
|
-
}, [anchorRef, offset,
|
|
185
|
+
}, [anchorRef, offset, resolvedPlacement, visible]);
|
|
186
|
+
const {
|
|
187
|
+
createPortal
|
|
188
|
+
} = usePortal();
|
|
189
|
+
const isClient = useDidMount();
|
|
241
190
|
const dropdownPanel = useMemo(() => {
|
|
242
|
-
if (!(visible || keepInDOM)) return null;
|
|
191
|
+
if (!(visible || isMounted || keepInDOM)) return null;
|
|
192
|
+
const panelVisible = _transition ? isMounted : visible;
|
|
193
|
+
const renderPanel = panelVisible || keepInDOM;
|
|
243
194
|
return /*#__PURE__*/_jsx(Container, {
|
|
244
195
|
"aria-label": "Press escape to close",
|
|
245
196
|
tabIndex: 0,
|
|
@@ -248,35 +199,23 @@ export const Dropdown = ({
|
|
|
248
199
|
display: "inline-block",
|
|
249
200
|
placement: placement,
|
|
250
201
|
style: {
|
|
202
|
+
...floatingStyles,
|
|
251
203
|
...(keepInDOM ? {
|
|
252
204
|
visibility: visible ? "visible" : "hidden"
|
|
253
205
|
} : {})
|
|
254
206
|
},
|
|
255
|
-
...(openDropdownByClick ? {} : {
|
|
256
|
-
onMouseEnter: handleMouseEnter,
|
|
257
|
-
onMouseLeave: handleMouseLeave
|
|
258
|
-
}),
|
|
259
207
|
maxHeight: maxHeight + offset,
|
|
260
208
|
...padding,
|
|
209
|
+
...getFloatingProps(),
|
|
261
210
|
...rest,
|
|
262
|
-
children: /*#__PURE__*/_jsx(Panel, {
|
|
263
|
-
|
|
211
|
+
children: renderPanel && /*#__PURE__*/_jsx(Panel, {
|
|
212
|
+
"data-status": panelVisible ? status : "initial",
|
|
213
|
+
"data-placement": resolvedPlacement,
|
|
214
|
+
$animate: _transition,
|
|
264
215
|
maxHeight: maxHeight,
|
|
265
|
-
style: transition ?
|
|
266
|
-
// In
|
|
267
|
-
{
|
|
268
|
-
opacity: 1,
|
|
269
|
-
transform: "translate(0)"
|
|
270
|
-
} :
|
|
271
|
-
// Out
|
|
272
|
-
{
|
|
273
|
-
opacity: 0,
|
|
274
|
-
transform: translation
|
|
275
|
-
},
|
|
276
216
|
children: /*#__PURE__*/_jsx(FocusOn, {
|
|
277
217
|
noIsolation: true,
|
|
278
218
|
enabled: focusEnabled,
|
|
279
|
-
onClickOutside: onHide,
|
|
280
219
|
returnFocus: returnFocus,
|
|
281
220
|
children: /*#__PURE__*/_jsx(Pane, {
|
|
282
221
|
maxHeight: maxHeight,
|
|
@@ -290,8 +229,11 @@ export const Dropdown = ({
|
|
|
290
229
|
})
|
|
291
230
|
})
|
|
292
231
|
});
|
|
293
|
-
|
|
294
|
-
|
|
232
|
+
}, [visible, isMounted, keepInDOM, dropdownZIndex, placement, resolvedPlacement, maxHeight, offset, _transition, status, focusEnabled, returnFocus, dropdown, padding, floatingStyles, getFloatingProps, rest]);
|
|
233
|
+
const anchorProps = getReferenceProps({
|
|
234
|
+
"aria-expanded": visible,
|
|
235
|
+
"aria-haspopup": true
|
|
236
|
+
});
|
|
295
237
|
return /*#__PURE__*/_jsxs(_Fragment, {
|
|
296
238
|
children: [children?.({
|
|
297
239
|
anchorRef: anchorRef,
|
|
@@ -306,13 +248,22 @@ export const Dropdown = ({
|
|
|
306
248
|
const Container = styled(Box).withConfig({
|
|
307
249
|
displayName: "Dropdown__Container",
|
|
308
250
|
componentId: "sc-je1xqj-0"
|
|
309
|
-
})(["
|
|
251
|
+
})(["text-align:left;outline:0;"]);
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Placement-aware transitions driven by data attributes, following the pattern
|
|
255
|
+
* from https://floating-ui.com/docs/useTransition#placement-aware-transitions
|
|
256
|
+
*
|
|
257
|
+
* CSS reads data-placement (which is always the *resolved* placement from
|
|
258
|
+
* Floating UI, including flips) on every frame, so there is never a stale
|
|
259
|
+
* slide direction — even when flip changes the placement after mount.
|
|
260
|
+
*/
|
|
310
261
|
const Panel = styled(Box).withConfig({
|
|
311
262
|
displayName: "Dropdown__Panel",
|
|
312
263
|
componentId: "sc-je1xqj-1"
|
|
313
|
-
})(["
|
|
314
|
-
|
|
315
|
-
}) =>
|
|
264
|
+
})(["", ""], ({
|
|
265
|
+
$animate
|
|
266
|
+
}) => $animate ? css(["transition-property:opacity,transform;&[data-status=\"open\"],&[data-status=\"close\"]{transition-duration:250ms;transition-timing-function:ease-out;}&[data-status=\"initial\"],&[data-status=\"close\"]{opacity:0;}&[data-status=\"initial\"][data-placement^=\"top\"],&[data-status=\"close\"][data-placement^=\"top\"]{transform:translateY(10px);}&[data-status=\"initial\"][data-placement^=\"bottom\"],&[data-status=\"close\"][data-placement^=\"bottom\"]{transform:translateY(-10px);}&[data-status=\"initial\"][data-placement^=\"left\"],&[data-status=\"close\"][data-placement^=\"left\"]{transform:translateX(10px);}&[data-status=\"initial\"][data-placement^=\"right\"],&[data-status=\"close\"][data-placement^=\"right\"]{transform:translateX(-10px);}"]) : css(["transition:none;"]));
|
|
316
267
|
const Pane = styled(Box).withConfig({
|
|
317
268
|
displayName: "Dropdown__Pane",
|
|
318
269
|
componentId: "sc-je1xqj-2"
|