@elliemae/ds-menu-button 3.45.0-rc.0 → 3.45.0-rc.2
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/cjs/DSMenuButton.js +16 -5
- package/dist/cjs/DSMenuButton.js.map +2 -2
- package/dist/cjs/config/useMenuButton.js +49 -18
- package/dist/cjs/config/useMenuButton.js.map +3 -3
- package/dist/cjs/config/useSplitInherithedProps.js +141 -0
- package/dist/cjs/config/useSplitInherithedProps.js.map +7 -0
- package/dist/cjs/config/useValidateProps.js.map +2 -2
- package/dist/cjs/constants/index.js +17 -4
- package/dist/cjs/constants/index.js.map +2 -2
- package/dist/cjs/index.js +7 -3
- package/dist/cjs/index.js.map +3 -3
- package/dist/cjs/parts/DSFlyoutMenu/DSFlyoutMenu.js +96 -0
- package/dist/cjs/parts/DSFlyoutMenu/DSFlyoutMenu.js.map +7 -0
- package/dist/cjs/parts/DSFlyoutMenu/config/useFlyoutMenu.js +54 -0
- package/dist/cjs/parts/DSFlyoutMenu/config/useFlyoutMenu.js.map +7 -0
- package/dist/cjs/parts/{ItemFactory.js → DSFlyoutMenu/config/useValidateProps.js} +9 -35
- package/dist/cjs/parts/DSFlyoutMenu/config/useValidateProps.js.map +7 -0
- package/dist/cjs/parts/DSFlyoutMenu/constants/index.js +46 -0
- package/dist/cjs/parts/DSFlyoutMenu/constants/index.js.map +7 -0
- package/dist/cjs/{DSMenuButtonCTX.js → parts/DSFlyoutMenu/index.js} +7 -8
- package/dist/cjs/parts/DSFlyoutMenu/index.js.map +7 -0
- package/dist/cjs/parts/DSFlyoutMenu/react-desc-prop-types.js +62 -0
- package/dist/cjs/parts/DSFlyoutMenu/react-desc-prop-types.js.map +7 -0
- package/dist/cjs/parts/DSMenuBehaviouralContextProvider/DSMenuBehaviouralContextProvider.js +70 -0
- package/dist/cjs/parts/DSMenuBehaviouralContextProvider/DSMenuBehaviouralContextProvider.js.map +7 -0
- package/dist/cjs/parts/DSMenuBehaviouralContextProvider/MenuBehaviouralContextProviderCTX.js +40 -0
- package/dist/cjs/parts/DSMenuBehaviouralContextProvider/MenuBehaviouralContextProviderCTX.js.map +7 -0
- package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useFocusTracker.js +186 -0
- package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useFocusTracker.js.map +7 -0
- package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useGlobalEvents.js +89 -0
- package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useGlobalEvents.js.map +7 -0
- package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useMenuBehaviouralContextProvider.js +92 -0
- package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useMenuBehaviouralContextProvider.js.map +7 -0
- package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useMenuItemEventsHandlers.js +315 -0
- package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useMenuItemEventsHandlers.js.map +7 -0
- package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useMenuOpenStatus.js +66 -0
- package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useMenuOpenStatus.js.map +7 -0
- package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useValidateProps.js +40 -0
- package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useValidateProps.js.map +7 -0
- package/dist/cjs/parts/DSMenuBehaviouralContextProvider/constants/Errors.js +58 -0
- package/dist/cjs/parts/DSMenuBehaviouralContextProvider/constants/Errors.js.map +7 -0
- package/dist/cjs/parts/DSMenuBehaviouralContextProvider/constants/index.js +44 -0
- package/dist/cjs/parts/DSMenuBehaviouralContextProvider/constants/index.js.map +7 -0
- package/dist/cjs/parts/DSMenuBehaviouralContextProvider/index.js +37 -0
- package/dist/cjs/parts/DSMenuBehaviouralContextProvider/index.js.map +7 -0
- package/dist/cjs/parts/DSMenuBehaviouralContextProvider/react-desc-prop-types.js +53 -0
- package/dist/cjs/parts/DSMenuBehaviouralContextProvider/react-desc-prop-types.js.map +7 -0
- package/dist/cjs/parts/DSMenuBehaviouralContextProvider/utils/multipleSelectionHelpers.js +139 -0
- package/dist/cjs/parts/DSMenuBehaviouralContextProvider/utils/multipleSelectionHelpers.js.map +7 -0
- package/dist/cjs/parts/DSMenuBehaviouralContextProvider/utils/nodeGettersByCriterias.js +144 -0
- package/dist/cjs/parts/DSMenuBehaviouralContextProvider/utils/nodeGettersByCriterias.js.map +7 -0
- package/dist/cjs/parts/DSMenuBehaviouralContextProvider/utils/singleSelectionHelpers.js +44 -0
- package/dist/cjs/parts/DSMenuBehaviouralContextProvider/utils/singleSelectionHelpers.js.map +7 -0
- package/dist/cjs/parts/DSMenuItemRendererFactory/ActivableMenuItem.js +116 -0
- package/dist/cjs/parts/DSMenuItemRendererFactory/ActivableMenuItem.js.map +7 -0
- package/dist/cjs/parts/DSMenuItemRendererFactory/ActivableWithSubmenuMenuItem.js +159 -0
- package/dist/cjs/parts/DSMenuItemRendererFactory/ActivableWithSubmenuMenuItem.js.map +7 -0
- package/dist/cjs/parts/DSMenuItemRendererFactory/DSMenuItemRendererFactory.js +97 -0
- package/dist/cjs/parts/DSMenuItemRendererFactory/DSMenuItemRendererFactory.js.map +7 -0
- package/dist/cjs/parts/DSMenuItemRendererFactory/MultipleSelectMenuItem.js +122 -0
- package/dist/cjs/parts/DSMenuItemRendererFactory/MultipleSelectMenuItem.js.map +7 -0
- package/dist/cjs/parts/DSMenuItemRendererFactory/MultipleSelectWithSubmenuMenuItem.js +173 -0
- package/dist/cjs/parts/DSMenuItemRendererFactory/MultipleSelectWithSubmenuMenuItem.js.map +7 -0
- package/dist/cjs/parts/DSMenuItemRendererFactory/SingleSelectMenuItem.js +130 -0
- package/dist/cjs/parts/DSMenuItemRendererFactory/SingleSelectMenuItem.js.map +7 -0
- package/dist/cjs/parts/DSMenuItemRendererFactory/SingleSelectWithSubmenuMenuItem.js +176 -0
- package/dist/cjs/parts/DSMenuItemRendererFactory/SingleSelectWithSubmenuMenuItem.js.map +7 -0
- package/dist/cjs/parts/DSMenuItemRendererFactory/WithSubmenuMenuItem.js +162 -0
- package/dist/cjs/parts/DSMenuItemRendererFactory/WithSubmenuMenuItem.js.map +7 -0
- package/dist/cjs/parts/DSMenuItemRendererFactory/config/useMenuItemRendererFactory.js +57 -0
- package/dist/cjs/parts/DSMenuItemRendererFactory/config/useMenuItemRendererFactory.js.map +7 -0
- package/dist/cjs/parts/DSMenuItemRendererFactory/config/useValidateProps.js +40 -0
- package/dist/cjs/parts/DSMenuItemRendererFactory/config/useValidateProps.js.map +7 -0
- package/dist/cjs/parts/DSMenuItemRendererFactory/constants/index.js +48 -0
- package/dist/cjs/parts/DSMenuItemRendererFactory/constants/index.js.map +7 -0
- package/dist/cjs/parts/DSMenuItemRendererFactory/index.js +37 -0
- package/dist/cjs/parts/DSMenuItemRendererFactory/index.js.map +7 -0
- package/dist/cjs/parts/DSMenuItemRendererFactory/react-desc-prop-types.js +51 -0
- package/dist/cjs/parts/DSMenuItemRendererFactory/react-desc-prop-types.js.map +7 -0
- package/dist/cjs/parts/DSMenuItemRendererFactory/useMenuItemHighlightState.js +62 -0
- package/dist/cjs/parts/DSMenuItemRendererFactory/useMenuItemHighlightState.js.map +7 -0
- package/dist/cjs/parts/DSOpinionatedButton/DSOpinionatedButton.js +100 -0
- package/dist/cjs/parts/DSOpinionatedButton/DSOpinionatedButton.js.map +7 -0
- package/dist/cjs/parts/DSOpinionatedButton/config/useOpinionatedButton.js +80 -0
- package/dist/cjs/parts/DSOpinionatedButton/config/useOpinionatedButton.js.map +7 -0
- package/dist/cjs/parts/DSOpinionatedButton/config/useTriggerEventsHandlers.js +98 -0
- package/dist/cjs/parts/DSOpinionatedButton/config/useTriggerEventsHandlers.js.map +7 -0
- package/dist/cjs/parts/DSOpinionatedButton/config/useValidateProps.js +40 -0
- package/dist/cjs/parts/DSOpinionatedButton/config/useValidateProps.js.map +7 -0
- package/dist/cjs/parts/DSOpinionatedButton/constants/index.js +48 -0
- package/dist/cjs/parts/DSOpinionatedButton/constants/index.js.map +7 -0
- package/dist/cjs/parts/DSOpinionatedButton/index.js +37 -0
- package/dist/cjs/parts/DSOpinionatedButton/index.js.map +7 -0
- package/dist/cjs/parts/DSOpinionatedButton/react-desc-prop-types.js +53 -0
- package/dist/cjs/parts/DSOpinionatedButton/react-desc-prop-types.js.map +7 -0
- package/dist/cjs/react-desc-prop-types.js +61 -25
- package/dist/cjs/react-desc-prop-types.js.map +2 -2
- package/dist/cjs/utils/nodesTypeguardsAndGetters.js +123 -0
- package/dist/cjs/utils/nodesTypeguardsAndGetters.js.map +7 -0
- package/dist/cjs/utils/useOptionsArrayToDsTree.js +55 -0
- package/dist/cjs/utils/useOptionsArrayToDsTree.js.map +7 -0
- package/dist/esm/DSMenuButton.js +19 -8
- package/dist/esm/DSMenuButton.js.map +2 -2
- package/dist/esm/config/useMenuButton.js +51 -20
- package/dist/esm/config/useMenuButton.js.map +3 -3
- package/dist/esm/config/useSplitInherithedProps.js +111 -0
- package/dist/esm/config/useSplitInherithedProps.js.map +7 -0
- package/dist/esm/config/useValidateProps.js.map +2 -2
- package/dist/esm/constants/index.js +17 -4
- package/dist/esm/constants/index.js.map +2 -2
- package/dist/esm/index.js +8 -4
- package/dist/esm/index.js.map +3 -3
- package/dist/esm/parts/DSFlyoutMenu/DSFlyoutMenu.js +66 -0
- package/dist/esm/parts/DSFlyoutMenu/DSFlyoutMenu.js.map +7 -0
- package/dist/esm/parts/DSFlyoutMenu/config/useFlyoutMenu.js +24 -0
- package/dist/esm/parts/DSFlyoutMenu/config/useFlyoutMenu.js.map +7 -0
- package/dist/esm/parts/DSFlyoutMenu/config/useValidateProps.js +10 -0
- package/dist/esm/parts/DSFlyoutMenu/config/useValidateProps.js.map +7 -0
- package/dist/esm/parts/DSFlyoutMenu/constants/index.js +16 -0
- package/dist/esm/parts/DSFlyoutMenu/constants/index.js.map +7 -0
- package/dist/esm/parts/DSFlyoutMenu/index.js +7 -0
- package/dist/esm/parts/DSFlyoutMenu/index.js.map +7 -0
- package/dist/esm/parts/DSFlyoutMenu/react-desc-prop-types.js +40 -0
- package/dist/esm/parts/DSFlyoutMenu/react-desc-prop-types.js.map +7 -0
- package/dist/esm/parts/DSMenuBehaviouralContextProvider/DSMenuBehaviouralContextProvider.js +42 -0
- package/dist/esm/parts/DSMenuBehaviouralContextProvider/DSMenuBehaviouralContextProvider.js.map +7 -0
- package/dist/esm/parts/DSMenuBehaviouralContextProvider/MenuBehaviouralContextProviderCTX.js +10 -0
- package/dist/esm/parts/DSMenuBehaviouralContextProvider/MenuBehaviouralContextProviderCTX.js.map +7 -0
- package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useFocusTracker.js +161 -0
- package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useFocusTracker.js.map +7 -0
- package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useGlobalEvents.js +59 -0
- package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useGlobalEvents.js.map +7 -0
- package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useMenuBehaviouralContextProvider.js +65 -0
- package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useMenuBehaviouralContextProvider.js.map +7 -0
- package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useMenuItemEventsHandlers.js +292 -0
- package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useMenuItemEventsHandlers.js.map +7 -0
- package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useMenuOpenStatus.js +36 -0
- package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useMenuOpenStatus.js.map +7 -0
- package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useValidateProps.js +10 -0
- package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useValidateProps.js.map +7 -0
- package/dist/esm/parts/DSMenuBehaviouralContextProvider/constants/Errors.js +28 -0
- package/dist/esm/parts/DSMenuBehaviouralContextProvider/constants/Errors.js.map +7 -0
- package/dist/esm/parts/DSMenuBehaviouralContextProvider/constants/index.js +14 -0
- package/dist/esm/parts/DSMenuBehaviouralContextProvider/constants/index.js.map +7 -0
- package/dist/esm/parts/DSMenuBehaviouralContextProvider/index.js +10 -0
- package/dist/esm/parts/DSMenuBehaviouralContextProvider/index.js.map +7 -0
- package/dist/esm/parts/DSMenuBehaviouralContextProvider/react-desc-prop-types.js +23 -0
- package/dist/esm/parts/DSMenuBehaviouralContextProvider/react-desc-prop-types.js.map +7 -0
- package/dist/esm/parts/DSMenuBehaviouralContextProvider/utils/multipleSelectionHelpers.js +113 -0
- package/dist/esm/parts/DSMenuBehaviouralContextProvider/utils/multipleSelectionHelpers.js.map +7 -0
- package/dist/esm/parts/DSMenuBehaviouralContextProvider/utils/nodeGettersByCriterias.js +123 -0
- package/dist/esm/parts/DSMenuBehaviouralContextProvider/utils/nodeGettersByCriterias.js.map +7 -0
- package/dist/esm/parts/DSMenuBehaviouralContextProvider/utils/singleSelectionHelpers.js +14 -0
- package/dist/esm/parts/DSMenuBehaviouralContextProvider/utils/singleSelectionHelpers.js.map +7 -0
- package/dist/esm/parts/DSMenuItemRendererFactory/ActivableMenuItem.js +91 -0
- package/dist/esm/parts/DSMenuItemRendererFactory/ActivableMenuItem.js.map +7 -0
- package/dist/esm/parts/DSMenuItemRendererFactory/ActivableWithSubmenuMenuItem.js +134 -0
- package/dist/esm/parts/DSMenuItemRendererFactory/ActivableWithSubmenuMenuItem.js.map +7 -0
- package/dist/esm/parts/DSMenuItemRendererFactory/DSMenuItemRendererFactory.js +78 -0
- package/dist/esm/parts/DSMenuItemRendererFactory/DSMenuItemRendererFactory.js.map +7 -0
- package/dist/esm/parts/DSMenuItemRendererFactory/MultipleSelectMenuItem.js +97 -0
- package/dist/esm/parts/DSMenuItemRendererFactory/MultipleSelectMenuItem.js.map +7 -0
- package/dist/esm/parts/DSMenuItemRendererFactory/MultipleSelectWithSubmenuMenuItem.js +148 -0
- package/dist/esm/parts/DSMenuItemRendererFactory/MultipleSelectWithSubmenuMenuItem.js.map +7 -0
- package/dist/esm/parts/DSMenuItemRendererFactory/SingleSelectMenuItem.js +105 -0
- package/dist/esm/parts/DSMenuItemRendererFactory/SingleSelectMenuItem.js.map +7 -0
- package/dist/esm/parts/DSMenuItemRendererFactory/SingleSelectWithSubmenuMenuItem.js +151 -0
- package/dist/esm/parts/DSMenuItemRendererFactory/SingleSelectWithSubmenuMenuItem.js.map +7 -0
- package/dist/esm/parts/DSMenuItemRendererFactory/WithSubmenuMenuItem.js +137 -0
- package/dist/esm/parts/DSMenuItemRendererFactory/WithSubmenuMenuItem.js.map +7 -0
- package/dist/esm/parts/DSMenuItemRendererFactory/config/useMenuItemRendererFactory.js +30 -0
- package/dist/esm/parts/DSMenuItemRendererFactory/config/useMenuItemRendererFactory.js.map +7 -0
- package/dist/esm/parts/DSMenuItemRendererFactory/config/useValidateProps.js +10 -0
- package/dist/esm/parts/DSMenuItemRendererFactory/config/useValidateProps.js.map +7 -0
- package/dist/esm/parts/DSMenuItemRendererFactory/constants/index.js +18 -0
- package/dist/esm/parts/DSMenuItemRendererFactory/constants/index.js.map +7 -0
- package/dist/esm/parts/DSMenuItemRendererFactory/index.js +7 -0
- package/dist/esm/parts/DSMenuItemRendererFactory/index.js.map +7 -0
- package/dist/esm/parts/DSMenuItemRendererFactory/react-desc-prop-types.js +26 -0
- package/dist/esm/parts/DSMenuItemRendererFactory/react-desc-prop-types.js.map +7 -0
- package/dist/esm/parts/DSMenuItemRendererFactory/useMenuItemHighlightState.js +32 -0
- package/dist/esm/parts/DSMenuItemRendererFactory/useMenuItemHighlightState.js.map +7 -0
- package/dist/esm/parts/DSOpinionatedButton/DSOpinionatedButton.js +70 -0
- package/dist/esm/parts/DSOpinionatedButton/DSOpinionatedButton.js.map +7 -0
- package/dist/esm/parts/DSOpinionatedButton/config/useOpinionatedButton.js +53 -0
- package/dist/esm/parts/DSOpinionatedButton/config/useOpinionatedButton.js.map +7 -0
- package/dist/esm/parts/DSOpinionatedButton/config/useTriggerEventsHandlers.js +68 -0
- package/dist/esm/parts/DSOpinionatedButton/config/useTriggerEventsHandlers.js.map +7 -0
- package/dist/esm/parts/DSOpinionatedButton/config/useValidateProps.js +10 -0
- package/dist/esm/parts/DSOpinionatedButton/config/useValidateProps.js.map +7 -0
- package/dist/esm/parts/DSOpinionatedButton/constants/index.js +18 -0
- package/dist/esm/parts/DSOpinionatedButton/constants/index.js.map +7 -0
- package/dist/esm/parts/DSOpinionatedButton/index.js +10 -0
- package/dist/esm/parts/DSOpinionatedButton/index.js.map +7 -0
- package/dist/esm/parts/DSOpinionatedButton/react-desc-prop-types.js +23 -0
- package/dist/esm/parts/DSOpinionatedButton/react-desc-prop-types.js.map +7 -0
- package/dist/esm/react-desc-prop-types.js +62 -26
- package/dist/esm/react-desc-prop-types.js.map +2 -2
- package/dist/esm/utils/nodesTypeguardsAndGetters.js +93 -0
- package/dist/esm/utils/nodesTypeguardsAndGetters.js.map +7 -0
- package/dist/esm/utils/useOptionsArrayToDsTree.js +25 -0
- package/dist/esm/utils/useOptionsArrayToDsTree.js.map +7 -0
- package/dist/types/DSMenuButton.d.ts +4 -6
- package/dist/types/config/useMenuButton.d.ts +9 -13
- package/dist/types/config/useSplitInherithedProps.d.ts +495 -0
- package/dist/types/config/useValidateProps.d.ts +3 -3
- package/dist/types/constants/index.d.ts +14 -2
- package/dist/types/index.d.ts +4 -2
- package/dist/types/parts/DSFlyoutMenu/DSFlyoutMenu.d.ts +5 -0
- package/dist/types/parts/DSFlyoutMenu/config/useFlyoutMenu.d.ts +8 -0
- package/dist/types/parts/DSFlyoutMenu/config/useValidateProps.d.ts +3 -0
- package/dist/types/parts/DSFlyoutMenu/constants/index.d.ts +7 -0
- package/dist/types/parts/DSFlyoutMenu/index.d.ts +1 -0
- package/dist/types/parts/DSFlyoutMenu/react-desc-prop-types.d.ts +25 -0
- package/dist/types/parts/DSMenuBehaviouralContextProvider/DSMenuBehaviouralContextProvider.d.ts +5 -0
- package/dist/types/parts/DSMenuBehaviouralContextProvider/MenuBehaviouralContextProviderCTX.d.ts +5 -0
- package/dist/types/parts/DSMenuBehaviouralContextProvider/config/useFocusTracker.d.ts +15 -0
- package/dist/types/parts/DSMenuBehaviouralContextProvider/config/useGlobalEvents.d.ts +15 -0
- package/dist/types/parts/DSMenuBehaviouralContextProvider/config/useMenuBehaviouralContextProvider.d.ts +15 -0
- package/dist/types/parts/DSMenuBehaviouralContextProvider/config/useMenuItemEventsHandlers.d.ts +18 -0
- package/dist/types/parts/DSMenuBehaviouralContextProvider/config/useMenuOpenStatus.d.ts +17 -0
- package/dist/types/parts/DSMenuBehaviouralContextProvider/config/useValidateProps.d.ts +3 -0
- package/dist/types/parts/DSMenuBehaviouralContextProvider/constants/Errors.d.ts +15 -0
- package/dist/types/parts/DSMenuBehaviouralContextProvider/constants/index.d.ts +7 -0
- package/dist/types/parts/DSMenuBehaviouralContextProvider/index.d.ts +1 -0
- package/dist/types/parts/DSMenuBehaviouralContextProvider/react-desc-prop-types.d.ts +24 -0
- package/dist/types/parts/DSMenuBehaviouralContextProvider/utils/multipleSelectionHelpers.d.ts +6 -0
- package/dist/types/parts/DSMenuBehaviouralContextProvider/utils/nodeGettersByCriterias.d.ts +35 -0
- package/dist/types/parts/DSMenuBehaviouralContextProvider/utils/singleSelectionHelpers.d.ts +13 -0
- package/dist/types/parts/DSMenuItemRendererFactory/ActivableMenuItem.d.ts +5 -0
- package/dist/types/parts/DSMenuItemRendererFactory/ActivableWithSubmenuMenuItem.d.ts +7 -0
- package/dist/types/parts/DSMenuItemRendererFactory/DSMenuItemRendererFactory.d.ts +5 -0
- package/dist/types/parts/DSMenuItemRendererFactory/MultipleSelectMenuItem.d.ts +5 -0
- package/dist/types/parts/DSMenuItemRendererFactory/MultipleSelectWithSubmenuMenuItem.d.ts +7 -0
- package/dist/types/parts/DSMenuItemRendererFactory/SingleSelectMenuItem.d.ts +5 -0
- package/dist/types/parts/DSMenuItemRendererFactory/SingleSelectWithSubmenuMenuItem.d.ts +7 -0
- package/dist/types/parts/DSMenuItemRendererFactory/WithSubmenuMenuItem.d.ts +7 -0
- package/dist/types/parts/DSMenuItemRendererFactory/config/useMenuItemRendererFactory.d.ts +6 -0
- package/dist/types/parts/DSMenuItemRendererFactory/config/useValidateProps.d.ts +3 -0
- package/dist/types/parts/DSMenuItemRendererFactory/constants/index.d.ts +6 -0
- package/dist/types/parts/DSMenuItemRendererFactory/index.d.ts +1 -0
- package/dist/types/parts/DSMenuItemRendererFactory/react-desc-prop-types.d.ts +24 -0
- package/dist/types/parts/DSMenuItemRendererFactory/useMenuItemHighlightState.d.ts +12 -0
- package/dist/types/parts/DSOpinionatedButton/DSOpinionatedButton.d.ts +5 -0
- package/dist/types/parts/DSOpinionatedButton/config/useOpinionatedButton.d.ts +38 -0
- package/dist/types/parts/DSOpinionatedButton/config/useTriggerEventsHandlers.d.ts +14 -0
- package/dist/types/parts/DSOpinionatedButton/config/useValidateProps.d.ts +3 -0
- package/dist/types/parts/DSOpinionatedButton/constants/index.d.ts +6 -0
- package/dist/types/parts/DSOpinionatedButton/index.d.ts +1 -0
- package/dist/types/parts/DSOpinionatedButton/react-desc-prop-types.d.ts +23 -0
- package/dist/types/react-desc-prop-types.d.ts +206 -41
- package/dist/types/utils/nodesTypeguardsAndGetters.d.ts +22 -0
- package/dist/types/utils/useOptionsArrayToDsTree.d.ts +8 -0
- package/package.json +18 -16
- package/dist/cjs/DSMenuButtonCTX.js.map +0 -7
- package/dist/cjs/parts/ItemFactory.js.map +0 -7
- package/dist/cjs/parts/Menu.js +0 -125
- package/dist/cjs/parts/Menu.js.map +0 -7
- package/dist/cjs/parts/MenuButtonContent.js +0 -156
- package/dist/cjs/parts/MenuButtonContent.js.map +0 -7
- package/dist/cjs/parts/MenuItem.js +0 -252
- package/dist/cjs/parts/MenuItem.js.map +0 -7
- package/dist/cjs/styled.js +0 -132
- package/dist/cjs/styled.js.map +0 -7
- package/dist/esm/DSMenuButtonCTX.js +0 -8
- package/dist/esm/DSMenuButtonCTX.js.map +0 -7
- package/dist/esm/parts/ItemFactory.js +0 -36
- package/dist/esm/parts/ItemFactory.js.map +0 -7
- package/dist/esm/parts/Menu.js +0 -95
- package/dist/esm/parts/Menu.js.map +0 -7
- package/dist/esm/parts/MenuButtonContent.js +0 -126
- package/dist/esm/parts/MenuButtonContent.js.map +0 -7
- package/dist/esm/parts/MenuItem.js +0 -229
- package/dist/esm/parts/MenuItem.js.map +0 -7
- package/dist/esm/styled.js +0 -102
- package/dist/esm/styled.js.map +0 -7
- package/dist/types/DSMenuButtonCTX.d.ts +0 -15
- package/dist/types/parts/ItemFactory.d.ts +0 -14
- package/dist/types/parts/Menu.d.ts +0 -14
- package/dist/types/parts/MenuButtonContent.d.ts +0 -1
- package/dist/types/parts/MenuItem.d.ts +0 -21
- package/dist/types/styled.d.ts +0 -16
@@ -0,0 +1,161 @@
|
|
1
|
+
import * as React from "react";
|
2
|
+
import React2 from "react";
|
3
|
+
import {
|
4
|
+
isFocusableNode,
|
5
|
+
isGroup,
|
6
|
+
isMenuNodeAllowedToHaveChildren,
|
7
|
+
isRootNode
|
8
|
+
} from "../../../utils/nodesTypeguardsAndGetters.js";
|
9
|
+
import { TREE_STRUCTURE_ERRORS } from "../constants/Errors.js";
|
10
|
+
import { MENU_FOCUS_REGIONS } from "../constants/index.js";
|
11
|
+
import { getFocusableSiblingsList } from "../utils/nodeGettersByCriterias.js";
|
12
|
+
const useFocusTracker = () => {
|
13
|
+
const [focusRegion, setFocusRegion] = React2.useState("");
|
14
|
+
const focusedRegionPerformanceHelper = React2.useRef("");
|
15
|
+
const preventBlurReset = React2.useRef(false);
|
16
|
+
const focusedElementItemNode = React2.useRef(
|
17
|
+
null
|
18
|
+
);
|
19
|
+
const trackFocusTrigger = React2.useCallback(() => {
|
20
|
+
setTimeout(() => {
|
21
|
+
setFocusRegion(MENU_FOCUS_REGIONS.TRIGGER);
|
22
|
+
focusedRegionPerformanceHelper.current = MENU_FOCUS_REGIONS.TRIGGER;
|
23
|
+
focusedElementItemNode.current = null;
|
24
|
+
});
|
25
|
+
return null;
|
26
|
+
}, []);
|
27
|
+
const trackFocusNode = React2.useCallback((nodeToFocus) => {
|
28
|
+
const newFocusRegion = MENU_FOCUS_REGIONS.ITEM_BY_DSID(nodeToFocus.dsId);
|
29
|
+
setTimeout(() => {
|
30
|
+
setFocusRegion(newFocusRegion);
|
31
|
+
focusedRegionPerformanceHelper.current = newFocusRegion;
|
32
|
+
focusedElementItemNode.current = nodeToFocus;
|
33
|
+
});
|
34
|
+
}, []);
|
35
|
+
const trackFocusRegionReset = React2.useCallback(() => {
|
36
|
+
setTimeout(() => {
|
37
|
+
setFocusRegion(MENU_FOCUS_REGIONS.RESET);
|
38
|
+
focusedRegionPerformanceHelper.current = MENU_FOCUS_REGIONS.RESET;
|
39
|
+
focusedElementItemNode.current = null;
|
40
|
+
});
|
41
|
+
return null;
|
42
|
+
}, []);
|
43
|
+
const trackFocusFirstChildItem = React2.useCallback(
|
44
|
+
(itemNode) => {
|
45
|
+
if (!isMenuNodeAllowedToHaveChildren(itemNode)) {
|
46
|
+
console.log("focus first child item > itemNode", itemNode);
|
47
|
+
throw TREE_STRUCTURE_ERRORS.NODE_CANNOT_HAVE_CHILDREN;
|
48
|
+
}
|
49
|
+
if (itemNode.children.length === 0) {
|
50
|
+
console.log(itemNode);
|
51
|
+
throw new Error("No children found in the item node");
|
52
|
+
}
|
53
|
+
const focusableChildrenNodes = getFocusableSiblingsList(itemNode.children[0]);
|
54
|
+
if (focusableChildrenNodes.length === 0) {
|
55
|
+
console.log("focus first child item > itemNode", itemNode);
|
56
|
+
throw new Error("No focusable nodes found in the children of the item node");
|
57
|
+
}
|
58
|
+
const newFocusedNode = focusableChildrenNodes[0];
|
59
|
+
trackFocusNode(newFocusedNode);
|
60
|
+
return newFocusedNode;
|
61
|
+
},
|
62
|
+
[trackFocusNode]
|
63
|
+
);
|
64
|
+
const trackFocusLastChildItem = React2.useCallback(
|
65
|
+
(itemNode) => {
|
66
|
+
if (!isMenuNodeAllowedToHaveChildren(itemNode)) {
|
67
|
+
console.log("focus last child item > itemNode", itemNode);
|
68
|
+
throw new Error("Item node is not allowed to have children");
|
69
|
+
}
|
70
|
+
if (itemNode.children.length === 0) {
|
71
|
+
console.log(itemNode);
|
72
|
+
throw new Error("No children found in the item node");
|
73
|
+
}
|
74
|
+
const focusableChildrenNodes = getFocusableSiblingsList(itemNode.children[0]);
|
75
|
+
if (focusableChildrenNodes.length === 0) {
|
76
|
+
console.log("focus last child item > itemNode", itemNode);
|
77
|
+
throw new Error("No focusable nodes found in the children of the item node");
|
78
|
+
}
|
79
|
+
trackFocusNode(focusableChildrenNodes[focusableChildrenNodes.length - 1]);
|
80
|
+
return focusableChildrenNodes[focusableChildrenNodes.length - 1];
|
81
|
+
},
|
82
|
+
[trackFocusNode]
|
83
|
+
);
|
84
|
+
const trackFocusNextItem = React2.useCallback(
|
85
|
+
(itemNode) => {
|
86
|
+
const focusableSiblingsNodes = getFocusableSiblingsList(itemNode);
|
87
|
+
const currIndex = focusableSiblingsNodes.findIndex((node) => node.dsId === itemNode.dsId);
|
88
|
+
const nextIndex = currIndex + 1 < focusableSiblingsNodes.length ? currIndex + 1 : 0;
|
89
|
+
const newFocusedNode = focusableSiblingsNodes[nextIndex];
|
90
|
+
trackFocusNode(newFocusedNode);
|
91
|
+
return newFocusedNode;
|
92
|
+
},
|
93
|
+
[trackFocusNode]
|
94
|
+
);
|
95
|
+
const trackFocusPreviousItem = React2.useCallback(
|
96
|
+
(itemNode) => {
|
97
|
+
const focusableSiblingsNodes = getFocusableSiblingsList(itemNode);
|
98
|
+
const currIndex = focusableSiblingsNodes.findIndex((node) => node.dsId === itemNode.dsId);
|
99
|
+
const previousIndex = currIndex - 1 >= 0 ? currIndex - 1 : focusableSiblingsNodes.length - 1;
|
100
|
+
const newFocusNode = focusableSiblingsNodes[previousIndex];
|
101
|
+
trackFocusNode(newFocusNode);
|
102
|
+
return newFocusNode;
|
103
|
+
},
|
104
|
+
[trackFocusNode]
|
105
|
+
);
|
106
|
+
const trackFocusParentItem = React2.useCallback(
|
107
|
+
(itemNode) => {
|
108
|
+
const { parent } = itemNode;
|
109
|
+
const parentNode = parent;
|
110
|
+
if (!parentNode) {
|
111
|
+
console.log("focus parent item", { itemNode, parentNode });
|
112
|
+
throw new Error(`No parent node found for the item node`);
|
113
|
+
}
|
114
|
+
let nodeToFocus = parentNode;
|
115
|
+
if (isGroup(parentNode)) {
|
116
|
+
const groupParent = parentNode.parent;
|
117
|
+
if (!isFocusableNode(groupParent) && !isRootNode(groupParent)) {
|
118
|
+
console.log("focus parent item", { itemNode, parentNode, groupParent });
|
119
|
+
throw new Error("No focusable parent node found for the item node");
|
120
|
+
}
|
121
|
+
nodeToFocus = groupParent;
|
122
|
+
}
|
123
|
+
const focusableNode = isRootNode(nodeToFocus) ? null : nodeToFocus;
|
124
|
+
const newFocusNode = focusableNode;
|
125
|
+
if (!newFocusNode) trackFocusTrigger();
|
126
|
+
else trackFocusNode(newFocusNode);
|
127
|
+
return focusableNode;
|
128
|
+
},
|
129
|
+
[trackFocusNode, trackFocusTrigger]
|
130
|
+
);
|
131
|
+
return React2.useMemo(
|
132
|
+
() => ({
|
133
|
+
preventBlurReset,
|
134
|
+
focusRegion,
|
135
|
+
focusedElementItemNode,
|
136
|
+
trackFocusTrigger,
|
137
|
+
trackFocusNode,
|
138
|
+
trackFocusRegionReset,
|
139
|
+
trackFocusFirstChildItem,
|
140
|
+
trackFocusLastChildItem,
|
141
|
+
trackFocusNextItem,
|
142
|
+
trackFocusPreviousItem,
|
143
|
+
trackFocusParentItem
|
144
|
+
}),
|
145
|
+
[
|
146
|
+
focusRegion,
|
147
|
+
trackFocusFirstChildItem,
|
148
|
+
trackFocusLastChildItem,
|
149
|
+
trackFocusNextItem,
|
150
|
+
trackFocusNode,
|
151
|
+
trackFocusParentItem,
|
152
|
+
trackFocusPreviousItem,
|
153
|
+
trackFocusRegionReset,
|
154
|
+
trackFocusTrigger
|
155
|
+
]
|
156
|
+
);
|
157
|
+
};
|
158
|
+
export {
|
159
|
+
useFocusTracker
|
160
|
+
};
|
161
|
+
//# sourceMappingURL=useFocusTracker.js.map
|
@@ -0,0 +1,7 @@
|
|
1
|
+
{
|
2
|
+
"version": 3,
|
3
|
+
"sources": ["../../../../../../../../scripts/build/transpile/react-shim.js", "../../../../../src/parts/DSMenuBehaviouralContextProvider/config/useFocusTracker.ts"],
|
4
|
+
"sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable no-console */\n/* eslint-disable max-lines */\n/* eslint-disable max-statements */\n/* eslint-disable complexity */\nimport React from 'react';\nimport type { DSMenuButtonT } from '../../../react-desc-prop-types.js';\nimport {\n isFocusableNode,\n isGroup,\n isMenuNodeAllowedToHaveChildren,\n isRootNode,\n} from '../../../utils/nodesTypeguardsAndGetters.js';\nimport { TREE_STRUCTURE_ERRORS } from '../constants/Errors.js';\nimport { MENU_FOCUS_REGIONS } from '../constants/index.js';\nimport { getFocusableSiblingsList } from '../utils/nodeGettersByCriterias.js';\n\ntype MenuFocusRegionsValues = (typeof MENU_FOCUS_REGIONS)[keyof typeof MENU_FOCUS_REGIONS];\n// if MenuFocusRegionsValues may be a string or a function that returns a string, we want only the resolved strings\ntype ValidRegionsValues<T extends MenuFocusRegionsValues = MenuFocusRegionsValues> = T extends string\n ? T\n : // eslint-disable-next-line @typescript-eslint/no-explicit-any\n T extends (...args: any) => any\n ? ReturnType<T>\n : never;\n\nexport const useFocusTracker = () => {\n const [focusRegion, setFocusRegion] = React.useState<ValidRegionsValues>('');\n // we want to keep the focus region trackers as stable as possible to avoid unnecessary re-renders\n // there is no need to change the trackers reference when the focus region changes,\n // since changing the focus region is always triggered by a final user interaction (so after reacts reconciliation)\n const focusedRegionPerformanceHelper = React.useRef('') as React.MutableRefObject<ValidRegionsValues>;\n const preventBlurReset = React.useRef(false);\n\n const focusedElementItemNode = React.useRef(\n null,\n ) as React.MutableRefObject<DSMenuButtonT.PseudoFocusableMenuNodes | null>;\n const trackFocusTrigger = React.useCallback(() => {\n // we need to guarantee that the focus is set after the current event loop or else bubbling events will trigger on the new focused element\n setTimeout(() => {\n setFocusRegion(MENU_FOCUS_REGIONS.TRIGGER);\n focusedRegionPerformanceHelper.current = MENU_FOCUS_REGIONS.TRIGGER;\n focusedElementItemNode.current = null;\n });\n return null;\n }, []);\n const trackFocusNode = React.useCallback((nodeToFocus: DSMenuButtonT.PseudoFocusableMenuNodes) => {\n const newFocusRegion = MENU_FOCUS_REGIONS.ITEM_BY_DSID(nodeToFocus.dsId);\n // we need to guarantee that the focus is set after the current event loop or else bubbling events will trigger on the new focused element\n setTimeout(() => {\n setFocusRegion(newFocusRegion);\n focusedRegionPerformanceHelper.current = newFocusRegion;\n // eslint-disable-next-line prefer-destructuring\n focusedElementItemNode.current = nodeToFocus;\n });\n }, []);\n\n const trackFocusRegionReset = React.useCallback(() => {\n // we need to guarantee that the focus is set after the current event loop or else bubbling events will trigger on the new focused element\n setTimeout(() => {\n setFocusRegion(MENU_FOCUS_REGIONS.RESET);\n focusedRegionPerformanceHelper.current = MENU_FOCUS_REGIONS.RESET;\n focusedElementItemNode.current = null;\n });\n return null;\n }, []);\n\n const trackFocusFirstChildItem = React.useCallback(\n (itemNode: DSMenuButtonT.PseudoFocusableMenuNodes) => {\n if (!isMenuNodeAllowedToHaveChildren(itemNode)) {\n console.log('focus first child item > itemNode', itemNode);\n throw TREE_STRUCTURE_ERRORS.NODE_CANNOT_HAVE_CHILDREN;\n }\n if (itemNode.children.length === 0) {\n console.log(itemNode);\n throw new Error('No children found in the item node');\n }\n const focusableChildrenNodes = getFocusableSiblingsList(itemNode.children[0]);\n if (focusableChildrenNodes.length === 0) {\n console.log('focus first child item > itemNode', itemNode);\n throw new Error('No focusable nodes found in the children of the item node');\n }\n\n const newFocusedNode = focusableChildrenNodes[0];\n trackFocusNode(newFocusedNode);\n return newFocusedNode;\n },\n [trackFocusNode],\n );\n\n const trackFocusLastChildItem = React.useCallback(\n (itemNode: DSMenuButtonT.PseudoFocusableMenuNodes) => {\n if (!isMenuNodeAllowedToHaveChildren(itemNode)) {\n console.log('focus last child item > itemNode', itemNode);\n throw new Error('Item node is not allowed to have children');\n }\n if (itemNode.children.length === 0) {\n console.log(itemNode);\n throw new Error('No children found in the item node');\n }\n const focusableChildrenNodes = getFocusableSiblingsList(itemNode.children[0]);\n if (focusableChildrenNodes.length === 0) {\n console.log('focus last child item > itemNode', itemNode);\n throw new Error('No focusable nodes found in the children of the item node');\n }\n trackFocusNode(focusableChildrenNodes[focusableChildrenNodes.length - 1]);\n return focusableChildrenNodes[focusableChildrenNodes.length - 1];\n },\n [trackFocusNode],\n );\n\n const trackFocusNextItem = React.useCallback(\n (itemNode: DSMenuButtonT.PseudoFocusableMenuNodes) => {\n const focusableSiblingsNodes = getFocusableSiblingsList(itemNode);\n // we find the current item node index in the focusableSiblingsNodes array\n const currIndex = focusableSiblingsNodes.findIndex((node) => node.dsId === itemNode.dsId);\n\n const nextIndex = currIndex + 1 < focusableSiblingsNodes.length ? currIndex + 1 : 0;\n const newFocusedNode = focusableSiblingsNodes[nextIndex];\n trackFocusNode(newFocusedNode);\n\n return newFocusedNode;\n },\n [trackFocusNode],\n );\n\n const trackFocusPreviousItem = React.useCallback(\n (itemNode: DSMenuButtonT.PseudoFocusableMenuNodes) => {\n const focusableSiblingsNodes = getFocusableSiblingsList(itemNode);\n // we find the current item node index in the focusableSiblingsNodes array\n const currIndex = focusableSiblingsNodes.findIndex((node) => node.dsId === itemNode.dsId);\n\n const previousIndex = currIndex - 1 >= 0 ? currIndex - 1 : focusableSiblingsNodes.length - 1;\n const newFocusNode = focusableSiblingsNodes[previousIndex];\n trackFocusNode(newFocusNode);\n return newFocusNode;\n },\n [trackFocusNode],\n );\n\n const trackFocusParentItem = React.useCallback(\n (itemNode: DSMenuButtonT.PseudoFocusableMenuNodes) => {\n const { parent } = itemNode;\n // this typecast is required because we are reading the parent property from the itemNode\n // while this function can receive any PseudoFocusableMenuNodes,\n // the parent property may be a non-pseudo focusable node (specifically when the parent property is group node)\n const parentNode = parent;\n if (!parentNode) {\n console.log('focus parent item', { itemNode, parentNode });\n throw new Error(`No parent node found for the item node`);\n }\n\n let nodeToFocus: DSMenuButtonT.PseudoFocusableMenuNodes | null = parentNode;\n // if parent is SingleSelectGroupNode then we can't focus it\n if (isGroup(parentNode)) {\n const groupParent = parentNode.parent;\n if (!isFocusableNode(groupParent) && !isRootNode(groupParent)) {\n console.log('focus parent item', { itemNode, parentNode, groupParent });\n throw new Error('No focusable parent node found for the item node');\n }\n nodeToFocus = groupParent;\n }\n\n const focusableNode = isRootNode(nodeToFocus) ? null : nodeToFocus;\n const newFocusNode = focusableNode;\n if (!newFocusNode) trackFocusTrigger();\n else trackFocusNode(newFocusNode);\n\n return focusableNode;\n },\n [trackFocusNode, trackFocusTrigger],\n );\n\n return React.useMemo(\n () => ({\n preventBlurReset,\n focusRegion,\n focusedElementItemNode,\n trackFocusTrigger,\n trackFocusNode,\n trackFocusRegionReset,\n trackFocusFirstChildItem,\n trackFocusLastChildItem,\n trackFocusNextItem,\n trackFocusPreviousItem,\n trackFocusParentItem,\n }),\n [\n focusRegion,\n trackFocusFirstChildItem,\n trackFocusLastChildItem,\n trackFocusNextItem,\n trackFocusNode,\n trackFocusParentItem,\n trackFocusPreviousItem,\n trackFocusRegionReset,\n trackFocusTrigger,\n ],\n );\n};\n"],
|
5
|
+
"mappings": "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",
|
6
|
+
"names": ["React"]
|
7
|
+
}
|
@@ -0,0 +1,59 @@
|
|
1
|
+
import * as React from "react";
|
2
|
+
import React2 from "react";
|
3
|
+
const useGlobalEvents = ({
|
4
|
+
menuOpenStatus,
|
5
|
+
handleChangeOpenedSubItems,
|
6
|
+
propsWithDefault
|
7
|
+
}) => {
|
8
|
+
const { onOpinionatedClose, isMenuOpen } = menuOpenStatus;
|
9
|
+
const { buttonDOMNodeRef } = propsWithDefault;
|
10
|
+
const mainMenuRef = React2.useRef(null);
|
11
|
+
const submenusRefs = React2.useRef({});
|
12
|
+
const handleSubmenusRefChange = React2.useCallback(
|
13
|
+
(htmlNode, dsId) => {
|
14
|
+
if (htmlNode) {
|
15
|
+
submenusRefs.current[dsId] = htmlNode;
|
16
|
+
} else {
|
17
|
+
delete submenusRefs.current[dsId];
|
18
|
+
}
|
19
|
+
},
|
20
|
+
[]
|
21
|
+
);
|
22
|
+
React2.useEffect(() => {
|
23
|
+
const closeMenuAndSubmenus = (e) => {
|
24
|
+
handleChangeOpenedSubItems([], { itemNode: null, event: e });
|
25
|
+
onOpinionatedClose({ skipFocus: true });
|
26
|
+
};
|
27
|
+
const detectIfClickIsOutsideMenuAndCloseIfSo = (e) => {
|
28
|
+
if (!isMenuOpen) return;
|
29
|
+
if (buttonDOMNodeRef.current === e.target) return;
|
30
|
+
const isClickInsideMainMenu = mainMenuRef.current?.contains(e.target);
|
31
|
+
if (isClickInsideMainMenu) return;
|
32
|
+
const submenuNodesToCheck = Object.values(submenusRefs.current).filter(Boolean);
|
33
|
+
const isClickInsideAnySubmenu = submenuNodesToCheck.some((node) => node.contains(e.target));
|
34
|
+
if (isClickInsideAnySubmenu) return;
|
35
|
+
handleChangeOpenedSubItems([], { itemNode: null, event: e });
|
36
|
+
onOpinionatedClose({ skipFocus: true });
|
37
|
+
};
|
38
|
+
window.addEventListener("blur", closeMenuAndSubmenus);
|
39
|
+
document.addEventListener("mousedown", detectIfClickIsOutsideMenuAndCloseIfSo);
|
40
|
+
document.addEventListener("touchstart", detectIfClickIsOutsideMenuAndCloseIfSo);
|
41
|
+
return () => {
|
42
|
+
window.removeEventListener("blur", closeMenuAndSubmenus);
|
43
|
+
document.removeEventListener("mousedown", detectIfClickIsOutsideMenuAndCloseIfSo);
|
44
|
+
document.removeEventListener("touchstart", detectIfClickIsOutsideMenuAndCloseIfSo);
|
45
|
+
};
|
46
|
+
}, [buttonDOMNodeRef, handleChangeOpenedSubItems, isMenuOpen, onOpinionatedClose]);
|
47
|
+
return React2.useMemo(
|
48
|
+
() => ({
|
49
|
+
mainMenuRef,
|
50
|
+
submenusRefs,
|
51
|
+
handleSubmenusRefChange
|
52
|
+
}),
|
53
|
+
[handleSubmenusRefChange]
|
54
|
+
);
|
55
|
+
};
|
56
|
+
export {
|
57
|
+
useGlobalEvents
|
58
|
+
};
|
59
|
+
//# sourceMappingURL=useGlobalEvents.js.map
|
@@ -0,0 +1,7 @@
|
|
1
|
+
{
|
2
|
+
"version": 3,
|
3
|
+
"sources": ["../../../../../../../../scripts/build/transpile/react-shim.js", "../../../../../src/parts/DSMenuBehaviouralContextProvider/config/useGlobalEvents.ts"],
|
4
|
+
"sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import React from 'react';\nimport type { DSMenuButtonT } from '../../../react-desc-prop-types.js';\nimport type { useMenuOpenStatus } from './useMenuOpenStatus.js';\nimport type { DSMenuBehaviouralContextProviderT } from '../react-desc-prop-types.js';\n\ntype UseGlobalEventsConfig = {\n menuOpenStatus: ReturnType<typeof useMenuOpenStatus>;\n handleChangeOpenedSubItems: Required<DSMenuButtonT.MenuBehaviouralLayerOptionalProps>['onDisplayedSubmenuChange'];\n propsWithDefault: DSMenuBehaviouralContextProviderT.InternalProps;\n};\n\nexport const useGlobalEvents = ({\n menuOpenStatus,\n handleChangeOpenedSubItems,\n propsWithDefault,\n}: UseGlobalEventsConfig) => {\n const { onOpinionatedClose, isMenuOpen } = menuOpenStatus;\n const { buttonDOMNodeRef } = propsWithDefault;\n const mainMenuRef = React.useRef<HTMLDivElement | null>(null);\n // we are using \"portal\" but then we check the native evenet to check if \"on click outside\" the menu\n // for such reason, we need to track the current HTML NODES of the submenus (topmost parent)\n // this will allow us to check if the click event is outside the menu or any of it's submenus\n const submenusRefs = React.useRef<Record<DSMenuButtonT.WithSubmenuMenuNodes['dsId'], HTMLElement>>({});\n const handleSubmenusRefChange = React.useCallback(\n (htmlNode: HTMLElement | null, dsId: DSMenuButtonT.WithSubmenuMenuNodes['dsId']) => {\n if (htmlNode) {\n submenusRefs.current[dsId] = htmlNode;\n } else {\n delete submenusRefs.current[dsId];\n }\n },\n [],\n );\n React.useEffect(() => {\n // when the window loses focus, close all the menus and submenus\n const closeMenuAndSubmenus = (e: FocusEvent) => {\n handleChangeOpenedSubItems([], { itemNode: null, event: e });\n onOpinionatedClose({ skipFocus: true });\n };\n // when the user clicks \"outside\" the menu and submenus, close all the menus and submenus\n const detectIfClickIsOutsideMenuAndCloseIfSo = (e: MouseEvent | TouchEvent) => {\n // we are running this on literally ALL the clicks that happen on the window\n // we don't want to be consuming resources that are not strictly necessary\n // if the main menu is not open, we don't need to check if the click is outside the menu ofc\n if (!isMenuOpen) return;\n // we discard the fastest to check \"trigger\" click first\n if (buttonDOMNodeRef.current === e.target) return;\n // fastest check is the mainmenu, cuz we don't loop through all the submenus\n const isClickInsideMainMenu = mainMenuRef.current?.contains(e.target as Node);\n if (isClickInsideMainMenu) return;\n const submenuNodesToCheck = Object.values(submenusRefs.current).filter(Boolean);\n // we check if the event.target is a child of any of our known HTML nodes (via native .contains)\n const isClickInsideAnySubmenu = submenuNodesToCheck.some((node) => node.contains(e.target as Node));\n if (isClickInsideAnySubmenu) return;\n handleChangeOpenedSubItems([], { itemNode: null, event: e });\n onOpinionatedClose({ skipFocus: true });\n };\n\n window.addEventListener('blur', closeMenuAndSubmenus);\n document.addEventListener('mousedown', detectIfClickIsOutsideMenuAndCloseIfSo);\n document.addEventListener('touchstart', detectIfClickIsOutsideMenuAndCloseIfSo);\n return () => {\n window.removeEventListener('blur', closeMenuAndSubmenus);\n document.removeEventListener('mousedown', detectIfClickIsOutsideMenuAndCloseIfSo);\n document.removeEventListener('touchstart', detectIfClickIsOutsideMenuAndCloseIfSo);\n };\n }, [buttonDOMNodeRef, handleChangeOpenedSubItems, isMenuOpen, onOpinionatedClose]);\n\n return React.useMemo(\n () => ({\n mainMenuRef,\n submenusRefs,\n handleSubmenusRefChange,\n }),\n [handleSubmenusRefChange],\n );\n};\n"],
|
5
|
+
"mappings": "AAAA,YAAY,WAAW;ACAvB,OAAOA,YAAW;AAWX,MAAM,kBAAkB,CAAC;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AACF,MAA6B;AAC3B,QAAM,EAAE,oBAAoB,WAAW,IAAI;AAC3C,QAAM,EAAE,iBAAiB,IAAI;AAC7B,QAAM,cAAcA,OAAM,OAA8B,IAAI;AAI5D,QAAM,eAAeA,OAAM,OAAwE,CAAC,CAAC;AACrG,QAAM,0BAA0BA,OAAM;AAAA,IACpC,CAAC,UAA8B,SAAqD;AAClF,UAAI,UAAU;AACZ,qBAAa,QAAQ,IAAI,IAAI;AAAA,MAC/B,OAAO;AACL,eAAO,aAAa,QAAQ,IAAI;AAAA,MAClC;AAAA,IACF;AAAA,IACA,CAAC;AAAA,EACH;AACA,EAAAA,OAAM,UAAU,MAAM;AAEpB,UAAM,uBAAuB,CAAC,MAAkB;AAC9C,iCAA2B,CAAC,GAAG,EAAE,UAAU,MAAM,OAAO,EAAE,CAAC;AAC3D,yBAAmB,EAAE,WAAW,KAAK,CAAC;AAAA,IACxC;AAEA,UAAM,yCAAyC,CAAC,MAA+B;AAI7E,UAAI,CAAC,WAAY;AAEjB,UAAI,iBAAiB,YAAY,EAAE,OAAQ;AAE3C,YAAM,wBAAwB,YAAY,SAAS,SAAS,EAAE,MAAc;AAC5E,UAAI,sBAAuB;AAC3B,YAAM,sBAAsB,OAAO,OAAO,aAAa,OAAO,EAAE,OAAO,OAAO;AAE9E,YAAM,0BAA0B,oBAAoB,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,MAAc,CAAC;AAClG,UAAI,wBAAyB;AAC7B,iCAA2B,CAAC,GAAG,EAAE,UAAU,MAAM,OAAO,EAAE,CAAC;AAC3D,yBAAmB,EAAE,WAAW,KAAK,CAAC;AAAA,IACxC;AAEA,WAAO,iBAAiB,QAAQ,oBAAoB;AACpD,aAAS,iBAAiB,aAAa,sCAAsC;AAC7E,aAAS,iBAAiB,cAAc,sCAAsC;AAC9E,WAAO,MAAM;AACX,aAAO,oBAAoB,QAAQ,oBAAoB;AACvD,eAAS,oBAAoB,aAAa,sCAAsC;AAChF,eAAS,oBAAoB,cAAc,sCAAsC;AAAA,IACnF;AAAA,EACF,GAAG,CAAC,kBAAkB,4BAA4B,YAAY,kBAAkB,CAAC;AAEjF,SAAOA,OAAM;AAAA,IACX,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,uBAAuB;AAAA,EAC1B;AACF;",
|
6
|
+
"names": ["React"]
|
7
|
+
}
|
package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useMenuBehaviouralContextProvider.js
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
import * as React from "react";
|
2
|
+
import { useMemoMergePropsWithDefault } from "@elliemae/ds-props-helpers";
|
3
|
+
import React2 from "react";
|
4
|
+
import { uid } from "uid";
|
5
|
+
import {
|
6
|
+
DSMenuBehaviouralContextProviderPropTypesSchema,
|
7
|
+
defaultProps
|
8
|
+
} from "../react-desc-prop-types.js";
|
9
|
+
import { useFocusTracker } from "./useFocusTracker.js";
|
10
|
+
import { useMenuItemEventsHandlers } from "./useMenuItemEventsHandlers.js";
|
11
|
+
import { useMenuOpenStatus } from "./useMenuOpenStatus.js";
|
12
|
+
import { useValidateProps } from "./useValidateProps.js";
|
13
|
+
import { useGlobalEvents } from "./useGlobalEvents.js";
|
14
|
+
const useMenuBehaviouralContextProvider = (propsFromUser) => {
|
15
|
+
const propsWithDefault = useMemoMergePropsWithDefault(
|
16
|
+
propsFromUser,
|
17
|
+
defaultProps
|
18
|
+
);
|
19
|
+
useValidateProps(propsWithDefault, DSMenuBehaviouralContextProviderPropTypesSchema);
|
20
|
+
const { onDisplayedSubmenuChange } = propsWithDefault;
|
21
|
+
const instanceUid = React2.useMemo(() => `ds-menu-behavioural-context-provider-${uid(5)}`, []);
|
22
|
+
const [openedSubItems, setOpenedSubItems] = React2.useState([]);
|
23
|
+
const handleChangeOpenedSubItems = React2.useCallback(
|
24
|
+
(newOpenedItems, metainfo) => {
|
25
|
+
setOpenedSubItems(newOpenedItems);
|
26
|
+
onDisplayedSubmenuChange?.(newOpenedItems, metainfo);
|
27
|
+
},
|
28
|
+
[onDisplayedSubmenuChange]
|
29
|
+
);
|
30
|
+
const focusTrackers = useFocusTracker();
|
31
|
+
const menuOpenStatus = useMenuOpenStatus({ propsWithDefault, focusTrackers });
|
32
|
+
const menuItemEventsHandlers = useMenuItemEventsHandlers({
|
33
|
+
propsWithDefault,
|
34
|
+
focusTrackers,
|
35
|
+
menuOpenStatus,
|
36
|
+
handleChangeOpenedSubItems
|
37
|
+
});
|
38
|
+
const globalEventsHelpers = useGlobalEvents({ menuOpenStatus, handleChangeOpenedSubItems, propsWithDefault });
|
39
|
+
return React2.useMemo(
|
40
|
+
() => ({
|
41
|
+
propsWithDefault,
|
42
|
+
instanceUid,
|
43
|
+
...focusTrackers,
|
44
|
+
...menuOpenStatus,
|
45
|
+
menuItemEventsHandlers,
|
46
|
+
openedSubItems,
|
47
|
+
handleChangeOpenedSubItems,
|
48
|
+
globalEventsHelpers
|
49
|
+
}),
|
50
|
+
[
|
51
|
+
propsWithDefault,
|
52
|
+
instanceUid,
|
53
|
+
focusTrackers,
|
54
|
+
menuOpenStatus,
|
55
|
+
menuItemEventsHandlers,
|
56
|
+
openedSubItems,
|
57
|
+
handleChangeOpenedSubItems,
|
58
|
+
globalEventsHelpers
|
59
|
+
]
|
60
|
+
);
|
61
|
+
};
|
62
|
+
export {
|
63
|
+
useMenuBehaviouralContextProvider
|
64
|
+
};
|
65
|
+
//# sourceMappingURL=useMenuBehaviouralContextProvider.js.map
|
@@ -0,0 +1,7 @@
|
|
1
|
+
{
|
2
|
+
"version": 3,
|
3
|
+
"sources": ["../../../../../../../../scripts/build/transpile/react-shim.js", "../../../../../src/parts/DSMenuBehaviouralContextProvider/config/useMenuBehaviouralContextProvider.ts"],
|
4
|
+
"sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { useMemoMergePropsWithDefault } from '@elliemae/ds-props-helpers';\nimport React from 'react';\nimport { uid } from 'uid';\nimport type { DSMenuButtonT } from '../../../react-desc-prop-types.js';\nimport {\n DSMenuBehaviouralContextProviderPropTypesSchema,\n defaultProps,\n type DSMenuBehaviouralContextProviderT,\n} from '../react-desc-prop-types.js';\nimport { useFocusTracker } from './useFocusTracker.js';\nimport { useMenuItemEventsHandlers } from './useMenuItemEventsHandlers.js';\nimport { useMenuOpenStatus } from './useMenuOpenStatus.js';\nimport { useValidateProps } from './useValidateProps.js';\nimport { useGlobalEvents } from './useGlobalEvents.js';\n\nexport interface MenuBehaviouralContextProviderCTX\n extends ReturnType<typeof useFocusTracker>,\n ReturnType<typeof useMenuOpenStatus> {\n propsWithDefault: DSMenuBehaviouralContextProviderT.InternalProps;\n instanceUid: string;\n menuItemEventsHandlers: ReturnType<typeof useMenuItemEventsHandlers>;\n openedSubItems: DSMenuButtonT.WithSubmenuMenuNodes[];\n handleChangeOpenedSubItems: Required<DSMenuButtonT.MenuBehaviouralLayerOptionalProps>['onDisplayedSubmenuChange'];\n globalEventsHelpers: ReturnType<typeof useGlobalEvents>;\n}\n\nexport const useMenuBehaviouralContextProvider = (propsFromUser: DSMenuBehaviouralContextProviderT.Props) => {\n // =============================================================================\n // MERGE WITH DEFAULT AND VALIDATE PROPS\n // =============================================================================\n const propsWithDefault = useMemoMergePropsWithDefault<DSMenuBehaviouralContextProviderT.InternalProps>(\n propsFromUser,\n defaultProps,\n );\n useValidateProps(propsWithDefault, DSMenuBehaviouralContextProviderPropTypesSchema);\n // =============================================================================\n // XSTYLED PROPS\n // =============================================================================\n // NO XSTYLED PROPS\n // this is 100% a pure logic context provider, it's not a visual component\n\n // =============================================================================\n // AD HOC PER COMPONENT LOGIC\n // =============================================================================\n // custom code goes here, this is an example\n const { onDisplayedSubmenuChange } = propsWithDefault;\n const instanceUid = React.useMemo(() => `ds-menu-behavioural-context-provider-${uid(5)}`, []);\n const [openedSubItems, setOpenedSubItems] = React.useState<DSMenuButtonT.WithSubmenuMenuNodes[]>([]);\n\n const handleChangeOpenedSubItems = React.useCallback<\n Required<DSMenuButtonT.MenuBehaviouralLayerOptionalProps>['onDisplayedSubmenuChange']\n >(\n (newOpenedItems, metainfo) => {\n setOpenedSubItems(newOpenedItems);\n onDisplayedSubmenuChange?.(newOpenedItems, metainfo);\n },\n [onDisplayedSubmenuChange],\n );\n\n // =============================================================================\n // HELPERS HOOKS CONFIGS\n // =============================================================================\n const focusTrackers = useFocusTracker();\n const menuOpenStatus = useMenuOpenStatus({ propsWithDefault, focusTrackers });\n\n // why item events handlers declared in the menu behaviour context provider and not in the menu item itself?\n // 1 - each menu item depending on it's own type (single select, multiple select, with submenu) will have different behaviours\n // having each menu item to declare it's own events handlers would make the single event handler way easier to create per se\n // BUT we would lose the big picture of how the menu items are interacting with each other\n // 2 - having each item to declare it's own event handler repeatdly is a waste of resources (even if it's a useless micro-optimization, it hurts me)\n const menuItemEventsHandlers = useMenuItemEventsHandlers({\n propsWithDefault,\n focusTrackers,\n menuOpenStatus,\n handleChangeOpenedSubItems,\n });\n\n // handle \"onClickOutside\" + on window blur...\n // the helpers contain a way to register the submenu refs/mainmenu refs, used in checking \"if click is outside\"\n const globalEventsHelpers = useGlobalEvents({ menuOpenStatus, handleChangeOpenedSubItems, propsWithDefault });\n\n return React.useMemo<MenuBehaviouralContextProviderCTX>(\n () => ({\n propsWithDefault,\n instanceUid,\n ...focusTrackers,\n ...menuOpenStatus,\n menuItemEventsHandlers,\n openedSubItems,\n handleChangeOpenedSubItems,\n globalEventsHelpers,\n }),\n [\n propsWithDefault,\n instanceUid,\n focusTrackers,\n menuOpenStatus,\n menuItemEventsHandlers,\n openedSubItems,\n handleChangeOpenedSubItems,\n globalEventsHelpers,\n ],\n );\n};\n"],
|
5
|
+
"mappings": "AAAA,YAAY,WAAW;ACAvB,SAAS,oCAAoC;AAC7C,OAAOA,YAAW;AAClB,SAAS,WAAW;AAEpB;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP,SAAS,uBAAuB;AAChC,SAAS,iCAAiC;AAC1C,SAAS,yBAAyB;AAClC,SAAS,wBAAwB;AACjC,SAAS,uBAAuB;AAazB,MAAM,oCAAoC,CAAC,kBAA2D;AAI3G,QAAM,mBAAmB;AAAA,IACvB;AAAA,IACA;AAAA,EACF;AACA,mBAAiB,kBAAkB,+CAA+C;AAWlF,QAAM,EAAE,yBAAyB,IAAI;AACrC,QAAM,cAAcA,OAAM,QAAQ,MAAM,wCAAwC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;AAC5F,QAAM,CAAC,gBAAgB,iBAAiB,IAAIA,OAAM,SAA+C,CAAC,CAAC;AAEnG,QAAM,6BAA6BA,OAAM;AAAA,IAGvC,CAAC,gBAAgB,aAAa;AAC5B,wBAAkB,cAAc;AAChC,iCAA2B,gBAAgB,QAAQ;AAAA,IACrD;AAAA,IACA,CAAC,wBAAwB;AAAA,EAC3B;AAKA,QAAM,gBAAgB,gBAAgB;AACtC,QAAM,iBAAiB,kBAAkB,EAAE,kBAAkB,cAAc,CAAC;AAO5E,QAAM,yBAAyB,0BAA0B;AAAA,IACvD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAID,QAAM,sBAAsB,gBAAgB,EAAE,gBAAgB,4BAA4B,iBAAiB,CAAC;AAE5G,SAAOA,OAAM;AAAA,IACX,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,GAAG;AAAA,MACH,GAAG;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;",
|
6
|
+
"names": ["React"]
|
7
|
+
}
|
@@ -0,0 +1,292 @@
|
|
1
|
+
import * as React from "react";
|
2
|
+
import debounce from "lodash/debounce";
|
3
|
+
import React2 from "react";
|
4
|
+
import {
|
5
|
+
isFocusableNode,
|
6
|
+
isMultipleSelectNode,
|
7
|
+
isRootNode,
|
8
|
+
isSingleSelectNode,
|
9
|
+
isWithSubmenuNode,
|
10
|
+
isWithSubmenuOnlyNode
|
11
|
+
} from "../../../utils/nodesTypeguardsAndGetters.js";
|
12
|
+
import { FORBIDDEN_BEHAVIOURS, UNEXPECTED_INTERNAL_ERRORS } from "../constants/Errors.js";
|
13
|
+
import { getNewSelectionMultipleSelect } from "../utils/multipleSelectionHelpers.js";
|
14
|
+
import { getSubMenusPath } from "../utils/nodeGettersByCriterias.js";
|
15
|
+
import { getNewSelectionSingleSelect } from "../utils/singleSelectionHelpers.js";
|
16
|
+
const useMenuItemEventsHandlers = ({
|
17
|
+
propsWithDefault,
|
18
|
+
focusTrackers,
|
19
|
+
menuOpenStatus,
|
20
|
+
handleChangeOpenedSubItems
|
21
|
+
}) => {
|
22
|
+
const { onItemSelected, onActivateItem, selectedItems } = propsWithDefault;
|
23
|
+
const { onOpinionatedClose } = menuOpenStatus;
|
24
|
+
const {
|
25
|
+
trackFocusFirstChildItem,
|
26
|
+
trackFocusLastChildItem,
|
27
|
+
trackFocusNextItem,
|
28
|
+
trackFocusPreviousItem,
|
29
|
+
trackFocusParentItem,
|
30
|
+
trackFocusNode,
|
31
|
+
focusedElementItemNode
|
32
|
+
} = focusTrackers;
|
33
|
+
const openSubmenu = React2.useCallback(
|
34
|
+
({
|
35
|
+
itemNode,
|
36
|
+
event
|
37
|
+
}) => {
|
38
|
+
if (!isWithSubmenuNode(itemNode)) {
|
39
|
+
console.log("openSubmenu -> itemNode:", itemNode);
|
40
|
+
throw FORBIDDEN_BEHAVIOURS.TRYING_TO_OPEN_SUBMENU_OF_NODE_WITHOUT_SUBMENU;
|
41
|
+
}
|
42
|
+
const subMenuNodesPath = getSubMenusPath(itemNode);
|
43
|
+
const metainfo = { itemNode, event };
|
44
|
+
const newOpenedItems = [...subMenuNodesPath, itemNode];
|
45
|
+
handleChangeOpenedSubItems(newOpenedItems, metainfo);
|
46
|
+
},
|
47
|
+
[handleChangeOpenedSubItems]
|
48
|
+
);
|
49
|
+
const closeCurrentSubmenu = React2.useCallback(
|
50
|
+
({
|
51
|
+
itemNode,
|
52
|
+
event
|
53
|
+
}) => {
|
54
|
+
const metainfo = { itemNode, event };
|
55
|
+
const subMenuNodesPath = getSubMenusPath(itemNode);
|
56
|
+
if (subMenuNodesPath.length === 0) {
|
57
|
+
handleChangeOpenedSubItems([], metainfo);
|
58
|
+
return { currentSubmenuWasMainMenu: true };
|
59
|
+
}
|
60
|
+
subMenuNodesPath.pop();
|
61
|
+
handleChangeOpenedSubItems(subMenuNodesPath, metainfo);
|
62
|
+
return { currentSubmenuWasMainMenu: false };
|
63
|
+
},
|
64
|
+
[handleChangeOpenedSubItems]
|
65
|
+
);
|
66
|
+
const handleMenuItemEnterKeyDown = React2.useCallback(
|
67
|
+
({ pseudoFocusedItemNode, event }) => {
|
68
|
+
if (isWithSubmenuOnlyNode(pseudoFocusedItemNode)) {
|
69
|
+
openSubmenu({ itemNode: pseudoFocusedItemNode, event });
|
70
|
+
trackFocusFirstChildItem(pseudoFocusedItemNode);
|
71
|
+
} else {
|
72
|
+
if (isMultipleSelectNode(pseudoFocusedItemNode)) {
|
73
|
+
const newSelection = getNewSelectionMultipleSelect(selectedItems, pseudoFocusedItemNode);
|
74
|
+
onItemSelected(newSelection, { itemNode: pseudoFocusedItemNode, event });
|
75
|
+
} else if (isSingleSelectNode(pseudoFocusedItemNode)) {
|
76
|
+
const newSelection = getNewSelectionSingleSelect(selectedItems, pseudoFocusedItemNode);
|
77
|
+
onItemSelected(newSelection, { itemNode: pseudoFocusedItemNode, event });
|
78
|
+
} else {
|
79
|
+
onActivateItem(pseudoFocusedItemNode, { itemNode: pseudoFocusedItemNode, event });
|
80
|
+
}
|
81
|
+
const metainfo = { itemNode: pseudoFocusedItemNode, event };
|
82
|
+
const newOpenedItems = [];
|
83
|
+
handleChangeOpenedSubItems(newOpenedItems, metainfo);
|
84
|
+
onOpinionatedClose();
|
85
|
+
}
|
86
|
+
},
|
87
|
+
[
|
88
|
+
trackFocusFirstChildItem,
|
89
|
+
openSubmenu,
|
90
|
+
handleChangeOpenedSubItems,
|
91
|
+
onOpinionatedClose,
|
92
|
+
selectedItems,
|
93
|
+
onItemSelected,
|
94
|
+
onActivateItem
|
95
|
+
]
|
96
|
+
);
|
97
|
+
const handleMenuItemSpaceKeyDown = React2.useCallback(
|
98
|
+
({ pseudoFocusedItemNode, event }) => {
|
99
|
+
if (isWithSubmenuOnlyNode(pseudoFocusedItemNode)) {
|
100
|
+
openSubmenu({ itemNode: pseudoFocusedItemNode, event });
|
101
|
+
trackFocusFirstChildItem(pseudoFocusedItemNode);
|
102
|
+
return;
|
103
|
+
}
|
104
|
+
if (isMultipleSelectNode(pseudoFocusedItemNode)) {
|
105
|
+
const newSelection = getNewSelectionMultipleSelect(selectedItems, pseudoFocusedItemNode);
|
106
|
+
onItemSelected(newSelection, { itemNode: pseudoFocusedItemNode, event });
|
107
|
+
return;
|
108
|
+
}
|
109
|
+
if (isSingleSelectNode(pseudoFocusedItemNode)) {
|
110
|
+
const newSelection = getNewSelectionSingleSelect(selectedItems, pseudoFocusedItemNode);
|
111
|
+
onItemSelected(newSelection, { itemNode: pseudoFocusedItemNode, event });
|
112
|
+
return;
|
113
|
+
}
|
114
|
+
onActivateItem(pseudoFocusedItemNode, { itemNode: pseudoFocusedItemNode, event });
|
115
|
+
const metainfo = { itemNode: pseudoFocusedItemNode, event };
|
116
|
+
const newOpenedItems = [];
|
117
|
+
handleChangeOpenedSubItems(newOpenedItems, metainfo);
|
118
|
+
onOpinionatedClose();
|
119
|
+
},
|
120
|
+
[
|
121
|
+
onActivateItem,
|
122
|
+
handleChangeOpenedSubItems,
|
123
|
+
onOpinionatedClose,
|
124
|
+
trackFocusFirstChildItem,
|
125
|
+
openSubmenu,
|
126
|
+
selectedItems,
|
127
|
+
onItemSelected
|
128
|
+
]
|
129
|
+
);
|
130
|
+
const handleMenuItemRightArrowKeyDown = React2.useCallback(
|
131
|
+
({ pseudoFocusedItemNode, event }) => {
|
132
|
+
if (isWithSubmenuNode(pseudoFocusedItemNode)) {
|
133
|
+
openSubmenu({ itemNode: pseudoFocusedItemNode, event });
|
134
|
+
trackFocusFirstChildItem(pseudoFocusedItemNode);
|
135
|
+
return;
|
136
|
+
}
|
137
|
+
return;
|
138
|
+
},
|
139
|
+
[openSubmenu, trackFocusFirstChildItem]
|
140
|
+
);
|
141
|
+
const handleMenuItemLeftArrowKeyDown = React2.useCallback(
|
142
|
+
({ pseudoFocusedItemNode, event }) => {
|
143
|
+
const { currentSubmenuWasMainMenu } = closeCurrentSubmenu({ itemNode: pseudoFocusedItemNode, event });
|
144
|
+
if (!currentSubmenuWasMainMenu) {
|
145
|
+
trackFocusParentItem(pseudoFocusedItemNode);
|
146
|
+
}
|
147
|
+
},
|
148
|
+
[closeCurrentSubmenu, trackFocusParentItem]
|
149
|
+
);
|
150
|
+
const handleFocusableMenuItemKeyDown = React2.useCallback(
|
151
|
+
(event) => {
|
152
|
+
const pseudoFocusedItemNode = focusedElementItemNode.current;
|
153
|
+
if (pseudoFocusedItemNode === null) throw UNEXPECTED_INTERNAL_ERRORS.FOCUSED_ITEM_NODE_NOT_SET;
|
154
|
+
if (pseudoFocusedItemNode.plainItem.onKeyDown) pseudoFocusedItemNode.plainItem.onKeyDown(event);
|
155
|
+
if (event.key === "ArrowDown") {
|
156
|
+
trackFocusNextItem(pseudoFocusedItemNode);
|
157
|
+
return;
|
158
|
+
}
|
159
|
+
if (event.key === "ArrowUp") {
|
160
|
+
trackFocusPreviousItem(pseudoFocusedItemNode);
|
161
|
+
return;
|
162
|
+
}
|
163
|
+
if (event.key === "ArrowLeft") {
|
164
|
+
handleMenuItemLeftArrowKeyDown({ pseudoFocusedItemNode, event });
|
165
|
+
return;
|
166
|
+
}
|
167
|
+
if (event.key === "Home") {
|
168
|
+
if (!pseudoFocusedItemNode.parent) {
|
169
|
+
console.log("handleFocusableMenuItemKeyDown -> Home > focused item node", pseudoFocusedItemNode);
|
170
|
+
throw UNEXPECTED_INTERNAL_ERRORS.FOCUSED_ITEM_HAS_NO_PARENT;
|
171
|
+
}
|
172
|
+
trackFocusFirstChildItem(pseudoFocusedItemNode.parent);
|
173
|
+
return;
|
174
|
+
}
|
175
|
+
if (event.key === "End") {
|
176
|
+
if (!pseudoFocusedItemNode.parent) {
|
177
|
+
console.log("handleFocusableMenuItemKeyDown -> Home > focused item node", pseudoFocusedItemNode);
|
178
|
+
throw UNEXPECTED_INTERNAL_ERRORS.FOCUSED_ITEM_HAS_NO_PARENT;
|
179
|
+
}
|
180
|
+
trackFocusLastChildItem(pseudoFocusedItemNode.parent);
|
181
|
+
return;
|
182
|
+
}
|
183
|
+
if (event.key === "Escape") {
|
184
|
+
const { currentSubmenuWasMainMenu } = closeCurrentSubmenu({ itemNode: pseudoFocusedItemNode, event });
|
185
|
+
trackFocusParentItem(pseudoFocusedItemNode);
|
186
|
+
if (currentSubmenuWasMainMenu) {
|
187
|
+
onOpinionatedClose();
|
188
|
+
}
|
189
|
+
return;
|
190
|
+
}
|
191
|
+
if (pseudoFocusedItemNode.plainItem.disabled) return;
|
192
|
+
if (event.key === "Enter") {
|
193
|
+
handleMenuItemEnterKeyDown({ pseudoFocusedItemNode, event });
|
194
|
+
return;
|
195
|
+
}
|
196
|
+
if (event.key === " ") {
|
197
|
+
handleMenuItemSpaceKeyDown({ pseudoFocusedItemNode, event });
|
198
|
+
return;
|
199
|
+
}
|
200
|
+
if (event.key === "ArrowRight") {
|
201
|
+
handleMenuItemRightArrowKeyDown({ pseudoFocusedItemNode, event });
|
202
|
+
return;
|
203
|
+
}
|
204
|
+
},
|
205
|
+
[
|
206
|
+
focusedElementItemNode,
|
207
|
+
handleMenuItemEnterKeyDown,
|
208
|
+
handleMenuItemSpaceKeyDown,
|
209
|
+
trackFocusNextItem,
|
210
|
+
trackFocusPreviousItem,
|
211
|
+
handleMenuItemRightArrowKeyDown,
|
212
|
+
handleMenuItemLeftArrowKeyDown,
|
213
|
+
trackFocusFirstChildItem,
|
214
|
+
trackFocusLastChildItem,
|
215
|
+
closeCurrentSubmenu,
|
216
|
+
trackFocusParentItem,
|
217
|
+
onOpinionatedClose
|
218
|
+
]
|
219
|
+
);
|
220
|
+
const handleFocusableMenuItemOnMouseEnter = React2.useCallback(
|
221
|
+
(itemNode, event) => {
|
222
|
+
if (!isFocusableNode(itemNode)) {
|
223
|
+
console.log("handleFocusableMenuItemOnMouseEnter > itemNode:", itemNode);
|
224
|
+
throw FORBIDDEN_BEHAVIOURS.TRYING_TO_FOCUS_NON_FOCUSABLE_NODE;
|
225
|
+
}
|
226
|
+
trackFocusNode(itemNode);
|
227
|
+
if (!isWithSubmenuNode(itemNode)) {
|
228
|
+
const subMenuNodesPath = getSubMenusPath(itemNode);
|
229
|
+
const metainfo = { itemNode, event };
|
230
|
+
const newOpenedItems = [...subMenuNodesPath];
|
231
|
+
handleChangeOpenedSubItems(newOpenedItems, metainfo);
|
232
|
+
return;
|
233
|
+
}
|
234
|
+
if (itemNode.plainItem.disabled) return;
|
235
|
+
openSubmenu({ itemNode, event });
|
236
|
+
},
|
237
|
+
[handleChangeOpenedSubItems, openSubmenu, trackFocusNode]
|
238
|
+
);
|
239
|
+
const handleFocusableMenuItemClick = React2.useCallback(
|
240
|
+
(event) => {
|
241
|
+
const pseudoFocusedItemNode = focusedElementItemNode.current;
|
242
|
+
if (pseudoFocusedItemNode === null) throw UNEXPECTED_INTERNAL_ERRORS.FOCUSED_ITEM_NODE_NOT_SET;
|
243
|
+
if (pseudoFocusedItemNode.plainItem.disabled) return;
|
244
|
+
const parentMenuNode = pseudoFocusedItemNode.parent;
|
245
|
+
if (isRootNode(parentMenuNode)) {
|
246
|
+
const metainfo = { itemNode: pseudoFocusedItemNode, event };
|
247
|
+
const newOpenedItems = [];
|
248
|
+
handleChangeOpenedSubItems(newOpenedItems, metainfo);
|
249
|
+
} else {
|
250
|
+
const newOpenedItems = [...getSubMenusPath(pseudoFocusedItemNode)];
|
251
|
+
if (isWithSubmenuNode(pseudoFocusedItemNode)) {
|
252
|
+
newOpenedItems.push(pseudoFocusedItemNode);
|
253
|
+
}
|
254
|
+
const metainfo = { itemNode: pseudoFocusedItemNode, event };
|
255
|
+
handleChangeOpenedSubItems(newOpenedItems, metainfo);
|
256
|
+
}
|
257
|
+
handleMenuItemSpaceKeyDown({ pseudoFocusedItemNode, event });
|
258
|
+
if (pseudoFocusedItemNode.plainItem.onClick) pseudoFocusedItemNode.plainItem.onClick(event);
|
259
|
+
},
|
260
|
+
[focusedElementItemNode, handleMenuItemSpaceKeyDown, handleChangeOpenedSubItems]
|
261
|
+
);
|
262
|
+
const handleMenuItemFocusReconciliation = React2.useCallback(
|
263
|
+
(itemNode) => {
|
264
|
+
debounce(
|
265
|
+
() => {
|
266
|
+
if (focusedElementItemNode.current?.dsId !== itemNode.dsId) trackFocusNode(itemNode);
|
267
|
+
},
|
268
|
+
10,
|
269
|
+
{ leading: false, trailing: true }
|
270
|
+
);
|
271
|
+
},
|
272
|
+
[focusedElementItemNode, trackFocusNode]
|
273
|
+
);
|
274
|
+
return React2.useMemo(
|
275
|
+
() => ({
|
276
|
+
handleFocusableMenuItemKeyDown,
|
277
|
+
handleFocusableMenuItemClick,
|
278
|
+
handleFocusableMenuItemOnMouseEnter,
|
279
|
+
handleMenuItemFocusReconciliation
|
280
|
+
}),
|
281
|
+
[
|
282
|
+
handleFocusableMenuItemClick,
|
283
|
+
handleFocusableMenuItemKeyDown,
|
284
|
+
handleFocusableMenuItemOnMouseEnter,
|
285
|
+
handleMenuItemFocusReconciliation
|
286
|
+
]
|
287
|
+
);
|
288
|
+
};
|
289
|
+
export {
|
290
|
+
useMenuItemEventsHandlers
|
291
|
+
};
|
292
|
+
//# sourceMappingURL=useMenuItemEventsHandlers.js.map
|