@navikt/ds-react 6.7.0 → 6.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/chat/Chat.d.ts +2 -1
- package/cjs/chat/Chat.js +2 -1
- package/cjs/chat/Chat.js.map +1 -1
- package/cjs/collapsible/parts/Collapsible.Trigger.d.ts +4 -0
- package/cjs/collapsible/parts/Collapsible.Trigger.js +1 -1
- package/cjs/collapsible/parts/Collapsible.Trigger.js.map +1 -1
- package/cjs/date/datepicker/parts/DropdownCaption.js +1 -1
- package/cjs/date/datepicker/parts/DropdownCaption.js.map +1 -1
- package/cjs/date/monthpicker/MonthCaption.js +1 -1
- package/cjs/date/utils/labels.d.ts +2 -2
- package/cjs/form/ReadOnlyIcon.d.ts +2 -2
- package/cjs/form/combobox/Combobox.js +7 -22
- package/cjs/form/combobox/Combobox.js.map +1 -1
- package/cjs/form/combobox/ComboboxProvider.js +2 -2
- package/cjs/form/combobox/ComboboxProvider.js.map +1 -1
- package/cjs/form/combobox/ComboboxWrapper.d.ts +1 -2
- package/cjs/form/combobox/ComboboxWrapper.js +4 -2
- package/cjs/form/combobox/ComboboxWrapper.js.map +1 -1
- package/cjs/form/combobox/FilteredOptions/FilteredOptions.js +4 -4
- package/cjs/form/combobox/FilteredOptions/FilteredOptions.js.map +1 -1
- package/cjs/form/combobox/FilteredOptions/filteredOptionsContext.d.ts +4 -4
- package/cjs/form/combobox/FilteredOptions/filteredOptionsContext.js +13 -15
- package/cjs/form/combobox/FilteredOptions/filteredOptionsContext.js.map +1 -1
- package/cjs/form/combobox/Input/{inputContext.d.ts → Input.context.d.ts} +7 -5
- package/cjs/form/combobox/Input/{inputContext.js → Input.context.js} +22 -22
- package/cjs/form/combobox/Input/Input.context.js.map +1 -0
- package/cjs/form/combobox/Input/Input.js +2 -2
- package/cjs/form/combobox/Input/Input.js.map +1 -1
- package/cjs/form/combobox/Input/InputController.d.ts +3 -0
- package/cjs/form/combobox/Input/InputController.js +70 -0
- package/cjs/form/combobox/Input/InputController.js.map +1 -0
- package/cjs/form/combobox/{ToggleListButton.js → Input/ToggleListButton.js} +1 -1
- package/cjs/form/combobox/Input/ToggleListButton.js.map +1 -0
- package/cjs/form/combobox/SelectedOptions/SelectedOptions.js +2 -2
- package/cjs/form/combobox/SelectedOptions/SelectedOptions.js.map +1 -1
- package/cjs/form/combobox/SelectedOptions/selectedOptionsContext.d.ts +4 -4
- package/cjs/form/combobox/SelectedOptions/selectedOptionsContext.js +7 -13
- package/cjs/form/combobox/SelectedOptions/selectedOptionsContext.js.map +1 -1
- package/cjs/form/combobox/customOptionsContext.d.ts +4 -4
- package/cjs/form/combobox/customOptionsContext.js +10 -13
- package/cjs/form/combobox/customOptionsContext.js.map +1 -1
- package/cjs/form/combobox/types.d.ts +1 -1
- package/cjs/form/file-upload/FileUpload.context.d.ts +1 -1
- package/cjs/form/file-upload/FileUpload.d.ts +1 -1
- package/cjs/form/file-upload/FileUpload.js.map +1 -1
- package/cjs/form/file-upload/parts/dropzone/Dropzone.js +1 -1
- package/cjs/form/file-upload/parts/dropzone/Dropzone.js.map +1 -1
- package/cjs/form/file-upload/parts/dropzone/dropzone.types.d.ts +1 -1
- package/cjs/form/file-upload/parts/item/Item.d.ts +1 -1
- package/cjs/form/file-upload/parts/item/Item.js +1 -1
- package/cjs/form/file-upload/parts/item/Item.js.map +1 -1
- package/cjs/form/form-progress/FormProgress.d.ts +66 -0
- package/cjs/form/form-progress/FormProgress.js +85 -0
- package/cjs/form/form-progress/FormProgress.js.map +1 -0
- package/cjs/form/form-progress/index.d.ts +1 -0
- package/cjs/form/form-progress/index.js +11 -0
- package/cjs/form/form-progress/index.js.map +1 -0
- package/cjs/help-text/HelpTextIcon.d.ts +1 -1
- package/cjs/index.d.ts +1 -0
- package/cjs/index.js +3 -1
- package/cjs/index.js.map +1 -1
- package/cjs/overlay/dismiss/DismissableLayer.d.ts +70 -0
- package/cjs/overlay/dismiss/DismissableLayer.js +253 -0
- package/cjs/overlay/dismiss/DismissableLayer.js.map +1 -0
- package/cjs/overlay/dismiss/util/dispatchCustomEvent.d.ts +50 -0
- package/cjs/overlay/dismiss/util/dispatchCustomEvent.js +65 -0
- package/cjs/overlay/dismiss/util/dispatchCustomEvent.js.map +1 -0
- package/cjs/overlay/dismiss/util/useEscapeKeydown.d.ts +1 -0
- package/cjs/overlay/dismiss/util/useEscapeKeydown.js +19 -0
- package/cjs/overlay/dismiss/util/useEscapeKeydown.js.map +1 -0
- package/cjs/overlay/dismiss/util/useFocusOutside.d.ts +8 -0
- package/cjs/overlay/dismiss/util/useFocusOutside.js +42 -0
- package/cjs/overlay/dismiss/util/useFocusOutside.js.map +1 -0
- package/cjs/overlay/dismiss/util/usePointerDownOutside.d.ts +10 -0
- package/cjs/overlay/dismiss/util/usePointerDownOutside.js +84 -0
- package/cjs/overlay/dismiss/util/usePointerDownOutside.js.map +1 -0
- package/cjs/overlays/floating/Floating.d.ts +53 -0
- package/cjs/overlays/floating/Floating.js +215 -0
- package/cjs/overlays/floating/Floating.js.map +1 -0
- package/cjs/overlays/floating/Floating.utils.d.ts +18 -0
- package/cjs/overlays/floating/Floating.utils.js +52 -0
- package/cjs/overlays/floating/Floating.utils.js.map +1 -0
- package/cjs/popover/Popover.js +13 -28
- package/cjs/popover/Popover.js.map +1 -1
- package/cjs/progress-bar/ProgressBar.d.ts +20 -8
- package/cjs/progress-bar/ProgressBar.js +19 -9
- package/cjs/progress-bar/ProgressBar.js.map +1 -1
- package/cjs/stepper/Step.js +1 -1
- package/cjs/stepper/Step.js.map +1 -1
- package/cjs/stepper/Stepper.d.ts +1 -1
- package/cjs/stepper/Stepper.js +1 -1
- package/cjs/tabs/Tabs.context.d.ts +7 -3
- package/cjs/tabs/Tabs.context.js +1 -0
- package/cjs/tabs/Tabs.context.js.map +1 -1
- package/cjs/timeline/AxisLabels.d.ts +1 -1
- package/cjs/toggle-group/ToggleGroup.context.d.ts +7 -3
- package/cjs/toggle-group/ToggleGroup.context.js +1 -0
- package/cjs/toggle-group/ToggleGroup.context.js.map +1 -1
- package/cjs/util/hooks/descendants/useDescendant.d.ts +2 -2
- package/cjs/util/hooks/descendants/useDescendant.js +49 -52
- package/cjs/util/hooks/descendants/useDescendant.js.map +1 -1
- package/cjs/util/i18n/get.js.map +1 -0
- package/cjs/util/i18n/i18n.context.js.map +1 -0
- package/cjs/util/i18n/i18n.types.js.map +1 -0
- package/{esm/form/file-upload → cjs/util}/i18n/locales/nb.d.ts +5 -0
- package/cjs/{form/file-upload → util}/i18n/locales/nb.js +5 -0
- package/cjs/util/i18n/locales/nb.js.map +1 -0
- package/cjs/util/i18n/merge.js.map +1 -0
- package/cjs/util/types/AsChild.d.ts +14 -0
- package/cjs/util/types/AsChild.js +3 -0
- package/cjs/util/types/AsChild.js.map +1 -0
- package/esm/chat/Chat.d.ts +2 -1
- package/esm/chat/Chat.js +1 -0
- package/esm/chat/Chat.js.map +1 -1
- package/esm/collapsible/parts/Collapsible.Trigger.d.ts +4 -0
- package/esm/collapsible/parts/Collapsible.Trigger.js +1 -1
- package/esm/collapsible/parts/Collapsible.Trigger.js.map +1 -1
- package/esm/date/datepicker/parts/DropdownCaption.js +1 -1
- package/esm/date/datepicker/parts/DropdownCaption.js.map +1 -1
- package/esm/date/monthpicker/MonthCaption.js +1 -1
- package/esm/date/utils/labels.d.ts +2 -2
- package/esm/form/ReadOnlyIcon.d.ts +2 -2
- package/esm/form/combobox/Combobox.js +8 -23
- package/esm/form/combobox/Combobox.js.map +1 -1
- package/esm/form/combobox/ComboboxProvider.js +1 -1
- package/esm/form/combobox/ComboboxProvider.js.map +1 -1
- package/esm/form/combobox/ComboboxWrapper.d.ts +1 -2
- package/esm/form/combobox/ComboboxWrapper.js +4 -2
- package/esm/form/combobox/ComboboxWrapper.js.map +1 -1
- package/esm/form/combobox/FilteredOptions/FilteredOptions.js +3 -3
- package/esm/form/combobox/FilteredOptions/FilteredOptions.js.map +1 -1
- package/esm/form/combobox/FilteredOptions/filteredOptionsContext.d.ts +4 -4
- package/esm/form/combobox/FilteredOptions/filteredOptionsContext.js +15 -16
- package/esm/form/combobox/FilteredOptions/filteredOptionsContext.js.map +1 -1
- package/esm/form/combobox/Input/{inputContext.d.ts → Input.context.d.ts} +7 -5
- package/esm/form/combobox/Input/{inputContext.js → Input.context.js} +22 -21
- package/esm/form/combobox/Input/Input.context.js.map +1 -0
- package/esm/form/combobox/Input/Input.js +1 -1
- package/esm/form/combobox/Input/Input.js.map +1 -1
- package/esm/form/combobox/Input/InputController.d.ts +3 -0
- package/esm/form/combobox/Input/InputController.js +41 -0
- package/esm/form/combobox/Input/InputController.js.map +1 -0
- package/esm/form/combobox/{ToggleListButton.js → Input/ToggleListButton.js} +1 -1
- package/esm/form/combobox/Input/ToggleListButton.js.map +1 -0
- package/esm/form/combobox/SelectedOptions/SelectedOptions.js +1 -1
- package/esm/form/combobox/SelectedOptions/SelectedOptions.js.map +1 -1
- package/esm/form/combobox/SelectedOptions/selectedOptionsContext.d.ts +4 -4
- package/esm/form/combobox/SelectedOptions/selectedOptionsContext.js +9 -14
- package/esm/form/combobox/SelectedOptions/selectedOptionsContext.js.map +1 -1
- package/esm/form/combobox/customOptionsContext.d.ts +4 -4
- package/esm/form/combobox/customOptionsContext.js +10 -12
- package/esm/form/combobox/customOptionsContext.js.map +1 -1
- package/esm/form/combobox/types.d.ts +1 -1
- package/esm/form/file-upload/FileUpload.context.d.ts +1 -1
- package/esm/form/file-upload/FileUpload.d.ts +1 -1
- package/esm/form/file-upload/FileUpload.js.map +1 -1
- package/esm/form/file-upload/parts/dropzone/Dropzone.js +1 -1
- package/esm/form/file-upload/parts/dropzone/Dropzone.js.map +1 -1
- package/esm/form/file-upload/parts/dropzone/dropzone.types.d.ts +1 -1
- package/esm/form/file-upload/parts/item/Item.d.ts +1 -1
- package/esm/form/file-upload/parts/item/Item.js +1 -1
- package/esm/form/file-upload/parts/item/Item.js.map +1 -1
- package/esm/form/form-progress/FormProgress.d.ts +66 -0
- package/esm/form/form-progress/FormProgress.js +56 -0
- package/esm/form/form-progress/FormProgress.js.map +1 -0
- package/esm/form/form-progress/index.d.ts +1 -0
- package/esm/form/form-progress/index.js +3 -0
- package/esm/form/form-progress/index.js.map +1 -0
- package/esm/help-text/HelpTextIcon.d.ts +1 -1
- package/esm/index.d.ts +1 -0
- package/esm/index.js +1 -0
- package/esm/index.js.map +1 -1
- package/esm/overlay/dismiss/DismissableLayer.d.ts +70 -0
- package/esm/overlay/dismiss/DismissableLayer.js +226 -0
- package/esm/overlay/dismiss/DismissableLayer.js.map +1 -0
- package/esm/overlay/dismiss/util/dispatchCustomEvent.d.ts +50 -0
- package/esm/overlay/dismiss/util/dispatchCustomEvent.js +58 -0
- package/esm/overlay/dismiss/util/dispatchCustomEvent.js.map +1 -0
- package/esm/overlay/dismiss/util/useEscapeKeydown.d.ts +1 -0
- package/esm/overlay/dismiss/util/useEscapeKeydown.js +15 -0
- package/esm/overlay/dismiss/util/useEscapeKeydown.js.map +1 -0
- package/esm/overlay/dismiss/util/useFocusOutside.d.ts +8 -0
- package/esm/overlay/dismiss/util/useFocusOutside.js +38 -0
- package/esm/overlay/dismiss/util/useFocusOutside.js.map +1 -0
- package/esm/overlay/dismiss/util/usePointerDownOutside.d.ts +10 -0
- package/esm/overlay/dismiss/util/usePointerDownOutside.js +80 -0
- package/esm/overlay/dismiss/util/usePointerDownOutside.js.map +1 -0
- package/esm/overlays/floating/Floating.d.ts +53 -0
- package/esm/overlays/floating/Floating.js +188 -0
- package/esm/overlays/floating/Floating.js.map +1 -0
- package/esm/overlays/floating/Floating.utils.d.ts +18 -0
- package/esm/overlays/floating/Floating.utils.js +48 -0
- package/esm/overlays/floating/Floating.utils.js.map +1 -0
- package/esm/popover/Popover.js +16 -31
- package/esm/popover/Popover.js.map +1 -1
- package/esm/progress-bar/ProgressBar.d.ts +20 -8
- package/esm/progress-bar/ProgressBar.js +20 -10
- package/esm/progress-bar/ProgressBar.js.map +1 -1
- package/esm/stepper/Step.js +1 -1
- package/esm/stepper/Step.js.map +1 -1
- package/esm/stepper/Stepper.d.ts +1 -1
- package/esm/stepper/Stepper.js +1 -1
- package/esm/tabs/Tabs.context.d.ts +7 -3
- package/esm/tabs/Tabs.context.js +1 -0
- package/esm/tabs/Tabs.context.js.map +1 -1
- package/esm/timeline/AxisLabels.d.ts +1 -1
- package/esm/toggle-group/ToggleGroup.context.d.ts +7 -3
- package/esm/toggle-group/ToggleGroup.context.js +1 -0
- package/esm/toggle-group/ToggleGroup.context.js.map +1 -1
- package/esm/util/hooks/descendants/useDescendant.d.ts +2 -2
- package/esm/util/hooks/descendants/useDescendant.js +49 -52
- package/esm/util/hooks/descendants/useDescendant.js.map +1 -1
- package/esm/util/i18n/get.js.map +1 -0
- package/esm/util/i18n/i18n.context.js.map +1 -0
- package/esm/util/i18n/i18n.types.js.map +1 -0
- package/{cjs/form/file-upload → esm/util}/i18n/locales/nb.d.ts +5 -0
- package/esm/{form/file-upload → util}/i18n/locales/nb.js +5 -0
- package/esm/util/i18n/locales/nb.js.map +1 -0
- package/esm/util/i18n/merge.js.map +1 -0
- package/esm/util/types/AsChild.d.ts +14 -0
- package/esm/util/types/AsChild.js +2 -0
- package/esm/util/types/AsChild.js.map +1 -0
- package/package.json +16 -5
- package/src/chat/Chat.tsx +2 -1
- package/src/collapsible/parts/Collapsible.Trigger.tsx +5 -1
- package/src/date/datepicker/parts/DropdownCaption.tsx +5 -1
- package/src/date/monthpicker/MonthCaption.tsx +1 -1
- package/src/form/combobox/Combobox.tsx +6 -76
- package/src/form/combobox/ComboboxProvider.tsx +1 -1
- package/src/form/combobox/ComboboxWrapper.tsx +4 -3
- package/src/form/combobox/FilteredOptions/FilteredOptions.tsx +3 -3
- package/src/form/combobox/FilteredOptions/filteredOptionsContext.tsx +19 -29
- package/src/form/combobox/Input/{inputContext.tsx → Input.context.tsx} +30 -33
- package/src/form/combobox/Input/Input.tsx +1 -1
- package/src/form/combobox/Input/InputController.tsx +102 -0
- package/src/form/combobox/{ToggleListButton.tsx → Input/ToggleListButton.tsx} +1 -1
- package/src/form/combobox/SelectedOptions/SelectedOptions.tsx +1 -1
- package/src/form/combobox/SelectedOptions/selectedOptionsContext.tsx +12 -26
- package/src/form/combobox/{combobox-utils.test.ts → __tests__/combobox-utils.test.ts} +1 -1
- package/src/form/combobox/{combobox.test.tsx → __tests__/combobox.test.tsx} +2 -3
- package/src/form/combobox/customOptionsContext.tsx +14 -18
- package/src/form/combobox/types.ts +3 -1
- package/src/form/file-upload/FileUpload.context.tsx +1 -1
- package/src/form/file-upload/FileUpload.tsx +1 -1
- package/src/form/file-upload/parts/dropzone/Dropzone.tsx +1 -1
- package/src/form/file-upload/parts/dropzone/dropzone.types.ts +1 -1
- package/src/form/file-upload/parts/item/Item.tsx +2 -2
- package/src/form/form-progress/FormProgress.tsx +152 -0
- package/src/form/form-progress/index.ts +7 -0
- package/src/index.ts +1 -0
- package/src/overlay/README.md +5 -0
- package/src/overlay/dismiss/DismissableLayer.tsx +368 -0
- package/src/overlay/dismiss/util/dispatchCustomEvent.ts +77 -0
- package/src/overlay/dismiss/util/useEscapeKeydown.ts +21 -0
- package/src/overlay/dismiss/util/useFocusOutside.ts +52 -0
- package/src/overlay/dismiss/util/usePointerDownOutside.ts +95 -0
- package/src/overlays/floating/Floating.tsx +399 -0
- package/src/overlays/floating/Floating.utils.ts +63 -0
- package/src/popover/Popover.tsx +38 -70
- package/src/progress-bar/ProgressBar.tsx +45 -20
- package/src/stepper/Step.tsx +1 -1
- package/src/stepper/Stepper.tsx +1 -1
- package/src/tabs/Tabs.context.ts +2 -0
- package/src/toggle-group/ToggleGroup.context.ts +1 -0
- package/src/util/hooks/descendants/useDescendant.tsx +55 -68
- package/src/{form/file-upload → util}/i18n/locales/nb.ts +5 -0
- package/src/util/types/AsChild.ts +15 -0
- package/cjs/form/combobox/ClearButton.d.ts +0 -7
- package/cjs/form/combobox/ClearButton.js +0 -28
- package/cjs/form/combobox/ClearButton.js.map +0 -1
- package/cjs/form/combobox/FilteredOptions/CheckIcon.d.ts +0 -3
- package/cjs/form/combobox/FilteredOptions/CheckIcon.js +0 -12
- package/cjs/form/combobox/FilteredOptions/CheckIcon.js.map +0 -1
- package/cjs/form/combobox/Input/inputContext.js.map +0 -1
- package/cjs/form/combobox/ToggleListButton.js.map +0 -1
- package/cjs/form/file-upload/i18n/get.js.map +0 -1
- package/cjs/form/file-upload/i18n/i18n.context.js.map +0 -1
- package/cjs/form/file-upload/i18n/i18n.types.js.map +0 -1
- package/cjs/form/file-upload/i18n/locales/nb.js.map +0 -1
- package/cjs/form/file-upload/i18n/merge.js.map +0 -1
- package/esm/form/combobox/ClearButton.d.ts +0 -7
- package/esm/form/combobox/ClearButton.js +0 -21
- package/esm/form/combobox/ClearButton.js.map +0 -1
- package/esm/form/combobox/FilteredOptions/CheckIcon.d.ts +0 -3
- package/esm/form/combobox/FilteredOptions/CheckIcon.js +0 -7
- package/esm/form/combobox/FilteredOptions/CheckIcon.js.map +0 -1
- package/esm/form/combobox/Input/inputContext.js.map +0 -1
- package/esm/form/combobox/ToggleListButton.js.map +0 -1
- package/esm/form/file-upload/i18n/get.js.map +0 -1
- package/esm/form/file-upload/i18n/i18n.context.js.map +0 -1
- package/esm/form/file-upload/i18n/i18n.types.js.map +0 -1
- package/esm/form/file-upload/i18n/locales/nb.js.map +0 -1
- package/esm/form/file-upload/i18n/merge.js.map +0 -1
- package/src/form/combobox/ClearButton.tsx +0 -29
- package/src/form/combobox/FilteredOptions/CheckIcon.tsx +0 -23
- /package/cjs/form/combobox/{ToggleListButton.d.ts → Input/ToggleListButton.d.ts} +0 -0
- /package/cjs/{form/file-upload → util}/i18n/get.d.ts +0 -0
- /package/cjs/{form/file-upload → util}/i18n/get.js +0 -0
- /package/cjs/{form/file-upload → util}/i18n/i18n.context.d.ts +0 -0
- /package/cjs/{form/file-upload → util}/i18n/i18n.context.js +0 -0
- /package/cjs/{form/file-upload → util}/i18n/i18n.types.d.ts +0 -0
- /package/cjs/{form/file-upload → util}/i18n/i18n.types.js +0 -0
- /package/cjs/{form/file-upload → util}/i18n/merge.d.ts +0 -0
- /package/cjs/{form/file-upload → util}/i18n/merge.js +0 -0
- /package/esm/form/combobox/{ToggleListButton.d.ts → Input/ToggleListButton.d.ts} +0 -0
- /package/esm/{form/file-upload → util}/i18n/get.d.ts +0 -0
- /package/esm/{form/file-upload → util}/i18n/get.js +0 -0
- /package/esm/{form/file-upload → util}/i18n/i18n.context.d.ts +0 -0
- /package/esm/{form/file-upload → util}/i18n/i18n.context.js +0 -0
- /package/esm/{form/file-upload → util}/i18n/i18n.types.d.ts +0 -0
- /package/esm/{form/file-upload → util}/i18n/i18n.types.js +0 -0
- /package/esm/{form/file-upload → util}/i18n/merge.d.ts +0 -0
- /package/esm/{form/file-upload → util}/i18n/merge.js +0 -0
- /package/src/{form/file-upload → util}/i18n/get.ts +0 -0
- /package/src/{form/file-upload → util}/i18n/i18n.context.test.tsx +0 -0
- /package/src/{form/file-upload → util}/i18n/i18n.context.ts +0 -0
- /package/src/{form/file-upload → util}/i18n/i18n.types.ts +0 -0
- /package/src/{form/file-upload → util}/i18n/merge.ts +0 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import React, { forwardRef, useEffect, useMemo, useRef, useState, } from "react";
|
|
13
|
+
import { Slot } from "../../util/Slot.js";
|
|
14
|
+
import { useMergeRefs } from "../../util/hooks/index.js";
|
|
15
|
+
import { createDescendantContext } from "../../util/hooks/descendants/useDescendant.js";
|
|
16
|
+
import { useEscapeKeydown } from "./util/useEscapeKeydown.js";
|
|
17
|
+
import { useFocusOutside } from "./util/useFocusOutside.js";
|
|
18
|
+
import { usePointerDownOutside } from "./util/usePointerDownOutside.js";
|
|
19
|
+
export const [DismissableDescendantsProvider, useDismissableDescendantsContext, useDismissableDescendants, useDismissableDescendant,] = createDescendantContext();
|
|
20
|
+
let originalBodyPointerEvents;
|
|
21
|
+
const DismissableLayer = forwardRef((props, ref) => {
|
|
22
|
+
const context = useDismissableDescendantsContext(false);
|
|
23
|
+
/**
|
|
24
|
+
* To correctly handle nested DismissableLayer,
|
|
25
|
+
* we only initialize the `Descendants`-API for the root layer to aboid resetting context
|
|
26
|
+
*/
|
|
27
|
+
return context ? (React.createElement(DismissableLayerNode, Object.assign({ ref: ref }, props))) : (React.createElement(DismissableRoot, null,
|
|
28
|
+
React.createElement(DismissableLayerNode, Object.assign({ ref: ref }, props))));
|
|
29
|
+
});
|
|
30
|
+
/**
|
|
31
|
+
* DismissableRoot
|
|
32
|
+
*
|
|
33
|
+
* Used to initialize the `Descendants`-API at the root layer.
|
|
34
|
+
* All subsequent layers will use the same context.
|
|
35
|
+
*/
|
|
36
|
+
const DismissableRoot = ({ children }) => {
|
|
37
|
+
const descendants = useDismissableDescendants();
|
|
38
|
+
return (React.createElement(DismissableDescendantsProvider, { value: descendants }, children));
|
|
39
|
+
};
|
|
40
|
+
const DismissableLayerNode = forwardRef((_a, ref) => {
|
|
41
|
+
var _b;
|
|
42
|
+
var { children, asChild, onEscapeKeyDown, onPointerDownOutside, onFocusOutside, onInteractOutside, onDismiss, safeZone, disableOutsidePointerEvents = false, enabled = true } = _a, rest = __rest(_a, ["children", "asChild", "onEscapeKeyDown", "onPointerDownOutside", "onFocusOutside", "onInteractOutside", "onDismiss", "safeZone", "disableOutsidePointerEvents", "enabled"]);
|
|
43
|
+
const { register, index, descendants } = useDismissableDescendant({
|
|
44
|
+
disableOutsidePointerEvents,
|
|
45
|
+
disabled: !enabled,
|
|
46
|
+
});
|
|
47
|
+
/**
|
|
48
|
+
* `node` will be set to the ref of the component or nested component
|
|
49
|
+
* Ex: If
|
|
50
|
+
* ```
|
|
51
|
+
* <DismissableLayer asChild>
|
|
52
|
+
* <Popover />
|
|
53
|
+
* </DismissableLayer>
|
|
54
|
+
* ```
|
|
55
|
+
* `node` will in this case be the Popover-element.
|
|
56
|
+
* We use State her and not ref since we want to trigger a rerender when the node changes.
|
|
57
|
+
*/
|
|
58
|
+
const [node, setNode] = useState(null);
|
|
59
|
+
const mergedRefs = useMergeRefs(setNode, register, ref);
|
|
60
|
+
/**
|
|
61
|
+
* In some cases the `node.ownerDocument` can differ from global document.
|
|
62
|
+
* This can happend when portaling elements or using web-components
|
|
63
|
+
*/
|
|
64
|
+
const ownerDocument = (_b = node === null || node === void 0 ? void 0 : node.ownerDocument) !== null && _b !== void 0 ? _b : globalThis === null || globalThis === void 0 ? void 0 : globalThis.document;
|
|
65
|
+
const hasInteractedOutsideRef = useRef(false);
|
|
66
|
+
const hasPointerDownOutsideRef = useRef(false);
|
|
67
|
+
const pointerEnabled = useMemo(() => {
|
|
68
|
+
let lastIndex = -1;
|
|
69
|
+
const descendantNodes = descendants.enabledValues();
|
|
70
|
+
descendantNodes.forEach((obj, _index) => {
|
|
71
|
+
if (obj.disableOutsidePointerEvents) {
|
|
72
|
+
lastIndex = _index;
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
return {
|
|
76
|
+
/**
|
|
77
|
+
* Makes sure we stop events at the highest layer with pointer events disabled.
|
|
78
|
+
* If not checked, we risk closing every layer when clicking outside the layer.
|
|
79
|
+
*/
|
|
80
|
+
isPointerEventsEnabled: index >= lastIndex,
|
|
81
|
+
/**
|
|
82
|
+
* If we find a node with `disableOutsidePointerEvents` we want to disable pointer events on the body.
|
|
83
|
+
*/
|
|
84
|
+
isBodyPointerEventsDisabled: lastIndex > -1,
|
|
85
|
+
};
|
|
86
|
+
}, [descendants, index]);
|
|
87
|
+
/**
|
|
88
|
+
* We want to prevent the Layer from closing when the trigger, anchor element, or its child elements are interacted with.
|
|
89
|
+
*
|
|
90
|
+
* To achieve this, we check if the event target is the trigger, anchor or a child. If it is, we prevent default event behavior.
|
|
91
|
+
*
|
|
92
|
+
* The `pointerDownOutside` and `focusOutside` handlers already check if the event target is within the DismissableLayer (`node`).
|
|
93
|
+
* However, since we don't add a `tabIndex` to the Popover/Tooltip, the `focusOutside` handler doesn't correctly handle focus events.
|
|
94
|
+
* Therefore, we also need to check that neither the trigger (`anchor`) nor the DismissableLayer (`dismissable`) are the event targets.
|
|
95
|
+
*/
|
|
96
|
+
function handleOutsideEvent(event) {
|
|
97
|
+
var _a, _b;
|
|
98
|
+
if ((!(safeZone === null || safeZone === void 0 ? void 0 : safeZone.anchor) && !(safeZone === null || safeZone === void 0 ? void 0 : safeZone.dismissable)) || !enabled) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
if (!event.defaultPrevented) {
|
|
102
|
+
hasInteractedOutsideRef.current = true;
|
|
103
|
+
if (event.detail.originalEvent.type === "pointerdown") {
|
|
104
|
+
hasPointerDownOutsideRef.current = true;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const target = event.target;
|
|
108
|
+
/**
|
|
109
|
+
* pointerdown-events works as expected, but focus-events does not.
|
|
110
|
+
* For focus-event we need to also check `safeZone.dismissable` (the Popover/Tooltip itself) since it does not have a tabIndex.
|
|
111
|
+
*/
|
|
112
|
+
if (event.detail.originalEvent.type === "pointerdown") {
|
|
113
|
+
const targetIsTrigger = ((_a = safeZone === null || safeZone === void 0 ? void 0 : safeZone.anchor) === null || _a === void 0 ? void 0 : _a.contains(target)) || target === (safeZone === null || safeZone === void 0 ? void 0 : safeZone.anchor);
|
|
114
|
+
targetIsTrigger && event.preventDefault();
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
const targetIsNotTrigger = target instanceof HTMLElement &&
|
|
118
|
+
![safeZone === null || safeZone === void 0 ? void 0 : safeZone.anchor, safeZone === null || safeZone === void 0 ? void 0 : safeZone.dismissable].some((element) => element === null || element === void 0 ? void 0 : element.contains(target)) &&
|
|
119
|
+
!target.contains((_b = safeZone === null || safeZone === void 0 ? void 0 : safeZone.dismissable) !== null && _b !== void 0 ? _b : null);
|
|
120
|
+
!targetIsNotTrigger && event.preventDefault();
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* In Safari, if the trigger element is inside a container with tabIndex={0}, a click on the trigger
|
|
124
|
+
* will first fire a 'pointerdownoutside' event on the trigger itself. However, it will then fire a
|
|
125
|
+
* 'focusoutside' event on the container.
|
|
126
|
+
*
|
|
127
|
+
* To handle this, we ignore any 'focusoutside' events if a 'pointerdownoutside' event has already occurred.
|
|
128
|
+
* 'pointerdownoutside' event is sufficient to indicate interaction outside the DismissableLayer.
|
|
129
|
+
*/
|
|
130
|
+
if (event.detail.originalEvent.type === "focusin" &&
|
|
131
|
+
hasPointerDownOutsideRef.current) {
|
|
132
|
+
event.preventDefault();
|
|
133
|
+
}
|
|
134
|
+
hasPointerDownOutsideRef.current = false;
|
|
135
|
+
hasInteractedOutsideRef.current = false;
|
|
136
|
+
}
|
|
137
|
+
const pointerDownOutside = usePointerDownOutside((event) => {
|
|
138
|
+
if (!pointerEnabled.isPointerEventsEnabled || !enabled) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* We call these before letting `handleOutsideEvent` do its checks to give consumer a chance to preventDefault based certain cases.
|
|
143
|
+
*/
|
|
144
|
+
onPointerDownOutside === null || onPointerDownOutside === void 0 ? void 0 : onPointerDownOutside(event);
|
|
145
|
+
onInteractOutside === null || onInteractOutside === void 0 ? void 0 : onInteractOutside(event);
|
|
146
|
+
/**
|
|
147
|
+
* Add safeZone to prevent closing when interacting with trigger/anchor or its children.
|
|
148
|
+
*/
|
|
149
|
+
safeZone && handleOutsideEvent(event);
|
|
150
|
+
/**
|
|
151
|
+
* Both `onPointerDownOutside` and `onInteractOutside` are able to preventDefault the event, thus stopping call for `onDismiss`.
|
|
152
|
+
*/
|
|
153
|
+
if (!event.defaultPrevented && onDismiss) {
|
|
154
|
+
onDismiss();
|
|
155
|
+
}
|
|
156
|
+
}, ownerDocument);
|
|
157
|
+
const focusOutside = useFocusOutside((event) => {
|
|
158
|
+
if (!enabled) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* We call these before letting `handleOutsideEvent` do its checks to give consumer a chance to preventDefault based certain cases.
|
|
163
|
+
*/
|
|
164
|
+
onFocusOutside === null || onFocusOutside === void 0 ? void 0 : onFocusOutside(event);
|
|
165
|
+
onInteractOutside === null || onInteractOutside === void 0 ? void 0 : onInteractOutside(event);
|
|
166
|
+
/**
|
|
167
|
+
* Add safeZone to prevent closing when interacting with trigger/anchor or its children.
|
|
168
|
+
*/
|
|
169
|
+
safeZone && handleOutsideEvent(event);
|
|
170
|
+
/**
|
|
171
|
+
* Both `onFocusOutside` and `onInteractOutside` are able to preventDefault the event, thus stopping call for `onDismiss`.
|
|
172
|
+
*/
|
|
173
|
+
if (!event.defaultPrevented && onDismiss) {
|
|
174
|
+
onDismiss();
|
|
175
|
+
}
|
|
176
|
+
}, ownerDocument);
|
|
177
|
+
useEscapeKeydown((event) => {
|
|
178
|
+
if (!enabled) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* The deepest nested element will always be last in the descendants list.
|
|
183
|
+
* This allows us to only close the highest layer when pressing escape.
|
|
184
|
+
*
|
|
185
|
+
* In some cases a layer might still exist, but be disabled. We want to ignore these layers.
|
|
186
|
+
*/
|
|
187
|
+
const isHighestLayer = index === descendants.enabledCount() - 1;
|
|
188
|
+
if (!isHighestLayer) {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* We call this before letting `handleOutsideEvent` do its checks to give consumer a chance to preventDefault based certain cases.
|
|
193
|
+
*/
|
|
194
|
+
onEscapeKeyDown === null || onEscapeKeyDown === void 0 ? void 0 : onEscapeKeyDown(event);
|
|
195
|
+
/**
|
|
196
|
+
* `onEscapeKeyDown` is able to preventDefault the event, thus stopping call for `onDismiss`.
|
|
197
|
+
* We want to `preventDefault` the escape-event to avoid sideeffect from other elements on screen
|
|
198
|
+
*/
|
|
199
|
+
if (!event.defaultPrevented && onDismiss) {
|
|
200
|
+
event.preventDefault();
|
|
201
|
+
onDismiss();
|
|
202
|
+
}
|
|
203
|
+
}, ownerDocument);
|
|
204
|
+
/**
|
|
205
|
+
* If `disableOutsidePointerEvents` is true,
|
|
206
|
+
* we want to disable pointer events on the body when the first layer is opened.
|
|
207
|
+
*/
|
|
208
|
+
useEffect(() => {
|
|
209
|
+
if (!node || !disableOutsidePointerEvents || index !== 0 || !enabled) {
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
originalBodyPointerEvents = ownerDocument.body.style.pointerEvents;
|
|
213
|
+
ownerDocument.body.style.pointerEvents = "none";
|
|
214
|
+
return () => {
|
|
215
|
+
ownerDocument.body.style.pointerEvents = originalBodyPointerEvents;
|
|
216
|
+
};
|
|
217
|
+
}, [node, ownerDocument, disableOutsidePointerEvents, index, enabled]);
|
|
218
|
+
const Comp = asChild ? Slot : "div";
|
|
219
|
+
return (React.createElement(Comp, Object.assign({ ref: mergedRefs }, rest, { onFocusCapture: focusOutside.onFocusCapture, onBlurCapture: focusOutside.onBlurCapture, onPointerDownCapture: pointerDownOutside.onPointerDownCapture, style: Object.assign({ pointerEvents: pointerEnabled.isBodyPointerEventsDisabled
|
|
220
|
+
? pointerEnabled.isPointerEventsEnabled
|
|
221
|
+
? "auto"
|
|
222
|
+
: "none"
|
|
223
|
+
: undefined }, rest.style) }), children));
|
|
224
|
+
});
|
|
225
|
+
export { DismissableLayer };
|
|
226
|
+
//# sourceMappingURL=DismissableLayer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DismissableLayer.js","sourceRoot":"","sources":["../../../src/overlay/dismiss/DismissableLayer.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
type CustomFocusEvent = CustomEvent<{
|
|
2
|
+
originalEvent: FocusEvent;
|
|
3
|
+
}>;
|
|
4
|
+
type CustomPointerDownEvent = CustomEvent<{
|
|
5
|
+
originalEvent: PointerEvent;
|
|
6
|
+
}>;
|
|
7
|
+
export { CustomFocusEvent, CustomPointerDownEvent };
|
|
8
|
+
export declare const CUSTOM_EVENTS: {
|
|
9
|
+
FOCUS_OUTSIDE: string;
|
|
10
|
+
POINTER_DOWN_OUTSIDE: string;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Use of `discrete` flushes custom event dispatch. This is to mimic the behavior React has for `discrete` events.
|
|
14
|
+
* https://github.com/facebook/react/blob/a8a4742f1c54493df00da648a3f9d26e3db9c8b5/packages/react-dom/src/events/ReactDOMEventListener.js#L318
|
|
15
|
+
*
|
|
16
|
+
* React batches *all* event handlers since version 18, this introduces certain considerations when using custom event types.
|
|
17
|
+
*
|
|
18
|
+
* Internally, React prioritises events in the following order:
|
|
19
|
+
* - discrete
|
|
20
|
+
* - continuous
|
|
21
|
+
* - default
|
|
22
|
+
*
|
|
23
|
+
* `discrete` is an important distinction as updates within these events are applied immediately.
|
|
24
|
+
* React however, is not able to infer the priority of custom event types due to how they are detected internally.
|
|
25
|
+
* Because of this, it's possible for updates from custom events to be unexpectedly batched when
|
|
26
|
+
* dispatched by another `discrete` event.
|
|
27
|
+
*
|
|
28
|
+
* In order to ensure that updates from custom events are applied predictably, we need to manually flush the batch.
|
|
29
|
+
* This utility should be used when dispatching a custom event from within another `discrete` event, this utility
|
|
30
|
+
* is not nessesary when dispatching known event types, or if dispatching a custom type inside a non-discrete event.
|
|
31
|
+
* For example:
|
|
32
|
+
*
|
|
33
|
+
* dispatching a known click 👎
|
|
34
|
+
* target.dispatchEvent(new Event(‘click’))
|
|
35
|
+
*
|
|
36
|
+
* dispatching a custom type within a non-discrete event 👎
|
|
37
|
+
* onScroll={(event) => event.target.dispatchEvent(new CustomEvent(‘customType’))}
|
|
38
|
+
*
|
|
39
|
+
* dispatching a custom type within a `discrete` event 👍
|
|
40
|
+
* onPointerDown={(event) => dispatchDiscreteCustomEvent(event.target, new CustomEvent(‘customType’))}
|
|
41
|
+
*
|
|
42
|
+
* Note: though React classifies `focus`, `focusin` and `focusout` events as `discrete`, it's not recommended to use
|
|
43
|
+
* this utility with them. This is because it's possible for those handlers to be called implicitly during render
|
|
44
|
+
* e.g. when focus is within a component as it is unmounted, or when managing focus on mount.
|
|
45
|
+
*/
|
|
46
|
+
export declare function dispatchCustomEvent<E extends CustomEvent, OriginalEvent extends Event>(name: string, handler: ((event: E) => void) | undefined, detail: {
|
|
47
|
+
originalEvent: OriginalEvent;
|
|
48
|
+
} & (E extends CustomEvent<infer D> ? D : never), { discrete }?: {
|
|
49
|
+
discrete: boolean;
|
|
50
|
+
}): void;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import ReactDOM from "react-dom";
|
|
2
|
+
export const CUSTOM_EVENTS = {
|
|
3
|
+
FOCUS_OUTSIDE: "AKSEL_FOCUS_OUTSIDE",
|
|
4
|
+
POINTER_DOWN_OUTSIDE: "AKSEL_POINTER_DOWN_OUTSIDE",
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Use of `discrete` flushes custom event dispatch. This is to mimic the behavior React has for `discrete` events.
|
|
8
|
+
* https://github.com/facebook/react/blob/a8a4742f1c54493df00da648a3f9d26e3db9c8b5/packages/react-dom/src/events/ReactDOMEventListener.js#L318
|
|
9
|
+
*
|
|
10
|
+
* React batches *all* event handlers since version 18, this introduces certain considerations when using custom event types.
|
|
11
|
+
*
|
|
12
|
+
* Internally, React prioritises events in the following order:
|
|
13
|
+
* - discrete
|
|
14
|
+
* - continuous
|
|
15
|
+
* - default
|
|
16
|
+
*
|
|
17
|
+
* `discrete` is an important distinction as updates within these events are applied immediately.
|
|
18
|
+
* React however, is not able to infer the priority of custom event types due to how they are detected internally.
|
|
19
|
+
* Because of this, it's possible for updates from custom events to be unexpectedly batched when
|
|
20
|
+
* dispatched by another `discrete` event.
|
|
21
|
+
*
|
|
22
|
+
* In order to ensure that updates from custom events are applied predictably, we need to manually flush the batch.
|
|
23
|
+
* This utility should be used when dispatching a custom event from within another `discrete` event, this utility
|
|
24
|
+
* is not nessesary when dispatching known event types, or if dispatching a custom type inside a non-discrete event.
|
|
25
|
+
* For example:
|
|
26
|
+
*
|
|
27
|
+
* dispatching a known click 👎
|
|
28
|
+
* target.dispatchEvent(new Event(‘click’))
|
|
29
|
+
*
|
|
30
|
+
* dispatching a custom type within a non-discrete event 👎
|
|
31
|
+
* onScroll={(event) => event.target.dispatchEvent(new CustomEvent(‘customType’))}
|
|
32
|
+
*
|
|
33
|
+
* dispatching a custom type within a `discrete` event 👍
|
|
34
|
+
* onPointerDown={(event) => dispatchDiscreteCustomEvent(event.target, new CustomEvent(‘customType’))}
|
|
35
|
+
*
|
|
36
|
+
* Note: though React classifies `focus`, `focusin` and `focusout` events as `discrete`, it's not recommended to use
|
|
37
|
+
* this utility with them. This is because it's possible for those handlers to be called implicitly during render
|
|
38
|
+
* e.g. when focus is within a component as it is unmounted, or when managing focus on mount.
|
|
39
|
+
*/
|
|
40
|
+
export function dispatchCustomEvent(name, handler, detail, { discrete } = { discrete: false }) {
|
|
41
|
+
if (!handler) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const target = detail.originalEvent.target;
|
|
45
|
+
const event = new CustomEvent(name, {
|
|
46
|
+
bubbles: false,
|
|
47
|
+
cancelable: true,
|
|
48
|
+
detail,
|
|
49
|
+
});
|
|
50
|
+
target.addEventListener(name, handler, { once: true });
|
|
51
|
+
if (discrete && target) {
|
|
52
|
+
ReactDOM.flushSync(() => target.dispatchEvent(event));
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
target.dispatchEvent(event);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=dispatchCustomEvent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatchCustomEvent.js","sourceRoot":"","sources":["../../../../src/overlay/dismiss/util/dispatchCustomEvent.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,WAAW,CAAC;AASjC,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,aAAa,EAAE,qBAAqB;IACpC,oBAAoB,EAAE,4BAA4B;CACnD,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,UAAU,mBAAmB,CAIjC,IAAY,EACZ,OAAyC,EACzC,MAEU,EACV,EAAE,QAAQ,KAA4B,EAAE,QAAQ,EAAE,KAAK,EAAE;IAEzD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;IACT,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC;IAC3C,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,IAAI,EAAE;QAClC,OAAO,EAAE,KAAK;QACd,UAAU,EAAE,IAAI;QAChB,MAAM;KACP,CAAC,CAAC;IAEH,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,OAAwB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAExE,IAAI,QAAQ,IAAI,MAAM,EAAE,CAAC;QACvB,QAAQ,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;IACxD,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function useEscapeKeydown(callback?: (event: KeyboardEvent) => void, ownerDocument?: Document): void;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
import { useCallbackRef } from "../../../util/hooks/index.js";
|
|
3
|
+
export function useEscapeKeydown(callback, ownerDocument = globalThis === null || globalThis === void 0 ? void 0 : globalThis.document) {
|
|
4
|
+
const onEscapeKeyDown = useCallbackRef(callback);
|
|
5
|
+
useEffect(() => {
|
|
6
|
+
const handleKeyDown = (event) => {
|
|
7
|
+
if (event.key === "Escape") {
|
|
8
|
+
onEscapeKeyDown(event);
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
ownerDocument.addEventListener("keydown", handleKeyDown, true);
|
|
12
|
+
return () => ownerDocument.removeEventListener("keydown", handleKeyDown, true);
|
|
13
|
+
}, [onEscapeKeyDown, ownerDocument]);
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=useEscapeKeydown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useEscapeKeydown.js","sourceRoot":"","sources":["../../../../src/overlay/dismiss/util/useEscapeKeydown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,MAAM,UAAU,gBAAgB,CAC9B,QAAyC,EACzC,gBAA0B,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,QAAQ;IAE9C,MAAM,eAAe,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;IAEjD,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,aAAa,GAAG,CAAC,KAAoB,EAAE,EAAE;YAC7C,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;gBAC3B,eAAe,CAAC,KAAK,CAAC,CAAC;YACzB,CAAC;QACH,CAAC,CAAC;QAEF,aAAa,CAAC,gBAAgB,CAAC,SAAS,EAAE,aAAa,EAAE,IAAI,CAAC,CAAC;QAC/D,OAAO,GAAG,EAAE,CACV,aAAa,CAAC,mBAAmB,CAAC,SAAS,EAAE,aAAa,EAAE,IAAI,CAAC,CAAC;IACtE,CAAC,EAAE,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { CustomFocusEvent } from "./dispatchCustomEvent.js";
|
|
2
|
+
/**
|
|
3
|
+
* Tracks focus outside a React subtree. Returns props for the subtree root.
|
|
4
|
+
*/
|
|
5
|
+
export declare function useFocusOutside(callback?: (event: CustomFocusEvent) => void, ownerDocument?: Document): {
|
|
6
|
+
onFocusCapture: () => boolean;
|
|
7
|
+
onBlurCapture: () => boolean;
|
|
8
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useEffect, useRef } from "react";
|
|
2
|
+
import { useCallbackRef } from "../../../util/hooks/index.js";
|
|
3
|
+
import { CUSTOM_EVENTS, dispatchCustomEvent, } from "./dispatchCustomEvent.js";
|
|
4
|
+
/**
|
|
5
|
+
* Tracks focus outside a React subtree. Returns props for the subtree root.
|
|
6
|
+
*/
|
|
7
|
+
export function useFocusOutside(callback, ownerDocument = globalThis === null || globalThis === void 0 ? void 0 : globalThis.document) {
|
|
8
|
+
const handleFocusOutside = useCallbackRef(callback);
|
|
9
|
+
const isFocusInsideReactTreeRef = useRef(false);
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
const handleFocus = (event) => {
|
|
12
|
+
if (event.target && !isFocusInsideReactTreeRef.current) {
|
|
13
|
+
const eventDetail = { originalEvent: event };
|
|
14
|
+
/**
|
|
15
|
+
* The `DismisableLayer`-API is based on the ability to stop events from propagating and in the end calling `onDismiss`
|
|
16
|
+
* if `useFocusOutside`-callback runs `event.preventDefault()`.
|
|
17
|
+
*
|
|
18
|
+
* Because of the `focusin`-event not being cancelable,
|
|
19
|
+
* we need to use a custom event to ensure that the event is cancelable.
|
|
20
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Element/focusin_event
|
|
21
|
+
* > The focusin event is not cancelable.
|
|
22
|
+
*/
|
|
23
|
+
dispatchCustomEvent(CUSTOM_EVENTS.FOCUS_OUTSIDE, handleFocusOutside, eventDetail);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
ownerDocument.addEventListener("focusin", handleFocus);
|
|
27
|
+
return () => ownerDocument.removeEventListener("focusin", handleFocus);
|
|
28
|
+
}, [ownerDocument, handleFocusOutside]);
|
|
29
|
+
/**
|
|
30
|
+
* By directly setting isFocusInsideReactTreeRef on focus-events at the root of the "dismissable" element,
|
|
31
|
+
* we can eliminate the need for DOM traversal to verify if the focused element is within the react tree.
|
|
32
|
+
*/
|
|
33
|
+
return {
|
|
34
|
+
onFocusCapture: () => (isFocusInsideReactTreeRef.current = true),
|
|
35
|
+
onBlurCapture: () => (isFocusInsideReactTreeRef.current = false),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=useFocusOutside.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFocusOutside.js","sourceRoot":"","sources":["../../../../src/overlay/dismiss/util/useFocusOutside.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EACL,aAAa,EAEb,mBAAmB,GACpB,MAAM,uBAAuB,CAAC;AAE/B;;GAEG;AACH,MAAM,UAAU,eAAe,CAC7B,QAA4C,EAC5C,gBAA0B,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,QAAQ;IAE9C,MAAM,kBAAkB,GAAG,cAAc,CAAC,QAAQ,CAAkB,CAAC;IACrE,MAAM,yBAAyB,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAEhD,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,WAAW,GAAG,CAAC,KAAiB,EAAE,EAAE;YACxC,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,yBAAyB,CAAC,OAAO,EAAE,CAAC;gBACvD,MAAM,WAAW,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC;gBAE7C;;;;;;;;mBAQG;gBACH,mBAAmB,CACjB,aAAa,CAAC,aAAa,EAC3B,kBAAkB,EAClB,WAAW,CACZ,CAAC;YACJ,CAAC;QACH,CAAC,CAAC;QACF,aAAa,CAAC,gBAAgB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QACvD,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,mBAAmB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IACzE,CAAC,EAAE,CAAC,aAAa,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAExC;;;OAGG;IACH,OAAO;QACL,cAAc,EAAE,GAAG,EAAE,CAAC,CAAC,yBAAyB,CAAC,OAAO,GAAG,IAAI,CAAC;QAChE,aAAa,EAAE,GAAG,EAAE,CAAC,CAAC,yBAAyB,CAAC,OAAO,GAAG,KAAK,CAAC;KACjE,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { CustomPointerDownEvent } from "./dispatchCustomEvent.js";
|
|
2
|
+
/**
|
|
3
|
+
* Listens for `pointerdown` outside a react subtree. We use `pointerdown` rather than `pointerup`
|
|
4
|
+
* to mimic layer dismissing behaviour present in OS.
|
|
5
|
+
* Returns props to pass to the node we want to check for outside events.
|
|
6
|
+
* By checking `isPointerInsideReactTreeRef` we can determine if the event happened outside the subtree of the node, saving some element-comparisons.
|
|
7
|
+
*/
|
|
8
|
+
export declare function usePointerDownOutside(callback?: (event: CustomPointerDownEvent) => void, ownerDocument?: Document): {
|
|
9
|
+
onPointerDownCapture: () => boolean;
|
|
10
|
+
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { useEffect, useRef } from "react";
|
|
2
|
+
import { useCallbackRef } from "../../../util/hooks/index.js";
|
|
3
|
+
import { CUSTOM_EVENTS, dispatchCustomEvent, } from "./dispatchCustomEvent.js";
|
|
4
|
+
/**
|
|
5
|
+
* Listens for `pointerdown` outside a react subtree. We use `pointerdown` rather than `pointerup`
|
|
6
|
+
* to mimic layer dismissing behaviour present in OS.
|
|
7
|
+
* Returns props to pass to the node we want to check for outside events.
|
|
8
|
+
* By checking `isPointerInsideReactTreeRef` we can determine if the event happened outside the subtree of the node, saving some element-comparisons.
|
|
9
|
+
*/
|
|
10
|
+
export function usePointerDownOutside(callback, ownerDocument = globalThis === null || globalThis === void 0 ? void 0 : globalThis.document) {
|
|
11
|
+
const handlePointerDownOutside = useCallbackRef(callback);
|
|
12
|
+
const isPointerInsideReactTreeRef = useRef(false);
|
|
13
|
+
const handleClickRef = useRef(() => { });
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
const handlePointerDown = (event) => {
|
|
16
|
+
/**
|
|
17
|
+
* The `DismisableLayer`-API is based on the ability to stop events from propagating and in the end calling `onDismiss`
|
|
18
|
+
* if `usePointerDownOutside` runs `event.preventDefault()`.
|
|
19
|
+
*
|
|
20
|
+
* Altrough `pointerdown` is already a cancelable event,
|
|
21
|
+
* to to make sure the batching of events works corretly with `focusIn` in `useFocusOutside`,
|
|
22
|
+
* we still use a custom event like in `useFocusOutside`.
|
|
23
|
+
*
|
|
24
|
+
* Since pointer-events are `discrete` events in React: https://github.com/facebook/react/blob/a8a4742f1c54493df00da648a3f9d26e3db9c8b5/packages/react-dom/src/events/ReactDOMEventListener.js#L318
|
|
25
|
+
* we need to to use flushSync to ensure that the event is dispatched before the next event is raised.
|
|
26
|
+
*/
|
|
27
|
+
function dispatchPointerEvent() {
|
|
28
|
+
dispatchCustomEvent(CUSTOM_EVENTS.POINTER_DOWN_OUTSIDE, handlePointerDownOutside, { originalEvent: event }, { discrete: true });
|
|
29
|
+
}
|
|
30
|
+
if (event.target && !isPointerInsideReactTreeRef.current) {
|
|
31
|
+
/**
|
|
32
|
+
* On touch devices, we delay reactivating pointer-events to account for the browser's delay in executing events after touch ends.
|
|
33
|
+
* This also handles cancellations when no click event is raised due to scrolling or long-pressing.
|
|
34
|
+
* We continuously remove the previous listener as we can't be sure it was raised and cleaned up.
|
|
35
|
+
*/
|
|
36
|
+
if (event.pointerType === "touch") {
|
|
37
|
+
ownerDocument.removeEventListener("click", handleClickRef.current);
|
|
38
|
+
handleClickRef.current = dispatchPointerEvent;
|
|
39
|
+
ownerDocument.addEventListener("click", handleClickRef.current, {
|
|
40
|
+
once: true,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
dispatchPointerEvent();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
// We need to remove the event listener in case the outside click has been canceled.
|
|
49
|
+
ownerDocument.removeEventListener("click", handleClickRef.current);
|
|
50
|
+
}
|
|
51
|
+
isPointerInsideReactTreeRef.current = false;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* If this hook executes in a component that mounts via a `pointerdown` event, the event
|
|
55
|
+
* would bubble up to the document and trigger a `pointerDownOutside` event. We avoid
|
|
56
|
+
* this by delaying the event listener registration on the document.
|
|
57
|
+
* This is not React specific, but rather how the DOM works, ie:
|
|
58
|
+
* ```
|
|
59
|
+
* button.addEventListener('pointerdown', () => {
|
|
60
|
+
* console.log('I will log');
|
|
61
|
+
* document.addEventListener('pointerdown', () => {
|
|
62
|
+
* console.log('I will also log');
|
|
63
|
+
* })
|
|
64
|
+
* });
|
|
65
|
+
*/
|
|
66
|
+
const timerId = window.setTimeout(() => {
|
|
67
|
+
ownerDocument.addEventListener("pointerdown", handlePointerDown);
|
|
68
|
+
}, 0);
|
|
69
|
+
return () => {
|
|
70
|
+
window.clearTimeout(timerId);
|
|
71
|
+
ownerDocument.removeEventListener("pointerdown", handlePointerDown);
|
|
72
|
+
ownerDocument.removeEventListener("click", handleClickRef.current);
|
|
73
|
+
};
|
|
74
|
+
}, [ownerDocument, handlePointerDownOutside]);
|
|
75
|
+
return {
|
|
76
|
+
// ensures we check React component tree (not just DOM tree)
|
|
77
|
+
onPointerDownCapture: () => (isPointerInsideReactTreeRef.current = true),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=usePointerDownOutside.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePointerDownOutside.js","sourceRoot":"","sources":["../../../../src/overlay/dismiss/util/usePointerDownOutside.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EACL,aAAa,EAEb,mBAAmB,GACpB,MAAM,uBAAuB,CAAC;AAE/B;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CACnC,QAAkD,EAClD,gBAA0B,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,QAAQ;IAE9C,MAAM,wBAAwB,GAAG,cAAc,CAAC,QAAQ,CAAkB,CAAC;IAC3E,MAAM,2BAA2B,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAClD,MAAM,cAAc,GAAG,MAAM,CAAkC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAEzE,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,iBAAiB,GAAG,CAAC,KAAmB,EAAE,EAAE;YAChD;;;;;;;;;;eAUG;YACH,SAAS,oBAAoB;gBAC3B,mBAAmB,CACjB,aAAa,CAAC,oBAAoB,EAClC,wBAAwB,EACxB,EAAE,aAAa,EAAE,KAAK,EAAE,EACxB,EAAE,QAAQ,EAAE,IAAI,EAAE,CACnB,CAAC;YACJ,CAAC;YAED,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,2BAA2B,CAAC,OAAO,EAAE,CAAC;gBACzD;;;;mBAIG;gBACH,IAAI,KAAK,CAAC,WAAW,KAAK,OAAO,EAAE,CAAC;oBAClC,aAAa,CAAC,mBAAmB,CAAC,OAAO,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC;oBACnE,cAAc,CAAC,OAAO,GAAG,oBAAoB,CAAC;oBAC9C,aAAa,CAAC,gBAAgB,CAAC,OAAO,EAAE,cAAc,CAAC,OAAO,EAAE;wBAC9D,IAAI,EAAE,IAAI;qBACX,CAAC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACN,oBAAoB,EAAE,CAAC;gBACzB,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,oFAAoF;gBACpF,aAAa,CAAC,mBAAmB,CAAC,OAAO,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC;YACrE,CAAC;YACD,2BAA2B,CAAC,OAAO,GAAG,KAAK,CAAC;QAC9C,CAAC,CAAC;QAEF;;;;;;;;;;;;WAYG;QACH,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE;YACrC,aAAa,CAAC,gBAAgB,CAAC,aAAa,EAAE,iBAAiB,CAAC,CAAC;QACnE,CAAC,EAAE,CAAC,CAAC,CAAC;QAEN,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;YAC7B,aAAa,CAAC,mBAAmB,CAAC,aAAa,EAAE,iBAAiB,CAAC,CAAC;YACpE,aAAa,CAAC,mBAAmB,CAAC,OAAO,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC;QACrE,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,aAAa,EAAE,wBAAwB,CAAC,CAAC,CAAC;IAE9C,OAAO;QACL,4DAA4D;QAC5D,oBAAoB,EAAE,GAAG,EAAE,CAAC,CAAC,2BAA2B,CAAC,OAAO,GAAG,IAAI,CAAC;KACzE,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import React, { HTMLAttributes } from "react";
|
|
2
|
+
import { AsChildProps } from "../../util/types/index.js";
|
|
3
|
+
import { type Align, type Measurable, type Side } from "./Floating.utils.js";
|
|
4
|
+
/**
|
|
5
|
+
* Floating Root
|
|
6
|
+
*/
|
|
7
|
+
type FloatingContextValue = {
|
|
8
|
+
anchor: Measurable | null;
|
|
9
|
+
onAnchorChange: (anchor: Measurable | null) => void;
|
|
10
|
+
};
|
|
11
|
+
export declare const FloatingProvider: React.ForwardRefExoticComponent<FloatingContextValue & {
|
|
12
|
+
children: React.ReactNode;
|
|
13
|
+
} & React.RefAttributes<unknown>>, useFloatingContext: <S extends boolean = true>(strict?: S) => S extends true ? FloatingContextValue : FloatingContextValue | undefined;
|
|
14
|
+
interface FloatingProps {
|
|
15
|
+
children: React.ReactNode;
|
|
16
|
+
}
|
|
17
|
+
interface FloatingComponent extends React.FC<FloatingProps> {
|
|
18
|
+
Anchor: typeof FloatingAnchor;
|
|
19
|
+
Content: typeof FloatingContent;
|
|
20
|
+
}
|
|
21
|
+
declare const Floating: FloatingComponent;
|
|
22
|
+
/**
|
|
23
|
+
* Floating Anchor
|
|
24
|
+
*/
|
|
25
|
+
type FloatingAnchorProps = HTMLAttributes<HTMLDivElement> & AsChildProps & {
|
|
26
|
+
virtualRef?: React.RefObject<Measurable>;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* `FloatingAnchor` provides an anchor for a Floating instance.
|
|
30
|
+
* Allows anchoring to non-DOM nodes like a cursor position when used with `virtualRef`.
|
|
31
|
+
*/
|
|
32
|
+
declare const FloatingAnchor: React.ForwardRefExoticComponent<FloatingAnchorProps & React.RefAttributes<HTMLDivElement>>;
|
|
33
|
+
type Boundary = Element | null;
|
|
34
|
+
interface FloatingContentProps extends HTMLAttributes<HTMLDivElement> {
|
|
35
|
+
side?: Side;
|
|
36
|
+
sideOffset?: number;
|
|
37
|
+
align?: Align;
|
|
38
|
+
alignOffset?: number;
|
|
39
|
+
avoidCollisions?: boolean;
|
|
40
|
+
collisionBoundary?: Boundary | Boundary[];
|
|
41
|
+
collisionPadding?: number | Partial<Record<Side, number>>;
|
|
42
|
+
hideWhenDetached?: boolean;
|
|
43
|
+
updatePositionStrategy?: "optimized" | "always";
|
|
44
|
+
onPlaced?: () => void;
|
|
45
|
+
arrow?: {
|
|
46
|
+
className?: string;
|
|
47
|
+
padding?: number;
|
|
48
|
+
width: number;
|
|
49
|
+
height: number;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
declare const FloatingContent: React.ForwardRefExoticComponent<FloatingContentProps & React.RefAttributes<HTMLDivElement>>;
|
|
53
|
+
export { Floating };
|