@basic-ui/core 0.0.50 → 0.0.52
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/README.md +3 -3
- package/build/cjs/index.js +106 -92
- package/build/cjs/index.js.map +1 -1
- package/build/esm/Accordion/Accordion.d.ts +9 -9
- package/build/esm/Accordion/Accordion.js.map +1 -1
- package/build/esm/Accordion/AccordionBody.d.ts +6 -6
- package/build/esm/Accordion/AccordionBody.js.map +1 -1
- package/build/esm/Accordion/AccordionHeader.d.ts +7 -7
- package/build/esm/Accordion/AccordionHeader.js.map +1 -1
- package/build/esm/Accordion/AccordionItem.d.ts +9 -9
- package/build/esm/Accordion/AccordionItem.js.map +1 -1
- package/build/esm/Accordion/context.d.ts +19 -19
- package/build/esm/Accordion/context.js.map +1 -1
- package/build/esm/Accordion/index.d.ts +4 -4
- package/build/esm/Accordion/index.js.map +1 -1
- package/build/esm/Accordion/scopeQuery.d.ts +2 -2
- package/build/esm/Accordion/scopeQuery.js.map +1 -1
- package/build/esm/CheckBox/CheckBox.d.ts +7 -7
- package/build/esm/CheckBox/CheckBox.js.map +1 -1
- package/build/esm/CheckBox/index.d.ts +1 -1
- package/build/esm/CheckBox/index.js.map +1 -1
- package/build/esm/ComboBox/Combobox.d.ts +18 -18
- package/build/esm/ComboBox/Combobox.js.map +1 -1
- package/build/esm/ComboBox/ComboboxButton.d.ts +9 -9
- package/build/esm/ComboBox/ComboboxButton.js.map +1 -1
- package/build/esm/ComboBox/ComboboxInput.d.ts +17 -17
- package/build/esm/ComboBox/ComboboxInput.js.map +1 -1
- package/build/esm/ComboBox/ComboboxLabel.d.ts +7 -7
- package/build/esm/ComboBox/ComboboxLabel.js.map +1 -1
- package/build/esm/ComboBox/ComboboxList.d.ts +8 -8
- package/build/esm/ComboBox/ComboboxList.js.map +1 -1
- package/build/esm/ComboBox/ComboboxOption.d.ts +11 -11
- package/build/esm/ComboBox/ComboboxOption.js.map +1 -1
- package/build/esm/ComboBox/ComboboxPopover.d.ts +9 -9
- package/build/esm/ComboBox/ComboboxPopover.js.map +1 -1
- package/build/esm/ComboBox/cities.d.ts +5 -5
- package/build/esm/ComboBox/cities.js.map +1 -1
- package/build/esm/ComboBox/context.d.ts +30 -30
- package/build/esm/ComboBox/context.js.map +1 -1
- package/build/esm/ComboBox/hooks.d.ts +37 -37
- package/build/esm/ComboBox/hooks.js.map +1 -1
- package/build/esm/ComboBox/index.d.ts +8 -8
- package/build/esm/ComboBox/index.js.map +1 -1
- package/build/esm/ComboBox/makeHash.d.ts +1 -1
- package/build/esm/ComboBox/makeHash.js.map +1 -1
- package/build/esm/ComboBox/scopeQuery.d.ts +1 -1
- package/build/esm/ComboBox/scopeQuery.js.map +1 -1
- package/build/esm/FocusLock/FocusLock.d.ts +9 -9
- package/build/esm/FocusLock/FocusLock.js.map +1 -1
- package/build/esm/FocusLock/index.d.ts +1 -1
- package/build/esm/FocusLock/index.js.map +1 -1
- package/build/esm/FocusLock/tabUtils.d.ts +3 -3
- package/build/esm/FocusLock/tabUtils.js.map +1 -1
- package/build/esm/FocusLock/useFocusLock.d.ts +7 -7
- package/build/esm/FocusLock/useFocusLock.js.map +1 -1
- package/build/esm/List/List.d.ts +7 -7
- package/build/esm/List/List.js.map +1 -1
- package/build/esm/List/ListItem.d.ts +7 -7
- package/build/esm/List/ListItem.js.map +1 -1
- package/build/esm/List/context.d.ts +4 -4
- package/build/esm/List/context.js.map +1 -1
- package/build/esm/List/index.d.ts +2 -2
- package/build/esm/List/index.js.map +1 -1
- package/build/esm/Menu/ContextMenuTrigger.d.ts +11 -11
- package/build/esm/Menu/ContextMenuTrigger.js.map +1 -1
- package/build/esm/Menu/Menu.d.ts +10 -10
- package/build/esm/Menu/Menu.js.map +1 -1
- package/build/esm/Menu/MenuButton.d.ts +11 -11
- package/build/esm/Menu/MenuButton.js.map +1 -1
- package/build/esm/Menu/MenuItem.d.ts +8 -8
- package/build/esm/Menu/MenuItem.js +1 -0
- package/build/esm/Menu/MenuItem.js.map +1 -1
- package/build/esm/Menu/MenuList.d.ts +7 -7
- package/build/esm/Menu/MenuList.js +17 -4
- package/build/esm/Menu/MenuList.js.map +1 -1
- package/build/esm/Menu/MenuPopover.d.ts +8 -8
- package/build/esm/Menu/MenuPopover.js.map +1 -1
- package/build/esm/Menu/context.d.ts +25 -25
- package/build/esm/Menu/context.js.map +1 -1
- package/build/esm/Menu/fixtures/countryList.d.ts +1 -1
- package/build/esm/Menu/fixtures/countryList.js.map +1 -1
- package/build/esm/Menu/index.d.ts +6 -6
- package/build/esm/Menu/index.js.map +1 -1
- package/build/esm/Menu/scope.d.ts +1 -1
- package/build/esm/Menu/scope.js.map +1 -1
- package/build/esm/Modal/Modal.d.ts +9 -9
- package/build/esm/Modal/Modal.js.map +1 -1
- package/build/esm/Modal/ModalBackdrop.d.ts +10 -10
- package/build/esm/Modal/ModalBackdrop.js.map +1 -1
- package/build/esm/Modal/index.d.ts +2 -2
- package/build/esm/Modal/index.js.map +1 -1
- package/build/esm/Popper/Popper.d.ts +35 -35
- package/build/esm/Popper/Popper.js.map +1 -1
- package/build/esm/Popper/PopperArrow.d.ts +6 -6
- package/build/esm/Popper/PopperArrow.js.map +1 -1
- package/build/esm/Popper/context.d.ts +6 -6
- package/build/esm/Popper/context.js.map +1 -1
- package/build/esm/Popper/index.d.ts +3 -3
- package/build/esm/Popper/index.js.map +1 -1
- package/build/esm/Portal/Portal.d.ts +6 -6
- package/build/esm/Portal/Portal.js.map +1 -1
- package/build/esm/Portal/index.d.ts +1 -1
- package/build/esm/Portal/index.js.map +1 -1
- package/build/esm/RadioButton/RadioButton.d.ts +10 -10
- package/build/esm/RadioButton/RadioButton.js.map +1 -1
- package/build/esm/RadioButton/RadioGroup.d.ts +12 -12
- package/build/esm/RadioButton/RadioGroup.js.map +1 -1
- package/build/esm/RadioButton/context.d.ts +9 -9
- package/build/esm/RadioButton/context.js.map +1 -1
- package/build/esm/RadioButton/index.d.ts +2 -2
- package/build/esm/RadioButton/index.js.map +1 -1
- package/build/esm/SkipNav/SkipNav.d.ts +7 -7
- package/build/esm/SkipNav/SkipNav.js.map +1 -1
- package/build/esm/SkipNav/index.d.ts +1 -1
- package/build/esm/SkipNav/index.js.map +1 -1
- package/build/esm/Slider/Slider.d.ts +197 -197
- package/build/esm/Slider/Slider.js +82 -82
- package/build/esm/Slider/Slider.js.map +1 -1
- package/build/esm/Slider/index.d.ts +1 -1
- package/build/esm/Slider/index.js.map +1 -1
- package/build/esm/Spinner/Spinner.d.ts +12 -12
- package/build/esm/Spinner/Spinner.js.map +1 -1
- package/build/esm/Spinner/SpinnerButton.d.ts +8 -8
- package/build/esm/Spinner/SpinnerButton.js.map +1 -1
- package/build/esm/Spinner/context.d.ts +12 -12
- package/build/esm/Spinner/context.js.map +1 -1
- package/build/esm/Spinner/index.d.ts +2 -2
- package/build/esm/Spinner/index.js.map +1 -1
- package/build/esm/Tabs/Tab.d.ts +7 -7
- package/build/esm/Tabs/Tab.js.map +1 -1
- package/build/esm/Tabs/TabList.d.ts +9 -9
- package/build/esm/Tabs/TabList.js.map +1 -1
- package/build/esm/Tabs/TabPanel.d.ts +8 -8
- package/build/esm/Tabs/TabPanel.js.map +1 -1
- package/build/esm/Tabs/TabPanels.d.ts +8 -8
- package/build/esm/Tabs/TabPanels.js.map +1 -1
- package/build/esm/Tabs/Tabs.d.ts +10 -10
- package/build/esm/Tabs/Tabs.js.map +1 -1
- package/build/esm/Tabs/context.d.ts +17 -17
- package/build/esm/Tabs/context.js.map +1 -1
- package/build/esm/Tabs/index.d.ts +5 -5
- package/build/esm/Tabs/index.js.map +1 -1
- package/build/esm/Tabs/scopeQuery.d.ts +1 -1
- package/build/esm/Tabs/scopeQuery.js.map +1 -1
- package/build/esm/Tooltip/Tooltip.d.ts +10 -10
- package/build/esm/Tooltip/Tooltip.js.map +1 -1
- package/build/esm/Tooltip/index.d.ts +1 -1
- package/build/esm/Tooltip/index.js.map +1 -1
- package/build/esm/Tooltip/stateMachine.d.ts +28 -28
- package/build/esm/Tooltip/stateMachine.js.map +1 -1
- package/build/esm/Tooltip/useTooltip.d.ts +10 -10
- package/build/esm/Tooltip/useTooltip.js.map +1 -1
- package/build/esm/hooks/index.d.ts +13 -13
- package/build/esm/hooks/index.js.map +1 -1
- package/build/esm/hooks/useAutoFocus.d.ts +2 -2
- package/build/esm/hooks/useAutoFocus.js.map +1 -1
- package/build/esm/hooks/useChildrenCounter.d.ts +7 -7
- package/build/esm/hooks/useChildrenCounter.js.map +1 -1
- package/build/esm/hooks/useControlledState.d.ts +3 -3
- package/build/esm/hooks/useControlledState.js +1 -1
- package/build/esm/hooks/useControlledState.js.map +1 -1
- package/build/esm/hooks/useFocusReturn.d.ts +2 -2
- package/build/esm/hooks/useFocusReturn.js.map +1 -1
- package/build/esm/hooks/useFocusState.d.ts +11 -11
- package/build/esm/hooks/useFocusState.js.map +1 -1
- package/build/esm/hooks/useGestureHandlers.d.ts +52 -52
- package/build/esm/hooks/useGestureHandlers.js.map +1 -1
- package/build/esm/hooks/useMeasure.d.ts +7 -7
- package/build/esm/hooks/useMeasure.js.map +1 -1
- package/build/esm/hooks/useOnClickOutside.d.ts +2 -2
- package/build/esm/hooks/useOnClickOutside.js.map +1 -1
- package/build/esm/hooks/useOnKeyDown.d.ts +1 -1
- package/build/esm/hooks/useOnKeyDown.js.map +1 -1
- package/build/esm/hooks/useReducerMachine.d.ts +24 -24
- package/build/esm/hooks/useReducerMachine.js.map +1 -1
- package/build/esm/hooks/useRemoveBodyScroll.d.ts +2 -2
- package/build/esm/hooks/useRemoveBodyScroll.js.map +1 -1
- package/build/esm/hooks/useScope.d.ts +11 -11
- package/build/esm/hooks/useScope.js.map +1 -1
- package/build/esm/hooks/useThrottle.d.ts +1 -1
- package/build/esm/hooks/useThrottle.js.map +1 -1
- package/build/esm/index.d.ts +15 -15
- package/build/esm/index.js.map +1 -1
- package/build/esm/utils/assign-ref.d.ts +3 -3
- package/build/esm/utils/assign-ref.js.map +1 -1
- package/build/esm/utils/can-use-dom.d.ts +1 -1
- package/build/esm/utils/can-use-dom.js.map +1 -1
- package/build/esm/utils/clamp.d.ts +1 -1
- package/build/esm/utils/clamp.js.map +1 -1
- package/build/esm/utils/context.d.ts +7 -7
- package/build/esm/utils/context.js.map +1 -1
- package/build/esm/utils/create-subscription.d.ts +4 -4
- package/build/esm/utils/create-subscription.js.map +1 -1
- package/build/esm/utils/get-circular-index.d.ts +1 -1
- package/build/esm/utils/get-circular-index.js.map +1 -1
- package/build/esm/utils/index.d.ts +10 -10
- package/build/esm/utils/index.js.map +1 -1
- package/build/esm/utils/is-right-click.d.ts +6 -6
- package/build/esm/utils/is-right-click.js +4 -4
- package/build/esm/utils/is-right-click.js.map +1 -1
- package/build/esm/utils/owner-document.d.ts +7 -7
- package/build/esm/utils/owner-document.js +5 -5
- package/build/esm/utils/owner-document.js.map +1 -1
- package/build/esm/utils/polymorphic.d.ts +39 -39
- package/build/esm/utils/polymorphic.js.map +1 -1
- package/build/esm/utils/rubber-band-clamp.d.ts +2 -2
- package/build/esm/utils/rubber-band-clamp.js.map +1 -1
- package/build/esm/utils/use-stable-callback.d.ts +16 -16
- package/build/esm/utils/use-stable-callback.js +16 -16
- package/build/esm/utils/use-stable-callback.js.map +1 -1
- package/build/esm/utils/wrap-event.d.ts +3 -3
- package/build/esm/utils/wrap-event.js.map +1 -1
- package/build/tsconfig-build.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/Accordion/Accordion.story.tsx +74 -74
- package/src/Accordion/Accordion.tsx +59 -59
- package/src/Accordion/AccordionBody.tsx +52 -52
- package/src/Accordion/AccordionHeader.tsx +167 -167
- package/src/Accordion/AccordionItem.tsx +50 -50
- package/src/Accordion/context.ts +37 -37
- package/src/Accordion/index.ts +4 -4
- package/src/Accordion/scopeQuery.ts +7 -7
- package/src/Accordion/styles.css +21 -21
- package/src/CheckBox/CheckBox.tsx +41 -41
- package/src/CheckBox/index.ts +1 -1
- package/src/ComboBox/ComboBox.story.tsx +120 -120
- package/src/ComboBox/Combobox.tsx +148 -148
- package/src/ComboBox/ComboboxButton.tsx +61 -61
- package/src/ComboBox/ComboboxInput.tsx +187 -187
- package/src/ComboBox/ComboboxLabel.tsx +33 -33
- package/src/ComboBox/ComboboxList.tsx +47 -47
- package/src/ComboBox/ComboboxOption.tsx +111 -111
- package/src/ComboBox/ComboboxPopover.tsx +64 -64
- package/src/ComboBox/cities.ts +23194 -23194
- package/src/ComboBox/context.ts +35 -35
- package/src/ComboBox/hooks.tsx +451 -451
- package/src/ComboBox/index.ts +8 -8
- package/src/ComboBox/makeHash.ts +19 -19
- package/src/ComboBox/scopeQuery.ts +6 -6
- package/src/ComboBox/styles.css +32 -32
- package/src/FocusLock/FocusLock.tsx +66 -66
- package/src/FocusLock/index.ts +1 -1
- package/src/FocusLock/tabUtils.ts +40 -40
- package/src/FocusLock/useFocusLock.ts +56 -56
- package/src/List/List.story.tsx +18 -18
- package/src/List/List.tsx +17 -17
- package/src/List/ListItem.tsx +23 -23
- package/src/List/context.ts +19 -19
- package/src/List/index.ts +2 -2
- package/src/Menu/ContextMenu.story.tsx +73 -73
- package/src/Menu/ContextMenuTrigger.tsx +76 -76
- package/src/Menu/Menu.story.tsx +160 -160
- package/src/Menu/Menu.tsx +83 -83
- package/src/Menu/MenuButton.tsx +83 -83
- package/src/Menu/MenuComplex.story.tsx +58 -58
- package/src/Menu/MenuItem.tsx +88 -87
- package/src/Menu/MenuList.tsx +254 -243
- package/src/Menu/MenuPopover.tsx +35 -35
- package/src/Menu/context.ts +44 -44
- package/src/Menu/fixtures/countryList.ts +198 -198
- package/src/Menu/index.ts +6 -6
- package/src/Menu/scope.ts +7 -7
- package/src/Menu/styles.css +42 -42
- package/src/Modal/Modal.story.tsx +258 -258
- package/src/Modal/Modal.tsx +48 -48
- package/src/Modal/ModalBackdrop.tsx +78 -78
- package/src/Modal/NavDrawer.story.tsx +158 -158
- package/src/Modal/index.ts +2 -2
- package/src/Modal/styles.css +46 -46
- package/src/Popper/Popper.story.tsx +263 -263
- package/src/Popper/Popper.tsx +154 -154
- package/src/Popper/PopperArrow.tsx +35 -35
- package/src/Popper/context.ts +10 -10
- package/src/Popper/index.ts +3 -3
- package/src/Popper/styles.css +60 -60
- package/src/Portal/Portal.tsx +20 -20
- package/src/Portal/index.ts +1 -1
- package/src/RadioButton/RadioButton.story.tsx +77 -77
- package/src/RadioButton/RadioButton.tsx +55 -55
- package/src/RadioButton/RadioGroup.tsx +60 -60
- package/src/RadioButton/context.ts +17 -17
- package/src/RadioButton/index.ts +2 -2
- package/src/SkipNav/SkipNav.tsx +16 -16
- package/src/SkipNav/index.tsx +1 -1
- package/src/Slider/Slider.story.tsx +45 -45
- package/src/Slider/Slider.tsx +1120 -1120
- package/src/Slider/index.ts +1 -1
- package/src/Slider/styles.css +131 -131
- package/src/Spinner/Spinner.story.tsx +31 -31
- package/src/Spinner/Spinner.tsx +117 -117
- package/src/Spinner/SpinnerButton.tsx +54 -54
- package/src/Spinner/context.ts +20 -20
- package/src/Spinner/index.ts +2 -2
- package/src/Spinner/styles.css +23 -23
- package/src/Tabs/Tab.story.tsx +80 -80
- package/src/Tabs/Tab.tsx +136 -136
- package/src/Tabs/TabList.tsx +71 -71
- package/src/Tabs/TabPanel.tsx +53 -53
- package/src/Tabs/TabPanels.tsx +30 -30
- package/src/Tabs/Tabs.tsx +46 -46
- package/src/Tabs/context.ts +30 -30
- package/src/Tabs/index.tsx +5 -5
- package/src/Tabs/scopeQuery.ts +6 -6
- package/src/Tooltip/Tooltip.story.tsx +61 -61
- package/src/Tooltip/Tooltip.tsx +50 -50
- package/src/Tooltip/index.ts +1 -1
- package/src/Tooltip/stateMachine.ts +192 -192
- package/src/Tooltip/styles.css +17 -17
- package/src/Tooltip/useTooltip.ts +136 -136
- package/src/hooks/index.ts +13 -13
- package/src/hooks/useAutoFocus.ts +22 -22
- package/src/hooks/useChildrenCounter.ts +51 -51
- package/src/hooks/useControlledState.ts +3 -3
- package/src/hooks/useFocusReturn.ts +43 -43
- package/src/hooks/useFocusState.ts +30 -30
- package/src/hooks/useGestureHandlers.ts +286 -286
- package/src/hooks/useMeasure.ts +33 -33
- package/src/hooks/useOnClickOutside.ts +32 -32
- package/src/hooks/useOnKeyDown.ts +19 -19
- package/src/hooks/useReducerMachine.ts +60 -60
- package/src/hooks/useRemoveBodyScroll.ts +39 -39
- package/src/hooks/useScope.ts +52 -52
- package/src/hooks/useThrottle.ts +19 -19
- package/src/index.ts +20 -20
- package/src/utils/assign-ref.ts +27 -27
- package/src/utils/can-use-dom.ts +7 -7
- package/src/utils/clamp.ts +3 -3
- package/src/utils/context.tsx +48 -48
- package/src/utils/create-subscription.ts +16 -16
- package/src/utils/get-circular-index.ts +7 -7
- package/src/utils/index.ts +10 -10
- package/src/utils/is-right-click.ts +14 -14
- package/src/utils/owner-document.ts +13 -13
- package/src/utils/polymorphic.ts +78 -78
- package/src/utils/rubber-band-clamp.ts +25 -25
- package/src/utils/use-stable-callback.ts +58 -58
- package/src/utils/wrap-event.ts +22 -22
|
@@ -1,148 +1,148 @@
|
|
|
1
|
-
import type { HTMLAttributes, ReactNode, ElementType } from 'react';
|
|
2
|
-
import { forwardRef, useRef, useMemo, useId } from 'react';
|
|
3
|
-
|
|
4
|
-
import type { ActionTypes } from './hooks';
|
|
5
|
-
import { stateChart, comboboxReducer, isVisible, INIT } from './hooks';
|
|
6
|
-
import type { ComboBoxContextProps } from './context';
|
|
7
|
-
import { ComboBoxProvider } from './context';
|
|
8
|
-
import { useReducerMachine } from '../hooks/useReducerMachine';
|
|
9
|
-
import type { Scope } from '../hooks';
|
|
10
|
-
import { getScope } from '../hooks';
|
|
11
|
-
|
|
12
|
-
export type SelectEventHandler = (
|
|
13
|
-
text: string,
|
|
14
|
-
itemId: string,
|
|
15
|
-
obj: any
|
|
16
|
-
) => void;
|
|
17
|
-
|
|
18
|
-
export type ComboboxProps = Omit<HTMLAttributes<HTMLDivElement>, 'onSelect'> & {
|
|
19
|
-
onSelect?: SelectEventHandler;
|
|
20
|
-
openOnFocus?: boolean;
|
|
21
|
-
selectOnBlur?: boolean;
|
|
22
|
-
children?: ReactNode;
|
|
23
|
-
as?: ElementType<any>;
|
|
24
|
-
innerAs?: ElementType<any>;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export const Combobox = forwardRef<HTMLDivElement, ComboboxProps>(
|
|
28
|
-
function Combobox(
|
|
29
|
-
{
|
|
30
|
-
// Called whenever the user selects an item from the list
|
|
31
|
-
onSelect,
|
|
32
|
-
|
|
33
|
-
// opens the list when the input receives focused (but only if there are
|
|
34
|
-
// items in the list)
|
|
35
|
-
openOnFocus = false,
|
|
36
|
-
|
|
37
|
-
// if set to true, it will select an item after blurring
|
|
38
|
-
selectOnBlur = false,
|
|
39
|
-
|
|
40
|
-
children,
|
|
41
|
-
as: Comp = 'div',
|
|
42
|
-
innerAs,
|
|
43
|
-
...rest
|
|
44
|
-
}: ComboboxProps,
|
|
45
|
-
ref
|
|
46
|
-
) {
|
|
47
|
-
// We store the values of all the ComboboxOptions on this ref. This makes it
|
|
48
|
-
// possible to perform the keyboard navigation from the input on the list. We
|
|
49
|
-
// manipulate this array through context so that we don't have to enforce a
|
|
50
|
-
// parent/child relationship between ComboboxList and ComboboxOption.
|
|
51
|
-
const optionsRef = useRef<{
|
|
52
|
-
[itemId: string]: {
|
|
53
|
-
value: string | unknown;
|
|
54
|
-
text: string;
|
|
55
|
-
};
|
|
56
|
-
}>({});
|
|
57
|
-
|
|
58
|
-
const listScope: Scope<HTMLElement> = useRef(getScope({ current: null }));
|
|
59
|
-
|
|
60
|
-
// Need this to focus it
|
|
61
|
-
const inputRef = useRef<HTMLInputElement>(null);
|
|
62
|
-
|
|
63
|
-
const popoverRef = useRef<HTMLDivElement>(null);
|
|
64
|
-
|
|
65
|
-
const buttonRef = useRef<HTMLButtonElement>(null);
|
|
66
|
-
|
|
67
|
-
// When <ComboboxInput autocomplete={false} /> we don't want cycle back to
|
|
68
|
-
// the user's value while navigating (because it's always the user's value),
|
|
69
|
-
// but we need to know this in useKeyDown which is far away from the prop
|
|
70
|
-
// here, so we do something sneaky and write it to this ref on context so we
|
|
71
|
-
// can use it anywhere else 😛. Another new trick for me and I'm excited
|
|
72
|
-
// about this one too!
|
|
73
|
-
const autocompletePropRef = useRef<boolean>(false);
|
|
74
|
-
|
|
75
|
-
const persistSelectionRef = useRef<boolean>(false);
|
|
76
|
-
|
|
77
|
-
const clearOnEscapeRef = useRef<boolean>(false);
|
|
78
|
-
|
|
79
|
-
const listboxIdRef = useRef<string | undefined>();
|
|
80
|
-
|
|
81
|
-
const labelIdRef = useRef<string | undefined>();
|
|
82
|
-
|
|
83
|
-
const defaultData = {
|
|
84
|
-
// initial state
|
|
85
|
-
state: stateChart.initial,
|
|
86
|
-
// the value the user has typed, we derived this also when the developer is
|
|
87
|
-
// controlling the value of ComboboxInput
|
|
88
|
-
text: '',
|
|
89
|
-
// the index the user has typed, we derived this also when the developer is
|
|
90
|
-
// controlling the value of ComboboxInput
|
|
91
|
-
item: '',
|
|
92
|
-
// the hash of the currently navigated item
|
|
93
|
-
navigationItem: '',
|
|
94
|
-
// the last submitted action
|
|
95
|
-
lastActionType: INIT as ActionTypes,
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
const [state, data, transition] = useReducerMachine(
|
|
99
|
-
stateChart,
|
|
100
|
-
comboboxReducer,
|
|
101
|
-
defaultData
|
|
102
|
-
);
|
|
103
|
-
|
|
104
|
-
listboxIdRef.current = useId();
|
|
105
|
-
|
|
106
|
-
labelIdRef.current = useId();
|
|
107
|
-
|
|
108
|
-
const context = useMemo(
|
|
109
|
-
(): ComboBoxContextProps => ({
|
|
110
|
-
data,
|
|
111
|
-
inputRef,
|
|
112
|
-
popoverRef,
|
|
113
|
-
buttonRef,
|
|
114
|
-
onSelect,
|
|
115
|
-
optionsRef,
|
|
116
|
-
listScope,
|
|
117
|
-
state,
|
|
118
|
-
transition,
|
|
119
|
-
listboxIdRef,
|
|
120
|
-
labelIdRef,
|
|
121
|
-
autocompletePropRef,
|
|
122
|
-
persistSelectionRef,
|
|
123
|
-
clearOnEscapeRef,
|
|
124
|
-
isVisible: isVisible(state),
|
|
125
|
-
openOnFocus,
|
|
126
|
-
selectOnBlur,
|
|
127
|
-
}),
|
|
128
|
-
[data, onSelect, listScope, state, transition, openOnFocus, selectOnBlur]
|
|
129
|
-
);
|
|
130
|
-
|
|
131
|
-
return (
|
|
132
|
-
<ComboBoxProvider value={context}>
|
|
133
|
-
<Comp
|
|
134
|
-
{...rest}
|
|
135
|
-
as={innerAs}
|
|
136
|
-
data-reach-combobox=""
|
|
137
|
-
ref={ref}
|
|
138
|
-
role="combobox"
|
|
139
|
-
aria-haspopup="listbox"
|
|
140
|
-
aria-owns={listboxIdRef.current}
|
|
141
|
-
aria-expanded={context.isVisible}
|
|
142
|
-
>
|
|
143
|
-
{children}
|
|
144
|
-
</Comp>
|
|
145
|
-
</ComboBoxProvider>
|
|
146
|
-
);
|
|
147
|
-
}
|
|
148
|
-
);
|
|
1
|
+
import type { HTMLAttributes, ReactNode, ElementType } from 'react';
|
|
2
|
+
import { forwardRef, useRef, useMemo, useId } from 'react';
|
|
3
|
+
|
|
4
|
+
import type { ActionTypes } from './hooks';
|
|
5
|
+
import { stateChart, comboboxReducer, isVisible, INIT } from './hooks';
|
|
6
|
+
import type { ComboBoxContextProps } from './context';
|
|
7
|
+
import { ComboBoxProvider } from './context';
|
|
8
|
+
import { useReducerMachine } from '../hooks/useReducerMachine';
|
|
9
|
+
import type { Scope } from '../hooks';
|
|
10
|
+
import { getScope } from '../hooks';
|
|
11
|
+
|
|
12
|
+
export type SelectEventHandler = (
|
|
13
|
+
text: string,
|
|
14
|
+
itemId: string,
|
|
15
|
+
obj: any
|
|
16
|
+
) => void;
|
|
17
|
+
|
|
18
|
+
export type ComboboxProps = Omit<HTMLAttributes<HTMLDivElement>, 'onSelect'> & {
|
|
19
|
+
onSelect?: SelectEventHandler;
|
|
20
|
+
openOnFocus?: boolean;
|
|
21
|
+
selectOnBlur?: boolean;
|
|
22
|
+
children?: ReactNode;
|
|
23
|
+
as?: ElementType<any>;
|
|
24
|
+
innerAs?: ElementType<any>;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const Combobox = forwardRef<HTMLDivElement, ComboboxProps>(
|
|
28
|
+
function Combobox(
|
|
29
|
+
{
|
|
30
|
+
// Called whenever the user selects an item from the list
|
|
31
|
+
onSelect,
|
|
32
|
+
|
|
33
|
+
// opens the list when the input receives focused (but only if there are
|
|
34
|
+
// items in the list)
|
|
35
|
+
openOnFocus = false,
|
|
36
|
+
|
|
37
|
+
// if set to true, it will select an item after blurring
|
|
38
|
+
selectOnBlur = false,
|
|
39
|
+
|
|
40
|
+
children,
|
|
41
|
+
as: Comp = 'div',
|
|
42
|
+
innerAs,
|
|
43
|
+
...rest
|
|
44
|
+
}: ComboboxProps,
|
|
45
|
+
ref
|
|
46
|
+
) {
|
|
47
|
+
// We store the values of all the ComboboxOptions on this ref. This makes it
|
|
48
|
+
// possible to perform the keyboard navigation from the input on the list. We
|
|
49
|
+
// manipulate this array through context so that we don't have to enforce a
|
|
50
|
+
// parent/child relationship between ComboboxList and ComboboxOption.
|
|
51
|
+
const optionsRef = useRef<{
|
|
52
|
+
[itemId: string]: {
|
|
53
|
+
value: string | unknown;
|
|
54
|
+
text: string;
|
|
55
|
+
};
|
|
56
|
+
}>({});
|
|
57
|
+
|
|
58
|
+
const listScope: Scope<HTMLElement> = useRef(getScope({ current: null }));
|
|
59
|
+
|
|
60
|
+
// Need this to focus it
|
|
61
|
+
const inputRef = useRef<HTMLInputElement>(null);
|
|
62
|
+
|
|
63
|
+
const popoverRef = useRef<HTMLDivElement>(null);
|
|
64
|
+
|
|
65
|
+
const buttonRef = useRef<HTMLButtonElement>(null);
|
|
66
|
+
|
|
67
|
+
// When <ComboboxInput autocomplete={false} /> we don't want cycle back to
|
|
68
|
+
// the user's value while navigating (because it's always the user's value),
|
|
69
|
+
// but we need to know this in useKeyDown which is far away from the prop
|
|
70
|
+
// here, so we do something sneaky and write it to this ref on context so we
|
|
71
|
+
// can use it anywhere else 😛. Another new trick for me and I'm excited
|
|
72
|
+
// about this one too!
|
|
73
|
+
const autocompletePropRef = useRef<boolean>(false);
|
|
74
|
+
|
|
75
|
+
const persistSelectionRef = useRef<boolean>(false);
|
|
76
|
+
|
|
77
|
+
const clearOnEscapeRef = useRef<boolean>(false);
|
|
78
|
+
|
|
79
|
+
const listboxIdRef = useRef<string | undefined>();
|
|
80
|
+
|
|
81
|
+
const labelIdRef = useRef<string | undefined>();
|
|
82
|
+
|
|
83
|
+
const defaultData = {
|
|
84
|
+
// initial state
|
|
85
|
+
state: stateChart.initial,
|
|
86
|
+
// the value the user has typed, we derived this also when the developer is
|
|
87
|
+
// controlling the value of ComboboxInput
|
|
88
|
+
text: '',
|
|
89
|
+
// the index the user has typed, we derived this also when the developer is
|
|
90
|
+
// controlling the value of ComboboxInput
|
|
91
|
+
item: '',
|
|
92
|
+
// the hash of the currently navigated item
|
|
93
|
+
navigationItem: '',
|
|
94
|
+
// the last submitted action
|
|
95
|
+
lastActionType: INIT as ActionTypes,
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const [state, data, transition] = useReducerMachine(
|
|
99
|
+
stateChart,
|
|
100
|
+
comboboxReducer,
|
|
101
|
+
defaultData
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
listboxIdRef.current = useId();
|
|
105
|
+
|
|
106
|
+
labelIdRef.current = useId();
|
|
107
|
+
|
|
108
|
+
const context = useMemo(
|
|
109
|
+
(): ComboBoxContextProps => ({
|
|
110
|
+
data,
|
|
111
|
+
inputRef,
|
|
112
|
+
popoverRef,
|
|
113
|
+
buttonRef,
|
|
114
|
+
onSelect,
|
|
115
|
+
optionsRef,
|
|
116
|
+
listScope,
|
|
117
|
+
state,
|
|
118
|
+
transition,
|
|
119
|
+
listboxIdRef,
|
|
120
|
+
labelIdRef,
|
|
121
|
+
autocompletePropRef,
|
|
122
|
+
persistSelectionRef,
|
|
123
|
+
clearOnEscapeRef,
|
|
124
|
+
isVisible: isVisible(state),
|
|
125
|
+
openOnFocus,
|
|
126
|
+
selectOnBlur,
|
|
127
|
+
}),
|
|
128
|
+
[data, onSelect, listScope, state, transition, openOnFocus, selectOnBlur]
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
return (
|
|
132
|
+
<ComboBoxProvider value={context}>
|
|
133
|
+
<Comp
|
|
134
|
+
{...rest}
|
|
135
|
+
as={innerAs}
|
|
136
|
+
data-reach-combobox=""
|
|
137
|
+
ref={ref}
|
|
138
|
+
role="combobox"
|
|
139
|
+
aria-haspopup="listbox"
|
|
140
|
+
aria-owns={listboxIdRef.current}
|
|
141
|
+
aria-expanded={context.isVisible}
|
|
142
|
+
>
|
|
143
|
+
{children}
|
|
144
|
+
</Comp>
|
|
145
|
+
</ComboBoxProvider>
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
);
|
|
@@ -1,61 +1,61 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
ButtonHTMLAttributes,
|
|
3
|
-
ElementType,
|
|
4
|
-
KeyboardEventHandler,
|
|
5
|
-
MouseEventHandler,
|
|
6
|
-
ReactNode,
|
|
7
|
-
} from 'react';
|
|
8
|
-
import { forwardRef } from 'react';
|
|
9
|
-
|
|
10
|
-
import { useComboBoxContext } from './context';
|
|
11
|
-
import { useKeyDown, IDLE, OPEN_WITH_BUTTON, CLOSE_WITH_BUTTON } from './hooks';
|
|
12
|
-
import { wrapEvent } from '../utils/wrap-event';
|
|
13
|
-
import { assignMultipleRefs } from '../utils/assign-ref';
|
|
14
|
-
|
|
15
|
-
export interface ComboboxButtonProps
|
|
16
|
-
extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
17
|
-
as?: ElementType<any>;
|
|
18
|
-
innerAs?: ElementType<any>;
|
|
19
|
-
onClick?: MouseEventHandler<HTMLButtonElement>;
|
|
20
|
-
onKeyDown?: KeyboardEventHandler<HTMLButtonElement>;
|
|
21
|
-
children?: ReactNode;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export const ComboboxButton = forwardRef<
|
|
25
|
-
HTMLButtonElement,
|
|
26
|
-
ComboboxButtonProps
|
|
27
|
-
>(function ComboboxButton(
|
|
28
|
-
{ as: Comp = 'button', innerAs, onClick, onKeyDown, ...props },
|
|
29
|
-
ref
|
|
30
|
-
) {
|
|
31
|
-
const { transition, data, state, buttonRef, listboxIdRef, isVisible } =
|
|
32
|
-
useComboBoxContext();
|
|
33
|
-
|
|
34
|
-
const handleKeyDown = useKeyDown();
|
|
35
|
-
|
|
36
|
-
const handleClick = () => {
|
|
37
|
-
const payload = {
|
|
38
|
-
item: data.navigationItem,
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
if (state === IDLE) {
|
|
42
|
-
transition(OPEN_WITH_BUTTON, payload);
|
|
43
|
-
} else {
|
|
44
|
-
transition(CLOSE_WITH_BUTTON, payload);
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
return (
|
|
49
|
-
<Comp
|
|
50
|
-
as={innerAs}
|
|
51
|
-
data-reach-combobox-button=""
|
|
52
|
-
aria-controls={listboxIdRef.current}
|
|
53
|
-
aria-haspopup="listbox"
|
|
54
|
-
aria-expanded={isVisible}
|
|
55
|
-
ref={assignMultipleRefs(ref, buttonRef)}
|
|
56
|
-
onClick={wrapEvent(onClick, handleClick)}
|
|
57
|
-
onKeyDown={wrapEvent(onKeyDown, handleKeyDown)}
|
|
58
|
-
{...props}
|
|
59
|
-
/>
|
|
60
|
-
);
|
|
61
|
-
});
|
|
1
|
+
import type {
|
|
2
|
+
ButtonHTMLAttributes,
|
|
3
|
+
ElementType,
|
|
4
|
+
KeyboardEventHandler,
|
|
5
|
+
MouseEventHandler,
|
|
6
|
+
ReactNode,
|
|
7
|
+
} from 'react';
|
|
8
|
+
import { forwardRef } from 'react';
|
|
9
|
+
|
|
10
|
+
import { useComboBoxContext } from './context';
|
|
11
|
+
import { useKeyDown, IDLE, OPEN_WITH_BUTTON, CLOSE_WITH_BUTTON } from './hooks';
|
|
12
|
+
import { wrapEvent } from '../utils/wrap-event';
|
|
13
|
+
import { assignMultipleRefs } from '../utils/assign-ref';
|
|
14
|
+
|
|
15
|
+
export interface ComboboxButtonProps
|
|
16
|
+
extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
17
|
+
as?: ElementType<any>;
|
|
18
|
+
innerAs?: ElementType<any>;
|
|
19
|
+
onClick?: MouseEventHandler<HTMLButtonElement>;
|
|
20
|
+
onKeyDown?: KeyboardEventHandler<HTMLButtonElement>;
|
|
21
|
+
children?: ReactNode;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const ComboboxButton = forwardRef<
|
|
25
|
+
HTMLButtonElement,
|
|
26
|
+
ComboboxButtonProps
|
|
27
|
+
>(function ComboboxButton(
|
|
28
|
+
{ as: Comp = 'button', innerAs, onClick, onKeyDown, ...props },
|
|
29
|
+
ref
|
|
30
|
+
) {
|
|
31
|
+
const { transition, data, state, buttonRef, listboxIdRef, isVisible } =
|
|
32
|
+
useComboBoxContext();
|
|
33
|
+
|
|
34
|
+
const handleKeyDown = useKeyDown();
|
|
35
|
+
|
|
36
|
+
const handleClick = () => {
|
|
37
|
+
const payload = {
|
|
38
|
+
item: data.navigationItem,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
if (state === IDLE) {
|
|
42
|
+
transition(OPEN_WITH_BUTTON, payload);
|
|
43
|
+
} else {
|
|
44
|
+
transition(CLOSE_WITH_BUTTON, payload);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<Comp
|
|
50
|
+
as={innerAs}
|
|
51
|
+
data-reach-combobox-button=""
|
|
52
|
+
aria-controls={listboxIdRef.current}
|
|
53
|
+
aria-haspopup="listbox"
|
|
54
|
+
aria-expanded={isVisible}
|
|
55
|
+
ref={assignMultipleRefs(ref, buttonRef)}
|
|
56
|
+
onClick={wrapEvent(onClick, handleClick)}
|
|
57
|
+
onKeyDown={wrapEvent(onKeyDown, handleKeyDown)}
|
|
58
|
+
{...props}
|
|
59
|
+
/>
|
|
60
|
+
);
|
|
61
|
+
});
|