@bigbinary/neeto-atoms 1.0.9 → 1.0.11
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/Accordion-Ch9S_qd3.js +22 -0
- package/dist/Accordion-Ch9S_qd3.js.map +1 -0
- package/dist/Alert-D_FV8xxo.js +65 -0
- package/dist/Alert-D_FV8xxo.js.map +1 -0
- package/dist/Avatar-D5YGlXVF.js +50 -0
- package/dist/Avatar-D5YGlXVF.js.map +1 -0
- package/dist/Badge-8FkscqDt.js +59 -0
- package/dist/Badge-8FkscqDt.js.map +1 -0
- package/dist/Button-Q7MPG6ph.js +92 -0
- package/dist/Button-Q7MPG6ph.js.map +1 -0
- package/dist/Calendar-pDD7nRF-.js +8025 -0
- package/dist/Calendar-pDD7nRF-.js.map +1 -0
- package/dist/Callout-B0w4GQtx.js +65 -0
- package/dist/Callout-B0w4GQtx.js.map +1 -0
- package/dist/Checkbox-zCxgcZiC.js +24 -0
- package/dist/Checkbox-zCxgcZiC.js.map +1 -0
- package/dist/{ColorPicker-D-7QGnf9.js → ColorPicker-DtOvy0Gy.js} +3 -2
- package/dist/ColorPicker-DtOvy0Gy.js.map +1 -0
- package/dist/DatePicker-COxwHPIZ.js +2960 -0
- package/dist/DatePicker-COxwHPIZ.js.map +1 -0
- package/dist/Dialog-BURSzxaP.js +61 -0
- package/dist/Dialog-BURSzxaP.js.map +1 -0
- package/dist/Empty-B2JwFmru.js +26 -0
- package/dist/Empty-B2JwFmru.js.map +1 -0
- package/dist/Input-C1gcv9o2.js +147 -0
- package/dist/Input-C1gcv9o2.js.map +1 -0
- package/dist/Kbd-EqbC0bua.js +36 -0
- package/dist/Kbd-EqbC0bua.js.map +1 -0
- package/dist/Label-BVy4hy9Z.js +58 -0
- package/dist/Label-BVy4hy9Z.js.map +1 -0
- package/dist/MultiEmailInput-SCTYovtX.js +139 -0
- package/dist/MultiEmailInput-SCTYovtX.js.map +1 -0
- package/dist/Pagination-DSc9yXPy.js +61 -0
- package/dist/Pagination-DSc9yXPy.js.map +1 -0
- package/dist/Popover-BFMrtVPq.js +95 -0
- package/dist/Popover-BFMrtVPq.js.map +1 -0
- package/dist/Progress-B9NlUm6e.js +13 -0
- package/dist/Progress-B9NlUm6e.js.map +1 -0
- package/dist/RadioGroup-BNeYQAoT.js +34 -0
- package/dist/RadioGroup-BNeYQAoT.js.map +1 -0
- package/dist/Select-TlFBcxcY.js +565 -0
- package/dist/Select-TlFBcxcY.js.map +1 -0
- package/dist/{components/SelectFieldWrapper.js → SelectFieldWrapper-BJzq9aCY.js} +3 -11
- package/dist/SelectFieldWrapper-BJzq9aCY.js.map +1 -0
- package/dist/Sheet-QFC_mHyj.js +63 -0
- package/dist/Sheet-QFC_mHyj.js.map +1 -0
- package/dist/Slider-BCQXhs0Q.js +25 -0
- package/dist/Slider-BCQXhs0Q.js.map +1 -0
- package/dist/Spinner-C8HSac-2.js +17 -0
- package/dist/Spinner-C8HSac-2.js.map +1 -0
- package/dist/Stepper-BoGkmkY0.js +29 -0
- package/dist/Stepper-BoGkmkY0.js.map +1 -0
- package/dist/Switch-B83TGxJ_.js +20 -0
- package/dist/Switch-B83TGxJ_.js.map +1 -0
- package/dist/Tabs-DWfKnl3S.js +38 -0
- package/dist/Tabs-DWfKnl3S.js.map +1 -0
- package/dist/Textarea-C0z50h0N.js +73 -0
- package/dist/Textarea-C0z50h0N.js.map +1 -0
- package/dist/TimePicker-C4x62jI1.js +142 -0
- package/dist/TimePicker-C4x62jI1.js.map +1 -0
- package/dist/TimePickerPanel-CiF0RExY.js +126 -0
- package/dist/TimePickerPanel-CiF0RExY.js.map +1 -0
- package/dist/Toastr-DYqpSaMd.js +115 -0
- package/dist/Toastr-DYqpSaMd.js.map +1 -0
- package/dist/Tooltip-DhwIZnOU.js +80 -0
- package/dist/Tooltip-DhwIZnOU.js.map +1 -0
- package/dist/TranslationProvider-Ba9rn47H.js.map +1 -1
- package/dist/Tree-C7r10UY5.js +7977 -0
- package/dist/Tree-C7r10UY5.js.map +1 -0
- package/dist/TreeSelect-DRGcYz-6.js +168 -0
- package/dist/TreeSelect-DRGcYz-6.js.map +1 -0
- package/dist/Typography-CMJ8OveZ.js +76 -0
- package/dist/Typography-CMJ8OveZ.js.map +1 -0
- package/dist/cjs/Accordion-BoTckTBI.js +28 -0
- package/dist/cjs/Accordion-BoTckTBI.js.map +1 -0
- package/dist/cjs/Alert-BVvLyM_d.js +67 -0
- package/dist/cjs/Alert-BVvLyM_d.js.map +1 -0
- package/dist/cjs/Avatar-CNao5gvP.js +52 -0
- package/dist/cjs/Avatar-CNao5gvP.js.map +1 -0
- package/dist/cjs/Badge-STBHzYLs.js +61 -0
- package/dist/cjs/Badge-STBHzYLs.js.map +1 -0
- package/dist/cjs/Button-Bt_AElge.js +94 -0
- package/dist/cjs/Button-Bt_AElge.js.map +1 -0
- package/dist/cjs/Calendar-Nk76Y9yP.js +8066 -0
- package/dist/cjs/Calendar-Nk76Y9yP.js.map +1 -0
- package/dist/cjs/Callout-CS2U6pM7.js +67 -0
- package/dist/cjs/Callout-CS2U6pM7.js.map +1 -0
- package/dist/cjs/Checkbox-DOlS2oCD.js +26 -0
- package/dist/cjs/Checkbox-DOlS2oCD.js.map +1 -0
- package/dist/cjs/{ColorPicker-DEELmqH8.js → ColorPicker-Uxgn8U0h.js} +3 -2
- package/dist/cjs/ColorPicker-Uxgn8U0h.js.map +1 -0
- package/dist/cjs/DatePicker-DpijPndg.js +2962 -0
- package/dist/cjs/DatePicker-DpijPndg.js.map +1 -0
- package/dist/cjs/Dialog-CtI_yWsJ.js +63 -0
- package/dist/cjs/Dialog-CtI_yWsJ.js.map +1 -0
- package/dist/cjs/Empty-qzle6YvT.js +28 -0
- package/dist/cjs/Empty-qzle6YvT.js.map +1 -0
- package/dist/cjs/Input-pkugjUb0.js +149 -0
- package/dist/cjs/Input-pkugjUb0.js.map +1 -0
- package/dist/cjs/Kbd-DHirsI--.js +38 -0
- package/dist/cjs/Kbd-DHirsI--.js.map +1 -0
- package/dist/cjs/Label-DpyfZsiT.js +60 -0
- package/dist/cjs/Label-DpyfZsiT.js.map +1 -0
- package/dist/cjs/MultiEmailInput-l0_YVjbp.js +141 -0
- package/dist/cjs/MultiEmailInput-l0_YVjbp.js.map +1 -0
- package/dist/cjs/Pagination-Byzt9Kmj.js +63 -0
- package/dist/cjs/Pagination-Byzt9Kmj.js.map +1 -0
- package/dist/cjs/Popover-LIxANoTc.js +101 -0
- package/dist/cjs/Popover-LIxANoTc.js.map +1 -0
- package/dist/cjs/Progress-DoCxZ_ZH.js +15 -0
- package/dist/cjs/Progress-DoCxZ_ZH.js.map +1 -0
- package/dist/cjs/RadioGroup-1RAoe38m.js +36 -0
- package/dist/cjs/RadioGroup-1RAoe38m.js.map +1 -0
- package/dist/cjs/Select-Br1AT_wm.js +571 -0
- package/dist/cjs/Select-Br1AT_wm.js.map +1 -0
- package/dist/cjs/{components/SelectFieldWrapper.js → SelectFieldWrapper-DEA--2wj.js} +2 -10
- package/dist/cjs/SelectFieldWrapper-DEA--2wj.js.map +1 -0
- package/dist/cjs/Sheet-CIhtNCBV.js +65 -0
- package/dist/cjs/Sheet-CIhtNCBV.js.map +1 -0
- package/dist/cjs/Slider-jNUS9vt8.js +27 -0
- package/dist/cjs/Slider-jNUS9vt8.js.map +1 -0
- package/dist/cjs/Spinner-DQutDMQq.js +19 -0
- package/dist/cjs/Spinner-DQutDMQq.js.map +1 -0
- package/dist/cjs/Stepper-DCoLl2ZS.js +35 -0
- package/dist/cjs/Stepper-DCoLl2ZS.js.map +1 -0
- package/dist/cjs/Switch-CFf8DtB_.js +22 -0
- package/dist/cjs/Switch-CFf8DtB_.js.map +1 -0
- package/dist/cjs/Tabs-D2247rd7.js +40 -0
- package/dist/cjs/Tabs-D2247rd7.js.map +1 -0
- package/dist/cjs/Textarea-BfdlAJ59.js +75 -0
- package/dist/cjs/Textarea-BfdlAJ59.js.map +1 -0
- package/dist/cjs/TimePicker-Ba2FdT1O.js +144 -0
- package/dist/cjs/TimePicker-Ba2FdT1O.js.map +1 -0
- package/dist/cjs/TimePickerPanel-DGNr97cj.js +132 -0
- package/dist/cjs/TimePickerPanel-DGNr97cj.js.map +1 -0
- package/dist/cjs/Toastr-BGp7-kmf.js +117 -0
- package/dist/cjs/Toastr-BGp7-kmf.js.map +1 -0
- package/dist/cjs/Tooltip-CtxI7QBY.js +86 -0
- package/dist/cjs/Tooltip-CtxI7QBY.js.map +1 -0
- package/dist/cjs/TranslationProvider-DBZHXmzX.js.map +1 -1
- package/dist/cjs/Tree-BPd0DuLh.js +7985 -0
- package/dist/cjs/Tree-BPd0DuLh.js.map +1 -0
- package/dist/cjs/TreeSelect-C9nQJKNo.js +170 -0
- package/dist/cjs/TreeSelect-C9nQJKNo.js.map +1 -0
- package/dist/cjs/Typography-PojQmdAY.js +79 -0
- package/dist/cjs/Typography-PojQmdAY.js.map +1 -0
- package/dist/cjs/components/Accordion.js +6 -28
- package/dist/cjs/components/Accordion.js.map +1 -1
- package/dist/cjs/components/Alert.js +9 -70
- package/dist/cjs/components/Alert.js.map +1 -1
- package/dist/cjs/components/Avatar.js +8 -51
- package/dist/cjs/components/Avatar.js.map +1 -1
- package/dist/cjs/components/Badge.js +10 -64
- package/dist/cjs/components/Badge.js.map +1 -1
- package/dist/cjs/components/Button.js +10 -94
- package/dist/cjs/components/Button.js.map +1 -1
- package/dist/cjs/components/Callout.js +9 -66
- package/dist/cjs/components/Callout.js.map +1 -1
- package/dist/cjs/components/Checkbox.js +8 -24
- package/dist/cjs/components/Checkbox.js.map +1 -1
- package/dist/cjs/components/ColorPicker.js +1 -1
- package/dist/cjs/components/DataTable.js +1 -1
- package/dist/cjs/components/DatePicker.js +45 -0
- package/dist/cjs/components/DatePicker.js.map +1 -0
- package/dist/cjs/components/Dialog.js +7 -63
- package/dist/cjs/components/Dialog.js.map +1 -1
- package/dist/cjs/components/DropdownMenu.js.map +1 -1
- package/dist/cjs/components/Empty.js +10 -29
- package/dist/cjs/components/Empty.js.map +1 -1
- package/dist/cjs/components/Input.js +8 -151
- package/dist/cjs/components/Input.js.map +1 -1
- package/dist/cjs/components/Kbd.js +8 -41
- package/dist/cjs/components/Kbd.js.map +1 -1
- package/dist/cjs/components/Label.js +11 -59
- package/dist/cjs/components/Label.js.map +1 -1
- package/dist/cjs/components/MultiEmailInput.js +20 -0
- package/dist/cjs/components/MultiEmailInput.js.map +1 -0
- package/dist/cjs/components/Pagination.js +21 -0
- package/dist/cjs/components/Pagination.js.map +1 -0
- package/dist/cjs/components/Popover.js +7 -103
- package/dist/cjs/components/Popover.js.map +1 -1
- package/dist/cjs/components/Progress.js +7 -13
- package/dist/cjs/components/Progress.js.map +1 -1
- package/dist/cjs/components/RadioGroup.js +9 -40
- package/dist/cjs/components/RadioGroup.js.map +1 -1
- package/dist/cjs/components/Select.js +33 -0
- package/dist/cjs/components/Select.js.map +1 -1
- package/dist/cjs/components/Sheet.js +7 -65
- package/dist/cjs/components/Sheet.js.map +1 -1
- package/dist/cjs/components/Slider.js +8 -25
- package/dist/cjs/components/Slider.js.map +1 -1
- package/dist/cjs/components/Spinner.js +7 -19
- package/dist/cjs/components/Spinner.js.map +1 -1
- package/dist/cjs/components/Stepper.js +6 -32
- package/dist/cjs/components/Stepper.js.map +1 -1
- package/dist/cjs/components/Switch.js +8 -20
- package/dist/cjs/components/Switch.js.map +1 -1
- package/dist/cjs/components/Tabs.js +8 -55
- package/dist/cjs/components/Tabs.js.map +1 -1
- package/dist/cjs/components/Textarea.js +8 -77
- package/dist/cjs/components/Textarea.js.map +1 -1
- package/dist/cjs/components/TimePicker.js +42 -0
- package/dist/cjs/components/TimePicker.js.map +1 -0
- package/dist/cjs/components/Toastr.js +4 -126
- package/dist/cjs/components/Toastr.js.map +1 -1
- package/dist/cjs/components/Tooltip.js +5 -85
- package/dist/cjs/components/Tooltip.js.map +1 -1
- package/dist/cjs/components/Tree.js +34 -0
- package/dist/cjs/components/Tree.js.map +1 -0
- package/dist/cjs/components/TreeSelect.js +45 -0
- package/dist/cjs/components/TreeSelect.js.map +1 -0
- package/dist/cjs/components/Typography.js +8 -98
- package/dist/cjs/components/Typography.js.map +1 -1
- package/dist/cjs/components/index.js +180 -0
- package/dist/cjs/components/index.js.map +1 -0
- package/dist/cjs/formik/ActionBlock.js +48 -0
- package/dist/cjs/formik/ActionBlock.js.map +1 -0
- package/dist/cjs/formik/BlockNavigation.js +111 -0
- package/dist/cjs/formik/BlockNavigation.js.map +1 -0
- package/dist/cjs/formik/Button.js +45 -0
- package/dist/cjs/formik/Button.js.map +1 -0
- package/dist/cjs/formik/Checkbox.js +38 -0
- package/dist/cjs/formik/Checkbox.js.map +1 -0
- package/dist/cjs/formik/Form.js +116 -0
- package/dist/cjs/formik/Form.js.map +1 -0
- package/dist/cjs/formik/Input.js +38 -0
- package/dist/cjs/formik/Input.js.map +1 -0
- package/dist/cjs/formik/MultiEmailInput.js +31 -0
- package/dist/cjs/formik/MultiEmailInput.js.map +1 -0
- package/dist/cjs/formik/RadioGroup.js +44 -0
- package/dist/cjs/formik/RadioGroup.js.map +1 -0
- package/dist/cjs/formik/Select.js +61 -0
- package/dist/cjs/formik/Select.js.map +1 -0
- package/dist/cjs/formik/Slider.js +39 -0
- package/dist/cjs/formik/Slider.js.map +1 -0
- package/dist/cjs/formik/Switch.js +33 -0
- package/dist/cjs/formik/Switch.js.map +1 -0
- package/dist/cjs/formik/Textarea.js +34 -0
- package/dist/cjs/formik/Textarea.js.map +1 -0
- package/dist/cjs/formik/TreeSelect.js +56 -0
- package/dist/cjs/formik/TreeSelect.js.map +1 -0
- package/dist/cjs/formik/index.js +110 -0
- package/dist/cjs/formik/index.js.map +1 -0
- package/dist/cjs/index.js +319 -428
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/primitives/Calendar.js +10 -8020
- package/dist/cjs/primitives/Calendar.js.map +1 -1
- package/dist/cjs/primitives/Chart.js +410 -207
- package/dist/cjs/primitives/Chart.js.map +1 -1
- package/dist/cjs/primitives/Combobox.js +783 -1096
- package/dist/cjs/primitives/Combobox.js.map +1 -1
- package/dist/cjs/primitives/Pagination.js +1 -1
- package/dist/cjs/primitives/Resizable.js +799 -778
- package/dist/cjs/primitives/Resizable.js.map +1 -1
- package/dist/cjs/primitives/ScrollArea.js +10 -10
- package/dist/cjs/primitives/Select.js +77 -77
- package/dist/cjs/primitives/index.js +3 -2
- package/dist/cjs/primitives/index.js.map +1 -1
- package/dist/cjs/redux-DEF7lAd1.js +240 -0
- package/dist/cjs/redux-DEF7lAd1.js.map +1 -0
- package/dist/cjs/search-CfYUGi4v.js +37 -0
- package/dist/cjs/search-CfYUGi4v.js.map +1 -0
- package/dist/cjs/with-selector-DeKHbQY7.js +121 -0
- package/dist/cjs/with-selector-DeKHbQY7.js.map +1 -0
- package/dist/components/{Accordion.d.ts → Accordion/Accordion.d.ts} +3 -1
- package/dist/components/Accordion/index.d.ts +2 -0
- package/dist/components/Accordion.js +5 -27
- package/dist/components/Accordion.js.map +1 -1
- package/dist/components/{Alert.d.ts → Alert/Alert.d.ts} +2 -2
- package/dist/components/Alert/constants.d.ts +3 -0
- package/dist/components/Alert/index.d.ts +2 -0
- package/dist/components/Alert.js +10 -75
- package/dist/components/Alert.js.map +1 -1
- package/dist/components/{Avatar.d.ts → Avatar/Avatar.d.ts} +2 -2
- package/dist/components/Avatar/constants.d.ts +3 -0
- package/dist/components/Avatar/index.d.ts +2 -0
- package/dist/components/Avatar/utils.d.ts +1 -0
- package/dist/components/Avatar.js +9 -56
- package/dist/components/Avatar.js.map +1 -1
- package/dist/components/{Badge.d.ts → Badge/Badge.d.ts} +1 -1
- package/dist/components/Badge/constants.d.ts +25 -0
- package/dist/components/Badge/index.d.ts +2 -0
- package/dist/components/Badge.js +8 -66
- package/dist/components/Badge.js.map +1 -1
- package/dist/components/Button/constants.d.ts +5 -0
- package/dist/components/Button/index.d.ts +2 -0
- package/dist/components/Button.js +11 -99
- package/dist/components/Button.js.map +1 -1
- package/dist/components/{Callout.d.ts → Callout/Callout.d.ts} +1 -1
- package/dist/components/Callout/constants.d.ts +8 -0
- package/dist/components/Callout/index.d.ts +2 -0
- package/dist/components/Callout.js +8 -69
- package/dist/components/Callout.js.map +1 -1
- package/dist/components/Checkbox/index.d.ts +2 -0
- package/dist/components/Checkbox.js +6 -26
- package/dist/components/Checkbox.js.map +1 -1
- package/dist/components/ColorPicker/ColorPicker.d.ts +1 -2
- package/dist/components/ColorPicker/Palette.d.ts +1 -1
- package/dist/components/ColorPicker/types.d.ts +6 -1
- package/dist/components/ColorPicker.js +3 -3
- package/dist/components/DataTable.js +4 -4
- package/dist/components/DatePicker/DatePicker.d.ts +4 -0
- package/dist/components/DatePicker/DatePickerFooter.d.ts +12 -0
- package/dist/components/DatePicker/TimezoneSelect.d.ts +8 -0
- package/dist/components/DatePicker/constants.d.ts +17 -0
- package/dist/components/DatePicker/index.d.ts +2 -0
- package/dist/components/DatePicker/types.d.ts +56 -0
- package/dist/components/DatePicker/utils.d.ts +6 -0
- package/dist/components/DatePicker.js +39 -0
- package/dist/components/DatePicker.js.map +1 -0
- package/dist/components/{Dialog.d.ts → Dialog/Dialog.d.ts} +1 -1
- package/dist/components/Dialog/constants.d.ts +2 -0
- package/dist/components/Dialog/index.d.ts +2 -0
- package/dist/components/Dialog.js +5 -65
- package/dist/components/Dialog.js.map +1 -1
- package/dist/components/DropdownMenu/MenuItemButton.d.ts +1 -2
- package/dist/components/DropdownMenu/index.d.ts +1 -0
- package/dist/components/DropdownMenu.js +3 -3
- package/dist/components/DropdownMenu.js.map +1 -1
- package/dist/components/Empty/index.d.ts +2 -0
- package/dist/components/Empty.js +11 -34
- package/dist/components/Empty.js.map +1 -1
- package/dist/components/{Input.d.ts → Input/Input.d.ts} +3 -1
- package/dist/components/Input/constants.d.ts +17 -0
- package/dist/components/Input/index.d.ts +2 -0
- package/dist/components/Input/utils.d.ts +7 -0
- package/dist/components/Input.js +6 -153
- package/dist/components/Input.js.map +1 -1
- package/dist/components/{Kbd.d.ts → Kbd/Kbd.d.ts} +1 -1
- package/dist/components/Kbd/constants.d.ts +1 -0
- package/dist/components/Kbd/index.d.ts +2 -0
- package/dist/components/Kbd.js +9 -46
- package/dist/components/Kbd.js.map +1 -1
- package/dist/components/Label/constants.d.ts +1 -0
- package/dist/components/Label/index.d.ts +2 -0
- package/dist/components/Label.js +13 -65
- package/dist/components/Label.js.map +1 -1
- package/dist/components/MultiEmailInput/MultiEmailInput.d.ts +2 -0
- package/dist/components/MultiEmailInput/constants.d.ts +3 -0
- package/dist/components/MultiEmailInput/index.d.ts +2 -0
- package/dist/components/MultiEmailInput/types.d.ts +53 -0
- package/dist/components/MultiEmailInput/useMultiEmailState.d.ts +18 -0
- package/dist/components/MultiEmailInput/utils.d.ts +9 -0
- package/dist/components/MultiEmailInput.js +14 -0
- package/dist/components/MultiEmailInput.js.map +1 -0
- package/dist/components/Pagination/Pagination.d.ts +18 -0
- package/dist/components/Pagination/constants.d.ts +1 -0
- package/dist/components/Pagination/hooks/usePaginationRange.d.ts +7 -0
- package/dist/components/Pagination/index.d.ts +2 -0
- package/dist/components/Pagination/utils.d.ts +1 -0
- package/dist/components/Pagination.js +15 -0
- package/dist/components/Pagination.js.map +1 -0
- package/dist/components/Popover/constants.d.ts +2 -0
- package/dist/components/Popover/index.d.ts +2 -0
- package/dist/components/Popover.js +8 -104
- package/dist/components/Popover.js.map +1 -1
- package/dist/components/Progress/index.d.ts +2 -0
- package/dist/components/Progress.js +5 -15
- package/dist/components/Progress.js.map +1 -1
- package/dist/components/{RadioGroup.d.ts → RadioGroup/RadioGroup.d.ts} +1 -1
- package/dist/components/RadioGroup/index.d.ts +2 -0
- package/dist/components/RadioGroup.js +7 -42
- package/dist/components/RadioGroup.js.map +1 -1
- package/dist/components/Select/MultiSelectCombobox.d.ts +2 -0
- package/dist/components/{MultiSelectCombobox.types.d.ts → Select/MultiSelectCombobox.types.d.ts} +3 -13
- package/dist/components/{OptionItem.d.ts → Select/OptionItem.d.ts} +1 -1
- package/dist/components/Select/Select.d.ts +4 -0
- package/dist/components/Select/SelectCombobox.d.ts +2 -0
- package/dist/components/Select/SelectCombobox.types.d.ts +73 -0
- package/dist/components/Select/dropdown.types.d.ts +12 -0
- package/dist/components/Select/index.d.ts +2 -0
- package/dist/components/Select/types.d.ts +148 -0
- package/dist/components/{MultiSelect.utils.d.ts → Select/utils.d.ts} +1 -1
- package/dist/components/Select.js +29 -1
- package/dist/components/Select.js.map +1 -1
- package/dist/components/Sheet/constants.d.ts +3 -0
- package/dist/components/Sheet/index.d.ts +2 -0
- package/dist/components/Sheet.js +5 -67
- package/dist/components/Sheet.js.map +1 -1
- package/dist/components/Slider/index.d.ts +2 -0
- package/dist/components/Slider.js +6 -27
- package/dist/components/Slider.js.map +1 -1
- package/dist/components/Spinner/constants.d.ts +1 -0
- package/dist/components/Spinner/index.d.ts +2 -0
- package/dist/components/Spinner.js +5 -21
- package/dist/components/Spinner.js.map +1 -1
- package/dist/components/Stepper/index.d.ts +2 -0
- package/dist/components/Stepper.js +5 -31
- package/dist/components/Stepper.js.map +1 -1
- package/dist/components/Switch/index.d.ts +2 -0
- package/dist/components/Switch.js +6 -22
- package/dist/components/Switch.js.map +1 -1
- package/dist/components/Tabs/constants.d.ts +5 -0
- package/dist/components/Tabs/index.d.ts +2 -0
- package/dist/components/Tabs.js +6 -57
- package/dist/components/Tabs.js.map +1 -1
- package/dist/components/{Textarea.d.ts → Textarea/Textarea.d.ts} +4 -2
- package/dist/components/Textarea/constants.d.ts +5 -0
- package/dist/components/Textarea/index.d.ts +2 -0
- package/dist/components/Textarea/utils.d.ts +2 -0
- package/dist/components/Textarea.js +6 -79
- package/dist/components/Textarea.js.map +1 -1
- package/dist/components/TimePicker/TimeColumn.d.ts +11 -0
- package/dist/components/TimePicker/TimePicker.d.ts +4 -0
- package/dist/components/TimePicker/TimePickerPanel.d.ts +3 -0
- package/dist/components/TimePicker/constants.d.ts +3 -0
- package/dist/components/TimePicker/index.d.ts +3 -0
- package/dist/components/TimePicker/types.d.ts +61 -0
- package/dist/components/TimePicker/utils.d.ts +11 -0
- package/dist/components/TimePicker.js +35 -0
- package/dist/components/TimePicker.js.map +1 -0
- package/dist/components/{Toastr.d.ts → Toastr/Toastr.d.ts} +2 -2
- package/dist/components/Toastr/index.d.ts +2 -0
- package/dist/components/Toastr/utils.d.ts +10 -0
- package/dist/components/Toastr.js +2 -128
- package/dist/components/Toastr.js.map +1 -1
- package/dist/components/Tooltip/constants.d.ts +2 -0
- package/dist/components/Tooltip/index.d.ts +2 -0
- package/dist/components/Tooltip.js +7 -87
- package/dist/components/Tooltip.js.map +1 -1
- package/dist/components/Tree/Tree.d.ts +2 -0
- package/dist/components/Tree/TreeContext.d.ts +26 -0
- package/dist/components/Tree/components/SwitcherIcon.d.ts +6 -0
- package/dist/components/Tree/components/TreeCheckbox.d.ts +8 -0
- package/dist/components/Tree/components/TreeNode.d.ts +3 -0
- package/dist/components/Tree/constants.d.ts +3 -0
- package/dist/components/Tree/hooks/useTreeCheck.d.ts +18 -0
- package/dist/components/Tree/hooks/useTreeExpansion.d.ts +18 -0
- package/dist/components/Tree/hooks/useTreeSelection.d.ts +16 -0
- package/dist/components/Tree/index.d.ts +3 -0
- package/dist/components/Tree/types.d.ts +110 -0
- package/dist/components/Tree/utils/adapter.d.ts +10 -0
- package/dist/components/Tree/utils/checkCascade.d.ts +5 -0
- package/dist/components/Tree/utils/search.d.ts +10 -0
- package/dist/components/Tree.js +25 -0
- package/dist/components/Tree.js.map +1 -0
- package/dist/components/TreeSelect/TreeSelect.d.ts +3 -0
- package/dist/components/TreeSelect/TreeSelectTrigger.d.ts +14 -0
- package/dist/components/{Select.constants.d.ts → TreeSelect/constants.d.ts} +2 -2
- package/dist/components/TreeSelect/hooks/useTreeSelectState.d.ts +30 -0
- package/dist/components/TreeSelect/hooks/useTreeSelectValue.d.ts +19 -0
- package/dist/components/TreeSelect/index.d.ts +2 -0
- package/dist/components/TreeSelect/types.d.ts +49 -0
- package/dist/components/TreeSelect/utils/pruneTree.d.ts +2 -0
- package/dist/components/TreeSelect/utils/resolveFieldNames.d.ts +5 -0
- package/dist/components/TreeSelect.js +39 -0
- package/dist/components/TreeSelect.js.map +1 -0
- package/dist/{shadcn/components/typography.d.ts → components/Typography/Typography.d.ts} +3 -3
- package/dist/components/Typography/index.d.ts +1 -0
- package/dist/components/Typography.js +6 -81
- package/dist/components/Typography.js.map +1 -1
- package/dist/components/index.d.ts +36 -0
- package/dist/components/index.js +128 -0
- package/dist/components/index.js.map +1 -0
- package/dist/{floating-ui.react-dom-CcGbtPEK.js → floating-ui.react-dom-D8_f_WWh.js} +2 -2
- package/dist/{floating-ui.react-dom-CcGbtPEK.js.map → floating-ui.react-dom-D8_f_WWh.js.map} +1 -1
- package/dist/formik/ActionBlock.d.ts +18 -0
- package/dist/formik/ActionBlock.js +46 -0
- package/dist/formik/ActionBlock.js.map +1 -0
- package/dist/formik/BlockNavigation/BlockNavigationAlert.d.ts +23 -0
- package/dist/formik/BlockNavigation/index.d.ts +11 -0
- package/dist/formik/BlockNavigation.js +109 -0
- package/dist/formik/BlockNavigation.js.map +1 -0
- package/dist/formik/Button.d.ts +7 -0
- package/dist/formik/Button.js +43 -0
- package/dist/formik/Button.js.map +1 -0
- package/dist/formik/Checkbox.d.ts +8 -0
- package/dist/formik/Checkbox.js +36 -0
- package/dist/formik/Checkbox.js.map +1 -0
- package/dist/formik/Form/FormWrapper.d.ts +9 -0
- package/dist/formik/Form/ScrollToErrorField/index.d.ts +5 -0
- package/dist/formik/Form/ScrollToErrorField/utils.d.ts +2 -0
- package/dist/formik/Form/index.d.ts +16 -0
- package/dist/formik/Form.js +114 -0
- package/dist/formik/Form.js.map +1 -0
- package/dist/formik/Input.d.ts +8 -0
- package/dist/formik/Input.js +36 -0
- package/dist/formik/Input.js.map +1 -0
- package/dist/formik/MultiEmailInput.d.ts +7 -0
- package/dist/formik/MultiEmailInput.js +29 -0
- package/dist/formik/MultiEmailInput.js.map +1 -0
- package/dist/formik/RadioGroup.d.ts +11 -0
- package/dist/formik/RadioGroup.js +42 -0
- package/dist/formik/RadioGroup.js.map +1 -0
- package/dist/formik/Select.d.ts +7 -0
- package/dist/formik/Select.js +59 -0
- package/dist/formik/Select.js.map +1 -0
- package/dist/formik/Slider.d.ts +8 -0
- package/dist/formik/Slider.js +37 -0
- package/dist/formik/Slider.js.map +1 -0
- package/dist/formik/Switch.d.ts +10 -0
- package/dist/formik/Switch.js +31 -0
- package/dist/formik/Switch.js.map +1 -0
- package/dist/formik/Textarea.d.ts +8 -0
- package/dist/formik/Textarea.js +32 -0
- package/dist/formik/Textarea.js.map +1 -0
- package/dist/formik/TreeSelect.d.ts +7 -0
- package/dist/formik/TreeSelect.js +54 -0
- package/dist/formik/TreeSelect.js.map +1 -0
- package/dist/formik/index.d.ts +26 -0
- package/dist/formik/index.js +92 -0
- package/dist/formik/index.js.map +1 -0
- package/dist/hooks/useAsyncOptions.d.ts +4 -4
- package/dist/hooks/useComboboxAnchor.d.ts +6 -0
- package/dist/hooks/useCreatableItems.d.ts +1 -1
- package/dist/hooks/useMultiSelectOptions.d.ts +22 -4
- package/dist/hooks/useMultiSelectState.d.ts +7 -4
- package/dist/hooks/useNavPrompt.d.ts +15 -0
- package/dist/hooks/useSelectState.d.ts +39 -14
- package/dist/{index-ByEpUy7w.js → index-C3hByjk3.js} +2 -2
- package/dist/{index-ByEpUy7w.js.map → index-C3hByjk3.js.map} +1 -1
- package/dist/{index-KzJfsx-e.js → index-DLPtgEJ_.js} +2 -2
- package/dist/{index-KzJfsx-e.js.map → index-DLPtgEJ_.js.map} +1 -1
- package/dist/index.css +2 -1
- package/dist/index.d.ts +13 -2
- package/dist/index.js +283 -403
- package/dist/index.js.map +1 -1
- package/dist/primitives/Calendar.js +8 -8003
- package/dist/primitives/Calendar.js.map +1 -1
- package/dist/primitives/Chart.js +253 -50
- package/dist/primitives/Chart.js.map +1 -1
- package/dist/primitives/Combobox.d.ts +3 -3
- package/dist/primitives/Combobox.js +787 -1100
- package/dist/primitives/Combobox.js.map +1 -1
- package/dist/primitives/ContextMenu.js +3 -3
- package/dist/primitives/DropdownMenu.js +3 -3
- package/dist/primitives/HoverCard.js +2 -2
- package/dist/primitives/Menubar.js +3 -3
- package/dist/primitives/Pagination.js +1 -1
- package/dist/primitives/Popover.js +2 -2
- package/dist/primitives/Resizable.js +799 -778
- package/dist/primitives/Resizable.js.map +1 -1
- package/dist/primitives/Select.js +4 -4
- package/dist/primitives/Sidebar.js +3 -3
- package/dist/primitives/Tooltip.js +3 -3
- package/dist/primitives/index.js +7 -6
- package/dist/primitives/index.js.map +1 -1
- package/dist/redux-BKH6DnBB.js +235 -0
- package/dist/redux-BKH6DnBB.js.map +1 -0
- package/dist/search-BK7Ozh5_.js +33 -0
- package/dist/search-BK7Ozh5_.js.map +1 -0
- package/dist/shadcn/components/combobox.d.ts +1 -1
- package/dist/{tooltip-DzjIJacP.js → tooltip-XkHLgxlU.js} +2 -2
- package/dist/{tooltip-DzjIJacP.js.map → tooltip-XkHLgxlU.js.map} +1 -1
- package/dist/utils/dayjs/index.d.ts +4 -0
- package/dist/utils/dayjs/timezonePlugin.d.ts +3 -0
- package/dist/with-selector-Dv0G_V_o.js +115 -0
- package/dist/with-selector-Dv0G_V_o.js.map +1 -0
- package/package.json +31 -4
- package/dist/ColorPicker-D-7QGnf9.js.map +0 -1
- package/dist/cjs/ColorPicker-DEELmqH8.js.map +0 -1
- package/dist/cjs/components/MultiSelect.js +0 -13
- package/dist/cjs/components/MultiSelect.js.map +0 -1
- package/dist/cjs/components/MultiSelectCombobox.js +0 -3
- package/dist/cjs/components/MultiSelectCombobox.js.map +0 -1
- package/dist/cjs/components/MultiSelectDropdown.js +0 -38
- package/dist/cjs/components/MultiSelectDropdown.js.map +0 -1
- package/dist/cjs/components/OptionItem.js +0 -34
- package/dist/cjs/components/OptionItem.js.map +0 -1
- package/dist/cjs/components/SelectFieldWrapper.js.map +0 -1
- package/dist/cjs/components/SelectOptions.js +0 -43
- package/dist/cjs/components/SelectOptions.js.map +0 -1
- package/dist/cjs/components/SelectTriggerContent.js +0 -47
- package/dist/cjs/components/SelectTriggerContent.js.map +0 -1
- package/dist/cjs/components/shared.js +0 -8
- package/dist/cjs/components/shared.js.map +0 -1
- package/dist/cjs/useCreatableItems-BTHtd7uo.js +0 -100
- package/dist/cjs/useCreatableItems-BTHtd7uo.js.map +0 -1
- package/dist/cjs/with-selector-u4xTSzCv.js +0 -457
- package/dist/cjs/with-selector-u4xTSzCv.js.map +0 -1
- package/dist/components/MultiSelect.d.ts +0 -4
- package/dist/components/MultiSelect.js +0 -4
- package/dist/components/MultiSelect.js.map +0 -1
- package/dist/components/MultiSelect.types.d.ts +0 -121
- package/dist/components/MultiSelectCombobox.d.ts +0 -3
- package/dist/components/MultiSelectCombobox.js +0 -2
- package/dist/components/MultiSelectCombobox.js.map +0 -1
- package/dist/components/MultiSelectDropdown.js +0 -36
- package/dist/components/MultiSelectDropdown.js.map +0 -1
- package/dist/components/OptionItem.js +0 -32
- package/dist/components/OptionItem.js.map +0 -1
- package/dist/components/Select.d.ts +0 -4
- package/dist/components/Select.types.d.ts +0 -58
- package/dist/components/SelectFieldWrapper.js.map +0 -1
- package/dist/components/SelectOptions.d.ts +0 -2
- package/dist/components/SelectOptions.js +0 -41
- package/dist/components/SelectOptions.js.map +0 -1
- package/dist/components/SelectTriggerContent.d.ts +0 -18
- package/dist/components/SelectTriggerContent.js +0 -45
- package/dist/components/SelectTriggerContent.js.map +0 -1
- package/dist/components/Typography.d.ts +0 -10
- package/dist/components/shared.js +0 -6
- package/dist/components/shared.js.map +0 -1
- package/dist/components/shared.types.d.ts +0 -16
- package/dist/useCreatableItems-B0seQA1_.js +0 -89
- package/dist/useCreatableItems-B0seQA1_.js.map +0 -1
- package/dist/with-selector--fY1NrB9.js +0 -448
- package/dist/with-selector--fY1NrB9.js.map +0 -1
- /package/dist/components/{Button.d.ts → Button/Button.d.ts} +0 -0
- /package/dist/components/{Checkbox.d.ts → Checkbox/Checkbox.d.ts} +0 -0
- /package/dist/components/{Empty.d.ts → Empty/Empty.d.ts} +0 -0
- /package/dist/components/{Label.d.ts → Label/Label.d.ts} +0 -0
- /package/dist/components/{Popover.d.ts → Popover/Popover.d.ts} +0 -0
- /package/dist/components/{Progress.d.ts → Progress/Progress.d.ts} +0 -0
- /package/dist/components/{MultiSelectDropdown.d.ts → Select/MultiSelectDropdown.d.ts} +0 -0
- /package/dist/components/{SelectFieldWrapper.d.ts → Select/SelectFieldWrapper.d.ts} +0 -0
- /package/dist/components/{MultiSelect.constants.d.ts → Select/constants.d.ts} +0 -0
- /package/dist/components/{Sheet.d.ts → Sheet/Sheet.d.ts} +0 -0
- /package/dist/components/{Slider.d.ts → Slider/Slider.d.ts} +0 -0
- /package/dist/components/{Spinner.d.ts → Spinner/Spinner.d.ts} +0 -0
- /package/dist/components/{Stepper.d.ts → Stepper/Stepper.d.ts} +0 -0
- /package/dist/components/{Switch.d.ts → Switch/Switch.d.ts} +0 -0
- /package/dist/components/{Tabs.d.ts → Tabs/Tabs.d.ts} +0 -0
- /package/dist/components/{Tooltip.d.ts → Tooltip/Tooltip.d.ts} +0 -0
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import { createElement } from 'react';
|
|
3
|
+
import React__default, { createElement } from 'react';
|
|
4
4
|
import { c as cn } from '../utils-DdHUxIdC.js';
|
|
5
5
|
import { B as Button } from '../button-COIbN8dg.js';
|
|
6
6
|
import { I as InputGroup, c as InputGroupInput, a as InputGroupAddon, d as InputGroupButton } from '../input-group-ytECR3Hw.js';
|
|
7
|
-
import { X } from '../x-_o2T3n6D.js';
|
|
8
7
|
import { C as Check } from '../check-Cpkv29p1.js';
|
|
8
|
+
import { X } from '../x-_o2T3n6D.js';
|
|
9
9
|
import { C as ChevronDown } from '../chevron-down-BNi0ntys.js';
|
|
10
|
-
import {
|
|
11
|
-
import * as ReactDOM from 'react-dom';
|
|
12
|
-
import { i as isHTMLElement, d as isShadowRoot, g as getComputedStyle$1, e as floor, j as getWindow, k as isOverflowElement, m as getNodeName, n as isNode, p as isWebKit$1, q as isElement, r as isLastTraversableNode, t as getParentNode, u as useFloating$1, v as evaluate, w as getPaddingObject, x as getAlignmentAxis, y as getAlignment, z as getAxisLength, A as clamp, h as hide$1, o as offset, f as flip, s as shift, l as limitShift, a as size, B as getSide, C as getSideAxis, c as autoUpdate } from '../floating-ui.react-dom-CcGbtPEK.js';
|
|
10
|
+
import { i as isHTMLElement, d as isShadowRoot, g as getComputedStyle, e as floor, j as getNodeName, k as getWindow, m as isOverflowElement, n as isNode, p as isWebKit$1, q as isElement, r as isLastTraversableNode, t as getParentNode, u as useFloating$1, v as evaluate, w as getPaddingObject, x as getAlignmentAxis, y as getAlignment, z as getAxisLength, A as clamp, h as hide$1, o as offset, f as flip, s as shift, l as limitShift, a as size, B as getSide, C as getSideAxis, c as autoUpdate } from '../floating-ui.react-dom-D8_f_WWh.js';
|
|
13
11
|
import { s as shimExports } from '../index-DZXbzIgC.js';
|
|
12
|
+
import { w as withSelectorExports } from '../with-selector-Dv0G_V_o.js';
|
|
13
|
+
import * as ReactDOM from 'react-dom';
|
|
14
14
|
import '../index-D7Zy7P05.js';
|
|
15
15
|
import '../index-CfriMyrd.js';
|
|
16
16
|
import '../index-BtkPdosV.js';
|
|
@@ -492,7 +492,7 @@ const EMPTY_PROPS = {};
|
|
|
492
492
|
* Props can either be provided as objects or as functions that take the previous props as an argument.
|
|
493
493
|
* The function will receive the merged props up to that point (going from left to right):
|
|
494
494
|
* so in the case of `(obj1, obj2, fn, obj3)`, `fn` will receive the merged props of `obj1` and `obj2`.
|
|
495
|
-
* The function is responsible for chaining event handlers if needed (
|
|
495
|
+
* The function is responsible for chaining event handlers if needed (that is, we don't run the merge logic).
|
|
496
496
|
*
|
|
497
497
|
* Event handlers returned by the functions are not automatically prevented when `preventBaseUIHandler` is called.
|
|
498
498
|
* They must check `event.baseUIHandlerPrevented` themselves and bail out if it's true.
|
|
@@ -508,18 +508,20 @@ const EMPTY_PROPS = {};
|
|
|
508
508
|
*/
|
|
509
509
|
|
|
510
510
|
function mergeProps$1(a, b, c, d, e) {
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
511
|
+
if (!c && !d && true && !a) {
|
|
512
|
+
return createInitialMergedProps(b);
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
// We need to mutably own `merged`.
|
|
516
|
+
let merged = createInitialMergedProps(a);
|
|
515
517
|
if (b) {
|
|
516
|
-
merged =
|
|
518
|
+
merged = mergeInto(merged, b);
|
|
517
519
|
}
|
|
518
520
|
if (c) {
|
|
519
|
-
merged =
|
|
521
|
+
merged = mergeInto(merged, c);
|
|
520
522
|
}
|
|
521
523
|
if (d) {
|
|
522
|
-
merged =
|
|
524
|
+
merged = mergeInto(merged, d);
|
|
523
525
|
}
|
|
524
526
|
return merged;
|
|
525
527
|
}
|
|
@@ -543,24 +545,46 @@ function mergePropsN(props) {
|
|
|
543
545
|
return EMPTY_PROPS;
|
|
544
546
|
}
|
|
545
547
|
if (props.length === 1) {
|
|
546
|
-
return
|
|
548
|
+
return createInitialMergedProps(props[0]);
|
|
547
549
|
}
|
|
548
550
|
|
|
549
|
-
// We need to mutably own `merged
|
|
550
|
-
let merged =
|
|
551
|
-
...resolvePropsGetter(props[0], EMPTY_PROPS)
|
|
552
|
-
};
|
|
551
|
+
// We need to mutably own `merged`.
|
|
552
|
+
let merged = createInitialMergedProps(props[0]);
|
|
553
553
|
for (let i = 1; i < props.length; i += 1) {
|
|
554
|
-
merged =
|
|
554
|
+
merged = mergeInto(merged, props[i]);
|
|
555
555
|
}
|
|
556
556
|
return merged;
|
|
557
557
|
}
|
|
558
|
-
function
|
|
558
|
+
function createInitialMergedProps(inputProps) {
|
|
559
559
|
if (isPropsGetter(inputProps)) {
|
|
560
|
-
|
|
560
|
+
// Getter-returned handlers intentionally keep their existing semantics.
|
|
561
|
+
return {
|
|
562
|
+
...resolvePropsGetter(inputProps, EMPTY_PROPS)
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
return copyInitialProps(inputProps);
|
|
566
|
+
}
|
|
567
|
+
function mergeInto(merged, inputProps) {
|
|
568
|
+
if (isPropsGetter(inputProps)) {
|
|
569
|
+
return resolvePropsGetter(inputProps, merged);
|
|
561
570
|
}
|
|
562
571
|
return mutablyMergeInto(merged, inputProps);
|
|
563
572
|
}
|
|
573
|
+
function copyInitialProps(inputProps) {
|
|
574
|
+
const copiedProps = {
|
|
575
|
+
...inputProps
|
|
576
|
+
};
|
|
577
|
+
|
|
578
|
+
// `copiedProps` is our fresh own-object copy, so iterating with `for...in` is safe here.
|
|
579
|
+
// eslint-disable-next-line guard-for-in
|
|
580
|
+
for (const propName in copiedProps) {
|
|
581
|
+
const propValue = copiedProps[propName];
|
|
582
|
+
if (isEventHandler(propName, propValue)) {
|
|
583
|
+
copiedProps[propName] = wrapEventHandler(propValue);
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
return copiedProps;
|
|
587
|
+
}
|
|
564
588
|
|
|
565
589
|
/**
|
|
566
590
|
* Merges two sets of props. In case of conflicts, the external props take precedence.
|
|
@@ -617,7 +641,7 @@ function mergeEventHandlers(ourHandler, theirHandler) {
|
|
|
617
641
|
return ourHandler;
|
|
618
642
|
}
|
|
619
643
|
if (!ourHandler) {
|
|
620
|
-
return theirHandler;
|
|
644
|
+
return wrapEventHandler(theirHandler);
|
|
621
645
|
}
|
|
622
646
|
return event => {
|
|
623
647
|
if (isSyntheticEvent(event)) {
|
|
@@ -634,6 +658,17 @@ function mergeEventHandlers(ourHandler, theirHandler) {
|
|
|
634
658
|
return result;
|
|
635
659
|
};
|
|
636
660
|
}
|
|
661
|
+
function wrapEventHandler(handler) {
|
|
662
|
+
if (!handler) {
|
|
663
|
+
return handler;
|
|
664
|
+
}
|
|
665
|
+
return event => {
|
|
666
|
+
if (isSyntheticEvent(event)) {
|
|
667
|
+
makeEventPreventable(event);
|
|
668
|
+
}
|
|
669
|
+
return handler(event);
|
|
670
|
+
};
|
|
671
|
+
}
|
|
637
672
|
function makeEventPreventable(event) {
|
|
638
673
|
event.preventBaseUIHandler = () => {
|
|
639
674
|
event.baseUIHandlerPrevented = true;
|
|
@@ -722,7 +757,12 @@ function useRenderElementProps(componentProps, params = {}) {
|
|
|
722
757
|
const className = enabled ? resolveClassName(classNameProp, state) : undefined;
|
|
723
758
|
const style = enabled ? resolveStyle(styleProp, state) : undefined;
|
|
724
759
|
const stateProps = enabled ? getStateAttributesProps(state, stateAttributesMapping) : EMPTY_OBJECT;
|
|
725
|
-
const
|
|
760
|
+
const resolvedProps = enabled && props ? resolveRenderFunctionProps(props) : undefined;
|
|
761
|
+
|
|
762
|
+
// Ensure outProps is always a new mutable object when enabled, never EMPTY_OBJECT.
|
|
763
|
+
// This prevents potential TypeError when setting ref, className, or style properties,
|
|
764
|
+
// since EMPTY_OBJECT is frozen and mutations would fail in strict mode.
|
|
765
|
+
const outProps = enabled ? mergeObjects(stateProps, resolvedProps) ?? {} : EMPTY_OBJECT;
|
|
726
766
|
|
|
727
767
|
// SAFETY: The `useMergedRefs` functions use a single hook to store the same value,
|
|
728
768
|
// switching between them at runtime is safe. If this assertion fails, React will
|
|
@@ -750,6 +790,12 @@ function useRenderElementProps(componentProps, params = {}) {
|
|
|
750
790
|
}
|
|
751
791
|
return outProps;
|
|
752
792
|
}
|
|
793
|
+
function resolveRenderFunctionProps(props) {
|
|
794
|
+
if (Array.isArray(props)) {
|
|
795
|
+
return mergePropsN(props);
|
|
796
|
+
}
|
|
797
|
+
return mergeProps$1(undefined, props);
|
|
798
|
+
}
|
|
753
799
|
|
|
754
800
|
// The symbol React uses internally for lazy components
|
|
755
801
|
// https://github.com/facebook/react/blob/a0566250b210499b4c5677f5ac2eedbd71d51a1b/packages/shared/ReactSymbols.js#L31
|
|
@@ -1090,70 +1136,67 @@ function useAnimationsFinished(elementOrRef, waitForStartingStyleRemoved = false
|
|
|
1090
1136
|
*/
|
|
1091
1137
|
signal = null) => {
|
|
1092
1138
|
frame.cancel();
|
|
1093
|
-
function done() {
|
|
1094
|
-
// Synchronously flush the unmounting of the component so that the browser doesn't
|
|
1095
|
-
// paint: https://github.com/mui/base-ui/issues/979
|
|
1096
|
-
ReactDOM.flushSync(fnToExecute);
|
|
1097
|
-
}
|
|
1098
1139
|
const element = resolveRef(elementOrRef);
|
|
1099
1140
|
if (element == null) {
|
|
1100
1141
|
return;
|
|
1101
1142
|
}
|
|
1102
1143
|
const resolvedElement = element;
|
|
1144
|
+
const done = () => {
|
|
1145
|
+
// Synchronously flush the unmounting of the component so that the browser doesn't
|
|
1146
|
+
// paint: https://github.com/mui/base-ui/issues/979
|
|
1147
|
+
ReactDOM.flushSync(fnToExecute);
|
|
1148
|
+
};
|
|
1103
1149
|
if (typeof resolvedElement.getAnimations !== 'function' || globalThis.BASE_UI_ANIMATIONS_DISABLED) {
|
|
1104
1150
|
fnToExecute();
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
// to give "open" animations a chance to be registered.
|
|
1111
|
-
if (!resolvedElement.hasAttribute(startingStyleAttribute)) {
|
|
1112
|
-
frame.request(exec);
|
|
1113
|
-
return;
|
|
1114
|
-
}
|
|
1115
|
-
|
|
1116
|
-
// Wait for `[data-starting-style]` to have been removed.
|
|
1117
|
-
const attributeObserver = new MutationObserver(() => {
|
|
1118
|
-
if (!resolvedElement.hasAttribute(startingStyleAttribute)) {
|
|
1119
|
-
attributeObserver.disconnect();
|
|
1120
|
-
exec();
|
|
1121
|
-
}
|
|
1122
|
-
});
|
|
1123
|
-
attributeObserver.observe(resolvedElement, {
|
|
1124
|
-
attributes: true,
|
|
1125
|
-
attributeFilter: [startingStyleAttribute]
|
|
1126
|
-
});
|
|
1127
|
-
signal?.addEventListener('abort', () => attributeObserver.disconnect(), {
|
|
1128
|
-
once: true
|
|
1129
|
-
});
|
|
1130
|
-
}
|
|
1131
|
-
function exec() {
|
|
1132
|
-
Promise.all(resolvedElement.getAnimations().map(anim => anim.finished)).then(() => {
|
|
1133
|
-
if (signal?.aborted) {
|
|
1134
|
-
return;
|
|
1135
|
-
}
|
|
1151
|
+
return;
|
|
1152
|
+
}
|
|
1153
|
+
function exec() {
|
|
1154
|
+
Promise.all(resolvedElement.getAnimations().map(animation => animation.finished)).then(() => {
|
|
1155
|
+
if (!signal?.aborted) {
|
|
1136
1156
|
done();
|
|
1137
|
-
}
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
return;
|
|
1142
|
-
}
|
|
1157
|
+
}
|
|
1158
|
+
}).catch(() => {
|
|
1159
|
+
if (treatAbortedAsFinished) {
|
|
1160
|
+
if (!signal?.aborted) {
|
|
1143
1161
|
done();
|
|
1144
|
-
} else if (currentAnimations.length > 0 && currentAnimations.some(anim => anim.pending || anim.playState !== 'finished')) {
|
|
1145
|
-
// Sometimes animations can be aborted because a property they depend on changes while the animation plays.
|
|
1146
|
-
// In such cases, we need to re-check if any new animations have started.
|
|
1147
|
-
exec();
|
|
1148
1162
|
}
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1163
|
+
return;
|
|
1164
|
+
}
|
|
1165
|
+
const currentAnimations = resolvedElement.getAnimations();
|
|
1166
|
+
if (!signal?.aborted && currentAnimations.length > 0 && currentAnimations.some(animation => animation.pending || animation.playState !== 'finished')) {
|
|
1167
|
+
// Sometimes animations can be aborted because a property they depend on changes while the animation plays.
|
|
1168
|
+
// In such cases, we need to re-check if any new animations have started.
|
|
1169
|
+
exec();
|
|
1170
|
+
}
|
|
1171
|
+
});
|
|
1172
|
+
}
|
|
1173
|
+
if (waitForStartingStyleRemoved) {
|
|
1174
|
+
const startingStyleAttribute = TransitionStatusDataAttributes.startingStyle;
|
|
1175
|
+
|
|
1176
|
+
// If `[data-starting-style]` isn't present, fall back to waiting one more frame
|
|
1177
|
+
// to give "open" animations a chance to be registered.
|
|
1178
|
+
if (!resolvedElement.hasAttribute(startingStyleAttribute)) {
|
|
1179
|
+
frame.request(exec);
|
|
1153
1180
|
return;
|
|
1154
1181
|
}
|
|
1155
|
-
|
|
1182
|
+
|
|
1183
|
+
// Wait for `[data-starting-style]` to have been removed.
|
|
1184
|
+
const attributeObserver = new MutationObserver(() => {
|
|
1185
|
+
if (!resolvedElement.hasAttribute(startingStyleAttribute)) {
|
|
1186
|
+
attributeObserver.disconnect();
|
|
1187
|
+
exec();
|
|
1188
|
+
}
|
|
1189
|
+
});
|
|
1190
|
+
attributeObserver.observe(resolvedElement, {
|
|
1191
|
+
attributes: true,
|
|
1192
|
+
attributeFilter: [startingStyleAttribute]
|
|
1193
|
+
});
|
|
1194
|
+
signal?.addEventListener('abort', () => attributeObserver.disconnect(), {
|
|
1195
|
+
once: true
|
|
1196
|
+
});
|
|
1197
|
+
return;
|
|
1156
1198
|
}
|
|
1199
|
+
frame.request(exec);
|
|
1157
1200
|
});
|
|
1158
1201
|
}
|
|
1159
1202
|
|
|
@@ -1212,12 +1255,12 @@ function useTransitionStatus(open, enableIdleState = false, deferEndingState = f
|
|
|
1212
1255
|
return () => {
|
|
1213
1256
|
AnimationFrame.cancel(frame);
|
|
1214
1257
|
};
|
|
1215
|
-
}, [enableIdleState, open, mounted,
|
|
1216
|
-
return
|
|
1258
|
+
}, [enableIdleState, open, mounted, transitionStatus]);
|
|
1259
|
+
return {
|
|
1217
1260
|
mounted,
|
|
1218
1261
|
setMounted,
|
|
1219
1262
|
transitionStatus
|
|
1220
|
-
}
|
|
1263
|
+
};
|
|
1221
1264
|
}
|
|
1222
1265
|
|
|
1223
1266
|
let IndexGuessBehavior = /*#__PURE__*/function (IndexGuessBehavior) {
|
|
@@ -1576,12 +1619,12 @@ function contains(parent, child) {
|
|
|
1576
1619
|
}
|
|
1577
1620
|
const rootNode = child.getRootNode?.();
|
|
1578
1621
|
|
|
1579
|
-
// First, attempt with faster native method
|
|
1622
|
+
// First, attempt with the faster native method.
|
|
1580
1623
|
if (parent.contains(child)) {
|
|
1581
1624
|
return true;
|
|
1582
1625
|
}
|
|
1583
1626
|
|
|
1584
|
-
//
|
|
1627
|
+
// Then fall back to traversing out of shadow roots when needed.
|
|
1585
1628
|
if (rootNode && isShadowRoot(rootNode)) {
|
|
1586
1629
|
let next = child;
|
|
1587
1630
|
while (next) {
|
|
@@ -1591,8 +1634,6 @@ function contains(parent, child) {
|
|
|
1591
1634
|
next = next.parentNode || next.host;
|
|
1592
1635
|
}
|
|
1593
1636
|
}
|
|
1594
|
-
|
|
1595
|
-
// Give up, the result is false
|
|
1596
1637
|
return false;
|
|
1597
1638
|
}
|
|
1598
1639
|
function getTarget(event) {
|
|
@@ -1600,10 +1641,11 @@ function getTarget(event) {
|
|
|
1600
1641
|
return event.composedPath()[0];
|
|
1601
1642
|
}
|
|
1602
1643
|
|
|
1603
|
-
// TS
|
|
1604
|
-
//
|
|
1644
|
+
// TS assumes `composedPath()` always exists, but older browsers without
|
|
1645
|
+
// shadow DOM support still fall back to `target`.
|
|
1605
1646
|
return event.target;
|
|
1606
1647
|
}
|
|
1648
|
+
|
|
1607
1649
|
function isEventTargetWithin(event, node) {
|
|
1608
1650
|
if (node == null) {
|
|
1609
1651
|
return false;
|
|
@@ -1622,6 +1664,9 @@ function isRootElement(element) {
|
|
|
1622
1664
|
function isTypeableElement(element) {
|
|
1623
1665
|
return isHTMLElement(element) && element.matches(TYPEABLE_SELECTOR);
|
|
1624
1666
|
}
|
|
1667
|
+
function isInteractiveElement(element) {
|
|
1668
|
+
return element?.closest(`button,a[href],[role="button"],select,[tabindex]:not([tabindex="-1"]),${TYPEABLE_SELECTOR}`) != null;
|
|
1669
|
+
}
|
|
1625
1670
|
function isTypeableCombobox(element) {
|
|
1626
1671
|
if (!element) {
|
|
1627
1672
|
return false;
|
|
@@ -1642,8 +1687,8 @@ function getFloatingFocusElement(floatingElement) {
|
|
|
1642
1687
|
/* eslint-disable @typescript-eslint/no-loop-func */
|
|
1643
1688
|
|
|
1644
1689
|
function getNodeChildren(nodes, id, onlyOpenChildren = true) {
|
|
1645
|
-
const directChildren = nodes.filter(node => node.parentId === id
|
|
1646
|
-
return directChildren.flatMap(child => [child, ...getNodeChildren(nodes, child.id, onlyOpenChildren)]);
|
|
1690
|
+
const directChildren = nodes.filter(node => node.parentId === id);
|
|
1691
|
+
return directChildren.flatMap(child => [...(!onlyOpenChildren || child.context?.open ? [child] : []), ...getNodeChildren(nodes, child.id, onlyOpenChildren)]);
|
|
1647
1692
|
}
|
|
1648
1693
|
function getNodeAncestors(nodes, id) {
|
|
1649
1694
|
let allAncestors = [];
|
|
@@ -1698,22 +1743,22 @@ function isClickLikeEvent(event) {
|
|
|
1698
1743
|
function isDifferentGridRow(index, cols, prevRow) {
|
|
1699
1744
|
return Math.floor(index / cols) !== prevRow;
|
|
1700
1745
|
}
|
|
1701
|
-
function isIndexOutOfListBounds(
|
|
1702
|
-
return index < 0 || index >=
|
|
1746
|
+
function isIndexOutOfListBounds(list, index) {
|
|
1747
|
+
return index < 0 || index >= list.length;
|
|
1703
1748
|
}
|
|
1704
1749
|
function getMinListIndex(listRef, disabledIndices) {
|
|
1705
|
-
return findNonDisabledListIndex(listRef, {
|
|
1750
|
+
return findNonDisabledListIndex(listRef.current, {
|
|
1706
1751
|
disabledIndices
|
|
1707
1752
|
});
|
|
1708
1753
|
}
|
|
1709
1754
|
function getMaxListIndex(listRef, disabledIndices) {
|
|
1710
|
-
return findNonDisabledListIndex(listRef, {
|
|
1755
|
+
return findNonDisabledListIndex(listRef.current, {
|
|
1711
1756
|
decrement: true,
|
|
1712
1757
|
startingIndex: listRef.current.length,
|
|
1713
1758
|
disabledIndices
|
|
1714
1759
|
});
|
|
1715
1760
|
}
|
|
1716
|
-
function findNonDisabledListIndex(
|
|
1761
|
+
function findNonDisabledListIndex(list, {
|
|
1717
1762
|
startingIndex = -1,
|
|
1718
1763
|
decrement = false,
|
|
1719
1764
|
disabledIndices,
|
|
@@ -1722,13 +1767,14 @@ function findNonDisabledListIndex(listRef, {
|
|
|
1722
1767
|
let index = startingIndex;
|
|
1723
1768
|
do {
|
|
1724
1769
|
index += decrement ? -amount : amount;
|
|
1725
|
-
} while (index >= 0 && index <=
|
|
1770
|
+
} while (index >= 0 && index <= list.length - 1 && isListIndexDisabled(list, index, disabledIndices));
|
|
1726
1771
|
return index;
|
|
1727
1772
|
}
|
|
1728
|
-
function getGridNavigatedIndex(
|
|
1773
|
+
function getGridNavigatedIndex(list, {
|
|
1729
1774
|
event,
|
|
1730
1775
|
orientation,
|
|
1731
1776
|
loopFocus,
|
|
1777
|
+
onLoop,
|
|
1732
1778
|
rtl,
|
|
1733
1779
|
cols,
|
|
1734
1780
|
disabledIndices,
|
|
@@ -1756,7 +1802,7 @@ function getGridNavigatedIndex(listRef, {
|
|
|
1756
1802
|
{
|
|
1757
1803
|
let currentRowEl = null;
|
|
1758
1804
|
let currentRowIndex = -1;
|
|
1759
|
-
|
|
1805
|
+
list.forEach((el, idx) => {
|
|
1760
1806
|
if (el == null) {
|
|
1761
1807
|
return;
|
|
1762
1808
|
}
|
|
@@ -1787,7 +1833,7 @@ function getGridNavigatedIndex(listRef, {
|
|
|
1787
1833
|
}
|
|
1788
1834
|
}
|
|
1789
1835
|
}
|
|
1790
|
-
const hasVirtualizedGaps = hasDomRows && visibleItemCount <
|
|
1836
|
+
const hasVirtualizedGaps = hasDomRows && visibleItemCount < list.length;
|
|
1791
1837
|
const verticalCols = inferredDomCols || cols;
|
|
1792
1838
|
const navigateVertically = direction => {
|
|
1793
1839
|
if (!hasDomRows || prevIndex === -1) {
|
|
@@ -1805,11 +1851,17 @@ function getGridNavigatedIndex(listRef, {
|
|
|
1805
1851
|
return undefined;
|
|
1806
1852
|
}
|
|
1807
1853
|
nextRow = nextRow < 0 ? rows.length - 1 : 0;
|
|
1854
|
+
if (onLoop) {
|
|
1855
|
+
const clampedCol = Math.min(colInRow, rows[nextRow].length - 1);
|
|
1856
|
+
const targetItemIndex = rows[nextRow][clampedCol] ?? rows[nextRow][0];
|
|
1857
|
+
const returnedItemIndex = onLoop(event, prevIndex, targetItemIndex);
|
|
1858
|
+
nextRow = rowIndexMap[returnedItemIndex] ?? nextRow;
|
|
1859
|
+
}
|
|
1808
1860
|
}
|
|
1809
1861
|
const targetRow = rows[nextRow];
|
|
1810
1862
|
for (let col = Math.min(colInRow, targetRow.length - 1); col >= 0; col -= 1) {
|
|
1811
1863
|
const candidate = targetRow[col];
|
|
1812
|
-
if (!isListIndexDisabled(
|
|
1864
|
+
if (!isListIndexDisabled(list, candidate, disabledIndices)) {
|
|
1813
1865
|
return candidate;
|
|
1814
1866
|
}
|
|
1815
1867
|
}
|
|
@@ -1833,7 +1885,7 @@ function getGridNavigatedIndex(listRef, {
|
|
|
1833
1885
|
}
|
|
1834
1886
|
const rowEnd = Math.min(rowStart + verticalCols - 1, maxIndex);
|
|
1835
1887
|
for (let candidate = Math.min(rowStart + colInRow, rowEnd); candidate >= rowStart; candidate -= 1) {
|
|
1836
|
-
if (!isListIndexDisabled(
|
|
1888
|
+
if (!isListIndexDisabled(list, candidate, disabledIndices)) {
|
|
1837
1889
|
return candidate;
|
|
1838
1890
|
}
|
|
1839
1891
|
}
|
|
@@ -1849,7 +1901,7 @@ function getGridNavigatedIndex(listRef, {
|
|
|
1849
1901
|
} else if (prevIndex === -1) {
|
|
1850
1902
|
nextIndex = verticalDirection === 'up' ? maxIndex : minIndex;
|
|
1851
1903
|
} else {
|
|
1852
|
-
nextIndex = findNonDisabledListIndex(
|
|
1904
|
+
nextIndex = findNonDisabledListIndex(list, {
|
|
1853
1905
|
startingIndex: prevIndex,
|
|
1854
1906
|
amount: verticalCols,
|
|
1855
1907
|
decrement: verticalDirection === 'up',
|
|
@@ -1865,17 +1917,23 @@ function getGridNavigatedIndex(listRef, {
|
|
|
1865
1917
|
} else {
|
|
1866
1918
|
nextIndex = maxCol > col ? offset : offset - verticalCols;
|
|
1867
1919
|
}
|
|
1920
|
+
if (onLoop) {
|
|
1921
|
+
nextIndex = onLoop(event, prevIndex, nextIndex);
|
|
1922
|
+
}
|
|
1868
1923
|
}
|
|
1869
1924
|
if (verticalDirection === 'down' && prevIndex + verticalCols > maxIndex) {
|
|
1870
|
-
nextIndex = findNonDisabledListIndex(
|
|
1925
|
+
nextIndex = findNonDisabledListIndex(list, {
|
|
1871
1926
|
startingIndex: prevIndex % verticalCols - verticalCols,
|
|
1872
1927
|
amount: verticalCols,
|
|
1873
1928
|
disabledIndices
|
|
1874
1929
|
});
|
|
1930
|
+
if (onLoop) {
|
|
1931
|
+
nextIndex = onLoop(event, prevIndex, nextIndex);
|
|
1932
|
+
}
|
|
1875
1933
|
}
|
|
1876
1934
|
}
|
|
1877
1935
|
}
|
|
1878
|
-
if (isIndexOutOfListBounds(
|
|
1936
|
+
if (isIndexOutOfListBounds(list, nextIndex)) {
|
|
1879
1937
|
nextIndex = prevIndex;
|
|
1880
1938
|
}
|
|
1881
1939
|
}
|
|
@@ -1888,21 +1946,27 @@ function getGridNavigatedIndex(listRef, {
|
|
|
1888
1946
|
stopEvent(event);
|
|
1889
1947
|
}
|
|
1890
1948
|
if (prevIndex % cols !== cols - 1) {
|
|
1891
|
-
nextIndex = findNonDisabledListIndex(
|
|
1949
|
+
nextIndex = findNonDisabledListIndex(list, {
|
|
1892
1950
|
startingIndex: prevIndex,
|
|
1893
1951
|
disabledIndices
|
|
1894
1952
|
});
|
|
1895
1953
|
if (loopFocus && isDifferentGridRow(nextIndex, cols, prevRow)) {
|
|
1896
|
-
nextIndex = findNonDisabledListIndex(
|
|
1954
|
+
nextIndex = findNonDisabledListIndex(list, {
|
|
1897
1955
|
startingIndex: prevIndex - prevIndex % cols - 1,
|
|
1898
1956
|
disabledIndices
|
|
1899
1957
|
});
|
|
1958
|
+
if (onLoop) {
|
|
1959
|
+
nextIndex = onLoop(event, prevIndex, nextIndex);
|
|
1960
|
+
}
|
|
1900
1961
|
}
|
|
1901
1962
|
} else if (loopFocus) {
|
|
1902
|
-
nextIndex = findNonDisabledListIndex(
|
|
1963
|
+
nextIndex = findNonDisabledListIndex(list, {
|
|
1903
1964
|
startingIndex: prevIndex - prevIndex % cols - 1,
|
|
1904
1965
|
disabledIndices
|
|
1905
1966
|
});
|
|
1967
|
+
if (onLoop) {
|
|
1968
|
+
nextIndex = onLoop(event, prevIndex, nextIndex);
|
|
1969
|
+
}
|
|
1906
1970
|
}
|
|
1907
1971
|
if (isDifferentGridRow(nextIndex, cols, prevRow)) {
|
|
1908
1972
|
nextIndex = prevIndex;
|
|
@@ -1913,36 +1977,45 @@ function getGridNavigatedIndex(listRef, {
|
|
|
1913
1977
|
stopEvent(event);
|
|
1914
1978
|
}
|
|
1915
1979
|
if (prevIndex % cols !== 0) {
|
|
1916
|
-
nextIndex = findNonDisabledListIndex(
|
|
1980
|
+
nextIndex = findNonDisabledListIndex(list, {
|
|
1917
1981
|
startingIndex: prevIndex,
|
|
1918
1982
|
decrement: true,
|
|
1919
1983
|
disabledIndices
|
|
1920
1984
|
});
|
|
1921
1985
|
if (loopFocus && isDifferentGridRow(nextIndex, cols, prevRow)) {
|
|
1922
|
-
nextIndex = findNonDisabledListIndex(
|
|
1986
|
+
nextIndex = findNonDisabledListIndex(list, {
|
|
1923
1987
|
startingIndex: prevIndex + (cols - prevIndex % cols),
|
|
1924
1988
|
decrement: true,
|
|
1925
1989
|
disabledIndices
|
|
1926
1990
|
});
|
|
1991
|
+
if (onLoop) {
|
|
1992
|
+
nextIndex = onLoop(event, prevIndex, nextIndex);
|
|
1993
|
+
}
|
|
1927
1994
|
}
|
|
1928
1995
|
} else if (loopFocus) {
|
|
1929
|
-
nextIndex = findNonDisabledListIndex(
|
|
1996
|
+
nextIndex = findNonDisabledListIndex(list, {
|
|
1930
1997
|
startingIndex: prevIndex + (cols - prevIndex % cols),
|
|
1931
1998
|
decrement: true,
|
|
1932
1999
|
disabledIndices
|
|
1933
2000
|
});
|
|
2001
|
+
if (onLoop) {
|
|
2002
|
+
nextIndex = onLoop(event, prevIndex, nextIndex);
|
|
2003
|
+
}
|
|
1934
2004
|
}
|
|
1935
2005
|
if (isDifferentGridRow(nextIndex, cols, prevRow)) {
|
|
1936
2006
|
nextIndex = prevIndex;
|
|
1937
2007
|
}
|
|
1938
2008
|
}
|
|
1939
2009
|
const lastRow = floor(maxIndex / cols) === prevRow;
|
|
1940
|
-
if (isIndexOutOfListBounds(
|
|
2010
|
+
if (isIndexOutOfListBounds(list, nextIndex)) {
|
|
1941
2011
|
if (loopFocus && lastRow) {
|
|
1942
|
-
nextIndex = event.key === (rtl ? ARROW_RIGHT : ARROW_LEFT) ? maxIndex : findNonDisabledListIndex(
|
|
2012
|
+
nextIndex = event.key === (rtl ? ARROW_RIGHT : ARROW_LEFT) ? maxIndex : findNonDisabledListIndex(list, {
|
|
1943
2013
|
startingIndex: prevIndex - prevIndex % cols - 1,
|
|
1944
2014
|
disabledIndices
|
|
1945
2015
|
});
|
|
2016
|
+
if (onLoop) {
|
|
2017
|
+
nextIndex = onLoop(event, prevIndex, nextIndex);
|
|
2018
|
+
}
|
|
1946
2019
|
} else {
|
|
1947
2020
|
nextIndex = prevIndex;
|
|
1948
2021
|
}
|
|
@@ -2013,12 +2086,12 @@ function getGridCellIndexOfCorner(index, sizes, cellMap, cols, corner) {
|
|
|
2013
2086
|
function getGridCellIndices(indices, cellMap) {
|
|
2014
2087
|
return cellMap.flatMap((index, cellIndex) => indices.includes(index) ? [cellIndex] : []);
|
|
2015
2088
|
}
|
|
2016
|
-
function isListIndexDisabled(
|
|
2089
|
+
function isListIndexDisabled(list, index, disabledIndices) {
|
|
2017
2090
|
const isExplicitlyDisabled = typeof disabledIndices === 'function' ? disabledIndices(index) : disabledIndices?.includes(index) ?? false;
|
|
2018
2091
|
if (isExplicitlyDisabled) {
|
|
2019
2092
|
return true;
|
|
2020
2093
|
}
|
|
2021
|
-
const element =
|
|
2094
|
+
const element = list[index];
|
|
2022
2095
|
if (!element) {
|
|
2023
2096
|
return false;
|
|
2024
2097
|
}
|
|
@@ -2028,599 +2101,137 @@ function isListIndexDisabled(listRef, index, disabledIndices) {
|
|
|
2028
2101
|
return !disabledIndices && (element.hasAttribute('disabled') || element.getAttribute('aria-disabled') === 'true');
|
|
2029
2102
|
}
|
|
2030
2103
|
function isElementVisible(element) {
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
/*!
|
|
2035
|
-
* tabbable 6.4.0
|
|
2036
|
-
* @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE
|
|
2037
|
-
*/
|
|
2038
|
-
// NOTE: separate `:not()` selectors has broader browser support than the newer
|
|
2039
|
-
// `:not([inert], [inert] *)` (Feb 2023)
|
|
2040
|
-
var candidateSelectors = ['input:not([inert]):not([inert] *)', 'select:not([inert]):not([inert] *)', 'textarea:not([inert]):not([inert] *)', 'a[href]:not([inert]):not([inert] *)', 'button:not([inert]):not([inert] *)', '[tabindex]:not(slot):not([inert]):not([inert] *)', 'audio[controls]:not([inert]):not([inert] *)', 'video[controls]:not([inert]):not([inert] *)', '[contenteditable]:not([contenteditable="false"]):not([inert]):not([inert] *)', 'details>summary:first-of-type:not([inert]):not([inert] *)', 'details:not([inert]):not([inert] *)'];
|
|
2041
|
-
var candidateSelector = /* #__PURE__ */candidateSelectors.join(',');
|
|
2042
|
-
var NoElement = typeof Element === 'undefined';
|
|
2043
|
-
var matches = NoElement ? function () {} : Element.prototype.matches || Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
|
|
2044
|
-
var getRootNode = !NoElement && Element.prototype.getRootNode ? function (element) {
|
|
2045
|
-
var _element$getRootNode;
|
|
2046
|
-
return element === null || element === void 0 ? void 0 : (_element$getRootNode = element.getRootNode) === null || _element$getRootNode === void 0 ? void 0 : _element$getRootNode.call(element);
|
|
2047
|
-
} : function (element) {
|
|
2048
|
-
return element === null || element === void 0 ? void 0 : element.ownerDocument;
|
|
2049
|
-
};
|
|
2050
|
-
|
|
2051
|
-
/**
|
|
2052
|
-
* Determines if a node is inert or in an inert ancestor.
|
|
2053
|
-
* @param {Node} [node]
|
|
2054
|
-
* @param {boolean} [lookUp] If true and `node` is not inert, looks up at ancestors to
|
|
2055
|
-
* see if any of them are inert. If false, only `node` itself is considered.
|
|
2056
|
-
* @returns {boolean} True if inert itself or by way of being in an inert ancestor.
|
|
2057
|
-
* False if `node` is falsy.
|
|
2058
|
-
*/
|
|
2059
|
-
var _isInert = function isInert(node, lookUp) {
|
|
2060
|
-
var _node$getAttribute;
|
|
2061
|
-
if (lookUp === void 0) {
|
|
2062
|
-
lookUp = true;
|
|
2063
|
-
}
|
|
2064
|
-
// CAREFUL: JSDom does not support inert at all, so we can't use the `HTMLElement.inert`
|
|
2065
|
-
// JS API property; we have to check the attribute, which can either be empty or 'true';
|
|
2066
|
-
// if it's `null` (not specified) or 'false', it's an active element
|
|
2067
|
-
var inertAtt = node === null || node === void 0 ? void 0 : (_node$getAttribute = node.getAttribute) === null || _node$getAttribute === void 0 ? void 0 : _node$getAttribute.call(node, 'inert');
|
|
2068
|
-
var inert = inertAtt === '' || inertAtt === 'true';
|
|
2069
|
-
|
|
2070
|
-
// NOTE: this could also be handled with `node.matches('[inert], :is([inert] *)')`
|
|
2071
|
-
// if it weren't for `matches()` not being a function on shadow roots; the following
|
|
2072
|
-
// code works for any kind of node
|
|
2073
|
-
var result = inert || lookUp && node && (
|
|
2074
|
-
// closest does not exist on shadow roots, so we fall back to a manual
|
|
2075
|
-
// lookup upward, in case it is not defined.
|
|
2076
|
-
typeof node.closest === 'function' ? node.closest('[inert]') : _isInert(node.parentNode));
|
|
2077
|
-
return result;
|
|
2078
|
-
};
|
|
2079
|
-
|
|
2080
|
-
/**
|
|
2081
|
-
* Determines if a node's content is editable.
|
|
2082
|
-
* @param {Element} [node]
|
|
2083
|
-
* @returns True if it's content-editable; false if it's not or `node` is falsy.
|
|
2084
|
-
*/
|
|
2085
|
-
var isContentEditable = function isContentEditable(node) {
|
|
2086
|
-
var _node$getAttribute2;
|
|
2087
|
-
// CAREFUL: JSDom does not support the `HTMLElement.isContentEditable` API so we have
|
|
2088
|
-
// to use the attribute directly to check for this, which can either be empty or 'true';
|
|
2089
|
-
// if it's `null` (not specified) or 'false', it's a non-editable element
|
|
2090
|
-
var attValue = node === null || node === void 0 ? void 0 : (_node$getAttribute2 = node.getAttribute) === null || _node$getAttribute2 === void 0 ? void 0 : _node$getAttribute2.call(node, 'contenteditable');
|
|
2091
|
-
return attValue === '' || attValue === 'true';
|
|
2092
|
-
};
|
|
2093
|
-
|
|
2094
|
-
/**
|
|
2095
|
-
* @param {Element} el container to check in
|
|
2096
|
-
* @param {boolean} includeContainer add container to check
|
|
2097
|
-
* @param {(node: Element) => boolean} filter filter candidates
|
|
2098
|
-
* @returns {Element[]}
|
|
2099
|
-
*/
|
|
2100
|
-
var getCandidates = function getCandidates(el, includeContainer, filter) {
|
|
2101
|
-
// even if `includeContainer=false`, we still have to check it for inertness because
|
|
2102
|
-
// if it's inert (either by itself or via its parent), then all its children are inert
|
|
2103
|
-
if (_isInert(el)) {
|
|
2104
|
-
return [];
|
|
2105
|
-
}
|
|
2106
|
-
var candidates = Array.prototype.slice.apply(el.querySelectorAll(candidateSelector));
|
|
2107
|
-
if (includeContainer && matches.call(el, candidateSelector)) {
|
|
2108
|
-
candidates.unshift(el);
|
|
2109
|
-
}
|
|
2110
|
-
candidates = candidates.filter(filter);
|
|
2111
|
-
return candidates;
|
|
2112
|
-
};
|
|
2113
|
-
|
|
2114
|
-
/**
|
|
2115
|
-
* @callback GetShadowRoot
|
|
2116
|
-
* @param {Element} element to check for shadow root
|
|
2117
|
-
* @returns {ShadowRoot|boolean} ShadowRoot if available or boolean indicating if a shadowRoot is attached but not available.
|
|
2118
|
-
*/
|
|
2119
|
-
|
|
2120
|
-
/**
|
|
2121
|
-
* @callback ShadowRootFilter
|
|
2122
|
-
* @param {Element} shadowHostNode the element which contains shadow content
|
|
2123
|
-
* @returns {boolean} true if a shadow root could potentially contain valid candidates.
|
|
2124
|
-
*/
|
|
2125
|
-
|
|
2126
|
-
/**
|
|
2127
|
-
* @typedef {Object} CandidateScope
|
|
2128
|
-
* @property {Element} scopeParent contains inner candidates
|
|
2129
|
-
* @property {Element[]} candidates list of candidates found in the scope parent
|
|
2130
|
-
*/
|
|
2131
|
-
|
|
2132
|
-
/**
|
|
2133
|
-
* @typedef {Object} IterativeOptions
|
|
2134
|
-
* @property {GetShadowRoot|boolean} getShadowRoot true if shadow support is enabled; falsy if not;
|
|
2135
|
-
* if a function, implies shadow support is enabled and either returns the shadow root of an element
|
|
2136
|
-
* or a boolean stating if it has an undisclosed shadow root
|
|
2137
|
-
* @property {(node: Element) => boolean} filter filter candidates
|
|
2138
|
-
* @property {boolean} flatten if true then result will flatten any CandidateScope into the returned list
|
|
2139
|
-
* @property {ShadowRootFilter} shadowRootFilter filter shadow roots;
|
|
2140
|
-
*/
|
|
2141
|
-
|
|
2142
|
-
/**
|
|
2143
|
-
* @param {Element[]} elements list of element containers to match candidates from
|
|
2144
|
-
* @param {boolean} includeContainer add container list to check
|
|
2145
|
-
* @param {IterativeOptions} options
|
|
2146
|
-
* @returns {Array.<Element|CandidateScope>}
|
|
2147
|
-
*/
|
|
2148
|
-
var _getCandidatesIteratively = function getCandidatesIteratively(elements, includeContainer, options) {
|
|
2149
|
-
var candidates = [];
|
|
2150
|
-
var elementsToCheck = Array.from(elements);
|
|
2151
|
-
while (elementsToCheck.length) {
|
|
2152
|
-
var element = elementsToCheck.shift();
|
|
2153
|
-
if (_isInert(element, false)) {
|
|
2154
|
-
// no need to look up since we're drilling down
|
|
2155
|
-
// anything inside this container will also be inert
|
|
2156
|
-
continue;
|
|
2157
|
-
}
|
|
2158
|
-
if (element.tagName === 'SLOT') {
|
|
2159
|
-
// add shadow dom slot scope (slot itself cannot be focusable)
|
|
2160
|
-
var assigned = element.assignedElements();
|
|
2161
|
-
var content = assigned.length ? assigned : element.children;
|
|
2162
|
-
var nestedCandidates = _getCandidatesIteratively(content, true, options);
|
|
2163
|
-
if (options.flatten) {
|
|
2164
|
-
candidates.push.apply(candidates, nestedCandidates);
|
|
2165
|
-
} else {
|
|
2166
|
-
candidates.push({
|
|
2167
|
-
scopeParent: element,
|
|
2168
|
-
candidates: nestedCandidates
|
|
2169
|
-
});
|
|
2170
|
-
}
|
|
2171
|
-
} else {
|
|
2172
|
-
// check candidate element
|
|
2173
|
-
var validCandidate = matches.call(element, candidateSelector);
|
|
2174
|
-
if (validCandidate && options.filter(element) && (includeContainer || !elements.includes(element))) {
|
|
2175
|
-
candidates.push(element);
|
|
2176
|
-
}
|
|
2177
|
-
|
|
2178
|
-
// iterate over shadow content if possible
|
|
2179
|
-
var shadowRoot = element.shadowRoot ||
|
|
2180
|
-
// check for an undisclosed shadow
|
|
2181
|
-
typeof options.getShadowRoot === 'function' && options.getShadowRoot(element);
|
|
2182
|
-
|
|
2183
|
-
// no inert look up because we're already drilling down and checking for inertness
|
|
2184
|
-
// on the way down, so all containers to this root node should have already been
|
|
2185
|
-
// vetted as non-inert
|
|
2186
|
-
var validShadowRoot = !_isInert(shadowRoot, false) && (!options.shadowRootFilter || options.shadowRootFilter(element));
|
|
2187
|
-
if (shadowRoot && validShadowRoot) {
|
|
2188
|
-
// add shadow dom scope IIF a shadow root node was given; otherwise, an undisclosed
|
|
2189
|
-
// shadow exists, so look at light dom children as fallback BUT create a scope for any
|
|
2190
|
-
// child candidates found because they're likely slotted elements (elements that are
|
|
2191
|
-
// children of the web component element (which has the shadow), in the light dom, but
|
|
2192
|
-
// slotted somewhere _inside_ the undisclosed shadow) -- the scope is created below,
|
|
2193
|
-
// _after_ we return from this recursive call
|
|
2194
|
-
var _nestedCandidates = _getCandidatesIteratively(shadowRoot === true ? element.children : shadowRoot.children, true, options);
|
|
2195
|
-
if (options.flatten) {
|
|
2196
|
-
candidates.push.apply(candidates, _nestedCandidates);
|
|
2197
|
-
} else {
|
|
2198
|
-
candidates.push({
|
|
2199
|
-
scopeParent: element,
|
|
2200
|
-
candidates: _nestedCandidates
|
|
2201
|
-
});
|
|
2202
|
-
}
|
|
2203
|
-
} else {
|
|
2204
|
-
// there's not shadow so just dig into the element's (light dom) children
|
|
2205
|
-
// __without__ giving the element special scope treatment
|
|
2206
|
-
elementsToCheck.unshift.apply(elementsToCheck, element.children);
|
|
2207
|
-
}
|
|
2208
|
-
}
|
|
2104
|
+
if (typeof element.checkVisibility === 'function') {
|
|
2105
|
+
return element.checkVisibility();
|
|
2209
2106
|
}
|
|
2210
|
-
return
|
|
2211
|
-
}
|
|
2107
|
+
return getComputedStyle(element).display !== 'none';
|
|
2108
|
+
}
|
|
2212
2109
|
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
* @param {HTMLElement} node
|
|
2217
|
-
* @returns {boolean} True if so; false if not.
|
|
2218
|
-
*/
|
|
2219
|
-
var hasTabIndex = function hasTabIndex(node) {
|
|
2220
|
-
return !isNaN(parseInt(node.getAttribute('tabindex'), 10));
|
|
2221
|
-
};
|
|
2110
|
+
function ownerDocument(node) {
|
|
2111
|
+
return node?.ownerDocument || document;
|
|
2112
|
+
}
|
|
2222
2113
|
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
*/
|
|
2229
|
-
var getTabIndex = function getTabIndex(node) {
|
|
2230
|
-
if (!node) {
|
|
2231
|
-
throw new Error('No node provided');
|
|
2232
|
-
}
|
|
2233
|
-
if (node.tabIndex < 0) {
|
|
2234
|
-
// in Chrome, <details/>, <audio controls/> and <video controls/> elements get a default
|
|
2235
|
-
// `tabIndex` of -1 when the 'tabindex' attribute isn't specified in the DOM,
|
|
2236
|
-
// yet they are still part of the regular tab order; in FF, they get a default
|
|
2237
|
-
// `tabIndex` of 0; since Chrome still puts those elements in the regular tab
|
|
2238
|
-
// order, consider their tab index to be 0.
|
|
2239
|
-
// Also browsers do not return `tabIndex` correctly for contentEditable nodes;
|
|
2240
|
-
// so if they don't have a tabindex attribute specifically set, assume it's 0.
|
|
2241
|
-
if ((/^(AUDIO|VIDEO|DETAILS)$/.test(node.tagName) || isContentEditable(node)) && !hasTabIndex(node)) {
|
|
2242
|
-
return 0;
|
|
2243
|
-
}
|
|
2114
|
+
const CANDIDATE_SELECTOR = 'a[href],button,input,select,textarea,summary,details,iframe,object,embed,[tabindex],[contenteditable]:not([contenteditable="false"]),audio[controls],video[controls]';
|
|
2115
|
+
function getParentElement(element) {
|
|
2116
|
+
const assignedSlot = element.assignedSlot;
|
|
2117
|
+
if (assignedSlot) {
|
|
2118
|
+
return assignedSlot;
|
|
2244
2119
|
}
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
/**
|
|
2249
|
-
* Determine the tab index of a given node __for sort order purposes__.
|
|
2250
|
-
* @param {HTMLElement} node
|
|
2251
|
-
* @param {boolean} [isScope] True for a custom element with shadow root or slot that, by default,
|
|
2252
|
-
* has tabIndex -1, but needs to be sorted by document order in order for its content to be
|
|
2253
|
-
* inserted into the correct sort position.
|
|
2254
|
-
* @returns {number} Tab order (negative, 0, or positive number).
|
|
2255
|
-
*/
|
|
2256
|
-
var getSortOrderTabIndex = function getSortOrderTabIndex(node, isScope) {
|
|
2257
|
-
var tabIndex = getTabIndex(node);
|
|
2258
|
-
if (tabIndex < 0 && isScope && !hasTabIndex(node)) {
|
|
2259
|
-
return 0;
|
|
2120
|
+
if (element.parentElement) {
|
|
2121
|
+
return element.parentElement;
|
|
2260
2122
|
}
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
};
|
|
2269
|
-
var isHiddenInput = function isHiddenInput(node) {
|
|
2270
|
-
return isInput(node) && node.type === 'hidden';
|
|
2271
|
-
};
|
|
2272
|
-
var isDetailsWithSummary = function isDetailsWithSummary(node) {
|
|
2273
|
-
var r = node.tagName === 'DETAILS' && Array.prototype.slice.apply(node.children).some(function (child) {
|
|
2274
|
-
return child.tagName === 'SUMMARY';
|
|
2275
|
-
});
|
|
2276
|
-
return r;
|
|
2277
|
-
};
|
|
2278
|
-
var getCheckedRadio = function getCheckedRadio(nodes, form) {
|
|
2279
|
-
for (var i = 0; i < nodes.length; i++) {
|
|
2280
|
-
if (nodes[i].checked && nodes[i].form === form) {
|
|
2281
|
-
return nodes[i];
|
|
2123
|
+
const rootNode = element.getRootNode();
|
|
2124
|
+
return isShadowRoot(rootNode) ? rootNode.host : null;
|
|
2125
|
+
}
|
|
2126
|
+
function getDetailsSummary(details) {
|
|
2127
|
+
for (const child of Array.from(details.children)) {
|
|
2128
|
+
if (getNodeName(child) === 'summary') {
|
|
2129
|
+
return child;
|
|
2282
2130
|
}
|
|
2283
2131
|
}
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2132
|
+
return null;
|
|
2133
|
+
}
|
|
2134
|
+
function isWithinOpenDetailsSummary(element, details) {
|
|
2135
|
+
const summary = getDetailsSummary(details);
|
|
2136
|
+
return !!summary && (element === summary || contains(summary, element));
|
|
2137
|
+
}
|
|
2138
|
+
function isFocusableCandidate(element) {
|
|
2139
|
+
const nodeName = element ? getNodeName(element) : '';
|
|
2140
|
+
return element != null && element.matches(CANDIDATE_SELECTOR) && (nodeName !== 'summary' || element.parentElement != null && getNodeName(element.parentElement) === 'details' && getDetailsSummary(element.parentElement) === element) && (nodeName !== 'details' || getDetailsSummary(element) == null) && (nodeName !== 'input' || element.type !== 'hidden');
|
|
2141
|
+
}
|
|
2142
|
+
function isFocusableElement(element) {
|
|
2143
|
+
if (!isFocusableCandidate(element) || !element.isConnected || element.matches(':disabled')) {
|
|
2144
|
+
return false;
|
|
2288
2145
|
}
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
};
|
|
2293
|
-
var radioSet;
|
|
2294
|
-
if (typeof window !== 'undefined' && typeof window.CSS !== 'undefined' && typeof window.CSS.escape === 'function') {
|
|
2295
|
-
radioSet = queryRadios(window.CSS.escape(node.name));
|
|
2296
|
-
} else {
|
|
2297
|
-
try {
|
|
2298
|
-
radioSet = queryRadios(node.name);
|
|
2299
|
-
} catch (err) {
|
|
2300
|
-
// eslint-disable-next-line no-console
|
|
2301
|
-
console.error('Looks like you have a radio button with a name attribute containing invalid CSS selector characters and need the CSS.escape polyfill: %s', err.message);
|
|
2146
|
+
for (let current = element; current; current = getParentElement(current)) {
|
|
2147
|
+
const isSlot = getNodeName(current) === 'slot';
|
|
2148
|
+
if (current.hasAttribute('inert')) {
|
|
2302
2149
|
return false;
|
|
2303
2150
|
}
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
return !checked || checked === node;
|
|
2307
|
-
};
|
|
2308
|
-
var isRadio = function isRadio(node) {
|
|
2309
|
-
return isInput(node) && node.type === 'radio';
|
|
2310
|
-
};
|
|
2311
|
-
var isNonTabbableRadio = function isNonTabbableRadio(node) {
|
|
2312
|
-
return isRadio(node) && !isTabbableRadio(node);
|
|
2313
|
-
};
|
|
2314
|
-
|
|
2315
|
-
// determines if a node is ultimately attached to the window's document
|
|
2316
|
-
var isNodeAttached = function isNodeAttached(node) {
|
|
2317
|
-
var _nodeRoot;
|
|
2318
|
-
// The root node is the shadow root if the node is in a shadow DOM; some document otherwise
|
|
2319
|
-
// (but NOT _the_ document; see second 'If' comment below for more).
|
|
2320
|
-
// If rootNode is shadow root, it'll have a host, which is the element to which the shadow
|
|
2321
|
-
// is attached, and the one we need to check if it's in the document or not (because the
|
|
2322
|
-
// shadow, and all nodes it contains, is never considered in the document since shadows
|
|
2323
|
-
// behave like self-contained DOMs; but if the shadow's HOST, which is part of the document,
|
|
2324
|
-
// is hidden, or is not in the document itself but is detached, it will affect the shadow's
|
|
2325
|
-
// visibility, including all the nodes it contains). The host could be any normal node,
|
|
2326
|
-
// or a custom element (i.e. web component). Either way, that's the one that is considered
|
|
2327
|
-
// part of the document, not the shadow root, nor any of its children (i.e. the node being
|
|
2328
|
-
// tested).
|
|
2329
|
-
// To further complicate things, we have to look all the way up until we find a shadow HOST
|
|
2330
|
-
// that is attached (or find none) because the node might be in nested shadows...
|
|
2331
|
-
// If rootNode is not a shadow root, it won't have a host, and so rootNode should be the
|
|
2332
|
-
// document (per the docs) and while it's a Document-type object, that document does not
|
|
2333
|
-
// appear to be the same as the node's `ownerDocument` for some reason, so it's safer
|
|
2334
|
-
// to ignore the rootNode at this point, and use `node.ownerDocument`. Otherwise,
|
|
2335
|
-
// using `rootNode.contains(node)` will _always_ be true we'll get false-positives when
|
|
2336
|
-
// node is actually detached.
|
|
2337
|
-
// NOTE: If `nodeRootHost` or `node` happens to be the `document` itself (which is possible
|
|
2338
|
-
// if a tabbable/focusable node was quickly added to the DOM, focused, and then removed
|
|
2339
|
-
// from the DOM as in https://github.com/focus-trap/focus-trap-react/issues/905), then
|
|
2340
|
-
// `ownerDocument` will be `null`, hence the optional chaining on it.
|
|
2341
|
-
var nodeRoot = node && getRootNode(node);
|
|
2342
|
-
var nodeRootHost = (_nodeRoot = nodeRoot) === null || _nodeRoot === void 0 ? void 0 : _nodeRoot.host;
|
|
2343
|
-
|
|
2344
|
-
// in some cases, a detached node will return itself as the root instead of a document or
|
|
2345
|
-
// shadow root object, in which case, we shouldn't try to look further up the host chain
|
|
2346
|
-
var attached = false;
|
|
2347
|
-
if (nodeRoot && nodeRoot !== node) {
|
|
2348
|
-
var _nodeRootHost, _nodeRootHost$ownerDo, _node$ownerDocument;
|
|
2349
|
-
attached = !!((_nodeRootHost = nodeRootHost) !== null && _nodeRootHost !== void 0 && (_nodeRootHost$ownerDo = _nodeRootHost.ownerDocument) !== null && _nodeRootHost$ownerDo !== void 0 && _nodeRootHost$ownerDo.contains(nodeRootHost) || node !== null && node !== void 0 && (_node$ownerDocument = node.ownerDocument) !== null && _node$ownerDocument !== void 0 && _node$ownerDocument.contains(node));
|
|
2350
|
-
while (!attached && nodeRootHost) {
|
|
2351
|
-
var _nodeRoot2, _nodeRootHost2, _nodeRootHost2$ownerD;
|
|
2352
|
-
// since it's not attached and we have a root host, the node MUST be in a nested shadow DOM,
|
|
2353
|
-
// which means we need to get the host's host and check if that parent host is contained
|
|
2354
|
-
// in (i.e. attached to) the document
|
|
2355
|
-
nodeRoot = getRootNode(nodeRootHost);
|
|
2356
|
-
nodeRootHost = (_nodeRoot2 = nodeRoot) === null || _nodeRoot2 === void 0 ? void 0 : _nodeRoot2.host;
|
|
2357
|
-
attached = !!((_nodeRootHost2 = nodeRootHost) !== null && _nodeRootHost2 !== void 0 && (_nodeRootHost2$ownerD = _nodeRootHost2.ownerDocument) !== null && _nodeRootHost2$ownerD !== void 0 && _nodeRootHost2$ownerD.contains(nodeRootHost));
|
|
2358
|
-
}
|
|
2359
|
-
}
|
|
2360
|
-
return attached;
|
|
2361
|
-
};
|
|
2362
|
-
var isZeroArea = function isZeroArea(node) {
|
|
2363
|
-
var _node$getBoundingClie = node.getBoundingClientRect(),
|
|
2364
|
-
width = _node$getBoundingClie.width,
|
|
2365
|
-
height = _node$getBoundingClie.height;
|
|
2366
|
-
return width === 0 && height === 0;
|
|
2367
|
-
};
|
|
2368
|
-
var isHidden = function isHidden(node, _ref) {
|
|
2369
|
-
var displayCheck = _ref.displayCheck,
|
|
2370
|
-
getShadowRoot = _ref.getShadowRoot;
|
|
2371
|
-
if (displayCheck === 'full-native') {
|
|
2372
|
-
if ('checkVisibility' in node) {
|
|
2373
|
-
// Chrome >= 105, Edge >= 105, Firefox >= 106, Safari >= 17.4
|
|
2374
|
-
// @see https://developer.mozilla.org/en-US/docs/Web/API/Element/checkVisibility#browser_compatibility
|
|
2375
|
-
var visible = node.checkVisibility({
|
|
2376
|
-
// Checking opacity might be desirable for some use cases, but natively,
|
|
2377
|
-
// opacity zero elements _are_ focusable and tabbable.
|
|
2378
|
-
checkOpacity: false,
|
|
2379
|
-
opacityProperty: false,
|
|
2380
|
-
contentVisibilityAuto: true,
|
|
2381
|
-
visibilityProperty: true,
|
|
2382
|
-
// This is an alias for `visibilityProperty`. Contemporary browsers
|
|
2383
|
-
// support both. However, this alias has wider browser support (Chrome
|
|
2384
|
-
// >= 105 and Firefox >= 106, vs. Chrome >= 121 and Firefox >= 122), so
|
|
2385
|
-
// we include it anyway.
|
|
2386
|
-
checkVisibilityCSS: true
|
|
2387
|
-
});
|
|
2388
|
-
return !visible;
|
|
2151
|
+
if (current !== element && getNodeName(current) === 'details' && !current.open && !isWithinOpenDetailsSummary(element, current) || current.hasAttribute('hidden') || !isSlot && !isElementVisible(current)) {
|
|
2152
|
+
return false;
|
|
2389
2153
|
}
|
|
2390
|
-
// Fall through to manual visibility checks
|
|
2391
|
-
}
|
|
2392
|
-
|
|
2393
|
-
// NOTE: visibility will be `undefined` if node is detached from the document
|
|
2394
|
-
// (see notes about this further down), which means we will consider it visible
|
|
2395
|
-
// (this is legacy behavior from a very long way back)
|
|
2396
|
-
// NOTE: we check this regardless of `displayCheck="none"` because this is a
|
|
2397
|
-
// _visibility_ check, not a _display_ check
|
|
2398
|
-
if (getComputedStyle(node).visibility === 'hidden') {
|
|
2399
|
-
return true;
|
|
2400
|
-
}
|
|
2401
|
-
var isDirectSummary = matches.call(node, 'details>summary:first-of-type');
|
|
2402
|
-
var nodeUnderDetails = isDirectSummary ? node.parentElement : node;
|
|
2403
|
-
if (matches.call(nodeUnderDetails, 'details:not([open]) *')) {
|
|
2404
|
-
return true;
|
|
2405
2154
|
}
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
while (node) {
|
|
2415
|
-
var parentElement = node.parentElement;
|
|
2416
|
-
var rootNode = getRootNode(node);
|
|
2417
|
-
if (parentElement && !parentElement.shadowRoot && getShadowRoot(parentElement) === true // check if there's an undisclosed shadow
|
|
2418
|
-
) {
|
|
2419
|
-
// node has an undisclosed shadow which means we can only treat it as a black box, so we
|
|
2420
|
-
// fall back to a non-zero-area test
|
|
2421
|
-
return isZeroArea(node);
|
|
2422
|
-
} else if (node.assignedSlot) {
|
|
2423
|
-
// iterate up slot
|
|
2424
|
-
node = node.assignedSlot;
|
|
2425
|
-
} else if (!parentElement && rootNode !== node.ownerDocument) {
|
|
2426
|
-
// cross shadow boundary
|
|
2427
|
-
node = rootNode.host;
|
|
2428
|
-
} else {
|
|
2429
|
-
// iterate up normal dom
|
|
2430
|
-
node = parentElement;
|
|
2431
|
-
}
|
|
2432
|
-
}
|
|
2433
|
-
node = originalNode;
|
|
2434
|
-
}
|
|
2435
|
-
// else, `getShadowRoot` might be true, but all that does is enable shadow DOM support
|
|
2436
|
-
// (i.e. it does not also presume that all nodes might have undisclosed shadows); or
|
|
2437
|
-
// it might be a falsy value, which means shadow DOM support is disabled
|
|
2438
|
-
|
|
2439
|
-
// Since we didn't find it sitting in an undisclosed shadow (or shadows are disabled)
|
|
2440
|
-
// now we can just test to see if it would normally be visible or not, provided it's
|
|
2441
|
-
// attached to the main document.
|
|
2442
|
-
// NOTE: We must consider case where node is inside a shadow DOM and given directly to
|
|
2443
|
-
// `isTabbable()` or `isFocusable()` -- regardless of `getShadowRoot` option setting.
|
|
2444
|
-
|
|
2445
|
-
if (isNodeAttached(node)) {
|
|
2446
|
-
// this works wherever the node is: if there's at least one client rect, it's
|
|
2447
|
-
// somehow displayed; it also covers the CSS 'display: contents' case where the
|
|
2448
|
-
// node itself is hidden in place of its contents; and there's no need to search
|
|
2449
|
-
// up the hierarchy either
|
|
2450
|
-
return !node.getClientRects().length;
|
|
2451
|
-
}
|
|
2452
|
-
|
|
2453
|
-
// Else, the node isn't attached to the document, which means the `getClientRects()`
|
|
2454
|
-
// API will __always__ return zero rects (this can happen, for example, if React
|
|
2455
|
-
// is used to render nodes onto a detached tree, as confirmed in this thread:
|
|
2456
|
-
// https://github.com/facebook/react/issues/9117#issuecomment-284228870)
|
|
2457
|
-
//
|
|
2458
|
-
// It also means that even window.getComputedStyle(node).display will return `undefined`
|
|
2459
|
-
// because styles are only computed for nodes that are in the document.
|
|
2460
|
-
//
|
|
2461
|
-
// NOTE: THIS HAS BEEN THE CASE FOR YEARS. It is not new, nor is it caused by tabbable
|
|
2462
|
-
// somehow. Though it was never stated officially, anyone who has ever used tabbable
|
|
2463
|
-
// APIs on nodes in detached containers has actually implicitly used tabbable in what
|
|
2464
|
-
// was later (as of v5.2.0 on Apr 9, 2021) called `displayCheck="none"` mode -- essentially
|
|
2465
|
-
// considering __everything__ to be visible because of the innability to determine styles.
|
|
2466
|
-
//
|
|
2467
|
-
// v6.0.0: As of this major release, the default 'full' option __no longer treats detached
|
|
2468
|
-
// nodes as visible with the 'none' fallback.__
|
|
2469
|
-
if (displayCheck !== 'legacy-full') {
|
|
2470
|
-
return true; // hidden
|
|
2471
|
-
}
|
|
2472
|
-
// else, fallback to 'none' mode and consider the node visible
|
|
2473
|
-
} else if (displayCheck === 'non-zero-area') {
|
|
2474
|
-
// NOTE: Even though this tests that the node's client rect is non-zero to determine
|
|
2475
|
-
// whether it's displayed, and that a detached node will __always__ have a zero-area
|
|
2476
|
-
// client rect, we don't special-case for whether the node is attached or not. In
|
|
2477
|
-
// this mode, we do want to consider nodes that have a zero area to be hidden at all
|
|
2478
|
-
// times, and that includes attached or not.
|
|
2479
|
-
return isZeroArea(node);
|
|
2480
|
-
}
|
|
2481
|
-
|
|
2482
|
-
// visible, as far as we can tell, or per current `displayCheck=none` mode, we assume
|
|
2483
|
-
// it's visible
|
|
2484
|
-
return false;
|
|
2485
|
-
};
|
|
2486
|
-
|
|
2487
|
-
// form fields (nested) inside a disabled fieldset are not focusable/tabbable
|
|
2488
|
-
// unless they are in the _first_ <legend> element of the top-most disabled
|
|
2489
|
-
// fieldset
|
|
2490
|
-
var isDisabledFromFieldset = function isDisabledFromFieldset(node) {
|
|
2491
|
-
if (/^(INPUT|BUTTON|SELECT|TEXTAREA)$/.test(node.tagName)) {
|
|
2492
|
-
var parentNode = node.parentElement;
|
|
2493
|
-
// check if `node` is contained in a disabled <fieldset>
|
|
2494
|
-
while (parentNode) {
|
|
2495
|
-
if (parentNode.tagName === 'FIELDSET' && parentNode.disabled) {
|
|
2496
|
-
// look for the first <legend> among the children of the disabled <fieldset>
|
|
2497
|
-
for (var i = 0; i < parentNode.children.length; i++) {
|
|
2498
|
-
var child = parentNode.children.item(i);
|
|
2499
|
-
// when the first <legend> (in document order) is found
|
|
2500
|
-
if (child.tagName === 'LEGEND') {
|
|
2501
|
-
// if its parent <fieldset> is not nested in another disabled <fieldset>,
|
|
2502
|
-
// return whether `node` is a descendant of its first <legend>
|
|
2503
|
-
return matches.call(parentNode, 'fieldset[disabled] *') ? true : !child.contains(node);
|
|
2504
|
-
}
|
|
2505
|
-
}
|
|
2506
|
-
// the disabled <fieldset> containing `node` has no <legend>
|
|
2507
|
-
return true;
|
|
2508
|
-
}
|
|
2509
|
-
parentNode = parentNode.parentElement;
|
|
2155
|
+
return true;
|
|
2156
|
+
}
|
|
2157
|
+
function getTabIndex(element) {
|
|
2158
|
+
const tabIndex = element.tabIndex;
|
|
2159
|
+
if (tabIndex < 0) {
|
|
2160
|
+
const nodeName = getNodeName(element);
|
|
2161
|
+
if (nodeName === 'details' || nodeName === 'audio' || nodeName === 'video' || isHTMLElement(element) && element.isContentEditable) {
|
|
2162
|
+
return 0;
|
|
2510
2163
|
}
|
|
2511
2164
|
}
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
var isNodeMatchingSelectorFocusable = function isNodeMatchingSelectorFocusable(options, node) {
|
|
2518
|
-
if (node.disabled || isHiddenInput(node) || isHidden(node, options) ||
|
|
2519
|
-
// For a details element with a summary, the summary element gets the focus
|
|
2520
|
-
isDetailsWithSummary(node) || isDisabledFromFieldset(node)) {
|
|
2521
|
-
return false;
|
|
2522
|
-
}
|
|
2523
|
-
return true;
|
|
2524
|
-
};
|
|
2525
|
-
var isNodeMatchingSelectorTabbable = function isNodeMatchingSelectorTabbable(options, node) {
|
|
2526
|
-
if (isNonTabbableRadio(node) || getTabIndex(node) < 0 || !isNodeMatchingSelectorFocusable(options, node)) {
|
|
2527
|
-
return false;
|
|
2165
|
+
return tabIndex;
|
|
2166
|
+
}
|
|
2167
|
+
function getNamedRadioInput(element) {
|
|
2168
|
+
if (getNodeName(element) !== 'input') {
|
|
2169
|
+
return null;
|
|
2528
2170
|
}
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2171
|
+
const input = element;
|
|
2172
|
+
return input.type === 'radio' && input.name !== '' ? input : null;
|
|
2173
|
+
}
|
|
2174
|
+
function isTabbableRadio(element, candidates) {
|
|
2175
|
+
const input = getNamedRadioInput(element);
|
|
2176
|
+
if (!input) {
|
|
2534
2177
|
return true;
|
|
2535
2178
|
}
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
};
|
|
2540
|
-
|
|
2541
|
-
/**
|
|
2542
|
-
* @param {Array.<Element|CandidateScope>} candidates
|
|
2543
|
-
* @returns Element[]
|
|
2544
|
-
*/
|
|
2545
|
-
var _sortByOrder = function sortByOrder(candidates) {
|
|
2546
|
-
var regularTabbables = [];
|
|
2547
|
-
var orderedTabbables = [];
|
|
2548
|
-
candidates.forEach(function (item, i) {
|
|
2549
|
-
var isScope = !!item.scopeParent;
|
|
2550
|
-
var element = isScope ? item.scopeParent : item;
|
|
2551
|
-
var candidateTabindex = getSortOrderTabIndex(element, isScope);
|
|
2552
|
-
var elements = isScope ? _sortByOrder(item.candidates) : element;
|
|
2553
|
-
if (candidateTabindex === 0) {
|
|
2554
|
-
isScope ? regularTabbables.push.apply(regularTabbables, elements) : regularTabbables.push(element);
|
|
2555
|
-
} else {
|
|
2556
|
-
orderedTabbables.push({
|
|
2557
|
-
documentOrder: i,
|
|
2558
|
-
tabIndex: candidateTabindex,
|
|
2559
|
-
item: item,
|
|
2560
|
-
isScope: isScope,
|
|
2561
|
-
content: elements
|
|
2562
|
-
});
|
|
2563
|
-
}
|
|
2179
|
+
const checkedRadio = candidates.find(candidate => {
|
|
2180
|
+
const radio = getNamedRadioInput(candidate);
|
|
2181
|
+
return radio?.name === input.name && radio.form === input.form && radio.checked;
|
|
2564
2182
|
});
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
flatten:
|
|
2577
|
-
getShadowRoot: options.getShadowRoot,
|
|
2578
|
-
shadowRootFilter: isShadowRootTabbable
|
|
2183
|
+
if (checkedRadio) {
|
|
2184
|
+
return checkedRadio === input;
|
|
2185
|
+
}
|
|
2186
|
+
return candidates.find(candidate => {
|
|
2187
|
+
const radio = getNamedRadioInput(candidate);
|
|
2188
|
+
return radio?.name === input.name && radio.form === input.form;
|
|
2189
|
+
}) === input;
|
|
2190
|
+
}
|
|
2191
|
+
function getComposedChildren(container) {
|
|
2192
|
+
if (isHTMLElement(container) && getNodeName(container) === 'slot') {
|
|
2193
|
+
const assignedElements = container.assignedElements({
|
|
2194
|
+
flatten: true
|
|
2579
2195
|
});
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
return _sortByOrder(candidates);
|
|
2584
|
-
};
|
|
2585
|
-
var focusable = function focusable(container, options) {
|
|
2586
|
-
options = options || {};
|
|
2587
|
-
var candidates;
|
|
2588
|
-
if (options.getShadowRoot) {
|
|
2589
|
-
candidates = _getCandidatesIteratively([container], options.includeContainer, {
|
|
2590
|
-
filter: isNodeMatchingSelectorFocusable.bind(null, options),
|
|
2591
|
-
flatten: true,
|
|
2592
|
-
getShadowRoot: options.getShadowRoot
|
|
2593
|
-
});
|
|
2594
|
-
} else {
|
|
2595
|
-
candidates = getCandidates(container, options.includeContainer, isNodeMatchingSelectorFocusable.bind(null, options));
|
|
2596
|
-
}
|
|
2597
|
-
return candidates;
|
|
2598
|
-
};
|
|
2599
|
-
var isTabbable = function isTabbable(node, options) {
|
|
2600
|
-
options = options || {};
|
|
2601
|
-
if (!node) {
|
|
2602
|
-
throw new Error('No node provided');
|
|
2196
|
+
if (assignedElements.length > 0) {
|
|
2197
|
+
return assignedElements;
|
|
2198
|
+
}
|
|
2603
2199
|
}
|
|
2604
|
-
if (
|
|
2605
|
-
return
|
|
2200
|
+
if (isHTMLElement(container) && container.shadowRoot) {
|
|
2201
|
+
return Array.from(container.shadowRoot.children);
|
|
2606
2202
|
}
|
|
2607
|
-
return
|
|
2608
|
-
}
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2203
|
+
return Array.from(container.children);
|
|
2204
|
+
}
|
|
2205
|
+
function appendCandidates(container, list) {
|
|
2206
|
+
getComposedChildren(container).forEach(child => {
|
|
2207
|
+
if (isFocusableCandidate(child)) {
|
|
2208
|
+
list.push(child);
|
|
2209
|
+
}
|
|
2210
|
+
appendCandidates(child, list);
|
|
2211
|
+
});
|
|
2212
|
+
}
|
|
2213
|
+
function appendMatchingElements(container, selector, list) {
|
|
2214
|
+
getComposedChildren(container).forEach(child => {
|
|
2215
|
+
if (isHTMLElement(child) && child.matches(selector)) {
|
|
2216
|
+
list.push(child);
|
|
2217
|
+
}
|
|
2218
|
+
appendMatchingElements(child, selector, list);
|
|
2219
|
+
});
|
|
2220
|
+
}
|
|
2221
|
+
function isTabbable(element) {
|
|
2222
|
+
return isFocusableElement(element) && getTabIndex(element) >= 0;
|
|
2223
|
+
}
|
|
2224
|
+
function focusable(container) {
|
|
2225
|
+
const candidates = [];
|
|
2226
|
+
appendCandidates(container, candidates);
|
|
2227
|
+
return candidates.filter(isFocusableElement);
|
|
2228
|
+
}
|
|
2229
|
+
function tabbable(container) {
|
|
2230
|
+
const candidates = focusable(container);
|
|
2231
|
+
return candidates.filter(element => getTabIndex(element) >= 0 && isTabbableRadio(element, candidates));
|
|
2612
2232
|
}
|
|
2613
|
-
|
|
2614
|
-
const getTabbableOptions = () => ({
|
|
2615
|
-
getShadowRoot: true,
|
|
2616
|
-
displayCheck:
|
|
2617
|
-
// JSDOM does not support the `tabbable` library. To solve this we can
|
|
2618
|
-
// check if `ResizeObserver` is a real function (not polyfilled), which
|
|
2619
|
-
// determines if the current environment is JSDOM-like.
|
|
2620
|
-
typeof ResizeObserver === 'function' && ResizeObserver.toString().includes('[native code]') ? 'full' : 'none'
|
|
2621
|
-
});
|
|
2622
2233
|
function getTabbableIn(container, dir) {
|
|
2623
|
-
const list = tabbable(container
|
|
2234
|
+
const list = tabbable(container);
|
|
2624
2235
|
const len = list.length;
|
|
2625
2236
|
if (len === 0) {
|
|
2626
2237
|
return undefined;
|
|
@@ -2643,14 +2254,15 @@ function isOutsideEvent(event, container) {
|
|
|
2643
2254
|
return !relatedTarget || !contains(containerElement, relatedTarget);
|
|
2644
2255
|
}
|
|
2645
2256
|
function disableFocusInside(container) {
|
|
2646
|
-
const tabbableElements = tabbable(container
|
|
2257
|
+
const tabbableElements = tabbable(container);
|
|
2647
2258
|
tabbableElements.forEach(element => {
|
|
2648
2259
|
element.dataset.tabindex = element.getAttribute('tabindex') || '';
|
|
2649
2260
|
element.setAttribute('tabindex', '-1');
|
|
2650
2261
|
});
|
|
2651
2262
|
}
|
|
2652
2263
|
function enableFocusInside(container) {
|
|
2653
|
-
const elements =
|
|
2264
|
+
const elements = [];
|
|
2265
|
+
appendMatchingElements(container, '[data-tabindex]', elements);
|
|
2654
2266
|
elements.forEach(element => {
|
|
2655
2267
|
const tabindex = element.dataset.tabindex;
|
|
2656
2268
|
delete element.dataset.tabindex;
|
|
@@ -2662,6 +2274,17 @@ function enableFocusInside(container) {
|
|
|
2662
2274
|
});
|
|
2663
2275
|
}
|
|
2664
2276
|
|
|
2277
|
+
/**
|
|
2278
|
+
* Adds an event listener and returns a cleanup function to remove it.
|
|
2279
|
+
*/
|
|
2280
|
+
|
|
2281
|
+
function addEventListener(target, type, listener, options) {
|
|
2282
|
+
target.addEventListener(type, listener, options);
|
|
2283
|
+
return () => {
|
|
2284
|
+
target.removeEventListener(type, listener, options);
|
|
2285
|
+
};
|
|
2286
|
+
}
|
|
2287
|
+
|
|
2665
2288
|
/**
|
|
2666
2289
|
* Calls the provided function when the CSS open/close animation or transition completes.
|
|
2667
2290
|
*/
|
|
@@ -2686,6 +2309,14 @@ function useOpenChangeComplete(parameters) {
|
|
|
2686
2309
|
}, [enabled, open, onComplete, runOnceAnimationsFinish]);
|
|
2687
2310
|
}
|
|
2688
2311
|
|
|
2312
|
+
function useOnFirstRender(fn) {
|
|
2313
|
+
const ref = React.useRef(true);
|
|
2314
|
+
if (ref.current) {
|
|
2315
|
+
ref.current = false;
|
|
2316
|
+
fn();
|
|
2317
|
+
}
|
|
2318
|
+
}
|
|
2319
|
+
|
|
2689
2320
|
const EMPTY = 0;
|
|
2690
2321
|
class Timeout {
|
|
2691
2322
|
static create() {
|
|
@@ -2884,16 +2515,15 @@ function preventScrollInsetScrollbars(referenceElement) {
|
|
|
2884
2515
|
resizeFrame.request(lockScroll);
|
|
2885
2516
|
}
|
|
2886
2517
|
lockScroll();
|
|
2887
|
-
|
|
2518
|
+
const unsubscribeResize = addEventListener(win, 'resize', handleResize);
|
|
2888
2519
|
return () => {
|
|
2889
2520
|
resizeFrame.cancel();
|
|
2890
2521
|
cleanup();
|
|
2891
|
-
// Sometimes this cleanup can
|
|
2892
|
-
//
|
|
2893
|
-
//
|
|
2894
|
-
// so we check for it to avoid test failures.
|
|
2522
|
+
// Sometimes this cleanup can run after test teardown because it is called
|
|
2523
|
+
// in a `setTimeout(fn, 0)`. Guard the returned cleanup to avoid calling
|
|
2524
|
+
// `removeEventListener` when it is no longer available in tests.
|
|
2895
2525
|
if (typeof win.removeEventListener === 'function') {
|
|
2896
|
-
|
|
2526
|
+
unsubscribeResize();
|
|
2897
2527
|
}
|
|
2898
2528
|
};
|
|
2899
2529
|
}
|
|
@@ -2962,6 +2592,20 @@ function useScrollLock(enabled = true, referenceElement = null) {
|
|
|
2962
2592
|
}, [enabled, referenceElement]);
|
|
2963
2593
|
}
|
|
2964
2594
|
|
|
2595
|
+
/**
|
|
2596
|
+
* Combines multiple cleanup functions into a single cleanup function.
|
|
2597
|
+
*/
|
|
2598
|
+
function mergeCleanups(...cleanups) {
|
|
2599
|
+
return () => {
|
|
2600
|
+
for (let i = 0; i < cleanups.length; i += 1) {
|
|
2601
|
+
const cleanup = cleanups[i];
|
|
2602
|
+
if (cleanup) {
|
|
2603
|
+
cleanup();
|
|
2604
|
+
}
|
|
2605
|
+
}
|
|
2606
|
+
};
|
|
2607
|
+
}
|
|
2608
|
+
|
|
2965
2609
|
/**
|
|
2966
2610
|
* Untracks the provided value by turning it into a ref to remove its reactivity.
|
|
2967
2611
|
*
|
|
@@ -3051,9 +2695,16 @@ function enqueueFocus(el, options = {}) {
|
|
|
3051
2695
|
});
|
|
3052
2696
|
if (sync) {
|
|
3053
2697
|
exec();
|
|
3054
|
-
|
|
3055
|
-
rafId = requestAnimationFrame(exec);
|
|
2698
|
+
return NOOP;
|
|
3056
2699
|
}
|
|
2700
|
+
const currentRafId = requestAnimationFrame(exec);
|
|
2701
|
+
rafId = currentRafId;
|
|
2702
|
+
return () => {
|
|
2703
|
+
if (rafId === currentRafId) {
|
|
2704
|
+
cancelAnimationFrame(currentRafId);
|
|
2705
|
+
rafId = 0;
|
|
2706
|
+
}
|
|
2707
|
+
};
|
|
3057
2708
|
}
|
|
3058
2709
|
|
|
3059
2710
|
// Modified to add conditional `aria-hidden` support:
|
|
@@ -3300,6 +2951,7 @@ const FloatingPortal = /*#__PURE__*/React.forwardRef(function FloatingPortal(com
|
|
|
3300
2951
|
className,
|
|
3301
2952
|
render,
|
|
3302
2953
|
renderGuards,
|
|
2954
|
+
style,
|
|
3303
2955
|
...elementProps
|
|
3304
2956
|
} = componentProps;
|
|
3305
2957
|
const {
|
|
@@ -3316,6 +2968,7 @@ const FloatingPortal = /*#__PURE__*/React.forwardRef(function FloatingPortal(com
|
|
|
3316
2968
|
const beforeInsideRef = React.useRef(null);
|
|
3317
2969
|
const afterInsideRef = React.useRef(null);
|
|
3318
2970
|
const [focusManagerState, setFocusManagerState] = React.useState(null);
|
|
2971
|
+
const focusInsideDisabledRef = React.useRef(false);
|
|
3319
2972
|
const modal = focusManagerState?.modal;
|
|
3320
2973
|
const open = focusManagerState?.open;
|
|
3321
2974
|
const shouldRenderGuards = typeof renderGuards === 'boolean' ? renderGuards : !!focusManagerState && !focusManagerState.modal && focusManagerState.open && !!portalNode;
|
|
@@ -3331,26 +2984,28 @@ const FloatingPortal = /*#__PURE__*/React.forwardRef(function FloatingPortal(com
|
|
|
3331
2984
|
// element outside or using the mouse.
|
|
3332
2985
|
function onFocus(event) {
|
|
3333
2986
|
if (portalNode && event.relatedTarget && isOutsideEvent(event)) {
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
2987
|
+
if (event.type === 'focusin') {
|
|
2988
|
+
if (focusInsideDisabledRef.current) {
|
|
2989
|
+
enableFocusInside(portalNode);
|
|
2990
|
+
focusInsideDisabledRef.current = false;
|
|
2991
|
+
}
|
|
2992
|
+
} else {
|
|
2993
|
+
disableFocusInside(portalNode);
|
|
2994
|
+
focusInsideDisabledRef.current = true;
|
|
2995
|
+
}
|
|
3337
2996
|
}
|
|
3338
2997
|
}
|
|
3339
2998
|
|
|
3340
2999
|
// Listen to the event on the capture phase so they run before the focus
|
|
3341
3000
|
// trap elements onFocus prop is called.
|
|
3342
|
-
|
|
3343
|
-
portalNode.addEventListener('focusout', onFocus, true);
|
|
3344
|
-
return () => {
|
|
3345
|
-
portalNode.removeEventListener('focusin', onFocus, true);
|
|
3346
|
-
portalNode.removeEventListener('focusout', onFocus, true);
|
|
3347
|
-
};
|
|
3001
|
+
return mergeCleanups(addEventListener(portalNode, 'focusin', onFocus, true), addEventListener(portalNode, 'focusout', onFocus, true));
|
|
3348
3002
|
}, [portalNode, modal]);
|
|
3349
3003
|
React.useEffect(() => {
|
|
3350
|
-
if (!portalNode || open) {
|
|
3004
|
+
if (!portalNode || open !== false) {
|
|
3351
3005
|
return;
|
|
3352
3006
|
}
|
|
3353
3007
|
enableFocusInside(portalNode);
|
|
3008
|
+
focusInsideDisabledRef.current = false;
|
|
3354
3009
|
}, [open, portalNode]);
|
|
3355
3010
|
const portalContextValue = React.useMemo(() => ({
|
|
3356
3011
|
beforeOutsideRef,
|
|
@@ -3429,7 +3084,7 @@ const useFloatingTree = externalTree => {
|
|
|
3429
3084
|
};
|
|
3430
3085
|
|
|
3431
3086
|
function getEventType(event, lastInteractionType) {
|
|
3432
|
-
const win = getWindow(event
|
|
3087
|
+
const win = getWindow(getTarget(event));
|
|
3433
3088
|
if (event instanceof win.KeyboardEvent) {
|
|
3434
3089
|
return 'keyboard';
|
|
3435
3090
|
}
|
|
@@ -3474,11 +3129,10 @@ function getFirstTabbableElement(container) {
|
|
|
3474
3129
|
if (!container) {
|
|
3475
3130
|
return null;
|
|
3476
3131
|
}
|
|
3477
|
-
|
|
3478
|
-
if (isTabbable(container, tabbableOptions)) {
|
|
3132
|
+
if (isTabbable(container)) {
|
|
3479
3133
|
return container;
|
|
3480
3134
|
}
|
|
3481
|
-
return tabbable(container
|
|
3135
|
+
return tabbable(container)[0] || container;
|
|
3482
3136
|
}
|
|
3483
3137
|
function isFocusable(element) {
|
|
3484
3138
|
if (!element || !element.isConnected) {
|
|
@@ -3490,14 +3144,16 @@ function isFocusable(element) {
|
|
|
3490
3144
|
return isElementVisible(element);
|
|
3491
3145
|
}
|
|
3492
3146
|
function handleTabIndex(floatingFocusElement, orderRef) {
|
|
3147
|
+
if (floatingFocusElement.hasAttribute('tabindex') && !floatingFocusElement.hasAttribute('data-tabindex')) {
|
|
3148
|
+
return;
|
|
3149
|
+
}
|
|
3493
3150
|
if (!orderRef.current.includes('floating') && !floatingFocusElement.getAttribute('role')?.includes('dialog')) {
|
|
3494
3151
|
return;
|
|
3495
3152
|
}
|
|
3496
|
-
const
|
|
3497
|
-
const focusableElements = focusable(floatingFocusElement, options);
|
|
3153
|
+
const focusableElements = focusable(floatingFocusElement);
|
|
3498
3154
|
const tabbableContent = focusableElements.filter(element => {
|
|
3499
3155
|
const dataTabIndex = element.getAttribute('data-tabindex') || '';
|
|
3500
|
-
return isTabbable(element
|
|
3156
|
+
return isTabbable(element) || element.hasAttribute('data-tabindex') && !dataTabIndex.startsWith('-');
|
|
3501
3157
|
});
|
|
3502
3158
|
const tabIndex = floatingFocusElement.getAttribute('tabindex');
|
|
3503
3159
|
if (orderRef.current.includes('floating') || tabbableContent.length === 0) {
|
|
@@ -3556,7 +3212,7 @@ function FloatingFocusManager(props) {
|
|
|
3556
3212
|
const preventReturnFocusRef = React.useRef(false);
|
|
3557
3213
|
const isPointerDownRef = React.useRef(false);
|
|
3558
3214
|
const pointerDownOutsideRef = React.useRef(false);
|
|
3559
|
-
const
|
|
3215
|
+
const lastFocusedTabbableRef = React.useRef(null);
|
|
3560
3216
|
const closeTypeRef = React.useRef('');
|
|
3561
3217
|
const lastInteractionTypeRef = React.useRef('');
|
|
3562
3218
|
const beforeGuardRef = React.useRef(null);
|
|
@@ -3569,13 +3225,9 @@ function FloatingFocusManager(props) {
|
|
|
3569
3225
|
const isInsidePortal = portalContext != null;
|
|
3570
3226
|
const floatingFocusElement = getFloatingFocusElement(floating);
|
|
3571
3227
|
const getTabbableContent = useStableCallback((container = floatingFocusElement) => {
|
|
3572
|
-
return container ? tabbable(container
|
|
3228
|
+
return container ? tabbable(container) : [];
|
|
3573
3229
|
});
|
|
3574
3230
|
const getResolvedInsideElements = useStableCallback(() => getInsideElements?.().filter(element => element != null) ?? []);
|
|
3575
|
-
const getTabbableElements = useStableCallback(container => {
|
|
3576
|
-
const content = getTabbableContent(container);
|
|
3577
|
-
return orderRef.current.map(() => content).filter(Boolean).flat();
|
|
3578
|
-
});
|
|
3579
3231
|
|
|
3580
3232
|
// Prevent Tab from escaping the modal when there are no tabbable elements.
|
|
3581
3233
|
React.useEffect(() => {
|
|
@@ -3590,12 +3242,9 @@ function FloatingFocusManager(props) {
|
|
|
3590
3242
|
}
|
|
3591
3243
|
}
|
|
3592
3244
|
}
|
|
3593
|
-
const doc = ownerDocument(floatingFocusElement);
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
doc.removeEventListener('keydown', onKeyDown);
|
|
3597
|
-
};
|
|
3598
|
-
}, [disabled, domReference, floatingFocusElement, modal, orderRef, isUntrappedTypeableCombobox, getTabbableContent, getTabbableElements]);
|
|
3245
|
+
const doc = ownerDocument(floatingFocusElement);
|
|
3246
|
+
return addEventListener(doc, 'keydown', onKeyDown);
|
|
3247
|
+
}, [disabled, domReference, floatingFocusElement, modal, orderRef, isUntrappedTypeableCombobox, getTabbableContent]);
|
|
3599
3248
|
|
|
3600
3249
|
// Track pointer/keyboard interactions to disambiguate focus and outside presses.
|
|
3601
3250
|
React.useEffect(() => {
|
|
@@ -3619,16 +3268,7 @@ function FloatingFocusManager(props) {
|
|
|
3619
3268
|
function onKeyDown() {
|
|
3620
3269
|
lastInteractionTypeRef.current = 'keyboard';
|
|
3621
3270
|
}
|
|
3622
|
-
|
|
3623
|
-
doc.addEventListener('pointerup', clearPointerDownOutside, true);
|
|
3624
|
-
doc.addEventListener('pointercancel', clearPointerDownOutside, true);
|
|
3625
|
-
doc.addEventListener('keydown', onKeyDown, true);
|
|
3626
|
-
return () => {
|
|
3627
|
-
doc.removeEventListener('pointerdown', onPointerDown, true);
|
|
3628
|
-
doc.removeEventListener('pointerup', clearPointerDownOutside, true);
|
|
3629
|
-
doc.removeEventListener('pointercancel', clearPointerDownOutside, true);
|
|
3630
|
-
doc.removeEventListener('keydown', onKeyDown, true);
|
|
3631
|
-
};
|
|
3271
|
+
return mergeCleanups(addEventListener(doc, 'pointerdown', onPointerDown, true), addEventListener(doc, 'pointerup', clearPointerDownOutside, true), addEventListener(doc, 'pointercancel', clearPointerDownOutside, true), addEventListener(doc, 'keydown', onKeyDown, true));
|
|
3632
3272
|
}, [disabled, floating, domReference, floatingFocusElement, open, portalContext, getResolvedInsideElements]);
|
|
3633
3273
|
|
|
3634
3274
|
// Close on focus out and restore focus within the floating tree when needed.
|
|
@@ -3647,10 +3287,8 @@ function FloatingFocusManager(props) {
|
|
|
3647
3287
|
}
|
|
3648
3288
|
function handleFocusIn(event) {
|
|
3649
3289
|
const target = getTarget(event);
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
if (tabbableIndex !== -1) {
|
|
3653
|
-
tabbableIndexRef.current = tabbableIndex;
|
|
3290
|
+
if (isTabbable(target)) {
|
|
3291
|
+
lastFocusedTabbableRef.current = target;
|
|
3654
3292
|
}
|
|
3655
3293
|
}
|
|
3656
3294
|
function handleFocusOutside(event) {
|
|
@@ -3687,9 +3325,9 @@ function FloatingFocusManager(props) {
|
|
|
3687
3325
|
return;
|
|
3688
3326
|
}
|
|
3689
3327
|
}
|
|
3690
|
-
const prevTabbableIndex = tabbableIndexRef.current;
|
|
3691
3328
|
const tabbableContent = getTabbableContent();
|
|
3692
|
-
const
|
|
3329
|
+
const prevTabbable = lastFocusedTabbableRef.current;
|
|
3330
|
+
const nodeToFocus = (prevTabbable && tabbableContent.includes(prevTabbable) ? prevTabbable : null) || tabbableContent[tabbableContent.length - 1] || floatingFocusElement;
|
|
3693
3331
|
if (isHTMLElement(nodeToFocus)) {
|
|
3694
3332
|
nodeToFocus.focus();
|
|
3695
3333
|
}
|
|
@@ -3727,37 +3365,10 @@ function FloatingFocusManager(props) {
|
|
|
3727
3365
|
});
|
|
3728
3366
|
}
|
|
3729
3367
|
const domReferenceElement = isHTMLElement(domReference) ? domReference : null;
|
|
3730
|
-
const cleanups = [];
|
|
3731
3368
|
if (!floating && !domReferenceElement) {
|
|
3732
3369
|
return undefined;
|
|
3733
3370
|
}
|
|
3734
|
-
|
|
3735
|
-
domReferenceElement.addEventListener('focusout', handleFocusOutside);
|
|
3736
|
-
domReferenceElement.addEventListener('pointerdown', handlePointerDown);
|
|
3737
|
-
cleanups.push(() => {
|
|
3738
|
-
domReferenceElement.removeEventListener('focusout', handleFocusOutside);
|
|
3739
|
-
domReferenceElement.removeEventListener('pointerdown', handlePointerDown);
|
|
3740
|
-
});
|
|
3741
|
-
}
|
|
3742
|
-
if (floating) {
|
|
3743
|
-
floating.addEventListener('focusin', handleFocusIn);
|
|
3744
|
-
floating.addEventListener('focusout', handleFocusOutside);
|
|
3745
|
-
if (portalContext) {
|
|
3746
|
-
floating.addEventListener('focusout', markInsideReactTree, true);
|
|
3747
|
-
cleanups.push(() => {
|
|
3748
|
-
floating.removeEventListener('focusout', markInsideReactTree, true);
|
|
3749
|
-
});
|
|
3750
|
-
}
|
|
3751
|
-
cleanups.push(() => {
|
|
3752
|
-
floating.removeEventListener('focusin', handleFocusIn);
|
|
3753
|
-
floating.removeEventListener('focusout', handleFocusOutside);
|
|
3754
|
-
});
|
|
3755
|
-
}
|
|
3756
|
-
return () => {
|
|
3757
|
-
cleanups.forEach(cleanup => {
|
|
3758
|
-
cleanup();
|
|
3759
|
-
});
|
|
3760
|
-
};
|
|
3371
|
+
return mergeCleanups(domReferenceElement && addEventListener(domReferenceElement, 'focusout', handleFocusOutside), domReferenceElement && addEventListener(domReferenceElement, 'pointerdown', handlePointerDown), floating && addEventListener(floating, 'focusin', handleFocusIn), floating && addEventListener(floating, 'focusout', handleFocusOutside), floating && portalContext && addEventListener(floating, 'focusout', markInsideReactTree, true));
|
|
3761
3372
|
}, [disabled, domReference, floating, floatingFocusElement, modal, tree, portalContext, store, closeOnFocusOut, restoreFocus, getTabbableContent, isUntrappedTypeableCombobox, getNodeId, orderRef, dataRef, blurTimeout, pointerDownTimeout, restoreFocusFrame, nextFocusableElement, previousFocusableElement, getResolvedInsideElements]);
|
|
3762
3373
|
|
|
3763
3374
|
// Hide everything outside the floating tree from assistive tech while open.
|
|
@@ -3794,7 +3405,6 @@ function FloatingFocusManager(props) {
|
|
|
3794
3405
|
|
|
3795
3406
|
// Wait for any layout effect state setters to execute to set `tabIndex`.
|
|
3796
3407
|
queueMicrotask(() => {
|
|
3797
|
-
const focusableElements = getTabbableElements(floatingFocusElement);
|
|
3798
3408
|
const initialFocusValueOrFn = initialFocusRef.current;
|
|
3799
3409
|
const resolvedInitialFocus = typeof initialFocusValueOrFn === 'function' ? initialFocusValueOrFn(openInteractionTypeRef.current || '') : initialFocusValueOrFn;
|
|
3800
3410
|
|
|
@@ -3802,22 +3412,29 @@ function FloatingFocusManager(props) {
|
|
|
3802
3412
|
if (resolvedInitialFocus === undefined || resolvedInitialFocus === false) {
|
|
3803
3413
|
return;
|
|
3804
3414
|
}
|
|
3415
|
+
const focusAlreadyInsideFloatingEl = contains(floatingFocusElement, previouslyFocusedElement);
|
|
3416
|
+
if (focusAlreadyInsideFloatingEl) {
|
|
3417
|
+
return;
|
|
3418
|
+
}
|
|
3419
|
+
let focusableElements = null;
|
|
3420
|
+
const getDefaultFocusElement = () => {
|
|
3421
|
+
if (focusableElements == null) {
|
|
3422
|
+
focusableElements = getTabbableContent(floatingFocusElement);
|
|
3423
|
+
}
|
|
3424
|
+
return focusableElements[0] || floatingFocusElement;
|
|
3425
|
+
};
|
|
3805
3426
|
let elToFocus;
|
|
3806
3427
|
if (resolvedInitialFocus === true || resolvedInitialFocus === null) {
|
|
3807
|
-
elToFocus =
|
|
3428
|
+
elToFocus = getDefaultFocusElement();
|
|
3808
3429
|
} else {
|
|
3809
3430
|
elToFocus = resolveRef(resolvedInitialFocus);
|
|
3810
3431
|
}
|
|
3811
|
-
elToFocus = elToFocus ||
|
|
3812
|
-
const focusAlreadyInsideFloatingEl = contains(floatingFocusElement, previouslyFocusedElement);
|
|
3813
|
-
if (focusAlreadyInsideFloatingEl) {
|
|
3814
|
-
return;
|
|
3815
|
-
}
|
|
3432
|
+
elToFocus = elToFocus || getDefaultFocusElement();
|
|
3816
3433
|
enqueueFocus(elToFocus, {
|
|
3817
3434
|
preventScroll: elToFocus === floatingFocusElement
|
|
3818
3435
|
});
|
|
3819
3436
|
});
|
|
3820
|
-
}, [disabled, open, floatingFocusElement, ignoreInitialFocus,
|
|
3437
|
+
}, [disabled, open, floatingFocusElement, ignoreInitialFocus, getTabbableContent, initialFocusRef, openInteractionTypeRef]);
|
|
3821
3438
|
|
|
3822
3439
|
// Track return focus targets and restore focus on unmount/close.
|
|
3823
3440
|
useIsoLayoutEffect(() => {
|
|
@@ -3846,7 +3463,7 @@ function FloatingFocusManager(props) {
|
|
|
3846
3463
|
preventReturnFocusRef.current = false;
|
|
3847
3464
|
} else {
|
|
3848
3465
|
let isPreventScrollSupported = false;
|
|
3849
|
-
|
|
3466
|
+
ownerDocument(floatingFocusElement).createElement('div').focus({
|
|
3850
3467
|
get preventScroll() {
|
|
3851
3468
|
isPreventScrollSupported = true;
|
|
3852
3469
|
return false;
|
|
@@ -3883,14 +3500,15 @@ function FloatingFocusManager(props) {
|
|
|
3883
3500
|
const activeEl = activeElement(doc);
|
|
3884
3501
|
const insideElements = getResolvedInsideElements();
|
|
3885
3502
|
const isFocusInsideFloatingTree = contains(floating, activeEl) || insideElements.some(element => element === activeEl || contains(element, activeEl)) || tree && getNodeChildren(tree.nodesRef.current, getNodeId(), false).some(node => contains(node.context?.elements.floating, activeEl));
|
|
3503
|
+
|
|
3504
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3505
|
+
const returnFocusValueOrFn = returnFocusRef.current;
|
|
3886
3506
|
const returnElement = getReturnElement();
|
|
3887
3507
|
queueMicrotask(() => {
|
|
3888
3508
|
// This is `returnElement`, if it's tabbable, or its first tabbable child.
|
|
3889
3509
|
const tabbableReturnElement = getFirstTabbableElement(returnElement);
|
|
3890
|
-
const hasExplicitReturnFocus = typeof
|
|
3891
|
-
if (
|
|
3892
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3893
|
-
returnFocusRef.current && !preventReturnFocusRef.current && isHTMLElement(tabbableReturnElement) && (
|
|
3510
|
+
const hasExplicitReturnFocus = typeof returnFocusValueOrFn !== 'boolean';
|
|
3511
|
+
if (returnFocusValueOrFn && !preventReturnFocusRef.current && isHTMLElement(tabbableReturnElement) && (
|
|
3894
3512
|
// If the focus moved somewhere else after mount, avoid returning focus
|
|
3895
3513
|
// since it likely entered a different element which should be
|
|
3896
3514
|
// respected: https://github.com/floating-ui/floating-ui/issues/2607
|
|
@@ -3954,7 +3572,7 @@ function FloatingFocusManager(props) {
|
|
|
3954
3572
|
ref: mergedBeforeGuardRef,
|
|
3955
3573
|
onFocus: event => {
|
|
3956
3574
|
if (modal) {
|
|
3957
|
-
const els =
|
|
3575
|
+
const els = getTabbableContent();
|
|
3958
3576
|
enqueueFocus(els[els.length - 1]);
|
|
3959
3577
|
} else if (portalContext?.portalNode) {
|
|
3960
3578
|
preventReturnFocusRef.current = false;
|
|
@@ -3971,7 +3589,7 @@ function FloatingFocusManager(props) {
|
|
|
3971
3589
|
ref: mergedAfterGuardRef,
|
|
3972
3590
|
onFocus: event => {
|
|
3973
3591
|
if (modal) {
|
|
3974
|
-
enqueueFocus(
|
|
3592
|
+
enqueueFocus(getTabbableContent()[0]);
|
|
3975
3593
|
} else if (portalContext?.portalNode) {
|
|
3976
3594
|
if (closeOnFocusOut) {
|
|
3977
3595
|
preventReturnFocusRef.current = true;
|
|
@@ -4028,8 +3646,9 @@ function useClick(context, props = {}) {
|
|
|
4028
3646
|
|
|
4029
3647
|
// Animations sometimes won't run on a typeable element if using a rAF.
|
|
4030
3648
|
// Focus is always set on these elements. For touch, we may delay opening.
|
|
4031
|
-
|
|
4032
|
-
|
|
3649
|
+
const target = getTarget(nativeEvent);
|
|
3650
|
+
if (isTypeableElement(target)) {
|
|
3651
|
+
const details = createChangeEventDetails(reason, nativeEvent, target);
|
|
4033
3652
|
if (nextOpen && pointerType === 'touch' && touchOpenDelay > 0) {
|
|
4034
3653
|
touchOpenTimeout.start(touchOpenDelay, () => {
|
|
4035
3654
|
store.setOpen(true, details);
|
|
@@ -4250,11 +3869,8 @@ function useDismiss(context, props = {}) {
|
|
|
4250
3869
|
}
|
|
4251
3870
|
const target = getTarget(event);
|
|
4252
3871
|
const inertSelector = `[${createAttribute('inert')}]`;
|
|
4253
|
-
let markers = Array.from(ownerDocument(store.select('floatingElement')).querySelectorAll(inertSelector));
|
|
4254
3872
|
const targetRoot = isElement(target) ? target.getRootNode() : null;
|
|
4255
|
-
|
|
4256
|
-
markers = markers.concat(Array.from(targetRoot.querySelectorAll(inertSelector)));
|
|
4257
|
-
}
|
|
3873
|
+
const markers = Array.from((isShadowRoot(targetRoot) ? targetRoot : ownerDocument(store.select('floatingElement'))).querySelectorAll(inertSelector));
|
|
4258
3874
|
const triggers = store.context.triggerElements;
|
|
4259
3875
|
|
|
4260
3876
|
// If another trigger is clicked, don't close the floating element.
|
|
@@ -4285,7 +3901,7 @@ function useDismiss(context, props = {}) {
|
|
|
4285
3901
|
// Skip for touch events: scrollbars don't receive touch events on most platforms
|
|
4286
3902
|
if (isHTMLElement(target) && !('touches' in event)) {
|
|
4287
3903
|
const lastTraversableNode = isLastTraversableNode(target);
|
|
4288
|
-
const style = getComputedStyle
|
|
3904
|
+
const style = getComputedStyle(target);
|
|
4289
3905
|
const scrollRe = /auto|scroll/;
|
|
4290
3906
|
const isScrollableX = lastTraversableNode || scrollRe.test(style.overflowX);
|
|
4291
3907
|
const isScrollableY = lastTraversableNode || scrollRe.test(style.overflowY);
|
|
@@ -4362,14 +3978,19 @@ function useDismiss(context, props = {}) {
|
|
|
4362
3978
|
});
|
|
4363
3979
|
}
|
|
4364
3980
|
}
|
|
4365
|
-
function
|
|
4366
|
-
currentPointerTypeRef.current = 'touch';
|
|
3981
|
+
function addTargetEventListenerOnce(event, listener) {
|
|
4367
3982
|
const target = getTarget(event);
|
|
4368
|
-
|
|
4369
|
-
|
|
4370
|
-
target?.removeEventListener(event.type, callback);
|
|
3983
|
+
if (!target) {
|
|
3984
|
+
return;
|
|
4371
3985
|
}
|
|
4372
|
-
|
|
3986
|
+
const unsubscribe = addEventListener(target, event.type, () => {
|
|
3987
|
+
listener(event);
|
|
3988
|
+
unsubscribe();
|
|
3989
|
+
});
|
|
3990
|
+
}
|
|
3991
|
+
function handleTouchStartCapture(event) {
|
|
3992
|
+
currentPointerTypeRef.current = 'touch';
|
|
3993
|
+
addTargetEventListenerOnce(event, handleTouchStart);
|
|
4373
3994
|
}
|
|
4374
3995
|
function closeOnPressOutsideCapture(event) {
|
|
4375
3996
|
cancelDismissOnEndTimeout.clear();
|
|
@@ -4379,16 +4000,13 @@ function useDismiss(context, props = {}) {
|
|
|
4379
4000
|
if (event.type === 'mousedown' && touchStateRef.current && !touchStateRef.current.dismissOnMouseDown) {
|
|
4380
4001
|
return;
|
|
4381
4002
|
}
|
|
4382
|
-
|
|
4383
|
-
|
|
4384
|
-
|
|
4385
|
-
handlePointerDown(event);
|
|
4003
|
+
addTargetEventListenerOnce(event, targetEvent => {
|
|
4004
|
+
if (targetEvent.type === 'pointerdown') {
|
|
4005
|
+
handlePointerDown(targetEvent);
|
|
4386
4006
|
} else {
|
|
4387
|
-
closeOnPressOutside(
|
|
4007
|
+
closeOnPressOutside(targetEvent);
|
|
4388
4008
|
}
|
|
4389
|
-
|
|
4390
|
-
}
|
|
4391
|
-
target?.addEventListener(event.type, callback);
|
|
4009
|
+
});
|
|
4392
4010
|
}
|
|
4393
4011
|
function handlePressEndCapture(event) {
|
|
4394
4012
|
if (!pressStartedInsideRef.current) {
|
|
@@ -4447,12 +4065,7 @@ function useDismiss(context, props = {}) {
|
|
|
4447
4065
|
}
|
|
4448
4066
|
}
|
|
4449
4067
|
function handleTouchMoveCapture(event) {
|
|
4450
|
-
|
|
4451
|
-
function callback() {
|
|
4452
|
-
handleTouchMove(event);
|
|
4453
|
-
target?.removeEventListener(event.type, callback);
|
|
4454
|
-
}
|
|
4455
|
-
target?.addEventListener(event.type, callback);
|
|
4068
|
+
addTargetEventListenerOnce(event, handleTouchMove);
|
|
4456
4069
|
}
|
|
4457
4070
|
function handleTouchEnd(event) {
|
|
4458
4071
|
if (getOutsidePressEvent() !== 'sloppy' || !touchStateRef.current || isEventTargetWithin(event, store.select('floatingElement')) || isEventTargetWithin(event, store.select('domReferenceElement'))) {
|
|
@@ -4465,47 +4078,12 @@ function useDismiss(context, props = {}) {
|
|
|
4465
4078
|
touchStateRef.current = null;
|
|
4466
4079
|
}
|
|
4467
4080
|
function handleTouchEndCapture(event) {
|
|
4468
|
-
|
|
4469
|
-
function callback() {
|
|
4470
|
-
handleTouchEnd(event);
|
|
4471
|
-
target?.removeEventListener(event.type, callback);
|
|
4472
|
-
}
|
|
4473
|
-
target?.addEventListener(event.type, callback);
|
|
4081
|
+
addTargetEventListenerOnce(event, handleTouchEnd);
|
|
4474
4082
|
}
|
|
4475
4083
|
const doc = ownerDocument(floatingElement);
|
|
4476
|
-
|
|
4477
|
-
doc.addEventListener('keydown', closeOnEscapeKeyDown);
|
|
4478
|
-
doc.addEventListener('compositionstart', handleCompositionStart);
|
|
4479
|
-
doc.addEventListener('compositionend', handleCompositionEnd);
|
|
4480
|
-
}
|
|
4481
|
-
if (outsidePressEnabled) {
|
|
4482
|
-
doc.addEventListener('click', closeOnPressOutsideCapture, true);
|
|
4483
|
-
doc.addEventListener('pointerdown', closeOnPressOutsideCapture, true);
|
|
4484
|
-
doc.addEventListener('pointerup', handlePressEndCapture, true);
|
|
4485
|
-
doc.addEventListener('pointercancel', handlePressEndCapture, true);
|
|
4486
|
-
doc.addEventListener('mousedown', closeOnPressOutsideCapture, true);
|
|
4487
|
-
doc.addEventListener('mouseup', handlePressEndCapture, true);
|
|
4488
|
-
doc.addEventListener('touchstart', handleTouchStartCapture, true);
|
|
4489
|
-
doc.addEventListener('touchmove', handleTouchMoveCapture, true);
|
|
4490
|
-
doc.addEventListener('touchend', handleTouchEndCapture, true);
|
|
4491
|
-
}
|
|
4084
|
+
const unsubscribe = mergeCleanups(escapeKey$1 && mergeCleanups(addEventListener(doc, 'keydown', closeOnEscapeKeyDown), addEventListener(doc, 'compositionstart', handleCompositionStart), addEventListener(doc, 'compositionend', handleCompositionEnd)), outsidePressEnabled && mergeCleanups(addEventListener(doc, 'click', closeOnPressOutsideCapture, true), addEventListener(doc, 'pointerdown', closeOnPressOutsideCapture, true), addEventListener(doc, 'pointerup', handlePressEndCapture, true), addEventListener(doc, 'pointercancel', handlePressEndCapture, true), addEventListener(doc, 'mousedown', closeOnPressOutsideCapture, true), addEventListener(doc, 'mouseup', handlePressEndCapture, true), addEventListener(doc, 'touchstart', handleTouchStartCapture, true), addEventListener(doc, 'touchmove', handleTouchMoveCapture, true), addEventListener(doc, 'touchend', handleTouchEndCapture, true)));
|
|
4492
4085
|
return () => {
|
|
4493
|
-
|
|
4494
|
-
doc.removeEventListener('keydown', closeOnEscapeKeyDown);
|
|
4495
|
-
doc.removeEventListener('compositionstart', handleCompositionStart);
|
|
4496
|
-
doc.removeEventListener('compositionend', handleCompositionEnd);
|
|
4497
|
-
}
|
|
4498
|
-
if (outsidePressEnabled) {
|
|
4499
|
-
doc.removeEventListener('click', closeOnPressOutsideCapture, true);
|
|
4500
|
-
doc.removeEventListener('pointerdown', closeOnPressOutsideCapture, true);
|
|
4501
|
-
doc.removeEventListener('pointerup', handlePressEndCapture, true);
|
|
4502
|
-
doc.removeEventListener('pointercancel', handlePressEndCapture, true);
|
|
4503
|
-
doc.removeEventListener('mousedown', closeOnPressOutsideCapture, true);
|
|
4504
|
-
doc.removeEventListener('mouseup', handlePressEndCapture, true);
|
|
4505
|
-
doc.removeEventListener('touchstart', handleTouchStartCapture, true);
|
|
4506
|
-
doc.removeEventListener('touchmove', handleTouchMoveCapture, true);
|
|
4507
|
-
doc.removeEventListener('touchend', handleTouchEndCapture, true);
|
|
4508
|
-
}
|
|
4086
|
+
unsubscribe();
|
|
4509
4087
|
compositionTimeout.clear();
|
|
4510
4088
|
preventedPressSuppressionTimeout.clear();
|
|
4511
4089
|
resetPressStartState();
|
|
@@ -4583,20 +4161,24 @@ function useDismiss(context, props = {}) {
|
|
|
4583
4161
|
} : {}, [enabled, reference, floating]);
|
|
4584
4162
|
}
|
|
4585
4163
|
|
|
4586
|
-
|
|
4164
|
+
/**
|
|
4165
|
+
* The NoOptionalParams type is a utility type that checks if a function has optional or default parameters.
|
|
4166
|
+
* If the function has optional or default parameters, it returns a string literal type with an error message.
|
|
4167
|
+
* Otherwise, it returns the original function type.
|
|
4168
|
+
*
|
|
4169
|
+
* This is used to enforce that the combiner function passed to createSelector does not have optional or default parameters,
|
|
4170
|
+
* as memoization relies on the Function.length property, which does not account for optional or default parameters.
|
|
4171
|
+
*/
|
|
4587
4172
|
|
|
4588
|
-
createSelectorCreator({
|
|
4589
|
-
memoize: lruMemoize,
|
|
4590
|
-
memoizeOptions: {
|
|
4591
|
-
maxSize: 1,
|
|
4592
|
-
equalityCheck: Object.is
|
|
4593
|
-
}
|
|
4594
|
-
});
|
|
4595
4173
|
/**
|
|
4596
4174
|
* Creates a selector function that can be used to derive values from the store's state.
|
|
4597
|
-
*
|
|
4175
|
+
*
|
|
4176
|
+
* The combiner function can have up to three additional parameters, but it **cannot have optional or default parameters**.
|
|
4177
|
+
*
|
|
4598
4178
|
* This function accepts up to six functions and combines them into a single selector function.
|
|
4599
|
-
* The
|
|
4179
|
+
* The resulting selector will take the state from the combined selectors and any additional parameters required by the combiner.
|
|
4180
|
+
*
|
|
4181
|
+
* The return type of the resulting selector is determined by the return type of the combiner function.
|
|
4600
4182
|
*
|
|
4601
4183
|
* @example
|
|
4602
4184
|
* const selector = createSelector(
|
|
@@ -4609,7 +4191,6 @@ createSelectorCreator({
|
|
|
4609
4191
|
* (state) => state.open,
|
|
4610
4192
|
* (disabled, open) => ({ disabled, open })
|
|
4611
4193
|
* );
|
|
4612
|
-
*
|
|
4613
4194
|
*/
|
|
4614
4195
|
/* eslint-disable id-denylist */
|
|
4615
4196
|
const createSelector = (a, b, c, d, e, f, ...other) => {
|
|
@@ -4624,6 +4205,7 @@ const createSelector = (a, b, c, d, e, f, ...other) => {
|
|
|
4624
4205
|
}
|
|
4625
4206
|
return selector;
|
|
4626
4207
|
};
|
|
4208
|
+
/* eslint-enable id-denylist */
|
|
4627
4209
|
|
|
4628
4210
|
/* Some tests fail in R18 with the raw useSyncExternalStore. It may be possible to make it work
|
|
4629
4211
|
* but for now we only enable it for R19+. */
|
|
@@ -4931,6 +4513,7 @@ class ReactStore extends Store {
|
|
|
4931
4513
|
|
|
4932
4514
|
const selectors$1 = {
|
|
4933
4515
|
open: createSelector(state => state.open),
|
|
4516
|
+
transitionStatus: createSelector(state => state.transitionStatus),
|
|
4934
4517
|
domReferenceElement: createSelector(state => state.domReferenceElement),
|
|
4935
4518
|
referenceElement: createSelector(state => state.positionReference ?? state.referenceElement),
|
|
4936
4519
|
floatingElement: createSelector(state => state.floatingElement),
|
|
@@ -4939,8 +4522,8 @@ const selectors$1 = {
|
|
|
4939
4522
|
class FloatingRootStore extends ReactStore {
|
|
4940
4523
|
constructor(options) {
|
|
4941
4524
|
const {
|
|
4525
|
+
syncOnly,
|
|
4942
4526
|
nested,
|
|
4943
|
-
noEmit,
|
|
4944
4527
|
onOpenChange,
|
|
4945
4528
|
triggerElements,
|
|
4946
4529
|
...initialState
|
|
@@ -4956,11 +4539,38 @@ class FloatingRootStore extends ReactStore {
|
|
|
4956
4539
|
},
|
|
4957
4540
|
events: createEventEmitter(),
|
|
4958
4541
|
nested,
|
|
4959
|
-
noEmit,
|
|
4960
4542
|
triggerElements
|
|
4961
4543
|
}, selectors$1);
|
|
4544
|
+
this.syncOnly = syncOnly;
|
|
4962
4545
|
}
|
|
4963
4546
|
|
|
4547
|
+
/**
|
|
4548
|
+
* Syncs the event used by hover logic to distinguish hover-open from click-like interaction.
|
|
4549
|
+
*/
|
|
4550
|
+
syncOpenEvent = (newOpen, event) => {
|
|
4551
|
+
if (!newOpen || !this.state.open ||
|
|
4552
|
+
// Prevent a pending hover-open from overwriting a click-open event, while allowing
|
|
4553
|
+
// click events to upgrade a hover-open.
|
|
4554
|
+
event != null && isClickLikeEvent(event)) {
|
|
4555
|
+
this.context.dataRef.current.openEvent = newOpen ? event : undefined;
|
|
4556
|
+
}
|
|
4557
|
+
};
|
|
4558
|
+
|
|
4559
|
+
/**
|
|
4560
|
+
* Runs the root-owned side effects for an open state change.
|
|
4561
|
+
*/
|
|
4562
|
+
dispatchOpenChange = (newOpen, eventDetails) => {
|
|
4563
|
+
this.syncOpenEvent(newOpen, eventDetails.event);
|
|
4564
|
+
const details = {
|
|
4565
|
+
open: newOpen,
|
|
4566
|
+
reason: eventDetails.reason,
|
|
4567
|
+
nativeEvent: eventDetails.event,
|
|
4568
|
+
nested: this.context.nested,
|
|
4569
|
+
triggerElement: eventDetails.trigger
|
|
4570
|
+
};
|
|
4571
|
+
this.context.events.emit('openchange', details);
|
|
4572
|
+
};
|
|
4573
|
+
|
|
4964
4574
|
/**
|
|
4965
4575
|
* Emits the `openchange` event through the internal event emitter and calls the `onOpenChange` handler with the provided arguments.
|
|
4966
4576
|
*
|
|
@@ -4968,22 +4578,11 @@ class FloatingRootStore extends ReactStore {
|
|
|
4968
4578
|
* @param eventDetails Details about the event that triggered the open state change.
|
|
4969
4579
|
*/
|
|
4970
4580
|
setOpen = (newOpen, eventDetails) => {
|
|
4971
|
-
if (
|
|
4972
|
-
|
|
4973
|
-
|
|
4974
|
-
isClickLikeEvent(eventDetails.event)) {
|
|
4975
|
-
this.context.dataRef.current.openEvent = newOpen ? eventDetails.event : undefined;
|
|
4976
|
-
}
|
|
4977
|
-
if (!this.context.noEmit) {
|
|
4978
|
-
const details = {
|
|
4979
|
-
open: newOpen,
|
|
4980
|
-
reason: eventDetails.reason,
|
|
4981
|
-
nativeEvent: eventDetails.event,
|
|
4982
|
-
nested: this.context.nested,
|
|
4983
|
-
triggerElement: eventDetails.trigger
|
|
4984
|
-
};
|
|
4985
|
-
this.context.events.emit('openchange', details);
|
|
4581
|
+
if (this.syncOnly) {
|
|
4582
|
+
this.context.onOpenChange?.(newOpen, eventDetails);
|
|
4583
|
+
return;
|
|
4986
4584
|
}
|
|
4585
|
+
this.dispatchOpenChange(newOpen, eventDetails);
|
|
4987
4586
|
this.context.onOpenChange?.(newOpen, eventDetails);
|
|
4988
4587
|
};
|
|
4989
4588
|
}
|
|
@@ -5086,13 +4685,14 @@ function useFloatingRootContext(options) {
|
|
|
5086
4685
|
const nested = useFloatingParentNodeId() != null;
|
|
5087
4686
|
const store = useRefWithInit(() => new FloatingRootStore({
|
|
5088
4687
|
open,
|
|
4688
|
+
transitionStatus: undefined,
|
|
5089
4689
|
onOpenChange,
|
|
5090
4690
|
referenceElement: elements.reference ?? null,
|
|
5091
4691
|
floatingElement: elements.floating ?? null,
|
|
5092
4692
|
triggerElements: new PopupTriggerMap(),
|
|
5093
4693
|
floatingId,
|
|
5094
|
-
|
|
5095
|
-
|
|
4694
|
+
syncOnly: false,
|
|
4695
|
+
nested
|
|
5096
4696
|
})).current;
|
|
5097
4697
|
useIsoLayoutEffect(() => {
|
|
5098
4698
|
const valuesToSync = {
|
|
@@ -5112,7 +4712,6 @@ function useFloatingRootContext(options) {
|
|
|
5112
4712
|
}, [open, floatingId, elements.reference, elements.floating, store]);
|
|
5113
4713
|
store.context.onOpenChange = onOpenChange;
|
|
5114
4714
|
store.context.nested = nested;
|
|
5115
|
-
store.context.noEmit = false;
|
|
5116
4715
|
return store;
|
|
5117
4716
|
}
|
|
5118
4717
|
|
|
@@ -5160,10 +4759,11 @@ function useFloating(options = {}) {
|
|
|
5160
4759
|
setPositionReferenceRaw(computedPositionReference);
|
|
5161
4760
|
position.refs.setReference(computedPositionReference);
|
|
5162
4761
|
}, [position.refs]);
|
|
5163
|
-
const [localDomReference, setLocalDomReference] = React.useState(
|
|
4762
|
+
const [localDomReference, setLocalDomReference] = React.useState(undefined);
|
|
5164
4763
|
const [localFloatingElement, setLocalFloatingElement] = React.useState(null);
|
|
5165
|
-
rootContext.useSyncedValue('referenceElement', localDomReference);
|
|
5166
|
-
|
|
4764
|
+
rootContext.useSyncedValue('referenceElement', localDomReference ?? null);
|
|
4765
|
+
const localDomReferenceElement = isElement(localDomReference) ? localDomReference : null;
|
|
4766
|
+
rootContext.useSyncedValue('domReferenceElement', localDomReference === undefined ? rootContextElements.domReference : localDomReferenceElement);
|
|
5167
4767
|
rootContext.useSyncedValue('floatingElement', localFloatingElement);
|
|
5168
4768
|
const setReference = React.useCallback(node => {
|
|
5169
4769
|
if (isElement(node) || node === null) {
|
|
@@ -5313,6 +4913,17 @@ function mutablyMergeProps(outputProps, props, isItem, eventHandlers) {
|
|
|
5313
4913
|
}
|
|
5314
4914
|
}
|
|
5315
4915
|
|
|
4916
|
+
function isMouseWithinBounds(event) {
|
|
4917
|
+
const targetRect = event.currentTarget.getBoundingClientRect();
|
|
4918
|
+
|
|
4919
|
+
// Safari randomly fires `mouseleave` incorrectly when the item is
|
|
4920
|
+
// aligned to the trigger. This is a workaround to prevent the highlight
|
|
4921
|
+
// from being removed while the cursor is still within the bounds of the item.
|
|
4922
|
+
// https://github.com/mui/base-ui/issues/869
|
|
4923
|
+
const isWithinBounds = targetRect.top + 1 <= event.clientY && event.clientY <= targetRect.bottom - 1 && targetRect.left + 1 <= event.clientX && event.clientX <= targetRect.right - 1;
|
|
4924
|
+
return isWithinBounds;
|
|
4925
|
+
}
|
|
4926
|
+
|
|
5316
4927
|
const ESCAPE = 'Escape';
|
|
5317
4928
|
function doSwitch(orientation, vertical, horizontal) {
|
|
5318
4929
|
switch (orientation) {
|
|
@@ -5400,6 +5011,7 @@ function useListNavigation(context, props) {
|
|
|
5400
5011
|
const previousOpenRef = React.useRef(open);
|
|
5401
5012
|
const forceSyncFocusRef = React.useRef(false);
|
|
5402
5013
|
const forceScrollIntoViewRef = React.useRef(false);
|
|
5014
|
+
const cancelQueuedFocusRef = React.useRef(null);
|
|
5403
5015
|
const disabledIndicesRef = useValueAsRef(disabledIndices);
|
|
5404
5016
|
const latestOpenRef = useValueAsRef(open);
|
|
5405
5017
|
const selectedIndexRef = useValueAsRef(selectedIndex);
|
|
@@ -5409,7 +5021,7 @@ function useListNavigation(context, props) {
|
|
|
5409
5021
|
if (virtual) {
|
|
5410
5022
|
tree?.events.emit('virtualfocus', item);
|
|
5411
5023
|
} else {
|
|
5412
|
-
enqueueFocus(item, {
|
|
5024
|
+
cancelQueuedFocusRef.current = enqueueFocus(item, {
|
|
5413
5025
|
sync: forceSyncFocusRef.current,
|
|
5414
5026
|
preventScroll: true
|
|
5415
5027
|
});
|
|
@@ -5513,7 +5125,7 @@ function useListNavigation(context, props) {
|
|
|
5513
5125
|
};
|
|
5514
5126
|
waitForListPopulated();
|
|
5515
5127
|
}
|
|
5516
|
-
} else if (!isIndexOutOfListBounds(listRef, activeIndex)) {
|
|
5128
|
+
} else if (!isIndexOutOfListBounds(listRef.current, activeIndex)) {
|
|
5517
5129
|
indexRef.current = activeIndex;
|
|
5518
5130
|
focusItem();
|
|
5519
5131
|
forceScrollIntoViewRef.current = false;
|
|
@@ -5548,17 +5160,17 @@ function useListNavigation(context, props) {
|
|
|
5548
5160
|
}
|
|
5549
5161
|
}, [open, focusItemOnOpen]);
|
|
5550
5162
|
const hasActiveIndex = activeIndex != null;
|
|
5551
|
-
const
|
|
5552
|
-
|
|
5553
|
-
|
|
5554
|
-
|
|
5555
|
-
|
|
5556
|
-
|
|
5557
|
-
|
|
5558
|
-
|
|
5559
|
-
onNavigate(event);
|
|
5560
|
-
}
|
|
5163
|
+
const syncCurrentTarget = useStableCallback(event => {
|
|
5164
|
+
if (!latestOpenRef.current) {
|
|
5165
|
+
return;
|
|
5166
|
+
}
|
|
5167
|
+
const index = listRef.current.indexOf(event.currentTarget);
|
|
5168
|
+
if (index !== -1 && (indexRef.current !== index || activeIndex !== index)) {
|
|
5169
|
+
indexRef.current = index;
|
|
5170
|
+
onNavigate(event);
|
|
5561
5171
|
}
|
|
5172
|
+
});
|
|
5173
|
+
const item = React.useMemo(() => {
|
|
5562
5174
|
const itemProps = {
|
|
5563
5175
|
onFocus(event) {
|
|
5564
5176
|
forceSyncFocusRef.current = true;
|
|
@@ -5583,15 +5195,17 @@ function useListNavigation(context, props) {
|
|
|
5583
5195
|
}
|
|
5584
5196
|
forceSyncFocusRef.current = true;
|
|
5585
5197
|
const relatedTarget = event.relatedTarget;
|
|
5198
|
+
if (isMouseWithinBounds(event)) {
|
|
5199
|
+
return;
|
|
5200
|
+
}
|
|
5586
5201
|
if (!focusItemOnHover || listRef.current.includes(relatedTarget)) {
|
|
5587
5202
|
return;
|
|
5588
5203
|
}
|
|
5589
5204
|
if (!resetOnPointerLeaveRef.current) {
|
|
5590
5205
|
return;
|
|
5591
5206
|
}
|
|
5592
|
-
|
|
5593
|
-
|
|
5594
|
-
});
|
|
5207
|
+
cancelQueuedFocusRef.current?.();
|
|
5208
|
+
cancelQueuedFocusRef.current = null;
|
|
5595
5209
|
indexRef.current = -1;
|
|
5596
5210
|
onNavigate(event);
|
|
5597
5211
|
if (!virtual) {
|
|
@@ -5606,7 +5220,7 @@ function useListNavigation(context, props) {
|
|
|
5606
5220
|
}
|
|
5607
5221
|
};
|
|
5608
5222
|
return itemProps;
|
|
5609
|
-
}, [latestOpenRef, floatingFocusElementRef, focusItemOnHover, listRef, onNavigate, resetOnPointerLeaveRef, virtual]);
|
|
5223
|
+
}, [syncCurrentTarget, latestOpenRef, floatingFocusElementRef, focusItemOnHover, listRef, onNavigate, resetOnPointerLeaveRef, virtual]);
|
|
5610
5224
|
const getParentOrientation = React.useCallback(() => {
|
|
5611
5225
|
return parentOrientation ?? tree?.nodesRef.current.find(node => node.id === parentId)?.context?.dataRef?.current.orientation;
|
|
5612
5226
|
}, [parentId, tree, parentOrientation]);
|
|
@@ -5671,12 +5285,10 @@ function useListNavigation(context, props) {
|
|
|
5671
5285
|
// To calculate movements on the grid, we use hypothetical cell indices
|
|
5672
5286
|
// as if every item was 1x1, then convert back to real indices.
|
|
5673
5287
|
const cellMap = createGridCellMap(sizes, cols);
|
|
5674
|
-
const minGridIndex = cellMap.findIndex(index => index != null && !isListIndexDisabled(listRef, index, disabledIndices));
|
|
5288
|
+
const minGridIndex = cellMap.findIndex(index => index != null && !isListIndexDisabled(listRef.current, index, disabledIndices));
|
|
5675
5289
|
// last enabled index
|
|
5676
|
-
const maxGridIndex = cellMap.reduce((foundIndex, index, cellIndex) => index != null && !isListIndexDisabled(listRef, index, disabledIndices) ? cellIndex : foundIndex, -1);
|
|
5677
|
-
const index = cellMap[getGridNavigatedIndex({
|
|
5678
|
-
current: cellMap.map(itemIndex => itemIndex != null ? listRef.current[itemIndex] : null)
|
|
5679
|
-
}, {
|
|
5290
|
+
const maxGridIndex = cellMap.reduce((foundIndex, index, cellIndex) => index != null && !isListIndexDisabled(listRef.current, index, disabledIndices) ? cellIndex : foundIndex, -1);
|
|
5291
|
+
const index = cellMap[getGridNavigatedIndex(cellMap.map(itemIndex => itemIndex != null ? listRef.current[itemIndex] : null), {
|
|
5680
5292
|
event,
|
|
5681
5293
|
orientation,
|
|
5682
5294
|
loopFocus,
|
|
@@ -5684,7 +5296,7 @@ function useListNavigation(context, props) {
|
|
|
5684
5296
|
cols,
|
|
5685
5297
|
// treat undefined (empty grid spaces) as disabled indices so we
|
|
5686
5298
|
// don't end up in them
|
|
5687
|
-
disabledIndices: getGridCellIndices([...((typeof disabledIndices !== 'function' ? disabledIndices : null) || listRef.current.map((_, listIndex) => isListIndexDisabled(listRef, listIndex, disabledIndices) ? listIndex : undefined)), undefined], cellMap),
|
|
5299
|
+
disabledIndices: getGridCellIndices([...((typeof disabledIndices !== 'function' ? disabledIndices : null) || listRef.current.map((_, listIndex) => isListIndexDisabled(listRef.current, listIndex, disabledIndices) ? listIndex : undefined)), undefined], cellMap),
|
|
5688
5300
|
minIndex: minGridIndex,
|
|
5689
5301
|
maxIndex: maxGridIndex,
|
|
5690
5302
|
prevIndex: getGridCellIndexOfCorner(indexRef.current > maxIndex ? minIndex : indexRef.current, sizes, cellMap, cols,
|
|
@@ -5723,13 +5335,13 @@ function useListNavigation(context, props) {
|
|
|
5723
5335
|
indexRef.current = minIndex;
|
|
5724
5336
|
}
|
|
5725
5337
|
} else {
|
|
5726
|
-
indexRef.current = findNonDisabledListIndex(listRef, {
|
|
5338
|
+
indexRef.current = findNonDisabledListIndex(listRef.current, {
|
|
5727
5339
|
startingIndex: currentIndex,
|
|
5728
5340
|
disabledIndices
|
|
5729
5341
|
});
|
|
5730
5342
|
}
|
|
5731
5343
|
} else {
|
|
5732
|
-
indexRef.current = Math.min(maxIndex, findNonDisabledListIndex(listRef, {
|
|
5344
|
+
indexRef.current = Math.min(maxIndex, findNonDisabledListIndex(listRef.current, {
|
|
5733
5345
|
startingIndex: currentIndex,
|
|
5734
5346
|
disabledIndices
|
|
5735
5347
|
}));
|
|
@@ -5744,20 +5356,20 @@ function useListNavigation(context, props) {
|
|
|
5744
5356
|
indexRef.current = maxIndex;
|
|
5745
5357
|
}
|
|
5746
5358
|
} else {
|
|
5747
|
-
indexRef.current = findNonDisabledListIndex(listRef, {
|
|
5359
|
+
indexRef.current = findNonDisabledListIndex(listRef.current, {
|
|
5748
5360
|
startingIndex: currentIndex,
|
|
5749
5361
|
decrement: true,
|
|
5750
5362
|
disabledIndices
|
|
5751
5363
|
});
|
|
5752
5364
|
}
|
|
5753
5365
|
} else {
|
|
5754
|
-
indexRef.current = Math.max(minIndex, findNonDisabledListIndex(listRef, {
|
|
5366
|
+
indexRef.current = Math.max(minIndex, findNonDisabledListIndex(listRef.current, {
|
|
5755
5367
|
startingIndex: currentIndex,
|
|
5756
5368
|
decrement: true,
|
|
5757
5369
|
disabledIndices
|
|
5758
5370
|
}));
|
|
5759
5371
|
}
|
|
5760
|
-
if (isIndexOutOfListBounds(listRef, indexRef.current)) {
|
|
5372
|
+
if (isIndexOutOfListBounds(listRef.current, indexRef.current)) {
|
|
5761
5373
|
indexRef.current = -1;
|
|
5762
5374
|
}
|
|
5763
5375
|
onNavigate(event);
|
|
@@ -6240,19 +5852,8 @@ const InternalBackdrop = /*#__PURE__*/React.forwardRef(function InternalBackdrop
|
|
|
6240
5852
|
} = props;
|
|
6241
5853
|
let clipPath;
|
|
6242
5854
|
if (cutout) {
|
|
6243
|
-
const rect = cutout
|
|
6244
|
-
clipPath = `polygon(
|
|
6245
|
-
0% 0%,
|
|
6246
|
-
100% 0%,
|
|
6247
|
-
100% 100%,
|
|
6248
|
-
0% 100%,
|
|
6249
|
-
0% 0%,
|
|
6250
|
-
${rect.left}px ${rect.top}px,
|
|
6251
|
-
${rect.left}px ${rect.bottom}px,
|
|
6252
|
-
${rect.right}px ${rect.bottom}px,
|
|
6253
|
-
${rect.right}px ${rect.top}px,
|
|
6254
|
-
${rect.left}px ${rect.top}px
|
|
6255
|
-
)`;
|
|
5855
|
+
const rect = cutout.getBoundingClientRect();
|
|
5856
|
+
clipPath = `polygon(0% 0%,100% 0%,100% 100%,0% 100%,0% 0%,${rect.left}px ${rect.top}px,${rect.left}px ${rect.bottom}px,${rect.right}px ${rect.bottom}px,${rect.right}px ${rect.top}px,${rect.left}px ${rect.top}px)`;
|
|
6256
5857
|
}
|
|
6257
5858
|
return /*#__PURE__*/jsx("div", {
|
|
6258
5859
|
ref: ref,
|
|
@@ -6272,14 +5873,6 @@ const InternalBackdrop = /*#__PURE__*/React.forwardRef(function InternalBackdrop
|
|
|
6272
5873
|
});
|
|
6273
5874
|
});
|
|
6274
5875
|
|
|
6275
|
-
function useOnFirstRender(fn) {
|
|
6276
|
-
const ref = React.useRef(true);
|
|
6277
|
-
if (ref.current) {
|
|
6278
|
-
ref.current = false;
|
|
6279
|
-
fn();
|
|
6280
|
-
}
|
|
6281
|
-
}
|
|
6282
|
-
|
|
6283
5876
|
const ComboboxRootContext = /*#__PURE__*/React.createContext(undefined);
|
|
6284
5877
|
const ComboboxFloatingContext = /*#__PURE__*/React.createContext(undefined);
|
|
6285
5878
|
const ComboboxDerivedItemsContext = /*#__PURE__*/React.createContext(undefined);
|
|
@@ -6463,7 +6056,6 @@ function resolveMultipleLabels(values, items, itemToStringLabel) {
|
|
|
6463
6056
|
const selectors = {
|
|
6464
6057
|
id: createSelector(state => state.id),
|
|
6465
6058
|
labelId: createSelector(state => state.labelId),
|
|
6466
|
-
query: createSelector(state => state.query),
|
|
6467
6059
|
items: createSelector(state => state.items),
|
|
6468
6060
|
selectedValue: createSelector(state => state.selectedValue),
|
|
6469
6061
|
hasSelectionChips: createSelector(state => {
|
|
@@ -6515,25 +6107,13 @@ const selectors = {
|
|
|
6515
6107
|
openMethod: createSelector(state => state.openMethod),
|
|
6516
6108
|
inputInsidePopup: createSelector(state => state.inputInsidePopup),
|
|
6517
6109
|
selectionMode: createSelector(state => state.selectionMode),
|
|
6518
|
-
listRef: createSelector(state => state.listRef),
|
|
6519
|
-
labelsRef: createSelector(state => state.labelsRef),
|
|
6520
|
-
popupRef: createSelector(state => state.popupRef),
|
|
6521
|
-
emptyRef: createSelector(state => state.emptyRef),
|
|
6522
|
-
inputRef: createSelector(state => state.inputRef),
|
|
6523
|
-
keyboardActiveRef: createSelector(state => state.keyboardActiveRef),
|
|
6524
|
-
chipsContainerRef: createSelector(state => state.chipsContainerRef),
|
|
6525
|
-
clearRef: createSelector(state => state.clearRef),
|
|
6526
|
-
valuesRef: createSelector(state => state.valuesRef),
|
|
6527
|
-
allValuesRef: createSelector(state => state.allValuesRef),
|
|
6528
6110
|
name: createSelector(state => state.name),
|
|
6111
|
+
form: createSelector(state => state.form),
|
|
6529
6112
|
disabled: createSelector(state => state.disabled),
|
|
6530
6113
|
readOnly: createSelector(state => state.readOnly),
|
|
6531
6114
|
required: createSelector(state => state.required),
|
|
6532
6115
|
grid: createSelector(state => state.grid),
|
|
6533
|
-
isGrouped: createSelector(state => state.isGrouped),
|
|
6534
6116
|
virtualized: createSelector(state => state.virtualized),
|
|
6535
|
-
onOpenChangeComplete: createSelector(state => state.onOpenChangeComplete),
|
|
6536
|
-
openOnInputClick: createSelector(state => state.openOnInputClick),
|
|
6537
6117
|
itemToStringLabel: createSelector(state => state.itemToStringLabel),
|
|
6538
6118
|
isItemEqualToValue: createSelector(state => state.isItemEqualToValue),
|
|
6539
6119
|
modal: createSelector(state => state.modal),
|
|
@@ -6641,6 +6221,7 @@ const FieldRootContext = /*#__PURE__*/React.createContext({
|
|
|
6641
6221
|
markedDirtyRef: {
|
|
6642
6222
|
current: false
|
|
6643
6223
|
},
|
|
6224
|
+
registerFieldControl: NOOP,
|
|
6644
6225
|
validation: {
|
|
6645
6226
|
getValidationProps: (props = EMPTY_OBJECT) => props,
|
|
6646
6227
|
getInputValidationProps: (props = EMPTY_OBJECT) => props,
|
|
@@ -6658,18 +6239,35 @@ function useFieldRootContext(optional = true) {
|
|
|
6658
6239
|
return context;
|
|
6659
6240
|
}
|
|
6660
6241
|
|
|
6661
|
-
|
|
6662
|
-
|
|
6663
|
-
|
|
6664
|
-
|
|
6665
|
-
|
|
6666
|
-
|
|
6667
|
-
|
|
6668
|
-
|
|
6669
|
-
|
|
6670
|
-
|
|
6242
|
+
function useRegisterFieldControl(controlRef, params) {
|
|
6243
|
+
const {
|
|
6244
|
+
enabled = true,
|
|
6245
|
+
getValue,
|
|
6246
|
+
id,
|
|
6247
|
+
value
|
|
6248
|
+
} = params;
|
|
6249
|
+
const {
|
|
6250
|
+
registerFieldControl
|
|
6251
|
+
} = useFieldRootContext();
|
|
6252
|
+
const sourceRef = React.useRef(null);
|
|
6253
|
+
if (!sourceRef.current) {
|
|
6254
|
+
sourceRef.current = Symbol();
|
|
6255
|
+
}
|
|
6256
|
+
useIsoLayoutEffect(() => {
|
|
6257
|
+
const source = sourceRef.current;
|
|
6258
|
+
if (!source || !enabled) {
|
|
6259
|
+
return undefined;
|
|
6671
6260
|
}
|
|
6672
|
-
|
|
6261
|
+
registerFieldControl(source, {
|
|
6262
|
+
controlRef,
|
|
6263
|
+
getValue,
|
|
6264
|
+
id,
|
|
6265
|
+
value
|
|
6266
|
+
});
|
|
6267
|
+
return () => {
|
|
6268
|
+
registerFieldControl(source, undefined);
|
|
6269
|
+
};
|
|
6270
|
+
}, [controlRef, enabled, getValue, id, registerFieldControl, value]);
|
|
6673
6271
|
}
|
|
6674
6272
|
|
|
6675
6273
|
const FormContext = /*#__PURE__*/React.createContext({
|
|
@@ -6689,74 +6287,6 @@ function useFormContext() {
|
|
|
6689
6287
|
return React.useContext(FormContext);
|
|
6690
6288
|
}
|
|
6691
6289
|
|
|
6692
|
-
function useField(params) {
|
|
6693
|
-
const {
|
|
6694
|
-
enabled = true,
|
|
6695
|
-
value,
|
|
6696
|
-
id,
|
|
6697
|
-
name,
|
|
6698
|
-
controlRef,
|
|
6699
|
-
commit
|
|
6700
|
-
} = params;
|
|
6701
|
-
const {
|
|
6702
|
-
formRef
|
|
6703
|
-
} = useFormContext();
|
|
6704
|
-
const {
|
|
6705
|
-
invalid,
|
|
6706
|
-
markedDirtyRef,
|
|
6707
|
-
validityData,
|
|
6708
|
-
setValidityData
|
|
6709
|
-
} = useFieldRootContext();
|
|
6710
|
-
const getValue = useStableCallback(params.getValue);
|
|
6711
|
-
useIsoLayoutEffect(() => {
|
|
6712
|
-
if (!enabled) {
|
|
6713
|
-
return;
|
|
6714
|
-
}
|
|
6715
|
-
let initialValue = value;
|
|
6716
|
-
if (initialValue === undefined) {
|
|
6717
|
-
initialValue = getValue();
|
|
6718
|
-
}
|
|
6719
|
-
if (validityData.initialValue === null && initialValue !== null) {
|
|
6720
|
-
setValidityData(prev => ({
|
|
6721
|
-
...prev,
|
|
6722
|
-
initialValue
|
|
6723
|
-
}));
|
|
6724
|
-
}
|
|
6725
|
-
}, [enabled, setValidityData, value, validityData.initialValue, getValue]);
|
|
6726
|
-
useIsoLayoutEffect(() => {
|
|
6727
|
-
if (!enabled || !id) {
|
|
6728
|
-
return;
|
|
6729
|
-
}
|
|
6730
|
-
formRef.current.fields.set(id, {
|
|
6731
|
-
getValue,
|
|
6732
|
-
name,
|
|
6733
|
-
controlRef,
|
|
6734
|
-
validityData: getCombinedFieldValidityData(validityData, invalid),
|
|
6735
|
-
validate(flushSync = true) {
|
|
6736
|
-
let nextValue = value;
|
|
6737
|
-
if (nextValue === undefined) {
|
|
6738
|
-
nextValue = getValue();
|
|
6739
|
-
}
|
|
6740
|
-
markedDirtyRef.current = true;
|
|
6741
|
-
if (!flushSync) {
|
|
6742
|
-
commit(nextValue);
|
|
6743
|
-
} else {
|
|
6744
|
-
// Synchronously update the validity state so the submit event can be prevented.
|
|
6745
|
-
ReactDOM.flushSync(() => commit(nextValue));
|
|
6746
|
-
}
|
|
6747
|
-
}
|
|
6748
|
-
});
|
|
6749
|
-
}, [commit, controlRef, enabled, formRef, getValue, id, invalid, markedDirtyRef, name, validityData, value]);
|
|
6750
|
-
useIsoLayoutEffect(() => {
|
|
6751
|
-
const fields = formRef.current.fields;
|
|
6752
|
-
return () => {
|
|
6753
|
-
if (id) {
|
|
6754
|
-
fields.delete(id);
|
|
6755
|
-
}
|
|
6756
|
-
};
|
|
6757
|
-
}, [formRef, id]);
|
|
6758
|
-
}
|
|
6759
|
-
|
|
6760
6290
|
/**
|
|
6761
6291
|
* A context for providing [labelable elements](https://html.spec.whatwg.org/multipage/forms.html#category-label)\
|
|
6762
6292
|
* with an accessible name (label) and description.
|
|
@@ -6946,9 +6476,12 @@ function AriaCombobox(props) {
|
|
|
6946
6476
|
onSelectedValueChange,
|
|
6947
6477
|
defaultInputValue: defaultInputValueProp,
|
|
6948
6478
|
inputValue: inputValueProp,
|
|
6479
|
+
open: openProp,
|
|
6480
|
+
defaultOpen = false,
|
|
6949
6481
|
selectionMode = 'none',
|
|
6950
6482
|
onItemHighlighted: onItemHighlightedProp,
|
|
6951
6483
|
name: nameProp,
|
|
6484
|
+
form,
|
|
6952
6485
|
disabled: disabledProp = false,
|
|
6953
6486
|
readOnly = false,
|
|
6954
6487
|
required = false,
|
|
@@ -7074,8 +6607,8 @@ function AriaCombobox(props) {
|
|
|
7074
6607
|
state: 'inputValue'
|
|
7075
6608
|
});
|
|
7076
6609
|
const [open, setOpenUnwrapped] = useControlled({
|
|
7077
|
-
controlled:
|
|
7078
|
-
default:
|
|
6610
|
+
controlled: openProp,
|
|
6611
|
+
default: defaultOpen,
|
|
7079
6612
|
name: 'Combobox',
|
|
7080
6613
|
state: 'open'
|
|
7081
6614
|
});
|
|
@@ -7177,6 +6710,7 @@ function AriaCombobox(props) {
|
|
|
7177
6710
|
allValuesRef,
|
|
7178
6711
|
selectionEventRef,
|
|
7179
6712
|
name,
|
|
6713
|
+
form,
|
|
7180
6714
|
disabled,
|
|
7181
6715
|
readOnly,
|
|
7182
6716
|
required,
|
|
@@ -7250,13 +6784,11 @@ function AriaCombobox(props) {
|
|
|
7250
6784
|
openMethod,
|
|
7251
6785
|
triggerProps
|
|
7252
6786
|
} = useOpenInteractionType(open);
|
|
7253
|
-
|
|
6787
|
+
const getFieldValue = useStableCallback(() => fieldStringValue);
|
|
6788
|
+
useRegisterFieldControl(inputInsidePopup ? triggerRef : inputRef, {
|
|
7254
6789
|
id,
|
|
7255
|
-
name,
|
|
7256
|
-
commit: validation.commit,
|
|
7257
6790
|
value: fieldRawValue,
|
|
7258
|
-
|
|
7259
|
-
getValue: () => fieldStringValue
|
|
6791
|
+
getValue: getFieldValue
|
|
7260
6792
|
});
|
|
7261
6793
|
const forceMount = useStableCallback(() => {
|
|
7262
6794
|
if (items) {
|
|
@@ -7437,9 +6969,9 @@ function AriaCombobox(props) {
|
|
|
7437
6969
|
if (!store.state.submitOnItemClick) {
|
|
7438
6970
|
return;
|
|
7439
6971
|
}
|
|
7440
|
-
const
|
|
7441
|
-
if (
|
|
7442
|
-
|
|
6972
|
+
const formElement = validation.inputRef.current?.form ?? store.state.inputElement?.form;
|
|
6973
|
+
if (formElement && typeof formElement.requestSubmit === 'function') {
|
|
6974
|
+
formElement.requestSubmit();
|
|
7443
6975
|
}
|
|
7444
6976
|
});
|
|
7445
6977
|
const handleUnmount = useStableCallback(() => {
|
|
@@ -7694,9 +7226,9 @@ function AriaCombobox(props) {
|
|
|
7694
7226
|
enabled: !readOnly && !disabled && openOnInputClick,
|
|
7695
7227
|
event: 'mousedown-only',
|
|
7696
7228
|
toggle: false,
|
|
7697
|
-
// Apply a small delay for touch to let
|
|
7229
|
+
// Apply a small delay for touch to let mobile viewport/keyboard positioning settle.
|
|
7698
7230
|
// This avoids top-bottom flip flickers if the preferred position is "top" when first tapping.
|
|
7699
|
-
touchOpenDelay: inputInsidePopup ? 0 :
|
|
7231
|
+
touchOpenDelay: inputInsidePopup ? 0 : 100,
|
|
7700
7232
|
reason: inputPress
|
|
7701
7233
|
});
|
|
7702
7234
|
const dismiss = useDismiss(floatingRootContext, {
|
|
@@ -7789,6 +7321,7 @@ function AriaCombobox(props) {
|
|
|
7789
7321
|
getItemProps,
|
|
7790
7322
|
selectionMode,
|
|
7791
7323
|
name,
|
|
7324
|
+
form,
|
|
7792
7325
|
disabled,
|
|
7793
7326
|
readOnly,
|
|
7794
7327
|
required,
|
|
@@ -7805,7 +7338,7 @@ function AriaCombobox(props) {
|
|
|
7805
7338
|
hasInputValue,
|
|
7806
7339
|
requestSubmit
|
|
7807
7340
|
});
|
|
7808
|
-
}, [store, id, selectedValue, open, mounted, transitionStatus, items, getFloatingProps, getReferenceProps, getItemProps, openMethod, triggerProps, selectionMode, name, disabled, readOnly, required, validation, grid, isGrouped, virtualized, onOpenChangeComplete, openOnInputClick, itemToStringLabel, modal, isItemEqualToValue, submitOnItemClick, hasInputValue, inlineProp, requestSubmit, autoHighlightMode]);
|
|
7341
|
+
}, [store, id, selectedValue, open, mounted, transitionStatus, items, getFloatingProps, getReferenceProps, getItemProps, openMethod, triggerProps, selectionMode, name, disabled, readOnly, required, validation, grid, isGrouped, virtualized, onOpenChangeComplete, openOnInputClick, itemToStringLabel, modal, isItemEqualToValue, submitOnItemClick, hasInputValue, inlineProp, requestSubmit, autoHighlightMode, form]);
|
|
7809
7342
|
const hiddenInputRef = useMergedRefs(inputRefProp, validation.inputRef);
|
|
7810
7343
|
const itemsContextValue = React.useMemo(() => ({
|
|
7811
7344
|
query,
|
|
@@ -7829,11 +7362,12 @@ function AriaCombobox(props) {
|
|
|
7829
7362
|
const currentSerializedValue = stringifyAsValue(value, itemToStringValue);
|
|
7830
7363
|
return /*#__PURE__*/jsx("input", {
|
|
7831
7364
|
type: "hidden",
|
|
7365
|
+
form: form,
|
|
7832
7366
|
name: name,
|
|
7833
7367
|
value: currentSerializedValue
|
|
7834
7368
|
}, currentSerializedValue);
|
|
7835
7369
|
});
|
|
7836
|
-
}, [multiple, selectedValue, name, itemToStringValue]);
|
|
7370
|
+
}, [multiple, selectedValue, form, name, itemToStringValue]);
|
|
7837
7371
|
const children = /*#__PURE__*/jsxs(React.Fragment, {
|
|
7838
7372
|
children: [props.children, /*#__PURE__*/jsx("input", {
|
|
7839
7373
|
...validation.getInputValidationProps({
|
|
@@ -7851,7 +7385,7 @@ function AriaCombobox(props) {
|
|
|
7851
7385
|
if (event.nativeEvent.defaultPrevented) {
|
|
7852
7386
|
return;
|
|
7853
7387
|
}
|
|
7854
|
-
const nextValue = event.
|
|
7388
|
+
const nextValue = event.currentTarget.value;
|
|
7855
7389
|
const details = createChangeEventDetails(none, event.nativeEvent);
|
|
7856
7390
|
function handleChange() {
|
|
7857
7391
|
// Browser autofill only writes a single scalar value.
|
|
@@ -7867,8 +7401,15 @@ function AriaCombobox(props) {
|
|
|
7867
7401
|
return;
|
|
7868
7402
|
}
|
|
7869
7403
|
const matchingValue = valuesRef.current.find(v => {
|
|
7870
|
-
|
|
7871
|
-
|
|
7404
|
+
// Try matching by value first (e.g., "US" for country code)
|
|
7405
|
+
const candidateValue = stringifyAsValue(v, itemToStringValue);
|
|
7406
|
+
if (candidateValue.toLowerCase() === nextValue.toLowerCase()) {
|
|
7407
|
+
return true;
|
|
7408
|
+
}
|
|
7409
|
+
// Also try matching by label for browser autofill compatibility
|
|
7410
|
+
// (browsers autofill with displayed text like "United States", not the underlying value)
|
|
7411
|
+
const candidateLabel = stringifyAsLabel(v, itemToStringLabel);
|
|
7412
|
+
if (candidateLabel.toLowerCase() === nextValue.toLowerCase()) {
|
|
7872
7413
|
return true;
|
|
7873
7414
|
}
|
|
7874
7415
|
return false;
|
|
@@ -7890,6 +7431,7 @@ function AriaCombobox(props) {
|
|
|
7890
7431
|
}
|
|
7891
7432
|
}),
|
|
7892
7433
|
id: id && hiddenInputName == null ? `${id}-hidden-input` : undefined,
|
|
7434
|
+
form: form,
|
|
7893
7435
|
name: hiddenInputName,
|
|
7894
7436
|
autoComplete: formAutoComplete,
|
|
7895
7437
|
disabled: disabled,
|
|
@@ -7899,7 +7441,8 @@ function AriaCombobox(props) {
|
|
|
7899
7441
|
ref: hiddenInputRef,
|
|
7900
7442
|
style: hiddenInputName ? visuallyHiddenInput : visuallyHidden,
|
|
7901
7443
|
tabIndex: -1,
|
|
7902
|
-
"aria-hidden": true
|
|
7444
|
+
"aria-hidden": true,
|
|
7445
|
+
suppressHydrationWarning: true
|
|
7903
7446
|
}), hiddenInputs]
|
|
7904
7447
|
});
|
|
7905
7448
|
return /*#__PURE__*/jsx(ComboboxRootContext.Provider, {
|
|
@@ -7930,8 +7473,9 @@ const triggerStateAttributesMapping = {
|
|
|
7930
7473
|
|
|
7931
7474
|
function getPseudoElementBounds(element) {
|
|
7932
7475
|
const elementRect = element.getBoundingClientRect();
|
|
7933
|
-
const
|
|
7934
|
-
const
|
|
7476
|
+
const win = getWindow(element);
|
|
7477
|
+
const beforeStyles = win.getComputedStyle(element, '::before');
|
|
7478
|
+
const afterStyles = win.getComputedStyle(element, '::after');
|
|
7935
7479
|
const hasPseudoElements = beforeStyles.content !== 'none' || afterStyles.content !== 'none';
|
|
7936
7480
|
if (!hasPseudoElements) {
|
|
7937
7481
|
return elementRect;
|
|
@@ -7967,6 +7511,8 @@ const BOUNDARY_OFFSET = 2;
|
|
|
7967
7511
|
/**
|
|
7968
7512
|
* A button that opens the popup.
|
|
7969
7513
|
* Renders a `<button>` element.
|
|
7514
|
+
*
|
|
7515
|
+
* Documentation: [Base UI Combobox](https://base-ui.com/react/components/combobox)
|
|
7970
7516
|
*/
|
|
7971
7517
|
const ComboboxTrigger$2 = /*#__PURE__*/React.forwardRef(function ComboboxTrigger(componentProps, forwardedRef) {
|
|
7972
7518
|
const {
|
|
@@ -7975,6 +7521,7 @@ const ComboboxTrigger$2 = /*#__PURE__*/React.forwardRef(function ComboboxTrigger
|
|
|
7975
7521
|
nativeButton = true,
|
|
7976
7522
|
disabled: disabledProp = false,
|
|
7977
7523
|
id: idProp,
|
|
7524
|
+
style,
|
|
7978
7525
|
...elementProps
|
|
7979
7526
|
} = componentProps;
|
|
7980
7527
|
const {
|
|
@@ -8070,7 +7617,7 @@ const ComboboxTrigger$2 = /*#__PURE__*/React.forwardRef(function ComboboxTrigger
|
|
|
8070
7617
|
disabled,
|
|
8071
7618
|
popupSide,
|
|
8072
7619
|
listEmpty,
|
|
8073
|
-
placeholder: !hasSelectedValue
|
|
7620
|
+
placeholder: selectionMode === 'none' ? false : !hasSelectedValue
|
|
8074
7621
|
};
|
|
8075
7622
|
const setTriggerElement = useStableCallback(element => {
|
|
8076
7623
|
store.set('triggerElement', element);
|
|
@@ -8215,6 +7762,7 @@ const ComboboxInput$2 = /*#__PURE__*/React.forwardRef(function ComboboxInput(com
|
|
|
8215
7762
|
className,
|
|
8216
7763
|
disabled: disabledProp = false,
|
|
8217
7764
|
id: idProp,
|
|
7765
|
+
style,
|
|
8218
7766
|
...elementProps
|
|
8219
7767
|
} = componentProps;
|
|
8220
7768
|
const {
|
|
@@ -8243,6 +7791,7 @@ const ComboboxInput$2 = /*#__PURE__*/React.forwardRef(function ComboboxInput(com
|
|
|
8243
7791
|
const comboboxDisabled = useStore(store, selectors.disabled);
|
|
8244
7792
|
const readOnly = useStore(store, selectors.readOnly);
|
|
8245
7793
|
const name = useStore(store, selectors.name);
|
|
7794
|
+
const form = useStore(store, selectors.form);
|
|
8246
7795
|
const selectionMode = useStore(store, selectors.selectionMode);
|
|
8247
7796
|
const autoHighlightMode = useStore(store, selectors.autoHighlight);
|
|
8248
7797
|
const inputProps = useStore(store, selectors.inputProps);
|
|
@@ -8295,6 +7844,7 @@ const ComboboxInput$2 = /*#__PURE__*/React.forwardRef(function ComboboxInput(com
|
|
|
8295
7844
|
const {
|
|
8296
7845
|
highlightedChipIndex
|
|
8297
7846
|
} = comboboxChipsContext;
|
|
7847
|
+
const renderedChipsCount = comboboxChipsContext.chipsRef.current.length;
|
|
8298
7848
|
if (highlightedChipIndex !== undefined) {
|
|
8299
7849
|
if (event.key === 'ArrowLeft') {
|
|
8300
7850
|
event.preventDefault();
|
|
@@ -8305,7 +7855,7 @@ const ComboboxInput$2 = /*#__PURE__*/React.forwardRef(function ComboboxInput(com
|
|
|
8305
7855
|
}
|
|
8306
7856
|
} else if (event.key === 'ArrowRight') {
|
|
8307
7857
|
event.preventDefault();
|
|
8308
|
-
if (highlightedChipIndex <
|
|
7858
|
+
if (highlightedChipIndex < renderedChipsCount - 1) {
|
|
8309
7859
|
nextIndex = highlightedChipIndex + 1;
|
|
8310
7860
|
} else {
|
|
8311
7861
|
nextIndex = undefined;
|
|
@@ -8328,8 +7878,7 @@ const ComboboxInput$2 = /*#__PURE__*/React.forwardRef(function ComboboxInput(com
|
|
|
8328
7878
|
// Handle navigation when no chip is highlighted
|
|
8329
7879
|
if (event.key === 'ArrowLeft' && (event.currentTarget.selectionStart ?? 0) === 0 && selectedValue.length > 0) {
|
|
8330
7880
|
event.preventDefault();
|
|
8331
|
-
|
|
8332
|
-
nextIndex = lastChipIndex;
|
|
7881
|
+
nextIndex = renderedChipsCount > 0 ? renderedChipsCount - 1 : undefined;
|
|
8333
7882
|
} else if (event.key === 'Backspace' && event.currentTarget.value === '' && selectedValue.length > 0) {
|
|
8334
7883
|
store.state.setIndices({
|
|
8335
7884
|
activeIndex: null,
|
|
@@ -8352,6 +7901,7 @@ const ComboboxInput$2 = /*#__PURE__*/React.forwardRef(function ComboboxInput(com
|
|
|
8352
7901
|
disabled,
|
|
8353
7902
|
readOnly,
|
|
8354
7903
|
required: selectionMode === 'none' ? required : undefined,
|
|
7904
|
+
form,
|
|
8355
7905
|
...(selectionMode === 'none' && name && {
|
|
8356
7906
|
name
|
|
8357
7907
|
}),
|
|
@@ -8519,7 +8069,9 @@ const ComboboxInput$2 = /*#__PURE__*/React.forwardRef(function ComboboxInput(com
|
|
|
8519
8069
|
|
|
8520
8070
|
// Handle deletion when no chip is highlighted and the input is empty.
|
|
8521
8071
|
if (comboboxChipsContext && event.key === 'Backspace' && input.value === '' && comboboxChipsContext.highlightedChipIndex === undefined && Array.isArray(selectedValue) && selectedValue.length > 0) {
|
|
8522
|
-
const
|
|
8072
|
+
const renderedChipsCount = comboboxChipsContext.chipsRef.current.length;
|
|
8073
|
+
const removalIndex = renderedChipsCount > 0 ? renderedChipsCount - 1 : selectedValue.length - 1;
|
|
8074
|
+
const newValue = selectedValue.filter((_, index) => index !== removalIndex);
|
|
8523
8075
|
// If the removed item was also the active (highlighted) item, clear highlight
|
|
8524
8076
|
store.state.setIndices({
|
|
8525
8077
|
activeIndex: null,
|
|
@@ -8579,6 +8131,25 @@ const ComboboxInput$2 = /*#__PURE__*/React.forwardRef(function ComboboxInput(com
|
|
|
8579
8131
|
});
|
|
8580
8132
|
});
|
|
8581
8133
|
|
|
8134
|
+
function handleInputPress(event, store, disabled, readOnly, shouldIgnoreTarget) {
|
|
8135
|
+
if (event.baseUIHandlerPrevented || readOnly) {
|
|
8136
|
+
return;
|
|
8137
|
+
}
|
|
8138
|
+
const target = getTarget(event.nativeEvent);
|
|
8139
|
+
const targetElement = isElement(target) ? target : null;
|
|
8140
|
+
if (targetElement !== event.currentTarget && (isInteractiveElement(targetElement))) {
|
|
8141
|
+
return;
|
|
8142
|
+
}
|
|
8143
|
+
event.preventDefault();
|
|
8144
|
+
if (disabled) {
|
|
8145
|
+
return;
|
|
8146
|
+
}
|
|
8147
|
+
store.state.inputRef.current?.focus();
|
|
8148
|
+
if (store.state.openOnInputClick) {
|
|
8149
|
+
store.state.setOpen(true, createChangeEventDetails(inputPress, event.nativeEvent));
|
|
8150
|
+
}
|
|
8151
|
+
}
|
|
8152
|
+
|
|
8582
8153
|
const stateAttributesMapping$1 = {
|
|
8583
8154
|
...transitionStatusMapping,
|
|
8584
8155
|
...triggerOpenStateMapping
|
|
@@ -8587,6 +8158,8 @@ const stateAttributesMapping$1 = {
|
|
|
8587
8158
|
/**
|
|
8588
8159
|
* Clears the value when clicked.
|
|
8589
8160
|
* Renders a `<button>` element.
|
|
8161
|
+
*
|
|
8162
|
+
* Documentation: [Base UI Combobox](https://base-ui.com/react/components/combobox)
|
|
8590
8163
|
*/
|
|
8591
8164
|
const ComboboxClear$1 = /*#__PURE__*/React.forwardRef(function ComboboxClear(componentProps, forwardedRef) {
|
|
8592
8165
|
const {
|
|
@@ -8595,6 +8168,7 @@ const ComboboxClear$1 = /*#__PURE__*/React.forwardRef(function ComboboxClear(com
|
|
|
8595
8168
|
disabled: disabledProp = false,
|
|
8596
8169
|
nativeButton = true,
|
|
8597
8170
|
keepMounted = false,
|
|
8171
|
+
style,
|
|
8598
8172
|
...elementProps
|
|
8599
8173
|
} = componentProps;
|
|
8600
8174
|
const {
|
|
@@ -8724,6 +8298,7 @@ const ComboboxList$2 = /*#__PURE__*/React.forwardRef(function ComboboxList(compo
|
|
|
8724
8298
|
const {
|
|
8725
8299
|
render,
|
|
8726
8300
|
className,
|
|
8301
|
+
style,
|
|
8727
8302
|
children,
|
|
8728
8303
|
...elementProps
|
|
8729
8304
|
} = componentProps;
|
|
@@ -8731,16 +8306,12 @@ const ComboboxList$2 = /*#__PURE__*/React.forwardRef(function ComboboxList(compo
|
|
|
8731
8306
|
const floatingRootContext = useComboboxFloatingContext();
|
|
8732
8307
|
const hasPositionerContext = Boolean(useComboboxPositionerContext(true));
|
|
8733
8308
|
const {
|
|
8734
|
-
filteredItems
|
|
8309
|
+
filteredItems,
|
|
8310
|
+
hasItems
|
|
8735
8311
|
} = useComboboxDerivedItemsContext();
|
|
8736
|
-
const items = useStore(store, selectors.items);
|
|
8737
|
-
const labelsRef = useStore(store, selectors.labelsRef);
|
|
8738
|
-
const listRef = useStore(store, selectors.listRef);
|
|
8739
8312
|
const selectionMode = useStore(store, selectors.selectionMode);
|
|
8740
8313
|
const grid = useStore(store, selectors.grid);
|
|
8741
8314
|
const popupProps = useStore(store, selectors.popupProps);
|
|
8742
|
-
const disabled = useStore(store, selectors.disabled);
|
|
8743
|
-
const readOnly = useStore(store, selectors.readOnly);
|
|
8744
8315
|
const virtualized = useStore(store, selectors.virtualized);
|
|
8745
8316
|
const multiple = selectionMode === 'multiple';
|
|
8746
8317
|
const empty = filteredItems.length === 0;
|
|
@@ -8777,7 +8348,7 @@ const ComboboxList$2 = /*#__PURE__*/React.forwardRef(function ComboboxList(compo
|
|
|
8777
8348
|
role: grid ? 'grid' : 'listbox',
|
|
8778
8349
|
'aria-multiselectable': multiple ? 'true' : undefined,
|
|
8779
8350
|
onKeyDown(event) {
|
|
8780
|
-
if (disabled || readOnly) {
|
|
8351
|
+
if (store.state.disabled || store.state.readOnly) {
|
|
8781
8352
|
return;
|
|
8782
8353
|
}
|
|
8783
8354
|
if (event.key === 'Enter') {
|
|
@@ -8808,12 +8379,62 @@ const ComboboxList$2 = /*#__PURE__*/React.forwardRef(function ComboboxList(compo
|
|
|
8808
8379
|
return element;
|
|
8809
8380
|
}
|
|
8810
8381
|
return /*#__PURE__*/jsx(CompositeList, {
|
|
8811
|
-
elementsRef: listRef,
|
|
8812
|
-
labelsRef:
|
|
8382
|
+
elementsRef: store.state.listRef,
|
|
8383
|
+
labelsRef: hasItems ? undefined : store.state.labelsRef,
|
|
8813
8384
|
children: element
|
|
8814
8385
|
});
|
|
8815
8386
|
});
|
|
8816
8387
|
|
|
8388
|
+
// Word Joiner is invisible and zero-width, so it forces a text mutation without shifting layout.
|
|
8389
|
+
const LIVE_REGION_MARKER = '\u2060';
|
|
8390
|
+
// Safari VoiceOver needed roughly 200ms to reliably notice the initial polite live-region change.
|
|
8391
|
+
const INITIAL_LIVE_REGION_TEXT_MUTATION_RESET_DELAY = 200;
|
|
8392
|
+
function findLastTextNode(root) {
|
|
8393
|
+
const walker = root.ownerDocument.createTreeWalker(root, NodeFilter.SHOW_TEXT);
|
|
8394
|
+
let lastTextNode = null;
|
|
8395
|
+
while (walker.nextNode()) {
|
|
8396
|
+
const textNode = walker.currentNode;
|
|
8397
|
+
if (textNode.nodeValue !== '') {
|
|
8398
|
+
lastTextNode = textNode;
|
|
8399
|
+
}
|
|
8400
|
+
}
|
|
8401
|
+
return lastTextNode;
|
|
8402
|
+
}
|
|
8403
|
+
function useInitialLiveRegionTextMutation() {
|
|
8404
|
+
const timeout = useTimeout();
|
|
8405
|
+
const rootRef = React.useRef(null);
|
|
8406
|
+
|
|
8407
|
+
// Only the initial mounted announcement needs the marker; later text updates announce naturally.
|
|
8408
|
+
React.useEffect(() => {
|
|
8409
|
+
if (isIOS) {
|
|
8410
|
+
return undefined;
|
|
8411
|
+
}
|
|
8412
|
+
const root = rootRef.current;
|
|
8413
|
+
if (root == null) {
|
|
8414
|
+
return undefined;
|
|
8415
|
+
}
|
|
8416
|
+
const textNode = findLastTextNode(root);
|
|
8417
|
+
if (textNode == null) {
|
|
8418
|
+
return undefined;
|
|
8419
|
+
}
|
|
8420
|
+
const originalValue = textNode.nodeValue ?? '';
|
|
8421
|
+
const markedValue = `${originalValue}${LIVE_REGION_MARKER}`;
|
|
8422
|
+
textNode.nodeValue = markedValue;
|
|
8423
|
+
timeout.start(INITIAL_LIVE_REGION_TEXT_MUTATION_RESET_DELAY, () => {
|
|
8424
|
+
if (textNode.nodeValue === markedValue) {
|
|
8425
|
+
textNode.nodeValue = originalValue;
|
|
8426
|
+
}
|
|
8427
|
+
});
|
|
8428
|
+
return () => {
|
|
8429
|
+
timeout.clear();
|
|
8430
|
+
if (textNode.nodeValue === markedValue) {
|
|
8431
|
+
textNode.nodeValue = originalValue;
|
|
8432
|
+
}
|
|
8433
|
+
};
|
|
8434
|
+
}, [rootRef, timeout]);
|
|
8435
|
+
return rootRef;
|
|
8436
|
+
}
|
|
8437
|
+
|
|
8817
8438
|
const ComboboxPortalContext = /*#__PURE__*/React.createContext(undefined);
|
|
8818
8439
|
function useComboboxPortalContext() {
|
|
8819
8440
|
const context = React.useContext(ComboboxPortalContext);
|
|
@@ -9032,6 +8653,7 @@ function useAnchorPositioning(params) {
|
|
|
9032
8653
|
const anchorFnCallback = useStableCallback(anchorFn);
|
|
9033
8654
|
const anchorDep = anchorFn ? anchorFnCallback : anchor;
|
|
9034
8655
|
const anchorValueRef = useValueAsRef(anchor);
|
|
8656
|
+
const mountedRef = useValueAsRef(mounted);
|
|
9035
8657
|
const direction = useDirection();
|
|
9036
8658
|
const isRtl = direction === 'rtl';
|
|
9037
8659
|
const side = mountSide || {
|
|
@@ -9157,12 +8779,15 @@ function useAnchorPositioning(params) {
|
|
|
9157
8779
|
availableHeight,
|
|
9158
8780
|
rects
|
|
9159
8781
|
}) {
|
|
8782
|
+
if (!mountedRef.current) {
|
|
8783
|
+
return;
|
|
8784
|
+
}
|
|
9160
8785
|
const floatingStyle = floating.style;
|
|
9161
8786
|
floatingStyle.setProperty('--available-width', `${availableWidth}px`);
|
|
9162
8787
|
floatingStyle.setProperty('--available-height', `${availableHeight}px`);
|
|
9163
8788
|
|
|
9164
8789
|
// Snap anchor dimensions to device pixels to ensure the popup's visual width matches the anchor's one.
|
|
9165
|
-
const dpr =
|
|
8790
|
+
const dpr = getWindow(floating).devicePixelRatio || 1;
|
|
9166
8791
|
const {
|
|
9167
8792
|
x,
|
|
9168
8793
|
y,
|
|
@@ -9177,7 +8802,7 @@ function useAnchorPositioning(params) {
|
|
|
9177
8802
|
}), arrow(() => ({
|
|
9178
8803
|
// `transform-origin` calculations rely on an element existing. If the arrow hasn't been set,
|
|
9179
8804
|
// we'll create a fake element.
|
|
9180
|
-
element: arrowRef.current ||
|
|
8805
|
+
element: arrowRef.current || ownerDocument(arrowRef.current).createElement('div'),
|
|
9181
8806
|
padding: arrowPadding,
|
|
9182
8807
|
offsetParent: 'floating'
|
|
9183
8808
|
}), [arrowPadding]), {
|
|
@@ -9221,7 +8846,8 @@ function useAnchorPositioning(params) {
|
|
|
9221
8846
|
floatingRootContext.update({
|
|
9222
8847
|
referenceElement: null,
|
|
9223
8848
|
floatingElement: null,
|
|
9224
|
-
domReferenceElement: null
|
|
8849
|
+
domReferenceElement: null,
|
|
8850
|
+
positionReference: null
|
|
9225
8851
|
});
|
|
9226
8852
|
}
|
|
9227
8853
|
}, [mounted, floatingRootContext]);
|
|
@@ -9242,6 +8868,7 @@ function useAnchorPositioning(params) {
|
|
|
9242
8868
|
floatingStyles: originalFloatingStyles
|
|
9243
8869
|
} = useFloating({
|
|
9244
8870
|
rootContext: floatingRootContext,
|
|
8871
|
+
open: keepMounted ? mounted : undefined,
|
|
9245
8872
|
placement,
|
|
9246
8873
|
middleware,
|
|
9247
8874
|
strategy: positionMethod,
|
|
@@ -9351,6 +8978,61 @@ function getDisabledMountTransitionStyles(transitionStatus) {
|
|
|
9351
8978
|
return transitionStatus === 'starting' ? DISABLED_TRANSITIONS_STYLE : EMPTY_OBJECT;
|
|
9352
8979
|
}
|
|
9353
8980
|
|
|
8981
|
+
/**
|
|
8982
|
+
* Renders the shared outer Positioner element used by popup components.
|
|
8983
|
+
* Applies the common role, hidden state, transition styles, state attributes, and optional inert styling.
|
|
8984
|
+
*/
|
|
8985
|
+
function usePositioner(componentProps, state, {
|
|
8986
|
+
styles,
|
|
8987
|
+
transitionStatus,
|
|
8988
|
+
props,
|
|
8989
|
+
refs,
|
|
8990
|
+
hidden,
|
|
8991
|
+
inert = false
|
|
8992
|
+
}) {
|
|
8993
|
+
const style = {
|
|
8994
|
+
...styles
|
|
8995
|
+
};
|
|
8996
|
+
if (inert) {
|
|
8997
|
+
style.pointerEvents = 'none';
|
|
8998
|
+
}
|
|
8999
|
+
return useRenderElement('div', componentProps, {
|
|
9000
|
+
state,
|
|
9001
|
+
ref: refs,
|
|
9002
|
+
props: [{
|
|
9003
|
+
role: 'presentation',
|
|
9004
|
+
hidden,
|
|
9005
|
+
style
|
|
9006
|
+
}, getDisabledMountTransitionStyles(transitionStatus), props],
|
|
9007
|
+
stateAttributesMapping: popupStateMapping
|
|
9008
|
+
});
|
|
9009
|
+
}
|
|
9010
|
+
|
|
9011
|
+
// Touch-opened popups normally avoid scroll locking so users can still swipe outside to dismiss.
|
|
9012
|
+
// This hook re-enables scroll lock only when the popup is effectively full-width.
|
|
9013
|
+
// Treat popups with up to 20px of total horizontal gutter as full-width so common ~10px side
|
|
9014
|
+
// padding still locks scroll, since that leaves too little outside space for a reliable swipe.
|
|
9015
|
+
const VIEWPORT_WIDTH_TOLERANCE_PX = 20;
|
|
9016
|
+
|
|
9017
|
+
/**
|
|
9018
|
+
* Manages scroll lock for anchored popups. For non-touch opens, scroll lock is applied when
|
|
9019
|
+
* enabled. For touch opens, scroll lock is applied only when the positioner width is effectively
|
|
9020
|
+
* viewport-sized.
|
|
9021
|
+
*/
|
|
9022
|
+
function useAnchoredPopupScrollLock(enabled, touchOpen, positionerElement, referenceElement) {
|
|
9023
|
+
const [touchOpenShouldLockScroll, setTouchOpenShouldLockScroll] = React.useState(false);
|
|
9024
|
+
useIsoLayoutEffect(() => {
|
|
9025
|
+
if (!enabled || !touchOpen || positionerElement == null) {
|
|
9026
|
+
setTouchOpenShouldLockScroll(false);
|
|
9027
|
+
return;
|
|
9028
|
+
}
|
|
9029
|
+
const viewportWidth = ownerDocument(positionerElement).documentElement.clientWidth;
|
|
9030
|
+
const popupWidth = positionerElement.offsetWidth;
|
|
9031
|
+
setTouchOpenShouldLockScroll(viewportWidth > 0 && popupWidth > 0 && popupWidth >= viewportWidth - VIEWPORT_WIDTH_TOLERANCE_PX);
|
|
9032
|
+
}, [enabled, touchOpen, positionerElement]);
|
|
9033
|
+
useScrollLock(enabled && (!touchOpen || touchOpenShouldLockScroll), referenceElement);
|
|
9034
|
+
}
|
|
9035
|
+
|
|
9354
9036
|
const ComboboxPositioner = /*#__PURE__*/React.forwardRef(function ComboboxPositioner(componentProps, forwardedRef) {
|
|
9355
9037
|
const {
|
|
9356
9038
|
render,
|
|
@@ -9367,6 +9049,7 @@ const ComboboxPositioner = /*#__PURE__*/React.forwardRef(function ComboboxPositi
|
|
|
9367
9049
|
sticky = false,
|
|
9368
9050
|
disableAnchorTracking = false,
|
|
9369
9051
|
collisionAvoidance = DROPDOWN_COLLISION_AVOIDANCE,
|
|
9052
|
+
style: styleProp,
|
|
9370
9053
|
...elementProps
|
|
9371
9054
|
} = componentProps;
|
|
9372
9055
|
const store = useComboboxRootContext();
|
|
@@ -9379,6 +9062,7 @@ const ComboboxPositioner = /*#__PURE__*/React.forwardRef(function ComboboxPositi
|
|
|
9379
9062
|
const open = useStore(store, selectors.open);
|
|
9380
9063
|
const mounted = useStore(store, selectors.mounted);
|
|
9381
9064
|
const openMethod = useStore(store, selectors.openMethod);
|
|
9065
|
+
const positionerElement = useStore(store, selectors.positionerElement);
|
|
9382
9066
|
const triggerElement = useStore(store, selectors.triggerElement);
|
|
9383
9067
|
const inputElement = useStore(store, selectors.inputElement);
|
|
9384
9068
|
const inputGroupElement = useStore(store, selectors.inputGroupElement);
|
|
@@ -9404,20 +9088,7 @@ const ComboboxPositioner = /*#__PURE__*/React.forwardRef(function ComboboxPositi
|
|
|
9404
9088
|
collisionAvoidance,
|
|
9405
9089
|
lazyFlip: true
|
|
9406
9090
|
});
|
|
9407
|
-
|
|
9408
|
-
const defaultProps = React.useMemo(() => {
|
|
9409
|
-
const style = {
|
|
9410
|
-
...positioning.positionerStyles
|
|
9411
|
-
};
|
|
9412
|
-
if (!open) {
|
|
9413
|
-
style.pointerEvents = 'none';
|
|
9414
|
-
}
|
|
9415
|
-
return {
|
|
9416
|
-
role: 'presentation',
|
|
9417
|
-
hidden: !mounted,
|
|
9418
|
-
style
|
|
9419
|
-
};
|
|
9420
|
-
}, [open, mounted, positioning.positionerStyles]);
|
|
9091
|
+
useAnchoredPopupScrollLock(open && modal, openMethod === 'touch', positionerElement, triggerElement);
|
|
9421
9092
|
const state = {
|
|
9422
9093
|
open,
|
|
9423
9094
|
side: positioning.side,
|
|
@@ -9428,26 +9099,19 @@ const ComboboxPositioner = /*#__PURE__*/React.forwardRef(function ComboboxPositi
|
|
|
9428
9099
|
useIsoLayoutEffect(() => {
|
|
9429
9100
|
store.set('popupSide', positioning.side);
|
|
9430
9101
|
}, [store, positioning.side]);
|
|
9431
|
-
const contextValue = React.useMemo(() => ({
|
|
9432
|
-
side: positioning.side,
|
|
9433
|
-
align: positioning.align,
|
|
9434
|
-
arrowRef: positioning.arrowRef,
|
|
9435
|
-
arrowUncentered: positioning.arrowUncentered,
|
|
9436
|
-
arrowStyles: positioning.arrowStyles,
|
|
9437
|
-
anchorHidden: positioning.anchorHidden,
|
|
9438
|
-
isPositioned: positioning.isPositioned
|
|
9439
|
-
}), [positioning.side, positioning.align, positioning.arrowRef, positioning.arrowUncentered, positioning.arrowStyles, positioning.anchorHidden, positioning.isPositioned]);
|
|
9440
9102
|
const setPositionerElement = useStableCallback(element => {
|
|
9441
9103
|
store.set('positionerElement', element);
|
|
9442
9104
|
});
|
|
9443
|
-
const element =
|
|
9444
|
-
|
|
9445
|
-
|
|
9446
|
-
props:
|
|
9447
|
-
|
|
9105
|
+
const element = usePositioner(componentProps, state, {
|
|
9106
|
+
styles: positioning.positionerStyles,
|
|
9107
|
+
transitionStatus,
|
|
9108
|
+
props: elementProps,
|
|
9109
|
+
refs: [forwardedRef, setPositionerElement],
|
|
9110
|
+
hidden: !mounted,
|
|
9111
|
+
inert: !open
|
|
9448
9112
|
});
|
|
9449
9113
|
return /*#__PURE__*/jsxs(ComboboxPositionerContext.Provider, {
|
|
9450
|
-
value:
|
|
9114
|
+
value: positioning,
|
|
9451
9115
|
children: [mounted && modal && /*#__PURE__*/jsx(InternalBackdrop, {
|
|
9452
9116
|
inert: inertValue(!open),
|
|
9453
9117
|
cutout: inputGroupElement ?? inputElement ?? triggerElement
|
|
@@ -9463,11 +9127,14 @@ const stateAttributesMapping = {
|
|
|
9463
9127
|
/**
|
|
9464
9128
|
* A container for the list.
|
|
9465
9129
|
* Renders a `<div>` element.
|
|
9130
|
+
*
|
|
9131
|
+
* Documentation: [Base UI Combobox](https://base-ui.com/react/components/combobox)
|
|
9466
9132
|
*/
|
|
9467
9133
|
const ComboboxPopup = /*#__PURE__*/React.forwardRef(function ComboboxPopup(componentProps, forwardedRef) {
|
|
9468
9134
|
const {
|
|
9469
9135
|
render,
|
|
9470
9136
|
className,
|
|
9137
|
+
style,
|
|
9471
9138
|
initialFocus,
|
|
9472
9139
|
finalFocus,
|
|
9473
9140
|
...elementProps
|
|
@@ -9560,6 +9227,7 @@ const ComboboxGroup$2 = /*#__PURE__*/React.forwardRef(function ComboboxGroup(com
|
|
|
9560
9227
|
const {
|
|
9561
9228
|
render,
|
|
9562
9229
|
className,
|
|
9230
|
+
style,
|
|
9563
9231
|
items,
|
|
9564
9232
|
...elementProps
|
|
9565
9233
|
} = componentProps;
|
|
@@ -9592,11 +9260,14 @@ const ComboboxGroup$2 = /*#__PURE__*/React.forwardRef(function ComboboxGroup(com
|
|
|
9592
9260
|
/**
|
|
9593
9261
|
* An accessible label that is automatically associated with its parent group.
|
|
9594
9262
|
* Renders a `<div>` element.
|
|
9263
|
+
*
|
|
9264
|
+
* Documentation: [Base UI Combobox](https://base-ui.com/react/components/combobox)
|
|
9595
9265
|
*/
|
|
9596
9266
|
const ComboboxGroupLabel = /*#__PURE__*/React.forwardRef(function ComboboxGroupLabel(componentProps, forwardedRef) {
|
|
9597
9267
|
const {
|
|
9598
9268
|
render,
|
|
9599
9269
|
className,
|
|
9270
|
+
style,
|
|
9600
9271
|
id: idProp,
|
|
9601
9272
|
...elementProps
|
|
9602
9273
|
} = componentProps;
|
|
@@ -9641,6 +9312,7 @@ const ComboboxItem$2 = /*#__PURE__*/React.memo(/*#__PURE__*/React.forwardRef(fun
|
|
|
9641
9312
|
index: indexProp,
|
|
9642
9313
|
disabled = false,
|
|
9643
9314
|
nativeButton = false,
|
|
9315
|
+
style,
|
|
9644
9316
|
...elementProps
|
|
9645
9317
|
} = componentProps;
|
|
9646
9318
|
const didPointerDownRef = React.useRef(false);
|
|
@@ -9756,6 +9428,11 @@ const ComboboxItem$2 = /*#__PURE__*/React.memo(/*#__PURE__*/React.forwardRef(fun
|
|
|
9756
9428
|
didPointerDownRef.current = true;
|
|
9757
9429
|
event.preventDefault();
|
|
9758
9430
|
},
|
|
9431
|
+
onMouseDown(event) {
|
|
9432
|
+
// iOS Safari can emit a synthetic mousedown for touch taps without a preceding
|
|
9433
|
+
// pointerdown. Prevent default here too so tapping an item does not blur the input.
|
|
9434
|
+
event.preventDefault();
|
|
9435
|
+
},
|
|
9759
9436
|
onClick(event) {
|
|
9760
9437
|
if (disabled || readOnly) {
|
|
9761
9438
|
return;
|
|
@@ -9790,12 +9467,19 @@ const ComboboxItem$2 = /*#__PURE__*/React.memo(/*#__PURE__*/React.forwardRef(fun
|
|
|
9790
9467
|
* Renders its children only when the list is empty.
|
|
9791
9468
|
* Requires the `items` prop on the root component.
|
|
9792
9469
|
* Announces changes politely to screen readers.
|
|
9470
|
+
* This component's root element must remain mounted in the DOM to announce
|
|
9471
|
+
* changes consistently across screen readers. Avoid hiding or removing the
|
|
9472
|
+
* component itself with `display: none`, `hidden`, `aria-hidden`, or conditional
|
|
9473
|
+
* rendering. Prefer updating or conditionally rendering its children instead.
|
|
9793
9474
|
* Renders a `<div>` element.
|
|
9475
|
+
*
|
|
9476
|
+
* Documentation: [Base UI Combobox](https://base-ui.com/react/components/combobox)
|
|
9794
9477
|
*/
|
|
9795
9478
|
const ComboboxEmpty$2 = /*#__PURE__*/React.forwardRef(function ComboboxEmpty(componentProps, forwardedRef) {
|
|
9796
9479
|
const {
|
|
9797
9480
|
render,
|
|
9798
9481
|
className,
|
|
9482
|
+
style,
|
|
9799
9483
|
children: childrenProp,
|
|
9800
9484
|
...elementProps
|
|
9801
9485
|
} = componentProps;
|
|
@@ -9803,9 +9487,10 @@ const ComboboxEmpty$2 = /*#__PURE__*/React.forwardRef(function ComboboxEmpty(com
|
|
|
9803
9487
|
filteredItems
|
|
9804
9488
|
} = useComboboxDerivedItemsContext();
|
|
9805
9489
|
const store = useComboboxRootContext();
|
|
9490
|
+
const emptyRef = useInitialLiveRegionTextMutation();
|
|
9806
9491
|
const children = filteredItems.length === 0 ? childrenProp : null;
|
|
9807
9492
|
return useRenderElement('div', componentProps, {
|
|
9808
|
-
ref: [forwardedRef, store.state.emptyRef],
|
|
9493
|
+
ref: [forwardedRef, store.state.emptyRef, emptyRef],
|
|
9809
9494
|
props: [{
|
|
9810
9495
|
children,
|
|
9811
9496
|
role: 'status',
|
|
@@ -9826,6 +9511,7 @@ const Separator = /*#__PURE__*/React.forwardRef(function SeparatorComponent(comp
|
|
|
9826
9511
|
className,
|
|
9827
9512
|
render,
|
|
9828
9513
|
orientation = 'horizontal',
|
|
9514
|
+
style,
|
|
9829
9515
|
...elementProps
|
|
9830
9516
|
} = componentProps;
|
|
9831
9517
|
const state = {
|
|
@@ -9911,6 +9597,7 @@ const Inner = /*#__PURE__*/React.memo(/*#__PURE__*/React.forwardRef((componentPr
|
|
|
9911
9597
|
const {
|
|
9912
9598
|
render,
|
|
9913
9599
|
className,
|
|
9600
|
+
style,
|
|
9914
9601
|
keepMounted,
|
|
9915
9602
|
...elementProps
|
|
9916
9603
|
} = componentProps;
|
|
@@ -9951,6 +9638,7 @@ const ComboboxChips$2 = /*#__PURE__*/React.forwardRef(function ComboboxChips(com
|
|
|
9951
9638
|
const {
|
|
9952
9639
|
render,
|
|
9953
9640
|
className,
|
|
9641
|
+
style,
|
|
9954
9642
|
...elementProps
|
|
9955
9643
|
} = componentProps;
|
|
9956
9644
|
const store = useComboboxRootContext();
|
|
@@ -9967,7 +9655,11 @@ const ComboboxChips$2 = /*#__PURE__*/React.forwardRef(function ComboboxChips(com
|
|
|
9967
9655
|
// arrow keys inside a container unless it has a toolbar role.
|
|
9968
9656
|
props: [hasSelectionChips ? {
|
|
9969
9657
|
role: 'toolbar'
|
|
9970
|
-
} : EMPTY_OBJECT,
|
|
9658
|
+
} : EMPTY_OBJECT, {
|
|
9659
|
+
onMouseDown(event) {
|
|
9660
|
+
handleInputPress(event, store, store.state.disabled, store.state.readOnly);
|
|
9661
|
+
}
|
|
9662
|
+
}, elementProps]
|
|
9971
9663
|
});
|
|
9972
9664
|
const contextValue = React.useMemo(() => ({
|
|
9973
9665
|
highlightedChipIndex,
|
|
@@ -9996,6 +9688,7 @@ const ComboboxChip$2 = /*#__PURE__*/React.forwardRef(function ComboboxChip(compo
|
|
|
9996
9688
|
const {
|
|
9997
9689
|
render,
|
|
9998
9690
|
className,
|
|
9691
|
+
style,
|
|
9999
9692
|
...elementProps
|
|
10000
9693
|
} = componentProps;
|
|
10001
9694
|
const store = useComboboxRootContext();
|
|
@@ -10021,7 +9714,7 @@ const ComboboxChip$2 = /*#__PURE__*/React.forwardRef(function ComboboxChip(compo
|
|
|
10021
9714
|
}
|
|
10022
9715
|
} else if (event.key === 'ArrowRight') {
|
|
10023
9716
|
event.preventDefault();
|
|
10024
|
-
if (index <
|
|
9717
|
+
if (index < chipsRef.current.length - 1) {
|
|
10025
9718
|
nextIndex = index + 1;
|
|
10026
9719
|
} else {
|
|
10027
9720
|
nextIndex = undefined;
|
|
@@ -10073,16 +9766,6 @@ const ComboboxChip$2 = /*#__PURE__*/React.forwardRef(function ComboboxChip(compo
|
|
|
10073
9766
|
} else {
|
|
10074
9767
|
chipsRef.current[nextIndex]?.focus();
|
|
10075
9768
|
}
|
|
10076
|
-
},
|
|
10077
|
-
onMouseDown(event) {
|
|
10078
|
-
if (readOnly) {
|
|
10079
|
-
return;
|
|
10080
|
-
}
|
|
10081
|
-
event.preventDefault();
|
|
10082
|
-
if (disabled) {
|
|
10083
|
-
return;
|
|
10084
|
-
}
|
|
10085
|
-
store.state.inputRef.current?.focus();
|
|
10086
9769
|
}
|
|
10087
9770
|
}, elementProps]
|
|
10088
9771
|
});
|
|
@@ -10098,6 +9781,8 @@ const ComboboxChip$2 = /*#__PURE__*/React.forwardRef(function ComboboxChip(compo
|
|
|
10098
9781
|
/**
|
|
10099
9782
|
* A button to remove a chip.
|
|
10100
9783
|
* Renders a `<button>` element.
|
|
9784
|
+
*
|
|
9785
|
+
* Documentation: [Base UI Combobox](https://base-ui.com/react/components/combobox)
|
|
10101
9786
|
*/
|
|
10102
9787
|
const ComboboxChipRemove = /*#__PURE__*/React.forwardRef(function ComboboxChipRemove(componentProps, forwardedRef) {
|
|
10103
9788
|
const {
|
|
@@ -10105,6 +9790,7 @@ const ComboboxChipRemove = /*#__PURE__*/React.forwardRef(function ComboboxChipRe
|
|
|
10105
9790
|
className,
|
|
10106
9791
|
disabled: disabledProp = false,
|
|
10107
9792
|
nativeButton = true,
|
|
9793
|
+
style,
|
|
10108
9794
|
...elementProps
|
|
10109
9795
|
} = componentProps;
|
|
10110
9796
|
const store = useComboboxRootContext();
|
|
@@ -10156,6 +9842,9 @@ const ComboboxChipRemove = /*#__PURE__*/React.forwardRef(function ComboboxChipRe
|
|
|
10156
9842
|
state,
|
|
10157
9843
|
props: [{
|
|
10158
9844
|
tabIndex: -1,
|
|
9845
|
+
onMouseDown(event) {
|
|
9846
|
+
event.preventDefault();
|
|
9847
|
+
},
|
|
10159
9848
|
onClick(event) {
|
|
10160
9849
|
if (disabled || readOnly) {
|
|
10161
9850
|
return;
|
|
@@ -10224,9 +9913,7 @@ function ComboboxChips$1({ className, ...props }) {
|
|
|
10224
9913
|
function ComboboxChip$1({ className, children, showRemove = true, ...props }) {
|
|
10225
9914
|
return (jsxs(ComboboxChip$2, { "data-slot": "combobox-chip", className: cn("flex h-[calc(--spacing(5.25))] w-fit items-center justify-center gap-1 rounded-sm bg-muted px-1.5 text-xs font-medium whitespace-nowrap text-foreground has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50 has-data-[slot=combobox-chip-remove]:pe-0", className), ...props, children: [children, showRemove && (jsx(ComboboxChipRemove, { render: jsx(Button, { variant: "ghost", size: "icon-xs" }), className: "-ms-1 opacity-50 hover:opacity-100", "data-slot": "combobox-chip-remove", children: jsx(X, { className: "pointer-events-none" }) }))] }));
|
|
10226
9915
|
}
|
|
10227
|
-
|
|
10228
|
-
return (jsx(ComboboxInput$2, { "data-slot": "combobox-chip-input", className: cn("min-w-16 flex-1 outline-none", className), ...props }));
|
|
10229
|
-
}
|
|
9916
|
+
const ComboboxChipsInput$1 = React.forwardRef(({ className, ...props }, ref) => (jsx(ComboboxInput$2, { ref: ref, "data-slot": "combobox-chip-input", className: cn("min-w-16 flex-1 outline-none", className), ...props })));
|
|
10230
9917
|
function useComboboxAnchor() {
|
|
10231
9918
|
return React.useRef(null);
|
|
10232
9919
|
}
|
|
@@ -10243,7 +9930,7 @@ const ComboboxEmpty = (props) => jsx(ComboboxEmpty$1, { ...props });
|
|
|
10243
9930
|
const ComboboxSeparator = (props) => jsx(ComboboxSeparator$1, { ...props });
|
|
10244
9931
|
const ComboboxChips = (props) => jsx(ComboboxChips$1, { ...props });
|
|
10245
9932
|
const ComboboxChip = (props) => jsx(ComboboxChip$1, { ...props });
|
|
10246
|
-
const ComboboxChipsInput = (props) => jsx(ComboboxChipsInput$1, { ...props });
|
|
9933
|
+
const ComboboxChipsInput = React__default.forwardRef((props, ref) => jsx(ComboboxChipsInput$1, { ref: ref, ...props }));
|
|
10247
9934
|
const ComboboxTrigger = (props) => jsx(ComboboxTrigger$1, { ...props });
|
|
10248
9935
|
const ComboboxValue = (props) => jsx(ComboboxValue$1, { ...props });
|
|
10249
9936
|
|