@finsemble/finsemble-ui 7.0.0 → 7.1.0-beta.2
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/package.json +13 -11
- package/react/actions/favoriteActions.d.ts +1 -0
- package/react/actions/favoriteActions.js +1 -0
- package/react/actions/favoriteActions.js.map +1 -1
- package/react/actions/menuActions.d.ts +1 -0
- package/react/actions/menuActions.js +1 -0
- package/react/actions/menuActions.js.map +1 -1
- package/react/actions/rootActions.d.ts +1 -0
- package/react/actions/rootActions.js +1 -0
- package/react/actions/rootActions.js.map +1 -1
- package/react/actions/searchActions.d.ts +1 -0
- package/react/actions/searchActions.js +1 -0
- package/react/actions/searchActions.js.map +1 -1
- package/react/actions/toolbarActions.d.ts +34 -0
- package/react/actions/toolbarActions.js +17 -0
- package/react/actions/toolbarActions.js.map +1 -1
- package/react/actions/workspaceActions.d.ts +1 -0
- package/react/actions/workspaceActions.js +1 -0
- package/react/actions/workspaceActions.js.map +1 -1
- package/react/assets/css/advancedAppLauncher.css +22 -19
- package/react/assets/css/appCatalog.css +67 -72
- package/react/assets/css/authentication.css +4 -3
- package/react/assets/css/button.css +3 -10
- package/react/assets/css/core/formElements.css +1 -1
- package/react/assets/css/core/icons.css +3 -2
- package/react/assets/css/core/notifications.css +2 -2
- package/react/assets/css/core/windowFrame.css +9 -9
- package/react/assets/css/dashbar.css +1 -1
- package/react/assets/css/defaultTheme.css +9 -53
- package/react/assets/css/dialogs.css +13 -11
- package/react/assets/css/favorites.css +3 -1
- package/react/assets/css/finsemble.css +3 -2
- package/react/assets/css/font-finance.css +233 -120
- package/react/assets/css/fonts/Open_Sans/OpenSans-Definition.css +10 -10
- package/react/assets/css/linkerWindow.css +2 -2
- package/react/assets/css/menus.css +10 -10
- package/react/assets/css/notificationsCenter.css +16 -31
- package/react/assets/css/processMonitor.css +7 -4
- package/react/assets/css/search.css +1 -1
- package/react/assets/css/shared/animations.css +10 -4
- package/react/assets/css/shared/common.css +2 -2
- package/react/assets/css/tags.css +10 -10
- package/react/assets/css/toolbar.css +22 -19
- package/react/assets/css/userPreferences.css +12 -14
- package/react/assets/css/windowTitleBar.css +75 -36
- package/react/componentTemplateGenerator.js +3 -2
- package/react/componentTemplateGenerator.js.map +1 -1
- package/react/components/FinsembleProvider.d.ts +7 -0
- package/react/components/FinsembleProvider.js +2 -0
- package/react/components/FinsembleProvider.js.map +1 -1
- package/react/components/appCatalog/AppCatalog.d.ts +4 -0
- package/react/components/appCatalog/AppCatalog.js +4 -0
- package/react/components/appCatalog/AppCatalog.js.map +1 -1
- package/react/components/appCatalog/AppCatalogComponent.d.ts +58 -0
- package/react/components/appCatalog/AppCatalogComponent.js +70 -1
- package/react/components/appCatalog/AppCatalogComponent.js.map +1 -1
- package/react/components/appCatalog/components/AppCard.d.ts +35 -0
- package/react/components/appCatalog/components/AppCard.js +42 -0
- package/react/components/appCatalog/components/AppCard.js.map +1 -1
- package/react/components/appCatalog/components/AppResults.d.ts +10 -0
- package/react/components/appCatalog/components/AppResults.js +24 -0
- package/react/components/appCatalog/components/AppResults.js.map +1 -1
- package/react/components/appCatalog/components/Carousel.d.ts +26 -0
- package/react/components/appCatalog/components/Carousel.js +34 -0
- package/react/components/appCatalog/components/Carousel.js.map +1 -1
- package/react/components/appCatalog/components/EmptyResults.d.ts +4 -0
- package/react/components/appCatalog/components/EmptyResults.js +8 -0
- package/react/components/appCatalog/components/EmptyResults.js.map +1 -1
- package/react/components/appCatalog/components/Hero.d.ts +15 -0
- package/react/components/appCatalog/components/Hero.js +15 -0
- package/react/components/appCatalog/components/Hero.js.map +1 -1
- package/react/components/appCatalog/components/Home.d.ts +6 -4
- package/react/components/appCatalog/components/Home.js +10 -0
- package/react/components/appCatalog/components/Home.js.map +1 -1
- package/react/components/appCatalog/components/SearchBar.d.ts +31 -0
- package/react/components/appCatalog/components/SearchBar.js +33 -0
- package/react/components/appCatalog/components/SearchBar.js.map +1 -1
- package/react/components/appCatalog/components/Showcase/AppDescription.d.ts +5 -0
- package/react/components/appCatalog/components/Showcase/AppDescription.js +9 -0
- package/react/components/appCatalog/components/Showcase/AppDescription.js.map +1 -1
- package/react/components/appCatalog/components/Showcase/AppDevNotes.d.ts +7 -0
- package/react/components/appCatalog/components/Showcase/AppDevNotes.js +15 -0
- package/react/components/appCatalog/components/Showcase/AppDevNotes.js.map +1 -1
- package/react/components/appCatalog/components/Showcase/AppShowcase.d.ts +17 -0
- package/react/components/appCatalog/components/Showcase/AppShowcase.js +25 -0
- package/react/components/appCatalog/components/Showcase/AppShowcase.js.map +1 -1
- package/react/components/appCatalog/components/Showcase/Header.d.ts +7 -0
- package/react/components/appCatalog/components/Showcase/Header.js +12 -0
- package/react/components/appCatalog/components/Showcase/Header.js.map +1 -1
- package/react/components/appCatalog/components/Showcase/ImageCarousel.d.ts +7 -0
- package/react/components/appCatalog/components/Showcase/ImageCarousel.js +11 -0
- package/react/components/appCatalog/components/Showcase/ImageCarousel.js.map +1 -1
- package/react/components/appCatalog/components/Showcase/Modal.d.ts +10 -0
- package/react/components/appCatalog/components/Showcase/Modal.js +10 -0
- package/react/components/appCatalog/components/Showcase/Modal.js.map +1 -1
- package/react/components/appCatalog/components/Showcase/ReleaseNotes.d.ts +5 -0
- package/react/components/appCatalog/components/Showcase/ReleaseNotes.js +9 -0
- package/react/components/appCatalog/components/Showcase/ReleaseNotes.js.map +1 -1
- package/react/components/appCatalog/components/Showcase/SupportNotes.d.ts +6 -0
- package/react/components/appCatalog/components/Showcase/SupportNotes.js +11 -0
- package/react/components/appCatalog/components/Showcase/SupportNotes.js.map +1 -1
- package/react/components/appCatalog/components/Showcase/VersionNotes.d.ts +5 -0
- package/react/components/appCatalog/components/Showcase/VersionNotes.js +9 -0
- package/react/components/appCatalog/components/Showcase/VersionNotes.js.map +1 -1
- package/react/components/appCatalog/components/Tag.d.ts +6 -0
- package/react/components/appCatalog/components/Tag.js +10 -0
- package/react/components/appCatalog/components/Tag.js.map +1 -1
- package/react/components/appCatalog/components/Toast.d.ts +5 -0
- package/react/components/appCatalog/components/Toast.js +9 -0
- package/react/components/appCatalog/components/Toast.js.map +1 -1
- package/react/components/appCatalog/components/helpers.js +1 -0
- package/react/components/appCatalog/components/helpers.js.map +1 -1
- package/react/components/appCatalog/modules/AppDirectory.d.ts +5 -0
- package/react/components/appCatalog/modules/AppDirectory.js +5 -0
- package/react/components/appCatalog/modules/AppDirectory.js.map +1 -1
- package/react/components/appCatalog/modules/FDC3.d.ts +37 -0
- package/react/components/appCatalog/modules/FDC3.js +40 -0
- package/react/components/appCatalog/modules/FDC3.js.map +1 -1
- package/react/components/appCatalog/stores/appStore.js +1 -0
- package/react/components/appCatalog/stores/appStore.js.map +1 -1
- package/react/components/appCatalog/stores/storeActions.d.ts +91 -0
- package/react/components/appCatalog/stores/storeActions.js +116 -1
- package/react/components/appCatalog/stores/storeActions.js.map +1 -1
- package/react/components/common/Checkbox.d.ts +1 -0
- package/react/components/common/Checkbox.js +2 -2
- package/react/components/common/Checkbox.js.map +1 -1
- package/react/components/common/ColorPicker.d.ts +5 -0
- package/react/components/common/ColorPicker.js +40 -0
- package/react/components/common/ColorPicker.js.map +1 -1
- package/react/components/common/DropZone.d.ts +11 -0
- package/react/components/common/DropZone.js +21 -1
- package/react/components/common/DropZone.js.map +1 -1
- package/react/components/common/DropdownButton.d.ts +4 -0
- package/react/components/common/DropdownButton.js +4 -0
- package/react/components/common/DropdownButton.js.map +1 -1
- package/react/components/common/ErrorBoundary.d.ts +18 -0
- package/react/components/common/ErrorBoundary.js +21 -0
- package/react/components/common/ErrorBoundary.js.map +1 -1
- package/react/components/common/FileInput.d.ts +8 -1
- package/react/components/common/FileInput.js +19 -4
- package/react/components/common/FileInput.js.map +1 -1
- package/react/components/common/FinsembleIcon.d.ts +10 -0
- package/react/components/common/FinsembleIcon.js +51 -2
- package/react/components/common/FinsembleIcon.js.map +1 -1
- package/react/components/common/FinsembleSelect.js +5 -1
- package/react/components/common/FinsembleSelect.js.map +1 -1
- package/react/components/common/FinsembleToggleButtonBar.js +1 -1
- package/react/components/common/FinsembleToggleButtonBar.js.map +1 -1
- package/react/components/common/InputTable.d.ts +7 -0
- package/react/components/common/InputTable.js +7 -0
- package/react/components/common/InputTable.js.map +1 -1
- package/react/components/common/Tab.js +3 -0
- package/react/components/common/Tab.js.map +1 -1
- package/react/components/common/TimeSelect.js +24 -0
- package/react/components/common/TimeSelect.js.map +1 -1
- package/react/components/common/Tooltip.js +2 -0
- package/react/components/common/Tooltip.js.map +1 -1
- package/react/components/common/css/accordion.css +9 -6
- package/react/components/common/css/application-edit-page.css +39 -44
- package/react/components/common/css/button.css +10 -5
- package/react/components/common/css/color-picker.css +3 -3
- package/react/components/common/css/drop-zone.css +2 -6
- package/react/components/common/css/file-input.css +5 -5
- package/react/components/common/css/header.css +3 -2
- package/react/components/common/css/icon.css +1 -1
- package/react/components/common/css/loading-spinner.css +7 -12
- package/react/components/common/css/selector.css +4 -4
- package/react/components/common/css/styles.css +22 -16
- package/react/components/common/css/tab.css +8 -8
- package/react/components/common/css/time-select.css +1 -0
- package/react/components/common/css/toggle.css +4 -4
- package/react/components/common/css/tooltip.css +2 -3
- package/react/components/common/file_helpers.js +2 -0
- package/react/components/common/file_helpers.js.map +1 -1
- package/react/components/common/helpers.js +1 -0
- package/react/components/common/helpers.js.map +1 -1
- package/react/components/common/stories/ColorPicker.stories.js +3 -0
- package/react/components/common/stories/ColorPicker.stories.js.map +1 -1
- package/react/components/common/stories/FileInput.stories.d.ts +3 -1
- package/react/components/common/stories/FileInput.stories.js +12 -0
- package/react/components/common/stories/FileInput.stories.js.map +1 -1
- package/react/components/common/tests/Accordion.spec.js +6 -0
- package/react/components/common/tests/Accordion.spec.js.map +1 -1
- package/react/components/common/tests/Checkbox.spec.js +1 -0
- package/react/components/common/tests/Checkbox.spec.js.map +1 -1
- package/react/components/common/tests/ColorPicker.spec.js +6 -0
- package/react/components/common/tests/ColorPicker.spec.js.map +1 -1
- package/react/components/common/tests/DropZone.spec.js +1 -0
- package/react/components/common/tests/DropZone.spec.js.map +1 -1
- package/react/components/common/tests/FileInput.spec.js +22 -0
- package/react/components/common/tests/FileInput.spec.js.map +1 -1
- package/react/components/common/tests/FinsembleSelect.spec.js +1 -0
- package/react/components/common/tests/FinsembleSelect.spec.js.map +1 -1
- package/react/components/common/tests/FinsembleToggle.spec.js +1 -0
- package/react/components/common/tests/FinsembleToggle.spec.js.map +1 -1
- package/react/components/common/tests/FinsembleToggleButtonBar.spec.js +1 -0
- package/react/components/common/tests/FinsembleToggleButtonBar.spec.js.map +1 -1
- package/react/components/common/tests/TimeSelect.spec.js +4 -0
- package/react/components/common/tests/TimeSelect.spec.js.map +1 -1
- package/react/components/common/tests/Tooltip.spec.js +16 -0
- package/react/components/common/tests/Tooltip.spec.js.map +1 -1
- package/react/components/favorites/FavoriteMaker.d.ts +8 -0
- package/react/components/favorites/FavoriteMaker.js +9 -0
- package/react/components/favorites/FavoriteMaker.js.map +1 -1
- package/react/components/favorites/FavoritesShell.d.ts +4 -0
- package/react/components/favorites/FavoritesShell.js +13 -1
- package/react/components/favorites/FavoritesShell.js.map +1 -1
- package/react/components/favorites/FavoritesShell.spec.js +3 -0
- package/react/components/favorites/FavoritesShell.spec.js.map +1 -1
- package/react/components/fdc3Resolver/ResolverContainer.js +8 -0
- package/react/components/fdc3Resolver/ResolverContainer.js.map +1 -1
- package/react/components/fdc3Resolver/ResolverDialog.css +16 -3
- package/react/components/fdc3Resolver/ResolverDialog.js +7 -2
- package/react/components/fdc3Resolver/ResolverDialog.js.map +1 -1
- package/react/components/fdc3Resolver/ResolverDialog.spec.js +3 -2
- package/react/components/fdc3Resolver/ResolverDialog.spec.js.map +1 -1
- package/react/components/fdc3Resolver/ResolverDialog.stories.js +2 -0
- package/react/components/fdc3Resolver/ResolverDialog.stories.js.map +1 -1
- package/react/components/icon/Icon.d.ts +13 -0
- package/react/components/icon/Icon.js +34 -0
- package/react/components/icon/Icon.js.map +1 -1
- package/react/components/legacyControls/FinsembleDialog.d.ts +4 -0
- package/react/components/legacyControls/FinsembleDialog.js +15 -0
- package/react/components/legacyControls/FinsembleDialog.js.map +1 -1
- package/react/components/legacyControls/FinsembleDialogButton.d.ts +3 -0
- package/react/components/legacyControls/FinsembleDialogButton.js +6 -1
- package/react/components/legacyControls/FinsembleDialogButton.js.map +1 -1
- package/react/components/legacyControls/FinsembleDialogQuestion.d.ts +7 -0
- package/react/components/legacyControls/FinsembleDialogQuestion.js +7 -0
- package/react/components/legacyControls/FinsembleDialogQuestion.js.map +1 -1
- package/react/components/legacyControls/FinsembleDialogTextInput.d.ts +3 -0
- package/react/components/legacyControls/FinsembleDialogTextInput.js +14 -0
- package/react/components/legacyControls/FinsembleDialogTextInput.js.map +1 -1
- package/react/components/legacyControls/FinsembleDnDContext.d.ts +19 -0
- package/react/components/legacyControls/FinsembleDnDContext.js +126 -1
- package/react/components/legacyControls/FinsembleDnDContext.js.map +1 -1
- package/react/components/legacyControls/FinsembleDraggable.d.ts +3 -0
- package/react/components/legacyControls/FinsembleDraggable.js +3 -0
- package/react/components/legacyControls/FinsembleDraggable.js.map +1 -1
- package/react/components/legacyControls/FinsembleHoverDetector.d.ts +15 -0
- package/react/components/legacyControls/FinsembleHoverDetector.js +26 -1
- package/react/components/legacyControls/FinsembleHoverDetector.js.map +1 -1
- package/react/components/legacyControls/FinsembleMenuSection.d.ts +4 -0
- package/react/components/legacyControls/FinsembleMenuSection.js +38 -0
- package/react/components/legacyControls/FinsembleMenuSection.js.map +1 -1
- package/react/components/legacyControls/tests/FinsembleDialogButton.spec.js +1 -0
- package/react/components/legacyControls/tests/FinsembleDialogButton.spec.js.map +1 -1
- package/react/components/legacyControls/tests/FinsembleDialogTextInput.spec.js +1 -0
- package/react/components/legacyControls/tests/FinsembleDialogTextInput.spec.js.map +1 -1
- package/react/components/linker/LinkerMenu.d.ts +3 -0
- package/react/components/linker/LinkerMenu.js +21 -0
- package/react/components/linker/LinkerMenu.js.map +1 -1
- package/react/components/linker/LinkerMenuDeprecated.d.ts +3 -0
- package/react/components/linker/LinkerMenuDeprecated.js +9 -0
- package/react/components/linker/LinkerMenuDeprecated.js.map +1 -1
- package/react/components/menu/Menu.d.ts +15 -0
- package/react/components/menu/Menu.js +15 -0
- package/react/components/menu/Menu.js.map +1 -1
- package/react/components/menu/MenuAutoResizer.d.ts +7 -0
- package/react/components/menu/MenuAutoResizer.js +27 -0
- package/react/components/menu/MenuAutoResizer.js.map +1 -1
- package/react/components/menu/MenuContent.d.ts +4 -0
- package/react/components/menu/MenuContent.js +4 -0
- package/react/components/menu/MenuContent.js.map +1 -1
- package/react/components/menu/MenuHotKey.d.ts +14 -0
- package/react/components/menu/MenuHotKey.js +15 -0
- package/react/components/menu/MenuHotKey.js.map +1 -1
- package/react/components/menu/MenuItem.d.ts +8 -0
- package/react/components/menu/MenuItem.js +13 -2
- package/react/components/menu/MenuItem.js.map +1 -1
- package/react/components/menu/MenuPortal.js +112 -2
- package/react/components/menu/MenuPortal.js.map +1 -1
- package/react/components/menu/MenuShell.d.ts +16 -0
- package/react/components/menu/MenuShell.js +26 -0
- package/react/components/menu/MenuShell.js.map +1 -1
- package/react/components/menu/MenuToggle.d.ts +3 -0
- package/react/components/menu/MenuToggle.js +3 -0
- package/react/components/menu/MenuToggle.js.map +1 -1
- package/react/components/menu/keyboardNavigation.d.ts +12 -0
- package/react/components/menu/keyboardNavigation.js +55 -0
- package/react/components/menu/keyboardNavigation.js.map +1 -1
- package/react/components/menu/menuContext.d.ts +6 -0
- package/react/components/menu/menuContext.js +6 -0
- package/react/components/menu/menuContext.js.map +1 -1
- package/react/components/menu/menuHelpers.d.ts +22 -0
- package/react/components/menu/menuHelpers.js +58 -1
- package/react/components/menu/menuHelpers.js.map +1 -1
- package/react/components/notifications/components/drawer/DrawerControls.js +8 -0
- package/react/components/notifications/components/drawer/DrawerControls.js.map +1 -1
- package/react/components/notifications/components/drawer/DrawerHeader.js +5 -0
- package/react/components/notifications/components/drawer/DrawerHeader.js.map +1 -1
- package/react/components/notifications/components/notificationsCenter/NotificationsCenter.js +18 -0
- package/react/components/notifications/components/notificationsCenter/NotificationsCenter.js.map +1 -1
- package/react/components/notifications/components/notificationsToasts/NotificationsToasts.js +3 -0
- package/react/components/notifications/components/notificationsToasts/NotificationsToasts.js.map +1 -1
- package/react/components/notifications/components/shared/CheckButton.js +1 -1
- package/react/components/notifications/components/shared/CheckButton.js.map +1 -1
- package/react/components/notifications/components/shared/NotificationCardShell.d.ts +9 -0
- package/react/components/notifications/components/shared/NotificationCardShell.js +13 -6
- package/react/components/notifications/components/shared/NotificationCardShell.js.map +1 -1
- package/react/components/notifications/components/shared/OverflowMenu.d.ts +4 -0
- package/react/components/notifications/components/shared/OverflowMenu.js +16 -2
- package/react/components/notifications/components/shared/OverflowMenu.js.map +1 -1
- package/react/components/notifications/components/views/CardView.js +3 -0
- package/react/components/notifications/components/views/CardView.js.map +1 -1
- package/react/components/notifications/components/views/ListView.js +8 -0
- package/react/components/notifications/components/views/ListView.js.map +1 -1
- package/react/components/notifications/notificationsContext.d.ts +4 -0
- package/react/components/notifications/notificationsContext.js +4 -0
- package/react/components/notifications/notificationsContext.js.map +1 -1
- package/react/components/notifications/types.d.ts +3 -0
- package/react/components/notifications/utils.d.ts +4 -0
- package/react/components/notifications/utils.js +4 -0
- package/react/components/notifications/utils.js.map +1 -1
- package/react/components/processMonitor/ProcessMonitor.d.ts +3 -0
- package/react/components/processMonitor/ProcessMonitor.js +17 -2
- package/react/components/processMonitor/ProcessMonitor.js.map +1 -1
- package/react/components/processMonitor/components/ChildWindow.d.ts +3 -0
- package/react/components/processMonitor/components/ChildWindow.js +5 -0
- package/react/components/processMonitor/components/ChildWindow.js.map +1 -1
- package/react/components/processMonitor/components/ListHeader.d.ts +5 -0
- package/react/components/processMonitor/components/ListHeader.js +7 -0
- package/react/components/processMonitor/components/ListHeader.js.map +1 -1
- package/react/components/processMonitor/components/ProcessStatistics.js +12 -1
- package/react/components/processMonitor/components/ProcessStatistics.js.map +1 -1
- package/react/components/processMonitor/constants.js +6 -0
- package/react/components/processMonitor/constants.js.map +1 -1
- package/react/components/processMonitor/helpers.d.ts +13 -0
- package/react/components/processMonitor/helpers.js +23 -3
- package/react/components/processMonitor/helpers.js.map +1 -1
- package/react/components/processMonitor/stores/ProcessMonitorStore.d.ts +39 -0
- package/react/components/processMonitor/stores/ProcessMonitorStore.js +50 -0
- package/react/components/processMonitor/stores/ProcessMonitorStore.js.map +1 -1
- package/react/components/quickComponentForm/QuickComponentForm.d.ts +3 -0
- package/react/components/quickComponentForm/QuickComponentForm.js +20 -0
- package/react/components/quickComponentForm/QuickComponentForm.js.map +1 -1
- package/react/components/quickComponentForm/quickComponent.css +1 -1
- package/react/components/sdd/AddApp.d.ts +4 -2
- package/react/components/sdd/AddApp.js +57 -49
- package/react/components/sdd/AddApp.js.map +1 -1
- package/react/components/sdd/AppEditAccess.js +8 -0
- package/react/components/sdd/AppEditAccess.js.map +1 -1
- package/react/components/sdd/AppEditPage.d.ts +2 -1
- package/react/components/sdd/AppEditPage.js +148 -361
- package/react/components/sdd/AppEditPage.js.map +1 -1
- package/react/components/sdd/Appearance.css +1 -1
- package/react/components/sdd/Appearance.js +3 -0
- package/react/components/sdd/Appearance.js.map +1 -1
- package/react/components/sdd/Application.js +39 -7
- package/react/components/sdd/Application.js.map +1 -1
- package/react/components/sdd/Applications.js +89 -13
- package/react/components/sdd/Applications.js.map +1 -1
- package/react/components/sdd/AssetsPage.css +3 -3
- package/react/components/sdd/EditPreload.js +10 -0
- package/react/components/sdd/EditPreload.js.map +1 -1
- package/react/components/sdd/ExportCloud.js +4 -0
- package/react/components/sdd/ExportCloud.js.map +1 -1
- package/react/components/sdd/Publish.js +2 -0
- package/react/components/sdd/Publish.js.map +1 -1
- package/react/components/sdd/PublishProgress.js +11 -1
- package/react/components/sdd/PublishProgress.js.map +1 -1
- package/react/components/sdd/SmartDesktopDesigner.js +17 -0
- package/react/components/sdd/SmartDesktopDesigner.js.map +1 -1
- package/react/components/sdd/ThemePage.css +6 -23
- package/react/components/sdd/ThemePage.js +1 -1
- package/react/components/sdd/ThemePage.js.map +1 -1
- package/react/components/sdd/Themes.js +2 -0
- package/react/components/sdd/Themes.js.map +1 -1
- package/react/components/sdd/Toolbar.js +7 -0
- package/react/components/sdd/Toolbar.js.map +1 -1
- package/react/components/sdd/appEditPage/Behavior.d.ts +34 -0
- package/react/components/sdd/appEditPage/Behavior.js +134 -0
- package/react/components/sdd/appEditPage/Behavior.js.map +1 -0
- package/react/components/sdd/appEditPage/Component.d.ts +22 -0
- package/react/components/sdd/appEditPage/Component.js +76 -0
- package/react/components/sdd/appEditPage/Component.js.map +1 -0
- package/react/components/sdd/appEditPage/DebugToolkit.d.ts +9 -0
- package/react/components/sdd/appEditPage/DebugToolkit.js +20 -0
- package/react/components/sdd/appEditPage/DebugToolkit.js.map +1 -0
- package/react/components/sdd/appEditPage/Interop.d.ts +10 -0
- package/react/components/sdd/appEditPage/Interop.js +40 -0
- package/react/components/sdd/appEditPage/Interop.js.map +1 -0
- package/react/components/sdd/appEditPage/Position.d.ts +18 -0
- package/react/components/sdd/appEditPage/Position.js +72 -0
- package/react/components/sdd/appEditPage/Position.js.map +1 -0
- package/react/components/sdd/appEditPage/Preloads.d.ts +9 -0
- package/react/components/sdd/appEditPage/Preloads.js +16 -0
- package/react/components/sdd/appEditPage/Preloads.js.map +1 -0
- package/react/components/sdd/appEditPage/SelectConnect.d.ts +15 -0
- package/react/components/sdd/appEditPage/SelectConnect.js +28 -0
- package/react/components/sdd/appEditPage/SelectConnect.js.map +1 -0
- package/react/components/sdd/appEditPage/Workspace.d.ts +12 -0
- package/react/components/sdd/appEditPage/Workspace.js +30 -0
- package/react/components/sdd/appEditPage/Workspace.js.map +1 -0
- package/react/components/sdd/common/getCSSVars.js +7 -2
- package/react/components/sdd/common/getCSSVars.js.map +1 -1
- package/react/components/sdd/common/setPreloadDefaults.js +4 -0
- package/react/components/sdd/common/setPreloadDefaults.js.map +1 -1
- package/react/components/sdd/css/addApp.css +18 -5
- package/react/components/sdd/css/appearance.css +6 -0
- package/react/components/sdd/css/applications.css +27 -14
- package/react/components/sdd/css/authentication.css +7 -6
- package/react/components/sdd/css/buttons.css +1 -1
- package/react/components/sdd/css/export.css +5 -3
- package/react/components/sdd/css/getting-started.css +2 -2
- package/react/components/sdd/css/nav.css +8 -11
- package/react/components/sdd/css/project-header.css +5 -7
- package/react/components/sdd/css/styles.css +29 -23
- package/react/components/sdd/css/views.css +4 -3
- package/react/components/sdd/fixtures/apps.js +12 -0
- package/react/components/sdd/fixtures/apps.js.map +1 -1
- package/react/components/sdd/fixtures/configTemplate.js +1 -0
- package/react/components/sdd/fixtures/configTemplate.js.map +1 -1
- package/react/components/sdd/fixtures/publishProgress.js +40 -0
- package/react/components/sdd/fixtures/publishProgress.js.map +1 -1
- package/react/components/sdd/sdd_helpers.d.ts +6 -0
- package/react/components/sdd/sdd_helpers.js +6 -0
- package/react/components/sdd/sdd_helpers.js.map +1 -1
- package/react/components/sdd/smartDesktopClient.d.ts +303 -0
- package/react/components/sdd/smartDesktopClient.js +334 -1
- package/react/components/sdd/smartDesktopClient.js.map +1 -1
- package/react/components/sdd/smartDesktopClient.spec.js +5 -2
- package/react/components/sdd/smartDesktopClient.spec.js.map +1 -1
- package/react/components/sdd/stories/AddApp.stories.d.ts +2 -1
- package/react/components/sdd/stories/AddApp.stories.js +8 -0
- package/react/components/sdd/stories/AddApp.stories.js.map +1 -1
- package/react/components/sdd/stories/AppEditPage.stories.d.ts +3 -1
- package/react/components/sdd/stories/AppEditPage.stories.js +3 -0
- package/react/components/sdd/stories/AppEditPage.stories.js.map +1 -1
- package/react/components/sdd/stories/Appearance.stories.js +1 -0
- package/react/components/sdd/stories/Appearance.stories.js.map +1 -1
- package/react/components/sdd/tests/AddApp.spec.js +40 -3
- package/react/components/sdd/tests/AddApp.spec.js.map +1 -1
- package/react/components/sdd/tests/AppEditPage.spec.js +16 -0
- package/react/components/sdd/tests/AppEditPage.spec.js.map +1 -1
- package/react/components/sdd/tests/Application.spec.js +33 -438
- package/react/components/sdd/tests/Application.spec.js.map +1 -1
- package/react/components/sdd/tests/Applications.spec.d.ts +1 -1
- package/react/components/sdd/tests/Applications.spec.js +29 -5
- package/react/components/sdd/tests/Applications.spec.js.map +1 -1
- package/react/components/sdd/tests/Authentication.spec.js +7 -0
- package/react/components/sdd/tests/Authentication.spec.js.map +1 -1
- package/react/components/sdd/tests/ContentHeader.spec.js +2 -0
- package/react/components/sdd/tests/ContentHeader.spec.js.map +1 -1
- package/react/components/sdd/tests/EditPreload.spec.js +13 -0
- package/react/components/sdd/tests/EditPreload.spec.js.map +1 -1
- package/react/components/sdd/tests/Export.spec.js +2 -1
- package/react/components/sdd/tests/Export.spec.js.map +1 -1
- package/react/components/sdd/tests/ItemList.spec.js +4 -0
- package/react/components/sdd/tests/ItemList.spec.js.map +1 -1
- package/react/components/sdd/tests/OptionalSettingsView.spec.js +29 -0
- package/react/components/sdd/tests/OptionalSettingsView.spec.js.map +1 -1
- package/react/components/sdd/tests/ProjectErrors.spec.js +2 -0
- package/react/components/sdd/tests/ProjectErrors.spec.js.map +1 -1
- package/react/components/sdd/tests/Themes.spec.js +1 -1
- package/react/components/sdd/tests/Themes.spec.js.map +1 -1
- package/react/components/sdd/tests/Toolbar.spec.js +53 -0
- package/react/components/sdd/tests/Toolbar.spec.js.map +1 -1
- package/react/components/sdd/tests/a11y_helper.js +8 -0
- package/react/components/sdd/tests/a11y_helper.js.map +1 -1
- package/react/components/search/Highlight.d.ts +6 -0
- package/react/components/search/Highlight.js +19 -0
- package/react/components/search/Highlight.js.map +1 -1
- package/react/components/search/SearchBestMatch.d.ts +4 -0
- package/react/components/search/SearchBestMatch.js +11 -0
- package/react/components/search/SearchBestMatch.js.map +1 -1
- package/react/components/search/SearchInput.d.ts +5 -0
- package/react/components/search/SearchInput.js +6 -0
- package/react/components/search/SearchInput.js.map +1 -1
- package/react/components/search/SearchProviderResults.js +2 -0
- package/react/components/search/SearchProviderResults.js.map +1 -1
- package/react/components/search/SearchResult.js +6 -0
- package/react/components/search/SearchResult.js.map +1 -1
- package/react/components/search/SearchResult.spec.js +7 -0
- package/react/components/search/SearchResult.spec.js.map +1 -1
- package/react/components/search/SearchResult.stories.js +4 -0
- package/react/components/search/SearchResult.stories.js.map +1 -1
- package/react/components/search/SearchResults.js +5 -1
- package/react/components/search/SearchResults.js.map +1 -1
- package/react/components/search/SearchResults.spec.js +7 -0
- package/react/components/search/SearchResults.spec.js.map +1 -1
- package/react/components/shared/Animate.d.ts +5 -0
- package/react/components/shared/Animate.js +12 -1
- package/react/components/shared/Animate.js.map +1 -1
- package/react/components/shared/DefaultDropdownButton.js +9 -0
- package/react/components/shared/DefaultDropdownButton.js.map +1 -1
- package/react/components/shared/Tag.d.ts +0 -4
- package/react/components/shared/Tag.js +4 -0
- package/react/components/shared/Tag.js.map +1 -1
- package/react/components/shared/TagsMenu.d.ts +6 -0
- package/react/components/shared/TagsMenu.js +7 -0
- package/react/components/shared/TagsMenu.js.map +1 -1
- package/react/components/shared/addProtocolToValidURL.d.ts +6 -0
- package/react/components/shared/addProtocolToValidURL.js +6 -0
- package/react/components/shared/addProtocolToValidURL.js.map +1 -1
- package/react/components/shared/openQuitConfirmationDialog.d.ts +1 -1
- package/react/components/shared/openQuitConfirmationDialog.js +4 -4
- package/react/components/shared/openQuitConfirmationDialog.js.map +1 -1
- package/react/components/shared/tests/addProtocolToValidURL.spec.js +1 -0
- package/react/components/shared/tests/addProtocolToValidURL.spec.js.map +1 -1
- package/react/components/shared/validateURL.d.ts +18 -0
- package/react/components/shared/validateURL.js +24 -5
- package/react/components/shared/validateURL.js.map +1 -1
- package/react/components/singleInputDialog/SingleInputDialog.css +1 -1
- package/react/components/singleInputDialog/SingleInputDialog.d.ts +3 -0
- package/react/components/singleInputDialog/SingleInputDialog.js +44 -0
- package/react/components/singleInputDialog/SingleInputDialog.js.map +1 -1
- package/react/components/smartDesktopDesigner/SmartDesktopDesigner.js +6 -0
- package/react/components/smartDesktopDesigner/SmartDesktopDesigner.js.map +1 -1
- package/react/components/system/System.d.ts +22 -0
- package/react/components/system/System.js +23 -1
- package/react/components/system/System.js.map +1 -1
- package/react/components/system/System.stories.js +1 -0
- package/react/components/system/System.stories.js.map +1 -1
- package/react/components/system/SystemTrayComponentShell.d.ts +6 -0
- package/react/components/system/SystemTrayComponentShell.js +9 -0
- package/react/components/system/SystemTrayComponentShell.js.map +1 -1
- package/react/components/toolbar/AutoArrange.d.ts +5 -0
- package/react/components/toolbar/AutoArrange.js +8 -1
- package/react/components/toolbar/AutoArrange.js.map +1 -1
- package/react/components/toolbar/AutoArrange.spec.js +1 -0
- package/react/components/toolbar/AutoArrange.spec.js.map +1 -1
- package/react/components/toolbar/AutoArrange.stories.js +1 -0
- package/react/components/toolbar/AutoArrange.stories.js.map +1 -1
- package/react/components/toolbar/DragHandle.d.ts +4 -0
- package/react/components/toolbar/DragHandle.js +11 -0
- package/react/components/toolbar/DragHandle.js.map +1 -1
- package/react/components/toolbar/DragHandle.spec.js +1 -0
- package/react/components/toolbar/DragHandle.spec.js.map +1 -1
- package/react/components/toolbar/DragHandle.stories.js +1 -0
- package/react/components/toolbar/DragHandle.stories.js.map +1 -1
- package/react/components/toolbar/MinimizeAll.d.ts +4 -0
- package/react/components/toolbar/MinimizeAll.js +7 -1
- package/react/components/toolbar/MinimizeAll.js.map +1 -1
- package/react/components/toolbar/MinimizeAll.spec.js +1 -0
- package/react/components/toolbar/MinimizeAll.spec.js.map +1 -1
- package/react/components/toolbar/MinimizeAll.stories.js +1 -0
- package/react/components/toolbar/MinimizeAll.stories.js.map +1 -1
- package/react/components/toolbar/NotificationControl.d.ts +5 -0
- package/react/components/toolbar/NotificationControl.js +8 -1
- package/react/components/toolbar/NotificationControl.js.map +1 -1
- package/react/components/toolbar/RevealAll.d.ts +4 -0
- package/react/components/toolbar/RevealAll.js +7 -1
- package/react/components/toolbar/RevealAll.js.map +1 -1
- package/react/components/toolbar/RevealAll.spec.js +1 -0
- package/react/components/toolbar/RevealAll.spec.js.map +1 -1
- package/react/components/toolbar/RevealAll.stories.js +1 -0
- package/react/components/toolbar/RevealAll.stories.js.map +1 -1
- package/react/components/toolbar/SddButton.d.ts +4 -0
- package/react/components/toolbar/SddButton.js +4 -0
- package/react/components/toolbar/SddButton.js.map +1 -1
- package/react/components/toolbar/ToolbarIcon.d.ts +4 -0
- package/react/components/toolbar/ToolbarIcon.js +4 -0
- package/react/components/toolbar/ToolbarIcon.js.map +1 -1
- package/react/components/toolbar/ToolbarSection.d.ts +7 -0
- package/react/components/toolbar/ToolbarSection.js +19 -1
- package/react/components/toolbar/ToolbarSection.js.map +1 -1
- package/react/components/toolbar/ToolbarShell.d.ts +5 -0
- package/react/components/toolbar/ToolbarShell.js +7 -0
- package/react/components/toolbar/ToolbarShell.js.map +1 -1
- package/react/components/toolbar/advancedAppLauncher/AdvancedAppLauncher.d.ts +16 -0
- package/react/components/toolbar/advancedAppLauncher/AdvancedAppLauncher.js +20 -0
- package/react/components/toolbar/advancedAppLauncher/AdvancedAppLauncher.js.map +1 -1
- package/react/components/toolbar/advancedAppLauncher/components/AddNewAppForm.d.ts +52 -0
- package/react/components/toolbar/advancedAppLauncher/components/AddNewAppForm.js +58 -0
- package/react/components/toolbar/advancedAppLauncher/components/AddNewAppForm.js.map +1 -1
- package/react/components/toolbar/advancedAppLauncher/components/AddNewFolder.d.ts +5 -0
- package/react/components/toolbar/advancedAppLauncher/components/AddNewFolder.js +5 -0
- package/react/components/toolbar/advancedAppLauncher/components/AddNewFolder.js.map +1 -1
- package/react/components/toolbar/advancedAppLauncher/components/AppActionsMenu.d.ts +27 -0
- package/react/components/toolbar/advancedAppLauncher/components/AppActionsMenu.js +49 -0
- package/react/components/toolbar/advancedAppLauncher/components/AppActionsMenu.js.map +1 -1
- package/react/components/toolbar/advancedAppLauncher/components/AppDefinition.d.ts +13 -0
- package/react/components/toolbar/advancedAppLauncher/components/AppDefinition.js +14 -0
- package/react/components/toolbar/advancedAppLauncher/components/AppDefinition.js.map +1 -1
- package/react/components/toolbar/advancedAppLauncher/components/Content.d.ts +5 -0
- package/react/components/toolbar/advancedAppLauncher/components/Content.js +19 -0
- package/react/components/toolbar/advancedAppLauncher/components/Content.js.map +1 -1
- package/react/components/toolbar/advancedAppLauncher/components/FilterSort.d.ts +4 -0
- package/react/components/toolbar/advancedAppLauncher/components/FilterSort.js +4 -0
- package/react/components/toolbar/advancedAppLauncher/components/FilterSort.js.map +1 -1
- package/react/components/toolbar/advancedAppLauncher/components/FoldersList.d.ts +16 -0
- package/react/components/toolbar/advancedAppLauncher/components/FoldersList.js +39 -0
- package/react/components/toolbar/advancedAppLauncher/components/FoldersList.js.map +1 -1
- package/react/components/toolbar/advancedAppLauncher/components/LeftNavBottomLinks.d.ts +4 -0
- package/react/components/toolbar/advancedAppLauncher/components/LeftNavBottomLinks.js +9 -0
- package/react/components/toolbar/advancedAppLauncher/components/LeftNavBottomLinks.js.map +1 -1
- package/react/components/toolbar/advancedAppLauncher/components/SearchBox.js +3 -0
- package/react/components/toolbar/advancedAppLauncher/components/SearchBox.js.map +1 -1
- package/react/components/toolbar/advancedAppLauncher/components/TagsMenu.d.ts +6 -0
- package/react/components/toolbar/advancedAppLauncher/components/TagsMenu.js +7 -0
- package/react/components/toolbar/advancedAppLauncher/components/TagsMenu.js.map +1 -1
- package/react/components/toolbar/advancedAppLauncher/components/ToggleFavoriteDropdown.d.ts +5 -0
- package/react/components/toolbar/advancedAppLauncher/components/ToggleFavoriteDropdown.js +5 -0
- package/react/components/toolbar/advancedAppLauncher/components/ToggleFavoriteDropdown.js.map +1 -1
- package/react/components/toolbar/advancedAppLauncher/modules/AppDirectory.d.ts +5 -0
- package/react/components/toolbar/advancedAppLauncher/modules/AppDirectory.js +5 -0
- package/react/components/toolbar/advancedAppLauncher/modules/AppDirectory.js.map +1 -1
- package/react/components/toolbar/advancedAppLauncher/modules/FDC3.d.ts +37 -0
- package/react/components/toolbar/advancedAppLauncher/modules/FDC3.js +40 -0
- package/react/components/toolbar/advancedAppLauncher/modules/FDC3.js.map +1 -1
- package/react/components/toolbar/advancedAppLauncher/stores/StoreActions.d.ts +3 -0
- package/react/components/toolbar/advancedAppLauncher/stores/StoreActions.js +82 -0
- package/react/components/toolbar/advancedAppLauncher/stores/StoreActions.js.map +1 -1
- package/react/components/toolbar/advancedAppLauncher/utils/sort-functions.d.ts +10 -0
- package/react/components/toolbar/advancedAppLauncher/utils/sort-functions.js +11 -0
- package/react/components/toolbar/advancedAppLauncher/utils/sort-functions.js.map +1 -1
- package/react/components/toolbar/appLauncher/AppLauncherMenu.d.ts +18 -0
- package/react/components/toolbar/appLauncher/AppLauncherMenu.js +20 -0
- package/react/components/toolbar/appLauncher/AppLauncherMenu.js.map +1 -1
- package/react/components/toolbar/appLauncher/StaticAppLauncherMenu.d.ts +9 -0
- package/react/components/toolbar/appLauncher/StaticAppLauncherMenu.js +12 -0
- package/react/components/toolbar/appLauncher/StaticAppLauncherMenu.js.map +1 -1
- package/react/components/toolbar/appLauncher/appLauncher.css +1 -1
- package/react/components/toolbar/appLauncher/components/componentList.d.ts +3 -0
- package/react/components/toolbar/appLauncher/components/componentList.js +17 -3
- package/react/components/toolbar/appLauncher/components/componentList.js.map +1 -1
- package/react/components/toolbar/appLauncher/stores/appLauncherStore.d.ts +6 -0
- package/react/components/toolbar/appLauncher/stores/appLauncherStore.js +26 -0
- package/react/components/toolbar/appLauncher/stores/appLauncherStore.js.map +1 -1
- package/react/components/toolbar/dashbar/Dashbar.js +70 -3
- package/react/components/toolbar/dashbar/Dashbar.js.map +1 -1
- package/react/components/toolbar/dashbar/DashbarItem.js +5 -0
- package/react/components/toolbar/dashbar/DashbarItem.js.map +1 -1
- package/react/components/toolbar/workspaceManagementMenu/WorkspaceManagementMenu.d.ts +7 -0
- package/react/components/toolbar/workspaceManagementMenu/WorkspaceManagementMenu.js +7 -0
- package/react/components/toolbar/workspaceManagementMenu/WorkspaceManagementMenu.js.map +1 -1
- package/react/components/toolbar/workspaceManagementMenu/components/Workspace.d.ts +16 -0
- package/react/components/toolbar/workspaceManagementMenu/components/Workspace.js +20 -0
- package/react/components/toolbar/workspaceManagementMenu/components/Workspace.js.map +1 -1
- package/react/components/toolbar/workspaceManagementMenu/components/WorkspaceActions.d.ts +26 -0
- package/react/components/toolbar/workspaceManagementMenu/components/WorkspaceActions.js +29 -0
- package/react/components/toolbar/workspaceManagementMenu/components/WorkspaceActions.js.map +1 -1
- package/react/components/toolbar/workspaceManagementMenu/components/WorkspaceList.d.ts +5 -0
- package/react/components/toolbar/workspaceManagementMenu/components/WorkspaceList.js +6 -0
- package/react/components/toolbar/workspaceManagementMenu/components/WorkspaceList.js.map +1 -1
- package/react/components/toolbar/workspaceManagementMenu/stores/workspaceManagementMenuStore.d.ts +76 -0
- package/react/components/toolbar/workspaceManagementMenu/stores/workspaceManagementMenuStore.js +140 -1
- package/react/components/toolbar/workspaceManagementMenu/stores/workspaceManagementMenuStore.js.map +1 -1
- package/react/components/toolbar/workspaceManagementMenu/workspaceManagementMenu.css +8 -18
- package/react/components/userPreferences/NotificationsPreferencesContext.d.ts +4 -0
- package/react/components/userPreferences/NotificationsPreferencesContext.js +4 -0
- package/react/components/userPreferences/NotificationsPreferencesContext.js.map +1 -1
- package/react/components/userPreferences/UserPreferenceTypes.d.ts +3 -0
- package/react/components/userPreferences/UserPreferences.d.ts +8 -0
- package/react/components/userPreferences/UserPreferences.js +8 -0
- package/react/components/userPreferences/UserPreferences.js.map +1 -1
- package/react/components/userPreferences/UserPreferencesBase.js +4 -0
- package/react/components/userPreferences/UserPreferencesBase.js.map +1 -1
- package/react/components/userPreferences/components/ContentSection.d.ts +5 -0
- package/react/components/userPreferences/components/LeftNav.d.ts +4 -0
- package/react/components/userPreferences/components/content/DashbarEditor.js +3 -0
- package/react/components/userPreferences/components/content/DashbarEditor.js.map +1 -1
- package/react/components/userPreferences/components/content/Notifications.js +3 -0
- package/react/components/userPreferences/components/content/Notifications.js.map +1 -1
- package/react/components/userPreferences/components/content/Workspaces.d.ts +12 -0
- package/react/components/userPreferences/components/content/Workspaces.js +33 -1
- package/react/components/userPreferences/components/content/Workspaces.js.map +1 -1
- package/react/components/userPreferences/components/content/notificationViews/NotificationsPreferencesHome.js +3 -0
- package/react/components/userPreferences/components/content/notificationViews/NotificationsPreferencesHome.js.map +1 -1
- package/react/components/userPreferences/components/content/notificationViews/NotificationsSourceTypes.js +3 -0
- package/react/components/userPreferences/components/content/notificationViews/NotificationsSourceTypes.js.map +1 -1
- package/react/components/userPreferences/components/content/notificationViews/NotificationsSourcesPreferences.js +3 -0
- package/react/components/userPreferences/components/content/notificationViews/NotificationsSourcesPreferences.js.map +1 -1
- package/react/components/userPreferences/components/general/ScheduledClose.js +11 -0
- package/react/components/userPreferences/components/general/ScheduledClose.js.map +1 -1
- package/react/components/userPreferences/components/workspaces/WorkspaceItem.js +3 -0
- package/react/components/userPreferences/components/workspaces/WorkspaceItem.js.map +1 -1
- package/react/components/userPreferences/stores/UserPreferencesStore.d.ts +17 -0
- package/react/components/userPreferences/stores/UserPreferencesStore.js +27 -0
- package/react/components/userPreferences/stores/UserPreferencesStore.js.map +1 -1
- package/react/components/userPreferences/tests/NotificationsPreferencesHome.spec.js +1 -0
- package/react/components/userPreferences/tests/NotificationsPreferencesHome.spec.js.map +1 -1
- package/react/components/userPreferences/tests/Workspace.spec.js +20 -0
- package/react/components/userPreferences/tests/Workspace.spec.js.map +1 -1
- package/react/components/windowTitleBar/WindowTitleBarShell.d.ts +124 -0
- package/react/components/windowTitleBar/WindowTitleBarShell.js +284 -35
- package/react/components/windowTitleBar/WindowTitleBarShell.js.map +1 -1
- package/react/components/windowTitleBar/components/center/Tab.d.ts +3 -0
- package/react/components/windowTitleBar/components/center/Tab.js +3 -0
- package/react/components/windowTitleBar/components/center/Tab.js.map +1 -1
- package/react/components/windowTitleBar/components/center/TabList.d.ts +90 -0
- package/react/components/windowTitleBar/components/center/TabList.js +170 -4
- package/react/components/windowTitleBar/components/center/TabList.js.map +1 -1
- package/react/components/windowTitleBar/components/left/LinkerButton.d.ts +9 -1
- package/react/components/windowTitleBar/components/left/LinkerButton.js +25 -9
- package/react/components/windowTitleBar/components/left/LinkerButton.js.map +1 -1
- package/react/components/windowTitleBar/components/left/LinkerButtonDeprecated.d.ts +47 -0
- package/react/components/windowTitleBar/components/left/LinkerButtonDeprecated.js +76 -1
- package/react/components/windowTitleBar/components/left/LinkerButtonDeprecated.js.map +1 -1
- package/react/components/windowTitleBar/components/left/LinkerGroups.d.ts +4 -0
- package/react/components/windowTitleBar/components/left/LinkerGroups.js +5 -0
- package/react/components/windowTitleBar/components/left/LinkerGroups.js.map +1 -1
- package/react/components/windowTitleBar/components/left/LinkerGroupsDeprecated.d.ts +18 -0
- package/react/components/windowTitleBar/components/left/LinkerGroupsDeprecated.js +49 -0
- package/react/components/windowTitleBar/components/left/LinkerGroupsDeprecated.js.map +1 -1
- package/react/components/windowTitleBar/components/left/ShareButton.d.ts +17 -0
- package/react/components/windowTitleBar/components/left/ShareButton.js +39 -0
- package/react/components/windowTitleBar/components/left/ShareButton.js.map +1 -1
- package/react/components/windowTitleBar/components/right/AlwaysOnTopButton.js +4 -0
- package/react/components/windowTitleBar/components/right/AlwaysOnTopButton.js.map +1 -1
- package/react/components/windowTitleBar/components/right/CloseButton.d.ts +27 -0
- package/react/components/windowTitleBar/components/right/CloseButton.js +27 -0
- package/react/components/windowTitleBar/components/right/CloseButton.js.map +1 -1
- package/react/components/windowTitleBar/components/right/GroupingButton.d.ts +37 -0
- package/react/components/windowTitleBar/components/right/GroupingButton.js +40 -0
- package/react/components/windowTitleBar/components/right/GroupingButton.js.map +1 -1
- package/react/components/windowTitleBar/components/right/MaximizeButton.d.ts +46 -0
- package/react/components/windowTitleBar/components/right/MaximizeButton.js +54 -0
- package/react/components/windowTitleBar/components/right/MaximizeButton.js.map +1 -1
- package/react/components/windowTitleBar/components/right/MinimizeButton.d.ts +26 -0
- package/react/components/windowTitleBar/components/right/MinimizeButton.js +26 -0
- package/react/components/windowTitleBar/components/right/MinimizeButton.js.map +1 -1
- package/react/components/windowTitleBar/components/windowTitle.d.ts +40 -0
- package/react/components/windowTitleBar/components/windowTitle.js +172 -10
- package/react/components/windowTitleBar/components/windowTitle.js.map +1 -1
- package/react/components/windowTitleBar/stores/windowTitleBarStore.d.ts +5 -0
- package/react/components/windowTitleBar/stores/windowTitleBarStore.js +72 -1
- package/react/components/windowTitleBar/stores/windowTitleBarStore.js.map +1 -1
- package/react/components/yesNoDialog/YesNoDialog.css +1 -1
- package/react/components/yesNoDialog/YesNoDialog.d.ts +3 -0
- package/react/components/yesNoDialog/YesNoDialog.js +63 -0
- package/react/components/yesNoDialog/YesNoDialog.js.map +1 -1
- package/react/components/yesNoDialog/YesNoDialog.spec.js +4 -0
- package/react/components/yesNoDialog/YesNoDialog.spec.js.map +1 -1
- package/react/components/yesNoDialog/timer.js +2 -0
- package/react/components/yesNoDialog/timer.js.map +1 -1
- package/react/enzymeSetup.js +5 -0
- package/react/enzymeSetup.js.map +1 -1
- package/react/hooks/useDashbar.js +10 -0
- package/react/hooks/useDashbar.js.map +1 -1
- package/react/hooks/useDeepEffect.d.ts +4 -0
- package/react/hooks/useDeepEffect.js +21 -0
- package/react/hooks/useDeepEffect.js.map +1 -1
- package/react/hooks/useFavorites.d.ts +15 -0
- package/react/hooks/useFavorites.js +3 -0
- package/react/hooks/useFavorites.js.map +1 -1
- package/react/hooks/useFavoritesShell.d.ts +4 -0
- package/react/hooks/useFavoritesShell.js +23 -0
- package/react/hooks/useFavoritesShell.js.map +1 -1
- package/react/hooks/useHotkey.d.ts +6 -0
- package/react/hooks/useHotkey.js +9 -0
- package/react/hooks/useHotkey.js.map +1 -1
- package/react/hooks/useLinker.js +14 -0
- package/react/hooks/useLinker.js.map +1 -1
- package/react/hooks/useMenu.d.ts +29 -0
- package/react/hooks/useMenu.js +12 -1
- package/react/hooks/useMenu.js.map +1 -1
- package/react/hooks/useNotifications.d.ts +44 -0
- package/react/hooks/useNotifications.js +90 -0
- package/react/hooks/useNotifications.js.map +1 -1
- package/react/hooks/useOutsideClickDetector.d.ts +3 -0
- package/react/hooks/useOutsideClickDetector.js +3 -0
- package/react/hooks/useOutsideClickDetector.js.map +1 -1
- package/react/hooks/usePubSub.d.ts +17 -0
- package/react/hooks/usePubSub.js +18 -0
- package/react/hooks/usePubSub.js.map +1 -1
- package/react/hooks/useSearch.d.ts +5 -0
- package/react/hooks/useSearch.js +30 -0
- package/react/hooks/useSearch.js.map +1 -1
- package/react/hooks/useToolbar.js +52 -0
- package/react/hooks/useToolbar.js.map +1 -1
- package/react/reducers/favoriteReducer.d.ts +3 -0
- package/react/reducers/linkerReducer.d.ts +3 -0
- package/react/reducers/linkerReducer.js +4 -0
- package/react/reducers/linkerReducer.js.map +1 -1
- package/react/reducers/menuReducer.d.ts +28 -0
- package/react/reducers/menuReducer.js +34 -0
- package/react/reducers/menuReducer.js.map +1 -1
- package/react/reducers/rootReducer.js +3 -0
- package/react/reducers/rootReducer.js.map +1 -1
- package/react/reducers/searchReducer.d.ts +7 -0
- package/react/reducers/searchReducer.js +6 -0
- package/react/reducers/searchReducer.js.map +1 -1
- package/react/reducers/workspaceReducer.js +1 -0
- package/react/reducers/workspaceReducer.js.map +1 -1
- package/react/store.d.ts +4 -0
- package/react/store.js +11 -0
- package/react/store.js.map +1 -1
- package/react/tsconfig.tsbuildinfo +1 -1
- package/react/types/fdc3.d.ts +2 -0
- package/react/types/linkerTypes.d.ts +13 -0
- package/react/types/linkerTypes.js +1 -0
- package/react/types/linkerTypes.js.map +1 -1
- package/react/types/smartDesktopDesignerTypes.d.ts +5 -0
- package/react/types/smartDesktopDesignerTypes.js.map +1 -1
- package/react/types/workspaceTypes.d.ts +8 -0
|
@@ -5,17 +5,30 @@ import { applyMenuKeyboardNavigation } from "./keyboardNavigation";
|
|
|
5
5
|
import { MenuAutoResizer } from "./MenuAutoResizer";
|
|
6
6
|
import { useState, useEffect, useContext } from "react";
|
|
7
7
|
import { useMenu } from "../../hooks/useMenu";
|
|
8
|
+
/**
|
|
9
|
+
* Proxy/fake events are needed because when `document.addEventListener` is used inside a component
|
|
10
|
+
* that is rendered inside react portal, `document` will refer to the toolbar's document instead
|
|
11
|
+
* of the childWindow's document. Clicking inside a portal will not therefore capture those events.
|
|
12
|
+
*
|
|
13
|
+
* This code intercepts these events inside the portal and then forwards them to the parent (toolbar).
|
|
14
|
+
*/
|
|
8
15
|
const setupEventForwarding = (newWindow) => {
|
|
9
16
|
["mouseDown", "click", "mouseUp"].forEach((eventName) => {
|
|
10
17
|
newWindow.document.addEventListener(eventName, (event) => {
|
|
11
18
|
document.dispatchEvent(new CustomEvent(`portal:${eventName}`, {
|
|
12
19
|
detail: {
|
|
20
|
+
// Devs may need access to the x and y of the cursor
|
|
13
21
|
mouseEvent: new MouseEvent(eventName, event),
|
|
22
|
+
// And possibly the target element
|
|
14
23
|
target: event.target,
|
|
15
24
|
},
|
|
16
25
|
}));
|
|
17
26
|
});
|
|
18
27
|
});
|
|
28
|
+
/**
|
|
29
|
+
* Proxies keyboard events from the portal up into the parent window.
|
|
30
|
+
* instead of e.key, you'll need to access e.detail.key.
|
|
31
|
+
*/
|
|
19
32
|
["keyup", "keydown", "keypress"].forEach((eventName) => {
|
|
20
33
|
newWindow === null || newWindow === void 0 ? void 0 : newWindow.document.addEventListener(eventName, (event) => {
|
|
21
34
|
document.dispatchEvent(new CustomEvent(`portal:${eventName}`, {
|
|
@@ -24,30 +37,84 @@ const setupEventForwarding = (newWindow) => {
|
|
|
24
37
|
});
|
|
25
38
|
});
|
|
26
39
|
};
|
|
40
|
+
/**
|
|
41
|
+
* The window (opened by window.open) is an empty html document.
|
|
42
|
+
* This function creates a containerDiv for the parent to insert its
|
|
43
|
+
* React DOM. That containerDiv is set through the `setElement()` method
|
|
44
|
+
* which must be passed in.
|
|
45
|
+
*
|
|
46
|
+
* This function also does portal housekeeping such as transferring CSS and window
|
|
47
|
+
* events.
|
|
48
|
+
*/
|
|
27
49
|
const insertWindowContent = ({ newWindow, isAutoResizable, className, setElement, menuHeight, }) => {
|
|
50
|
+
// Set the child window's <html> tag to class "menu-portal" for scrollbar styling
|
|
28
51
|
newWindow.document.documentElement.className = "menu-portal";
|
|
29
52
|
if (isAutoResizable)
|
|
30
53
|
newWindow.document.body.setAttribute("resizing", "true");
|
|
54
|
+
// Create the element which will hold our react elements and then append it into the child window's body.
|
|
31
55
|
const containerDiv = document.createElement("div");
|
|
32
56
|
newWindow.document.body.appendChild(containerDiv);
|
|
57
|
+
// The className that was passed to MenuShell is added to the child window's <body>
|
|
33
58
|
className === null || className === void 0 ? void 0 : className.split(" ").forEach((name) => newWindow.document.body.classList.add(name));
|
|
59
|
+
// This will update local state which will cause the parent React Functional Component
|
|
60
|
+
// to return a react portal. See comments at the end of this file.
|
|
34
61
|
setElement(containerDiv);
|
|
62
|
+
// Inject css into the child window's <head>
|
|
35
63
|
injectCSS(newWindow);
|
|
64
|
+
// THE FOLLOWING IS LIKELY DEPRECATED BUT KEEPING JUST IN CASE
|
|
65
|
+
// Place height on the portal.
|
|
66
|
+
// inside of the portal, window.outerHeight === 39 (toolbar height).
|
|
67
|
+
// Knowing the height of the window is important because some menus use that
|
|
68
|
+
// information to force overflow on certain sections of the menu.
|
|
36
69
|
newWindow.portalHeight = menuHeight;
|
|
37
70
|
};
|
|
71
|
+
/**
|
|
72
|
+
* React hook to create a drop down menu. This hook creates a new window using window.open
|
|
73
|
+
* and assigns it as the childWindow to the MenuPortal. It then uses insertWindowContent()
|
|
74
|
+
* to establish the React/DOM connection with the parent (e.g. Toolbar).
|
|
75
|
+
*/
|
|
38
76
|
const useCreateDropdown = ({ setElement, childWindow, setChildWindow, }) => {
|
|
39
77
|
const { thisMenuId, menuWidth, menuHeight, className, maxHeight, minHeight } = useContext(MenuContext);
|
|
40
78
|
const { blurMenu } = useMenu();
|
|
41
79
|
const isAutoResizable = !menuHeight;
|
|
80
|
+
/**
|
|
81
|
+
* Initialize the window. This should only run once though it is possible
|
|
82
|
+
* to run multiple times if MenuContext changes.
|
|
83
|
+
*/
|
|
42
84
|
useEffect(() => {
|
|
43
85
|
let menuAutoResizer = null;
|
|
86
|
+
/**
|
|
87
|
+
* Initial size and location of the menu is irrelevant because it is hidden.
|
|
88
|
+
* The menu will be resized and positioned correctly when it is shown.
|
|
89
|
+
*/
|
|
44
90
|
const features = `height=1,width=${menuWidth},left=0,top=0,opacity=1`;
|
|
91
|
+
/**
|
|
92
|
+
* Opens the window which will contain the menu contents. This looks like a browser window open
|
|
93
|
+
* but actually opens an Electron window which FEA intercepts. FEA uses the `childWindowOptions`
|
|
94
|
+
* json configuration to determine how to display the window. `childWindowOptions.show` should
|
|
95
|
+
* be set to `false` otherwise a white window will flash prior to the menu being rendered.
|
|
96
|
+
*
|
|
97
|
+
*
|
|
98
|
+
* The "/component/toolbar/menu.html" is just an empty page. It's necessary to reference a real page
|
|
99
|
+
* rather than about:blank in order that the "origin" is correct for the page. Many CSS ui-assets such
|
|
100
|
+
* as fonts and images are set with relative paths that require a correct origin.
|
|
101
|
+
*
|
|
102
|
+
* Note, we append the menu ID for automated testing. This allows Selenium to
|
|
103
|
+
* uniquely identify each menu.
|
|
104
|
+
*/
|
|
45
105
|
const newWindow = window.open(`./menu.html#${thisMenuId}`, `(Menu) ${thisMenuId}`, features);
|
|
46
106
|
setChildWindow(newWindow);
|
|
47
107
|
if (newWindow) {
|
|
48
108
|
const onLoad = () => {
|
|
49
109
|
insertWindowContent({ newWindow, isAutoResizable, className, setElement, menuHeight });
|
|
50
110
|
setupEventForwarding(newWindow);
|
|
111
|
+
/* Close window when a user clicks away.
|
|
112
|
+
Are you wondering why not just close the window without calling
|
|
113
|
+
toggle? because we want to update the state in the store first
|
|
114
|
+
which will cause openMenuId to no longer match the shell id
|
|
115
|
+
and eventually destroy this component which will cause the window
|
|
116
|
+
to close (see cleanup function).
|
|
117
|
+
*/
|
|
51
118
|
newWindow.addEventListener("blur", blurMenu);
|
|
52
119
|
newWindow.addEventListener("keydown", (e) => {
|
|
53
120
|
if (e.key === "Escape") {
|
|
@@ -55,6 +122,7 @@ const useCreateDropdown = ({ setElement, childWindow, setChildWindow, }) => {
|
|
|
55
122
|
}
|
|
56
123
|
});
|
|
57
124
|
applyMenuKeyboardNavigation(newWindow);
|
|
125
|
+
// Attach MenuAutoResizer only if the menu doesn't have a fixed height
|
|
58
126
|
if (isAutoResizable)
|
|
59
127
|
menuAutoResizer = new MenuAutoResizer(newWindow, thisMenuId, menuWidth, maxHeight, minHeight);
|
|
60
128
|
};
|
|
@@ -64,6 +132,7 @@ const useCreateDropdown = ({ setElement, childWindow, setChildWindow, }) => {
|
|
|
64
132
|
FSBL.Clients.Logger.system.error(`MenuPortal error: window.open returned null for "./menu.html#${thisMenuId}"`);
|
|
65
133
|
}
|
|
66
134
|
return () => {
|
|
135
|
+
// imesner 20210406 childwindow and keyboardNavigation were both null but hadn't closed the window or released global hotkeys
|
|
67
136
|
const win = childWindow || (menuAutoResizer === null || menuAutoResizer === void 0 ? void 0 : menuAutoResizer.childWindow);
|
|
68
137
|
menuAutoResizer === null || menuAutoResizer === void 0 ? void 0 : menuAutoResizer.disconnect();
|
|
69
138
|
win === null || win === void 0 ? void 0 : win.close();
|
|
@@ -71,6 +140,10 @@ const useCreateDropdown = ({ setElement, childWindow, setChildWindow, }) => {
|
|
|
71
140
|
};
|
|
72
141
|
}, [blurMenu, className, menuWidth, menuHeight, maxHeight, thisMenuId]);
|
|
73
142
|
};
|
|
143
|
+
/**
|
|
144
|
+
* Sets visibility, size and location of the window. This can be called numerous times
|
|
145
|
+
* during the lifetime of the MenuPortal.
|
|
146
|
+
*/
|
|
74
147
|
const showHideResizeWindow = async ({ childWindow, show, thisMenuId, menuHeight, maxHeight, minHeight, }) => {
|
|
75
148
|
const finWindow = childWindow.fin.desktop.Window.getCurrent();
|
|
76
149
|
if (show) {
|
|
@@ -83,8 +156,19 @@ const showHideResizeWindow = async ({ childWindow, show, thisMenuId, menuHeight,
|
|
|
83
156
|
forceOntoMonitor: "monitorRect",
|
|
84
157
|
};
|
|
85
158
|
const { name } = childWindow;
|
|
159
|
+
/**
|
|
160
|
+
* Use Finsemble to show the window. We might be tempted simply to use childWindow.moveTo() or childWindow.resizeTo()
|
|
161
|
+
* but those commands limit the child window to a single monitor. We want to position the window relative to the
|
|
162
|
+
* monitor on which the toolbar currently resides. showWindow() is monitor aware, so by using monitor="mine" we can
|
|
163
|
+
* ensure that the menu will always open on the same monitor as the toolbar. Since our toolbar has built in logic
|
|
164
|
+
* to avoid straddling, we can be sure that the menu will never have to guess whether it exists on the left or right
|
|
165
|
+
* side of the toolbar. Finally, showWindow() forces windows to open entirely on a monitor, so it will slide the
|
|
166
|
+
* menu to the left or right as necessary to prevent it from straddling.
|
|
167
|
+
*/
|
|
86
168
|
FSBL.Clients.LauncherClient.showWindow({ windowName: name }, params);
|
|
169
|
+
// Ensures that the menu has keyboard focus for accessibility
|
|
87
170
|
finWindow.focus();
|
|
171
|
+
// Ensures that the menu is positioned above any other windows that have setAlwaysOnTop flagged
|
|
88
172
|
FSBL.FinsembleWindow.getInstance({ name: name }, (e, fsblWindow) => {
|
|
89
173
|
fsblWindow.setAlwaysOnTop({ alwaysOnTop: true });
|
|
90
174
|
});
|
|
@@ -97,36 +181,62 @@ const showHideResizeWindow = async ({ childWindow, show, thisMenuId, menuHeight,
|
|
|
97
181
|
finWindow.hide();
|
|
98
182
|
}
|
|
99
183
|
};
|
|
184
|
+
/**
|
|
185
|
+
* Closes the menu portal if the menu button is removed from the toolbar
|
|
186
|
+
*
|
|
187
|
+
* @param {Node} element - HTML element to observe
|
|
188
|
+
*
|
|
189
|
+
*/
|
|
100
190
|
const closePortal = (element) => {
|
|
101
191
|
const { closeMenu } = useMenu();
|
|
102
192
|
const options = {
|
|
103
193
|
childList: true,
|
|
104
194
|
subtree: true,
|
|
105
195
|
};
|
|
196
|
+
/**
|
|
197
|
+
* MutationObserver interface provides the ability to watch for
|
|
198
|
+
* changes to the DOM tree using the observe method
|
|
199
|
+
*/
|
|
106
200
|
const mutationObserver = new MutationObserver((mutations) => {
|
|
107
201
|
mutations.forEach((mutation) => {
|
|
108
|
-
var _a;
|
|
109
|
-
if ((_a = mutation.removedNodes) === null || _a === void 0 ? void 0 : _a.length)
|
|
202
|
+
var _a, _b;
|
|
203
|
+
if (((_a = mutation.removedNodes) === null || _a === void 0 ? void 0 : _a.length) &&
|
|
204
|
+
// prevents menu closing if the favorite apps have been changed
|
|
205
|
+
((_b = mutation.target) === null || _b === void 0 ? void 0 : _b.id) !== "favoritesContainer") {
|
|
110
206
|
closeMenu();
|
|
207
|
+
}
|
|
208
|
+
// stops the MutationObserver from receiving notification from observer
|
|
111
209
|
mutationObserver.disconnect();
|
|
112
210
|
});
|
|
113
211
|
});
|
|
212
|
+
// watches for DOM changes
|
|
114
213
|
mutationObserver.observe(element, options);
|
|
115
214
|
};
|
|
116
215
|
export const MenuPortal = ({ show, children }) => {
|
|
117
216
|
const { thisMenuId, menuHeight, maxHeight, minHeight } = useContext(MenuContext);
|
|
217
|
+
// Container div for React portal
|
|
118
218
|
const [element, setElement] = useState();
|
|
119
219
|
const [childWindow, setChildWindow] = useState(null);
|
|
220
|
+
/**
|
|
221
|
+
* Show and hide window. This effect will run whenever the `show` prop changes,
|
|
222
|
+
* generally initiated by a click to <MenuToggle>.
|
|
223
|
+
*/
|
|
120
224
|
useEffect(() => {
|
|
225
|
+
// If child window isn't yet initialized then no-op
|
|
121
226
|
if (!childWindow)
|
|
122
227
|
return;
|
|
123
228
|
showHideResizeWindow({ childWindow, show, thisMenuId, menuHeight, maxHeight, minHeight });
|
|
124
229
|
return () => { };
|
|
125
230
|
}, [show]);
|
|
231
|
+
// Create the dropdown. (if MenuContext changes then the dropdown will be removed and recreated).
|
|
126
232
|
useCreateDropdown({ childWindow, setElement, setChildWindow });
|
|
127
233
|
const toolbar = document.getElementById("Toolbar-tsx");
|
|
128
234
|
if (toolbar)
|
|
129
235
|
closePortal(toolbar);
|
|
236
|
+
// We should only return a react portal when window is ready
|
|
237
|
+
// and container div appended to its body
|
|
238
|
+
// See Dan abramov comment about this at:
|
|
239
|
+
// https://github.com/facebook/react/issues/12355#issuecomment-410996235
|
|
130
240
|
return element ? ReactDOM.createPortal(children, element) : null;
|
|
131
241
|
};
|
|
132
242
|
//# sourceMappingURL=MenuPortal.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MenuPortal.js","sourceRoot":"","sources":["../../../src/components/menu/MenuPortal.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from \"react\";\nimport * as ReactDOM from \"react-dom\";\nimport { MenuContext } from \"./menuContext\";\nimport { calculateDimensions, injectCSS } from \"./menuHelpers\";\nimport { applyMenuKeyboardNavigation } from \"./keyboardNavigation\";\nimport { MenuAutoResizer } from \"./MenuAutoResizer\";\nimport { useState, useEffect, useContext } from \"react\";\nimport { useMenu } from \"../../hooks/useMenu\";\nimport { services, FEA } from \"@finsemble/finsemble-api\";\n\ntype SpawnParams = services.window.types.SpawnParams;\n\n/**\n * Proxy/fake events are needed because when `document.addEventListener` is used inside a component\n * that is rendered inside react portal, `document` will refer to the toolbar's document instead\n * of the childWindow's document. Clicking inside a portal will not therefore capture those events.\n *\n * This code intercepts these events inside the portal and then forwards them to the parent (toolbar).\n */\nconst setupEventForwarding = (newWindow: Window) => {\n\t[\"mouseDown\", \"click\", \"mouseUp\"].forEach((eventName) => {\n\t\tnewWindow.document.addEventListener(eventName, (event) => {\n\t\t\tdocument.dispatchEvent(\n\t\t\t\tnew CustomEvent(`portal:${eventName}`, {\n\t\t\t\t\tdetail: {\n\t\t\t\t\t\t// Devs may need access to the x and y of the cursor\n\t\t\t\t\t\tmouseEvent: new MouseEvent(eventName, event),\n\t\t\t\t\t\t// And possibly the target element\n\t\t\t\t\t\ttarget: event.target,\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t);\n\t\t});\n\t});\n\n\t/**\n\t * Proxies keyboard events from the portal up into the parent window.\n\t * instead of e.key, you'll need to access e.detail.key.\n\t */\n\t[\"keyup\", \"keydown\", \"keypress\"].forEach((eventName) => {\n\t\tnewWindow?.document.addEventListener(eventName, (event) => {\n\t\t\tdocument.dispatchEvent(\n\t\t\t\tnew CustomEvent(`portal:${eventName}`, {\n\t\t\t\t\tdetail: new KeyboardEvent(event.type, event),\n\t\t\t\t})\n\t\t\t);\n\t\t});\n\t});\n};\n\n/**\n * The window (opened by window.open) is an empty html document.\n * This function creates a containerDiv for the parent to insert its\n * React DOM. That containerDiv is set through the `setElement()` method\n * which must be passed in.\n *\n * This function also does portal housekeeping such as transferring CSS and window\n * events.\n */\nconst insertWindowContent = ({\n\tnewWindow,\n\tisAutoResizable,\n\tclassName,\n\tsetElement,\n\tmenuHeight,\n}: {\n\tnewWindow: Window;\n\tisAutoResizable: boolean;\n\tclassName?: string;\n\tmenuHeight?: number;\n\tsetElement: React.Dispatch<React.SetStateAction<HTMLElement | undefined>>;\n}) => {\n\t// Set the child window's <html> tag to class \"menu-portal\" for scrollbar styling\n\tnewWindow.document.documentElement.className = \"menu-portal\";\n\tif (isAutoResizable) newWindow.document.body.setAttribute(\"resizing\", \"true\");\n\n\t// Create the element which will hold our react elements and then append it into the child window's body.\n\tconst containerDiv: HTMLElement = document.createElement(\"div\");\n\tnewWindow.document.body.appendChild(containerDiv);\n\n\t// The className that was passed to MenuShell is added to the child window's <body>\n\tclassName?.split(\" \").forEach((name: string) => newWindow!.document.body.classList.add(name));\n\n\t// This will update local state which will cause the parent React Functional Component\n\t// to return a react portal. See comments at the end of this file.\n\tsetElement(containerDiv);\n\n\t// Inject css into the child window's <head>\n\tinjectCSS(newWindow);\n\n\t// THE FOLLOWING IS LIKELY DEPRECATED BUT KEEPING JUST IN CASE\n\t// Place height on the portal.\n\t// inside of the portal, window.outerHeight === 39 (toolbar height).\n\t// Knowing the height of the window is important because some menus use that\n\t// information to force overflow on certain sections of the menu.\n\t(newWindow as any).portalHeight = menuHeight;\n};\n\n/**\n * React hook to create a drop down menu. This hook creates a new window using window.open\n * and assigns it as the childWindow to the MenuPortal. It then uses insertWindowContent()\n * to establish the React/DOM connection with the parent (e.g. Toolbar).\n */\nconst useCreateDropdown = ({\n\tsetElement,\n\tchildWindow,\n\tsetChildWindow,\n}: {\n\tsetElement: React.Dispatch<React.SetStateAction<HTMLElement | undefined>>;\n\tchildWindow: Window | null;\n\tsetChildWindow: React.Dispatch<React.SetStateAction<Window | null>>;\n}) => {\n\tconst { thisMenuId, menuWidth, menuHeight, className, maxHeight, minHeight } = useContext(MenuContext);\n\tconst { blurMenu } = useMenu();\n\tconst isAutoResizable = !menuHeight;\n\n\t/**\n\t * Initialize the window. This should only run once though it is possible\n\t * to run multiple times if MenuContext changes.\n\t */\n\tuseEffect(() => {\n\t\tlet menuAutoResizer: any = null;\n\n\t\t/**\n\t\t * Initial size and location of the menu is irrelevant because it is hidden.\n\t\t * The menu will be resized and positioned correctly when it is shown.\n\t\t */\n\t\tconst features = `height=1,width=${menuWidth},left=0,top=0,opacity=1`;\n\n\t\t/**\n\t\t * Opens the window which will contain the menu contents. This looks like a browser window open\n\t\t * but actually opens an Electron window which FEA intercepts. FEA uses the `childWindowOptions`\n\t\t * json configuration to determine how to display the window. `childWindowOptions.show` should\n\t\t * be set to `false` otherwise a white window will flash prior to the menu being rendered.\n\t\t *\n\t\t *\n\t\t * The \"/component/toolbar/menu.html\" is just an empty page. It's necessary to reference a real page\n\t\t * rather than about:blank in order that the \"origin\" is correct for the page. Many CSS ui-assets such\n\t\t * as fonts and images are set with relative paths that require a correct origin.\n\t\t *\n\t\t * Note, we append the menu ID for automated testing. This allows Selenium to\n\t\t * uniquely identify each menu.\n\t\t */\n\t\tconst newWindow = window.open(`./menu.html#${thisMenuId}`, `(Menu) ${thisMenuId}`, features);\n\t\tsetChildWindow(newWindow);\n\n\t\tif (newWindow) {\n\t\t\tconst onLoad = () => {\n\t\t\t\tinsertWindowContent({ newWindow, isAutoResizable, className, setElement, menuHeight });\n\t\t\t\tsetupEventForwarding(newWindow);\n\t\t\t\t/* Close window when a user clicks away.\n\t\t\t\t\tAre you wondering why not just close the window without calling\n\t\t\t\t\ttoggle? because we want to update the state in the store first\n\t\t\t\t\twhich will cause openMenuId to no longer match the shell id\n\t\t\t\t\tand eventually destroy this component which will cause the window\n\t\t\t\t\tto close (see cleanup function).\n\t\t\t\t*/\n\t\t\t\tnewWindow.addEventListener(\"blur\", blurMenu);\n\t\t\t\tnewWindow.addEventListener(\"keydown\", (e) => {\n\t\t\t\t\tif (e.key === \"Escape\") {\n\t\t\t\t\t\tblurMenu();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tapplyMenuKeyboardNavigation(newWindow);\n\n\t\t\t\t// Attach MenuAutoResizer only if the menu doesn't have a fixed height\n\t\t\t\tif (isAutoResizable)\n\t\t\t\t\tmenuAutoResizer = new MenuAutoResizer(newWindow, thisMenuId, menuWidth, maxHeight, minHeight);\n\t\t\t};\n\t\t\tnewWindow.addEventListener(\"load\", onLoad, true);\n\t\t} else {\n\t\t\tFSBL.Clients.Logger.system.error(`MenuPortal error: window.open returned null for \"./menu.html#${thisMenuId}\"`);\n\t\t}\n\n\t\treturn () => {\n\t\t\t// imesner 20210406 childwindow and keyboardNavigation were both null but hadn't closed the window or released global hotkeys\n\t\t\tconst win = childWindow || menuAutoResizer?.childWindow;\n\n\t\t\tmenuAutoResizer?.disconnect();\n\t\t\twin?.close();\n\t\t\tsetChildWindow(null);\n\t\t};\n\t}, [blurMenu, className, menuWidth, menuHeight, maxHeight, thisMenuId]);\n};\n\n/**\n * Sets visibility, size and location of the window. This can be called numerous times\n * during the lifetime of the MenuPortal.\n */\nconst showHideResizeWindow = async ({\n\tchildWindow,\n\tshow,\n\tthisMenuId,\n\tmenuHeight,\n\tmaxHeight,\n\tminHeight,\n}: {\n\tchildWindow: Window;\n\tshow: boolean;\n\tthisMenuId: string;\n\tmenuHeight?: number;\n\tmaxHeight: number;\n\tminHeight: number;\n}) => {\n\tconst finWindow: FEA.FEAWindow = childWindow.fin.desktop.Window.getCurrent();\n\tif (show) {\n\t\tconst { left, top, height } = await calculateDimensions(childWindow, thisMenuId, menuHeight, maxHeight, minHeight);\n\n\t\tconst params: SpawnParams = {\n\t\t\tposition: \"absolute\",\n\t\t\tleft: left,\n\t\t\ttop: top,\n\t\t\theight: height,\n\t\t\tforceOntoMonitor: \"monitorRect\",\n\t\t};\n\n\t\tconst { name } = childWindow;\n\n\t\t/**\n\t\t * Use Finsemble to show the window. We might be tempted simply to use childWindow.moveTo() or childWindow.resizeTo()\n\t\t * but those commands limit the child window to a single monitor. We want to position the window relative to the\n\t\t * monitor on which the toolbar currently resides. showWindow() is monitor aware, so by using monitor=\"mine\" we can\n\t\t * ensure that the menu will always open on the same monitor as the toolbar. Since our toolbar has built in logic\n\t\t * to avoid straddling, we can be sure that the menu will never have to guess whether it exists on the left or right\n\t\t * side of the toolbar. Finally, showWindow() forces windows to open entirely on a monitor, so it will slide the\n\t\t * menu to the left or right as necessary to prevent it from straddling.\n\t\t */\n\t\tFSBL.Clients.LauncherClient.showWindow({ windowName: name }, params);\n\n\t\t// Ensures that the menu has keyboard focus for accessibility\n\t\tfinWindow.focus();\n\n\t\t// Ensures that the menu is positioned above any other windows that have setAlwaysOnTop flagged\n\t\tFSBL.FinsembleWindow.getInstance({ name: name }, (e: any, fsblWindow: any) => {\n\t\t\tfsblWindow.setAlwaysOnTop({ alwaysOnTop: true });\n\t\t});\n\t} else {\n\t\tconst { name } = childWindow;\n\t\tFSBL.FinsembleWindow.getInstance({ name: name }, (e: any, fsblWindow: any) => {\n\t\t\tfsblWindow.setAlwaysOnTop({ alwaysOnTop: false });\n\t\t});\n\n\t\tfinWindow.hide();\n\t}\n};\n\n/**\n * Closes the menu portal if the menu button is removed from the toolbar\n *\n * @param {Node} element - HTML element to observe\n *\n */\nconst closePortal = (element: Node) => {\n\tconst { closeMenu } = useMenu();\n\n\tconst options = {\n\t\tchildList: true,\n\t\tsubtree: true,\n\t};\n\n\t/**\n\t * MutationObserver interface provides the ability to watch for\n\t * changes to the DOM tree using the observe method\n\t */\n\tconst mutationObserver = new MutationObserver((mutations) => {\n\t\tmutations.forEach((mutation) => {\n\t\t\tif (mutation.removedNodes?.length) closeMenu();\n\n\t\t\t// stops the MutationObserver from receiving notification from observer\n\t\t\tmutationObserver.disconnect();\n\t\t});\n\t});\n\n\t// watches for DOM changes\n\tmutationObserver.observe(element, options);\n};\n\nexport const MenuPortal: React.FunctionComponent<{\n\tshow: boolean;\n}> = ({ show, children }) => {\n\tconst { thisMenuId, menuHeight, maxHeight, minHeight } = useContext(MenuContext);\n\n\t// Container div for React portal\n\tconst [element, setElement] = useState<HTMLElement>();\n\tconst [childWindow, setChildWindow] = useState<Window | null>(null);\n\n\t/**\n\t * Show and hide window. This effect will run whenever the `show` prop changes,\n\t * generally initiated by a click to <MenuToggle>.\n\t */\n\tuseEffect(() => {\n\t\t// If child window isn't yet initialized then no-op\n\t\tif (!childWindow) return;\n\n\t\tshowHideResizeWindow({ childWindow, show, thisMenuId, menuHeight, maxHeight, minHeight });\n\t\treturn () => {};\n\t}, [show]);\n\n\t// Create the dropdown. (if MenuContext changes then the dropdown will be removed and recreated).\n\tuseCreateDropdown({ childWindow, setElement, setChildWindow });\n\n\tconst toolbar = document.getElementById(\"Toolbar-tsx\");\n\n\tif (toolbar) closePortal(toolbar);\n\n\t// We should only return a react portal when window is ready\n\t// and container div appended to its body\n\t// See Dan abramov comment about this at:\n\t// https://github.com/facebook/react/issues/12355#issuecomment-410996235\n\treturn element ? ReactDOM.createPortal(children, element) : null;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"MenuPortal.js","sourceRoot":"","sources":["../../../src/components/menu/MenuPortal.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from \"react\";\nimport * as ReactDOM from \"react-dom\";\nimport { MenuContext } from \"./menuContext\";\nimport { calculateDimensions, injectCSS } from \"./menuHelpers\";\nimport { applyMenuKeyboardNavigation } from \"./keyboardNavigation\";\nimport { MenuAutoResizer } from \"./MenuAutoResizer\";\nimport { useState, useEffect, useContext } from \"react\";\nimport { useMenu } from \"../../hooks/useMenu\";\nimport { services, FEA } from \"@finsemble/finsemble-api\";\n\ntype SpawnParams = services.window.types.SpawnParams;\n\n/**\n * Proxy/fake events are needed because when `document.addEventListener` is used inside a component\n * that is rendered inside react portal, `document` will refer to the toolbar's document instead\n * of the childWindow's document. Clicking inside a portal will not therefore capture those events.\n *\n * This code intercepts these events inside the portal and then forwards them to the parent (toolbar).\n */\nconst setupEventForwarding = (newWindow: Window) => {\n\t[\"mouseDown\", \"click\", \"mouseUp\"].forEach((eventName) => {\n\t\tnewWindow.document.addEventListener(eventName, (event) => {\n\t\t\tdocument.dispatchEvent(\n\t\t\t\tnew CustomEvent(`portal:${eventName}`, {\n\t\t\t\t\tdetail: {\n\t\t\t\t\t\t// Devs may need access to the x and y of the cursor\n\t\t\t\t\t\tmouseEvent: new MouseEvent(eventName, event),\n\t\t\t\t\t\t// And possibly the target element\n\t\t\t\t\t\ttarget: event.target,\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t);\n\t\t});\n\t});\n\n\t/**\n\t * Proxies keyboard events from the portal up into the parent window.\n\t * instead of e.key, you'll need to access e.detail.key.\n\t */\n\t[\"keyup\", \"keydown\", \"keypress\"].forEach((eventName) => {\n\t\tnewWindow?.document.addEventListener(eventName, (event) => {\n\t\t\tdocument.dispatchEvent(\n\t\t\t\tnew CustomEvent(`portal:${eventName}`, {\n\t\t\t\t\tdetail: new KeyboardEvent(event.type, event),\n\t\t\t\t})\n\t\t\t);\n\t\t});\n\t});\n};\n\n/**\n * The window (opened by window.open) is an empty html document.\n * This function creates a containerDiv for the parent to insert its\n * React DOM. That containerDiv is set through the `setElement()` method\n * which must be passed in.\n *\n * This function also does portal housekeeping such as transferring CSS and window\n * events.\n */\nconst insertWindowContent = ({\n\tnewWindow,\n\tisAutoResizable,\n\tclassName,\n\tsetElement,\n\tmenuHeight,\n}: {\n\tnewWindow: Window;\n\tisAutoResizable: boolean;\n\tclassName?: string;\n\tmenuHeight?: number;\n\tsetElement: React.Dispatch<React.SetStateAction<HTMLElement | undefined>>;\n}) => {\n\t// Set the child window's <html> tag to class \"menu-portal\" for scrollbar styling\n\tnewWindow.document.documentElement.className = \"menu-portal\";\n\tif (isAutoResizable) newWindow.document.body.setAttribute(\"resizing\", \"true\");\n\n\t// Create the element which will hold our react elements and then append it into the child window's body.\n\tconst containerDiv: HTMLElement = document.createElement(\"div\");\n\tnewWindow.document.body.appendChild(containerDiv);\n\n\t// The className that was passed to MenuShell is added to the child window's <body>\n\tclassName?.split(\" \").forEach((name: string) => newWindow!.document.body.classList.add(name));\n\n\t// This will update local state which will cause the parent React Functional Component\n\t// to return a react portal. See comments at the end of this file.\n\tsetElement(containerDiv);\n\n\t// Inject css into the child window's <head>\n\tinjectCSS(newWindow);\n\n\t// THE FOLLOWING IS LIKELY DEPRECATED BUT KEEPING JUST IN CASE\n\t// Place height on the portal.\n\t// inside of the portal, window.outerHeight === 39 (toolbar height).\n\t// Knowing the height of the window is important because some menus use that\n\t// information to force overflow on certain sections of the menu.\n\t(newWindow as any).portalHeight = menuHeight;\n};\n\n/**\n * React hook to create a drop down menu. This hook creates a new window using window.open\n * and assigns it as the childWindow to the MenuPortal. It then uses insertWindowContent()\n * to establish the React/DOM connection with the parent (e.g. Toolbar).\n */\nconst useCreateDropdown = ({\n\tsetElement,\n\tchildWindow,\n\tsetChildWindow,\n}: {\n\tsetElement: React.Dispatch<React.SetStateAction<HTMLElement | undefined>>;\n\tchildWindow: Window | null;\n\tsetChildWindow: React.Dispatch<React.SetStateAction<Window | null>>;\n}) => {\n\tconst { thisMenuId, menuWidth, menuHeight, className, maxHeight, minHeight } = useContext(MenuContext);\n\tconst { blurMenu } = useMenu();\n\tconst isAutoResizable = !menuHeight;\n\n\t/**\n\t * Initialize the window. This should only run once though it is possible\n\t * to run multiple times if MenuContext changes.\n\t */\n\tuseEffect(() => {\n\t\tlet menuAutoResizer: any = null;\n\n\t\t/**\n\t\t * Initial size and location of the menu is irrelevant because it is hidden.\n\t\t * The menu will be resized and positioned correctly when it is shown.\n\t\t */\n\t\tconst features = `height=1,width=${menuWidth},left=0,top=0,opacity=1`;\n\n\t\t/**\n\t\t * Opens the window which will contain the menu contents. This looks like a browser window open\n\t\t * but actually opens an Electron window which FEA intercepts. FEA uses the `childWindowOptions`\n\t\t * json configuration to determine how to display the window. `childWindowOptions.show` should\n\t\t * be set to `false` otherwise a white window will flash prior to the menu being rendered.\n\t\t *\n\t\t *\n\t\t * The \"/component/toolbar/menu.html\" is just an empty page. It's necessary to reference a real page\n\t\t * rather than about:blank in order that the \"origin\" is correct for the page. Many CSS ui-assets such\n\t\t * as fonts and images are set with relative paths that require a correct origin.\n\t\t *\n\t\t * Note, we append the menu ID for automated testing. This allows Selenium to\n\t\t * uniquely identify each menu.\n\t\t */\n\t\tconst newWindow = window.open(`./menu.html#${thisMenuId}`, `(Menu) ${thisMenuId}`, features);\n\t\tsetChildWindow(newWindow);\n\n\t\tif (newWindow) {\n\t\t\tconst onLoad = () => {\n\t\t\t\tinsertWindowContent({ newWindow, isAutoResizable, className, setElement, menuHeight });\n\t\t\t\tsetupEventForwarding(newWindow);\n\t\t\t\t/* Close window when a user clicks away.\n\t\t\t\t\tAre you wondering why not just close the window without calling\n\t\t\t\t\ttoggle? because we want to update the state in the store first\n\t\t\t\t\twhich will cause openMenuId to no longer match the shell id\n\t\t\t\t\tand eventually destroy this component which will cause the window\n\t\t\t\t\tto close (see cleanup function).\n\t\t\t\t*/\n\t\t\t\tnewWindow.addEventListener(\"blur\", blurMenu);\n\t\t\t\tnewWindow.addEventListener(\"keydown\", (e) => {\n\t\t\t\t\tif (e.key === \"Escape\") {\n\t\t\t\t\t\tblurMenu();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tapplyMenuKeyboardNavigation(newWindow);\n\n\t\t\t\t// Attach MenuAutoResizer only if the menu doesn't have a fixed height\n\t\t\t\tif (isAutoResizable)\n\t\t\t\t\tmenuAutoResizer = new MenuAutoResizer(newWindow, thisMenuId, menuWidth, maxHeight, minHeight);\n\t\t\t};\n\t\t\tnewWindow.addEventListener(\"load\", onLoad, true);\n\t\t} else {\n\t\t\tFSBL.Clients.Logger.system.error(`MenuPortal error: window.open returned null for \"./menu.html#${thisMenuId}\"`);\n\t\t}\n\n\t\treturn () => {\n\t\t\t// imesner 20210406 childwindow and keyboardNavigation were both null but hadn't closed the window or released global hotkeys\n\t\t\tconst win = childWindow || menuAutoResizer?.childWindow;\n\n\t\t\tmenuAutoResizer?.disconnect();\n\t\t\twin?.close();\n\t\t\tsetChildWindow(null);\n\t\t};\n\t}, [blurMenu, className, menuWidth, menuHeight, maxHeight, thisMenuId]);\n};\n\n/**\n * Sets visibility, size and location of the window. This can be called numerous times\n * during the lifetime of the MenuPortal.\n */\nconst showHideResizeWindow = async ({\n\tchildWindow,\n\tshow,\n\tthisMenuId,\n\tmenuHeight,\n\tmaxHeight,\n\tminHeight,\n}: {\n\tchildWindow: Window;\n\tshow: boolean;\n\tthisMenuId: string;\n\tmenuHeight?: number;\n\tmaxHeight: number;\n\tminHeight: number;\n}) => {\n\tconst finWindow: FEA.FEAWindow = childWindow.fin.desktop.Window.getCurrent();\n\tif (show) {\n\t\tconst { left, top, height } = await calculateDimensions(childWindow, thisMenuId, menuHeight, maxHeight, minHeight);\n\n\t\tconst params: SpawnParams = {\n\t\t\tposition: \"absolute\",\n\t\t\tleft: left,\n\t\t\ttop: top,\n\t\t\theight: height,\n\t\t\tforceOntoMonitor: \"monitorRect\",\n\t\t};\n\n\t\tconst { name } = childWindow;\n\n\t\t/**\n\t\t * Use Finsemble to show the window. We might be tempted simply to use childWindow.moveTo() or childWindow.resizeTo()\n\t\t * but those commands limit the child window to a single monitor. We want to position the window relative to the\n\t\t * monitor on which the toolbar currently resides. showWindow() is monitor aware, so by using monitor=\"mine\" we can\n\t\t * ensure that the menu will always open on the same monitor as the toolbar. Since our toolbar has built in logic\n\t\t * to avoid straddling, we can be sure that the menu will never have to guess whether it exists on the left or right\n\t\t * side of the toolbar. Finally, showWindow() forces windows to open entirely on a monitor, so it will slide the\n\t\t * menu to the left or right as necessary to prevent it from straddling.\n\t\t */\n\t\tFSBL.Clients.LauncherClient.showWindow({ windowName: name }, params);\n\n\t\t// Ensures that the menu has keyboard focus for accessibility\n\t\tfinWindow.focus();\n\n\t\t// Ensures that the menu is positioned above any other windows that have setAlwaysOnTop flagged\n\t\tFSBL.FinsembleWindow.getInstance({ name: name }, (e: any, fsblWindow: any) => {\n\t\t\tfsblWindow.setAlwaysOnTop({ alwaysOnTop: true });\n\t\t});\n\t} else {\n\t\tconst { name } = childWindow;\n\t\tFSBL.FinsembleWindow.getInstance({ name: name }, (e: any, fsblWindow: any) => {\n\t\t\tfsblWindow.setAlwaysOnTop({ alwaysOnTop: false });\n\t\t});\n\n\t\tfinWindow.hide();\n\t}\n};\n\n/**\n * Closes the menu portal if the menu button is removed from the toolbar\n *\n * @param {Node} element - HTML element to observe\n *\n */\nconst closePortal = (element: Node) => {\n\tconst { closeMenu } = useMenu();\n\n\tconst options = {\n\t\tchildList: true,\n\t\tsubtree: true,\n\t};\n\n\t/**\n\t * MutationObserver interface provides the ability to watch for\n\t * changes to the DOM tree using the observe method\n\t */\n\tconst mutationObserver = new MutationObserver((mutations) => {\n\t\tmutations.forEach((mutation) => {\n\t\t\tif (\n\t\t\t\tmutation.removedNodes?.length &&\n\t\t\t\t// prevents menu closing if the favorite apps have been changed\n\t\t\t\t(mutation.target as HTMLDivElement)?.id !== \"favoritesContainer\"\n\t\t\t) {\n\t\t\t\tcloseMenu();\n\t\t\t}\n\n\t\t\t// stops the MutationObserver from receiving notification from observer\n\t\t\tmutationObserver.disconnect();\n\t\t});\n\t});\n\n\t// watches for DOM changes\n\tmutationObserver.observe(element, options);\n};\n\nexport const MenuPortal: React.FunctionComponent<{\n\tshow: boolean;\n}> = ({ show, children }) => {\n\tconst { thisMenuId, menuHeight, maxHeight, minHeight } = useContext(MenuContext);\n\n\t// Container div for React portal\n\tconst [element, setElement] = useState<HTMLElement>();\n\tconst [childWindow, setChildWindow] = useState<Window | null>(null);\n\n\t/**\n\t * Show and hide window. This effect will run whenever the `show` prop changes,\n\t * generally initiated by a click to <MenuToggle>.\n\t */\n\tuseEffect(() => {\n\t\t// If child window isn't yet initialized then no-op\n\t\tif (!childWindow) return;\n\n\t\tshowHideResizeWindow({ childWindow, show, thisMenuId, menuHeight, maxHeight, minHeight });\n\t\treturn () => {};\n\t}, [show]);\n\n\t// Create the dropdown. (if MenuContext changes then the dropdown will be removed and recreated).\n\tuseCreateDropdown({ childWindow, setElement, setChildWindow });\n\n\tconst toolbar = document.getElementById(\"Toolbar-tsx\");\n\n\tif (toolbar) closePortal(toolbar);\n\n\t// We should only return a react portal when window is ready\n\t// and container div appended to its body\n\t// See Dan abramov comment about this at:\n\t// https://github.com/facebook/react/issues/12355#issuecomment-410996235\n\treturn element ? ReactDOM.createPortal(children, element) : null;\n};\n"]}
|
|
@@ -10,5 +10,21 @@ declare type ShellProps = {
|
|
|
10
10
|
openHotkey?: Array<string>;
|
|
11
11
|
width?: number;
|
|
12
12
|
};
|
|
13
|
+
/**
|
|
14
|
+
* The higher level menu component that manages the menu state, renders different parts of the menu, and facilitates
|
|
15
|
+
* communication between them.
|
|
16
|
+
*
|
|
17
|
+
* If window.FSBL.debug==true then windows won't automatically close on blur. This is useful for debugging events that occur in the windows.
|
|
18
|
+
*
|
|
19
|
+
* @param {string} [className] - Custom body class for the menu contents. These classes will be set on the <body> tag for the Menu's drop down window.
|
|
20
|
+
* @param {array} [closeHotkey=["escape"] ] - A hotkey combination to close the menu. Defaults to ["escape"].
|
|
21
|
+
* @param {number} [height] - Custom height for the menu. If not set then the height will be automatically calculated based on the content height and available monitor space.
|
|
22
|
+
* @param {string} [id] - Unique ID for the menu. Defaults to a random string.
|
|
23
|
+
* @param {number} [maxHeight=Infinity] - Maximum height of the menu.
|
|
24
|
+
* @param {number} [minHeight] - Minimum height of the menu
|
|
25
|
+
* @param {array} [openHotkey] - A hotkey combination to open the menu.
|
|
26
|
+
* @param {number} [width=180] - Custom width for the menu.
|
|
27
|
+
*
|
|
28
|
+
*/
|
|
13
29
|
export declare const MenuShell: React.FunctionComponent<ShellProps>;
|
|
14
30
|
export {};
|
|
@@ -4,7 +4,33 @@ import "../../assets/css/menus.css";
|
|
|
4
4
|
import { useMemo } from "react";
|
|
5
5
|
import { MenuHotKey } from "./MenuHotKey";
|
|
6
6
|
const MENU_WIDTH = 180;
|
|
7
|
+
/**
|
|
8
|
+
* The higher level menu component that manages the menu state, renders different parts of the menu, and facilitates
|
|
9
|
+
* communication between them.
|
|
10
|
+
*
|
|
11
|
+
* If window.FSBL.debug==true then windows won't automatically close on blur. This is useful for debugging events that occur in the windows.
|
|
12
|
+
*
|
|
13
|
+
* @param {string} [className] - Custom body class for the menu contents. These classes will be set on the <body> tag for the Menu's drop down window.
|
|
14
|
+
* @param {array} [closeHotkey=["escape"] ] - A hotkey combination to close the menu. Defaults to ["escape"].
|
|
15
|
+
* @param {number} [height] - Custom height for the menu. If not set then the height will be automatically calculated based on the content height and available monitor space.
|
|
16
|
+
* @param {string} [id] - Unique ID for the menu. Defaults to a random string.
|
|
17
|
+
* @param {number} [maxHeight=Infinity] - Maximum height of the menu.
|
|
18
|
+
* @param {number} [minHeight] - Minimum height of the menu
|
|
19
|
+
* @param {array} [openHotkey] - A hotkey combination to open the menu.
|
|
20
|
+
* @param {number} [width=180] - Custom width for the menu.
|
|
21
|
+
*
|
|
22
|
+
*/
|
|
7
23
|
export const MenuShell = ({ children, id, width = MENU_WIDTH, height, className, maxHeight = Infinity, minHeight = 0, openHotkey, closeHotkey = ["escape"], }) => {
|
|
24
|
+
/**
|
|
25
|
+
* Every menu has its own context which contains information that child components need to use.
|
|
26
|
+
* Here, we initialize that context. We do this with useMemo() for efficiency. Without useMemo,
|
|
27
|
+
* our context value *object* would be recreated with every render cycle, and would thus trigger
|
|
28
|
+
* every object that depended on context to re-render. Instead, useMenu creates a stable object
|
|
29
|
+
* that only updates when one of *its* dependencies updates. So in essence, so long as MenuShell's
|
|
30
|
+
* props are stable, context and all child props will also be stable.
|
|
31
|
+
*
|
|
32
|
+
* If id is passed in as a prop then we'll use that to initialize thisMenuId. Otherwise we'll set it to a random string.
|
|
33
|
+
*/
|
|
8
34
|
const contextValue = useMemo(() => {
|
|
9
35
|
return {
|
|
10
36
|
thisMenuId: id || `MENU_${((Math.random() * 0xffffff) << 0).toString(16)}`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MenuShell.js","sourceRoot":"","sources":["../../../src/components/menu/MenuShell.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,4BAA4B,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,MAAM,UAAU,GAAW,GAAG,CAAC;
|
|
1
|
+
{"version":3,"file":"MenuShell.js","sourceRoot":"","sources":["../../../src/components/menu/MenuShell.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,4BAA4B,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,MAAM,UAAU,GAAW,GAAG,CAAC;AAa/B;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,CAAC,MAAM,SAAS,GAAwC,CAAC,EAC9D,QAAQ,EACR,EAAE,EACF,KAAK,GAAG,UAAU,EAClB,MAAM,EACN,SAAS,EACT,SAAS,GAAG,QAAQ,EACpB,SAAS,GAAG,CAAC,EACb,UAAU,EACV,WAAW,GAAG,CAAC,QAAQ,CAAC,GACxB,EAAE,EAAE;IACJ;;;;;;;;;OASG;IACH,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,EAAE;QACjC,OAAO;YACN,UAAU,EAAE,EAAE,IAAI,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE;YAC1E,SAAS,EAAE,SAAS;YACpB,SAAS,EAAE,SAAS;YACpB,SAAS,EAAE,SAAS;YACpB,SAAS,EAAE,KAAK;YAChB,UAAU,EAAE,MAAM;SAClB,CAAC;IACH,CAAC,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IAEzD,OAAO,CACN,oBAAC,WAAW,CAAC,QAAQ,IAAC,KAAK,EAAE,YAAY;QACxC,oBAAC,UAAU,IAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,GAAI;QACnD,QAAQ,CACa,CACvB,CAAC;AACH,CAAC,CAAC","sourcesContent":["import * as React from \"react\";\nimport { MenuContext } from \"./menuContext\";\nimport \"../../assets/css/menus.css\";\nimport { useMemo } from \"react\";\nimport { MenuHotKey } from \"./MenuHotKey\";\n\nconst MENU_WIDTH: number = 180;\n\ntype ShellProps = {\n\tclassName?: string;\n\tcloseHotkey?: Array<string>;\n\theight?: number;\n\tid?: string;\n\tmaxHeight?: number;\n\tminHeight?: number;\n\topenHotkey?: Array<string>;\n\twidth?: number;\n};\n\n/**\n * The higher level menu component that manages the menu state, renders different parts of the menu, and facilitates\n * communication between them.\n *\n * If window.FSBL.debug==true then windows won't automatically close on blur. This is useful for debugging events that occur in the windows.\n *\n * @param {string} [className] - Custom body class for the menu contents. These classes will be set on the <body> tag for the Menu's drop down window.\n * @param {array} [closeHotkey=[\"escape\"] ] - A hotkey combination to close the menu. Defaults to [\"escape\"].\n * @param {number} [height] - Custom height for the menu. If not set then the height will be automatically calculated based on the content height and available monitor space.\n * @param {string} [id] - Unique ID for the menu. Defaults to a random string.\n * @param {number} [maxHeight=Infinity] - Maximum height of the menu.\n * @param {number} [minHeight] - Minimum height of the menu\n * @param {array} [openHotkey] - A hotkey combination to open the menu.\n * @param {number} [width=180] - Custom width for the menu.\n *\n */\n\nexport const MenuShell: React.FunctionComponent<ShellProps> = ({\n\tchildren,\n\tid,\n\twidth = MENU_WIDTH,\n\theight,\n\tclassName,\n\tmaxHeight = Infinity,\n\tminHeight = 0,\n\topenHotkey,\n\tcloseHotkey = [\"escape\"],\n}) => {\n\t/**\n\t * Every menu has its own context which contains information that child components need to use.\n\t * Here, we initialize that context. We do this with useMemo() for efficiency. Without useMemo,\n\t * our context value *object* would be recreated with every render cycle, and would thus trigger\n\t * every object that depended on context to re-render. Instead, useMenu creates a stable object\n\t * that only updates when one of *its* dependencies updates. So in essence, so long as MenuShell's\n\t * props are stable, context and all child props will also be stable.\n\t *\n\t * If id is passed in as a prop then we'll use that to initialize thisMenuId. Otherwise we'll set it to a random string.\n\t */\n\tconst contextValue = useMemo(() => {\n\t\treturn {\n\t\t\tthisMenuId: id || `MENU_${((Math.random() * 0xffffff) << 0).toString(16)}`,\n\t\t\tclassName: className,\n\t\t\tmaxHeight: maxHeight,\n\t\t\tminHeight: minHeight,\n\t\t\tmenuWidth: width,\n\t\t\tmenuHeight: height,\n\t\t};\n\t}, [id, className, maxHeight, minHeight, width, height]);\n\n\treturn (\n\t\t<MenuContext.Provider value={contextValue}>\n\t\t\t<MenuHotKey open={openHotkey} close={closeHotkey} />\n\t\t\t{children}\n\t\t</MenuContext.Provider>\n\t);\n};\n"]}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { MenuContext } from "./menuContext";
|
|
3
3
|
import { useMenu } from "../../hooks/useMenu";
|
|
4
|
+
/**
|
|
5
|
+
* A menu button that opens and closes the menu.
|
|
6
|
+
*/
|
|
4
7
|
export const MenuToggle = ({ children }) => {
|
|
5
8
|
const { toggleMenu, isMenuActive } = useMenu();
|
|
6
9
|
const { thisMenuId } = React.useContext(MenuContext);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MenuToggle.js","sourceRoot":"","sources":["../../../src/components/menu/MenuToggle.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"MenuToggle.js","sourceRoot":"","sources":["../../../src/components/menu/MenuToggle.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAE9C;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAA4B,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE;IACnE,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,GAAG,OAAO,EAAE,CAAC;IAC/C,MAAM,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;IAErD,MAAM,eAAe,GAAW,YAAY,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;IAEpE,OAAO,CACN,6BACC,EAAE,EAAE,GAAG,UAAU,cAAc,EAC/B,SAAS,EAAE,4BAA4B,eAAe,EAAE,EACxD,WAAW,EAAE,UAAU,EACvB,IAAI,EAAC,QAAQ,EACb,QAAQ,EAAE,CAAC,EACX,SAAS,EAAE,CAAC,CAAsC,EAAE,EAAE;YACrD,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;gBACvC,UAAU,EAAE,CAAC;aACb;QACF,CAAC;QAEA,QAAQ;QACT,2BAAG,SAAS,EAAC,+CAA+C,iBAAa,MAAM,GAAK,CAC/E,CACN,CAAC;AACH,CAAC,CAAC","sourcesContent":["import * as React from \"react\";\nimport { MenuContext } from \"./menuContext\";\nimport { useMenu } from \"../../hooks/useMenu\";\n\n/**\n * A menu button that opens and closes the menu.\n */\nexport const MenuToggle: React.FunctionComponent = ({ children }) => {\n\tconst { toggleMenu, isMenuActive } = useMenu();\n\tconst { thisMenuId } = React.useContext(MenuContext);\n\n\tconst menuActiveClass: string = isMenuActive() ? \"menu-active\" : \"\";\n\n\treturn (\n\t\t<div\n\t\t\tid={`${thisMenuId}-menu-toggle`}\n\t\t\tclassName={`finsemble-toolbar-button ${menuActiveClass}`}\n\t\t\tonMouseDown={toggleMenu}\n\t\t\trole=\"button\"\n\t\t\ttabIndex={0}\n\t\t\tonKeyDown={(e: React.KeyboardEvent<HTMLDivElement>) => {\n\t\t\t\tif ([\"Enter\", \"Space\"].includes(e.key)) {\n\t\t\t\t\ttoggleMenu();\n\t\t\t\t}\n\t\t\t}}\n\t\t>\n\t\t\t{children}\n\t\t\t<i className=\"finsemble-toolbar-button-icon ff-chevron-down\" aria-hidden=\"true\"></i>\n\t\t</div>\n\t);\n};\n"]}
|
|
@@ -1 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keyboard navigation allows the end user to navigate through menus using
|
|
3
|
+
* arrow keys and to select items using the enter key.
|
|
4
|
+
*
|
|
5
|
+
* When an element is selected then the keyboard navigation state is reset
|
|
6
|
+
* so that the user will begin again with the first item.
|
|
7
|
+
*
|
|
8
|
+
* @param childWin - Main window or child window reference.
|
|
9
|
+
* @param [className] - Selector of elements to apply navigation on.
|
|
10
|
+
* @example
|
|
11
|
+
* applyMenuKeyboardNavigation(window, ".menu-item");
|
|
12
|
+
*/
|
|
1
13
|
export declare const applyMenuKeyboardNavigation: (childWin: Window, className?: string) => void;
|
|
@@ -1,22 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keyboard navigation allows the end user to navigate through menus using
|
|
3
|
+
* arrow keys and to select items using the enter key.
|
|
4
|
+
*
|
|
5
|
+
* When an element is selected then the keyboard navigation state is reset
|
|
6
|
+
* so that the user will begin again with the first item.
|
|
7
|
+
*
|
|
8
|
+
* @param childWin - Main window or child window reference.
|
|
9
|
+
* @param [className] - Selector of elements to apply navigation on.
|
|
10
|
+
* @example
|
|
11
|
+
* applyMenuKeyboardNavigation(window, ".menu-item");
|
|
12
|
+
*/
|
|
1
13
|
export const applyMenuKeyboardNavigation = (childWin, className = ".menu-item") => {
|
|
2
14
|
let selectedItem = 0;
|
|
3
15
|
let selectedIcon = -1;
|
|
4
16
|
new MutationObserver(() => {
|
|
17
|
+
// Reset selectedIndex when elements added or removed
|
|
18
|
+
// from the DOM. The motivation behind this was an issue
|
|
19
|
+
// with Brad's search menu where the order of focus is
|
|
20
|
+
// messed up when his list of result changes.
|
|
5
21
|
selectedItem = 0;
|
|
6
22
|
}).observe(childWin.document.body, {
|
|
7
23
|
childList: true,
|
|
8
24
|
characterData: false,
|
|
9
25
|
subtree: true,
|
|
10
26
|
});
|
|
27
|
+
/**
|
|
28
|
+
* Returns list of elements
|
|
29
|
+
*/
|
|
11
30
|
const getElements = () => childWin.document.querySelectorAll(className);
|
|
12
31
|
const getMenuItemIcons = (index) => {
|
|
13
32
|
const menuItems = getElements();
|
|
14
33
|
return menuItems[index].querySelectorAll(".menu-item-icon");
|
|
15
34
|
};
|
|
35
|
+
/**
|
|
36
|
+
* Sets the focus on a menu item
|
|
37
|
+
* @param index The index of the menu item in the list
|
|
38
|
+
*/
|
|
16
39
|
const focusOn = (index) => {
|
|
17
40
|
const menuItems = getElements();
|
|
41
|
+
// Menu could have no items
|
|
18
42
|
if (!menuItems.length)
|
|
19
43
|
return;
|
|
44
|
+
// Focus on element and scroll if needed
|
|
20
45
|
menuItems[index].focus();
|
|
21
46
|
};
|
|
22
47
|
const focusOnFirst = () => {
|
|
@@ -32,20 +57,31 @@ export const applyMenuKeyboardNavigation = (childWin, className = ".menu-item")
|
|
|
32
57
|
focusOn(length - 1);
|
|
33
58
|
}
|
|
34
59
|
};
|
|
60
|
+
/**
|
|
61
|
+
* Sets the focus on a menu item's icon
|
|
62
|
+
* @param index The index of the menu item in the list
|
|
63
|
+
* @param iconIndex The index of the menu item's icon (-1 = menu text, not icon)
|
|
64
|
+
*/
|
|
35
65
|
const focusOnIcon = (index, iconIndex) => {
|
|
36
66
|
const menuItems = getElements();
|
|
67
|
+
// Menu could have no items
|
|
37
68
|
if (!menuItems.length)
|
|
38
69
|
return;
|
|
39
70
|
const icons = getMenuItemIcons(index);
|
|
71
|
+
// Defend against possible js runtime error
|
|
40
72
|
if (icons.length <= iconIndex) {
|
|
41
73
|
return;
|
|
42
74
|
}
|
|
75
|
+
// Focus on menu item text, if relevant
|
|
43
76
|
if (iconIndex === -1) {
|
|
44
77
|
menuItems[index].focus();
|
|
45
78
|
return;
|
|
46
79
|
}
|
|
47
80
|
icons[iconIndex].focus();
|
|
48
81
|
};
|
|
82
|
+
/**
|
|
83
|
+
* Simulates mouse events
|
|
84
|
+
*/
|
|
49
85
|
const clickOnItem = () => {
|
|
50
86
|
const elements = getElements();
|
|
51
87
|
const selectedItemElement = elements[selectedItem];
|
|
@@ -73,25 +109,40 @@ export const applyMenuKeyboardNavigation = (childWin, className = ".menu-item")
|
|
|
73
109
|
}
|
|
74
110
|
});
|
|
75
111
|
};
|
|
112
|
+
/**
|
|
113
|
+
* Invoked when a user presses on the arrow up key
|
|
114
|
+
*/
|
|
76
115
|
const onArrowUp = () => {
|
|
77
116
|
selectedIcon = -1;
|
|
117
|
+
// Set the focus on the previous item
|
|
78
118
|
selectedItem--;
|
|
79
119
|
if (selectedItem < 0) {
|
|
120
|
+
// If we are back to the begining
|
|
121
|
+
// set the focus on last item
|
|
80
122
|
focusOnLast();
|
|
81
123
|
return;
|
|
82
124
|
}
|
|
83
125
|
focusOn(selectedItem);
|
|
84
126
|
};
|
|
127
|
+
/**
|
|
128
|
+
* Invoked when user press the arrow down key
|
|
129
|
+
*/
|
|
85
130
|
const onArrowDown = () => {
|
|
86
131
|
selectedIcon = -1;
|
|
132
|
+
// The the focus on the next item
|
|
87
133
|
selectedItem++;
|
|
134
|
+
// If we reached the end, then go back to first item
|
|
88
135
|
if (selectedItem === getElements().length) {
|
|
89
136
|
selectedItem = 0;
|
|
90
137
|
}
|
|
91
138
|
focusOn(selectedItem);
|
|
92
139
|
};
|
|
140
|
+
/**
|
|
141
|
+
* Invoked when user press the arrow right key
|
|
142
|
+
*/
|
|
93
143
|
const onArrowRight = () => {
|
|
94
144
|
const menuItems = getElements();
|
|
145
|
+
// Menu could have no items
|
|
95
146
|
if (!menuItems.length)
|
|
96
147
|
return;
|
|
97
148
|
const icons = getMenuItemIcons(selectedItem);
|
|
@@ -104,8 +155,12 @@ export const applyMenuKeyboardNavigation = (childWin, className = ".menu-item")
|
|
|
104
155
|
}
|
|
105
156
|
focusOnIcon(selectedItem, selectedIcon);
|
|
106
157
|
};
|
|
158
|
+
/**
|
|
159
|
+
* Invoked when user press the arrow left key
|
|
160
|
+
*/
|
|
107
161
|
const onArrowLeft = () => {
|
|
108
162
|
const menuItems = getElements();
|
|
163
|
+
// Menu could have no items
|
|
109
164
|
if (!menuItems.length)
|
|
110
165
|
return;
|
|
111
166
|
const icons = getMenuItemIcons(selectedItem);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keyboardNavigation.js","sourceRoot":"","sources":["../../../src/components/menu/keyboardNavigation.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Keyboard navigation allows the end user to navigate through menus using\n * arrow keys and to select items using the enter key.\n *\n * When an element is selected then the keyboard navigation state is reset\n * so that the user will begin again with the first item.\n *\n * @param childWin - Main window or child window reference.\n * @param [className] - Selector of elements to apply navigation on.\n * @example\n * applyMenuKeyboardNavigation(window, \".menu-item\");\n */\nexport const applyMenuKeyboardNavigation = (childWin: Window, className: string = \".menu-item\") => {\n\tlet selectedItem: number = 0;\n\n\tlet selectedIcon: number = -1;\n\n\tnew MutationObserver(() => {\n\t\t// Reset selectedIndex when elements added or removed\n\t\t// from the DOM. The motivation behind this was an issue\n\t\t// with Brad's search menu where the order of focus is\n\t\t// messed up when his list of result changes.\n\t\tselectedItem = 0;\n\t}).observe(childWin.document.body, {\n\t\tchildList: true,\n\t\tcharacterData: false,\n\t\tsubtree: true,\n\t});\n\n\t/**\n\t * Returns list of elements\n\t */\n\tconst getElements = () => childWin.document.querySelectorAll(className) as NodeListOf<HTMLElement>;\n\n\tconst getMenuItemIcons = (index: number) => {\n\t\tconst menuItems = getElements();\n\t\treturn menuItems[index].querySelectorAll(\".menu-item-icon\") as NodeListOf<HTMLElement>;\n\t};\n\n\t/**\n\t * Sets the focus on a menu item\n\t * @param index The index of the menu item in the list\n\t */\n\tconst focusOn = (index: number) => {\n\t\tconst menuItems = getElements();\n\n\t\t// Menu could have no items\n\t\tif (!menuItems.length) return;\n\n\t\t// Focus on element and scroll if needed\n\t\tmenuItems[index].focus();\n\t};\n\n\tconst focusOnFirst = () => {\n\t\tselectedItem = 0;\n\t\tselectedIcon = -1;\n\t\tfocusOn(0);\n\t};\n\n\tconst focusOnLast = () => {\n\t\tselectedIcon = -1;\n\t\tconst { length } = getElements();\n\t\tif (length) {\n\t\t\tselectedItem = length - 1;\n\t\t\tfocusOn(length - 1);\n\t\t}\n\t};\n\n\t/**\n\t * Sets the focus on a menu item's icon\n\t * @param index The index of the menu item in the list\n\t * @param iconIndex The index of the menu item's icon (-1 = menu text, not icon)\n\t */\n\tconst focusOnIcon = (index: number, iconIndex: number) => {\n\t\tconst menuItems = getElements();\n\t\t// Menu could have no items\n\t\tif (!menuItems.length) return;\n\n\t\tconst icons = getMenuItemIcons(index);\n\t\t// Defend against possible js runtime error\n\t\tif (icons.length <= iconIndex) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Focus on menu item text, if relevant\n\t\tif (iconIndex === -1) {\n\t\t\tmenuItems[index].focus();\n\t\t\treturn;\n\t\t}\n\n\t\ticons[iconIndex].focus();\n\t};\n\n\t/**\n\t * Simulates mouse events\n\t */\n\tconst clickOnItem = () => {\n\t\tconst elements = getElements();\n\t\tconst selectedItemElement = elements[selectedItem as any];\n\t\t[\"mousedown\", \"click\", \"mouseup\"].forEach((event) => {\n\t\t\tif (selectedIcon > -1) {\n\t\t\t\tconst icons = getMenuItemIcons(selectedItem as any);\n\t\t\t\tconst selectedIconElement = icons[selectedIcon as any];\n\t\t\t\tif (selectedIconElement) {\n\t\t\t\t\tselectedIconElement.dispatchEvent(\n\t\t\t\t\t\tnew MouseEvent(event, {\n\t\t\t\t\t\t\tview: childWin,\n\t\t\t\t\t\t\tbubbles: true,\n\t\t\t\t\t\t\tcancelable: true,\n\t\t\t\t\t\t\tbuttons: 1,\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (selectedItemElement && selectedItemElement.dispatchEvent) {\n\t\t\t\tselectedItemElement.dispatchEvent(\n\t\t\t\t\tnew MouseEvent(event, {\n\t\t\t\t\t\tview: childWin,\n\t\t\t\t\t\tbubbles: true,\n\t\t\t\t\t\tcancelable: true,\n\t\t\t\t\t\tbuttons: 1,\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\t};\n\n\t/**\n\t * Invoked when a user presses on the arrow up key\n\t */\n\tconst onArrowUp = () => {\n\t\tselectedIcon = -1;\n\n\t\t// Set the focus on the previous item\n\t\tselectedItem--;\n\t\tif (selectedItem < 0) {\n\t\t\t// If we are back to the begining\n\t\t\t// set the focus on last item\n\t\t\tfocusOnLast();\n\t\t\treturn;\n\t\t}\n\t\tfocusOn(selectedItem);\n\t};\n\n\t/**\n\t * Invoked when user press the arrow down key\n\t */\n\tconst onArrowDown = () => {\n\t\tselectedIcon = -1;\n\n\t\t// The the focus on the next item\n\t\tselectedItem++;\n\t\t// If we reached the end, then go back to first item\n\t\tif (selectedItem === getElements().length) {\n\t\t\tselectedItem = 0;\n\t\t}\n\t\tfocusOn(selectedItem);\n\t};\n\n\t/**\n\t * Invoked when user press the arrow right key\n\t */\n\tconst onArrowRight = () => {\n\t\tconst menuItems = getElements();\n\t\t// Menu could have no items\n\t\tif (!menuItems.length) return;\n\n\t\tconst icons = getMenuItemIcons(selectedItem);\n\t\tif (icons.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tselectedIcon++;\n\t\tif (selectedIcon === icons.length) {\n\t\t\tselectedIcon = -1;\n\t\t}\n\t\tfocusOnIcon(selectedItem, selectedIcon);\n\t};\n\n\t/**\n\t * Invoked when user press the arrow left key\n\t */\n\tconst onArrowLeft = () => {\n\t\tconst menuItems = getElements();\n\t\t// Menu could have no items\n\t\tif (!menuItems.length) return;\n\n\t\tconst icons = getMenuItemIcons(selectedItem);\n\t\tif (icons.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tselectedIcon--;\n\t\tif (selectedIcon === icons.length) {\n\t\t\tselectedIcon = -1;\n\t\t}\n\t\tfocusOnIcon(selectedItem, selectedIcon);\n\t};\n\n\tconst actionDictionary = {\n\t\tArrowDown: onArrowDown,\n\t\tArrowUp: onArrowUp,\n\t\tArrowLeft: onArrowLeft,\n\t\tArrowRight: onArrowRight,\n\t\tEnter: clickOnItem,\n\t\tHome: focusOnFirst,\n\t\tEnd: focusOnLast,\n\t};\n\n\tchildWin.addEventListener(\"keydown\", (e) => {\n\t\tconst { key } = e as KeyboardEvent;\n\n\t\tif (key in actionDictionary) {\n\t\t\tactionDictionary[key as keyof typeof actionDictionary]?.();\n\t\t\te.preventDefault();\n\t\t}\n\t});\n\n\tchildWin.addEventListener(\"blur\", focusOnFirst);\n\tchildWin.addEventListener(\"focus\", focusOnFirst);\n};\n"]}
|
|
1
|
+
{"version":3,"file":"keyboardNavigation.js","sourceRoot":"","sources":["../../../src/components/menu/keyboardNavigation.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Keyboard navigation allows the end user to navigate through menus using\n * arrow keys and to select items using the enter key.\n *\n * When an element is selected then the keyboard navigation state is reset\n * so that the user will begin again with the first item.\n *\n * @param childWin - Main window or child window reference.\n * @param [className] - Selector of elements to apply navigation on.\n * @example\n * applyMenuKeyboardNavigation(window, \".menu-item\");\n */\nexport const applyMenuKeyboardNavigation = (childWin: Window, className: string = \".menu-item\") => {\n\tlet selectedItem: number = 0;\n\n\tlet selectedIcon: number = -1;\n\n\tnew MutationObserver(() => {\n\t\t// Reset selectedIndex when elements added or removed\n\t\t// from the DOM. The motivation behind this was an issue\n\t\t// with Brad's search menu where the order of focus is\n\t\t// messed up when his list of result changes.\n\t\tselectedItem = 0;\n\t}).observe(childWin.document.body, {\n\t\tchildList: true,\n\t\tcharacterData: false,\n\t\tsubtree: true,\n\t});\n\n\t/**\n\t * Returns list of elements\n\t */\n\tconst getElements = () => childWin.document.querySelectorAll(className) as NodeListOf<HTMLElement>;\n\n\tconst getMenuItemIcons = (index: number) => {\n\t\tconst menuItems = getElements();\n\t\treturn menuItems[index].querySelectorAll(\".menu-item-icon\") as NodeListOf<HTMLElement>;\n\t};\n\n\t/**\n\t * Sets the focus on a menu item\n\t * @param index The index of the menu item in the list\n\t */\n\tconst focusOn = (index: number) => {\n\t\tconst menuItems = getElements();\n\n\t\t// Menu could have no items\n\t\tif (!menuItems.length) return;\n\n\t\t// Focus on element and scroll if needed\n\t\tmenuItems[index].focus();\n\t};\n\n\tconst focusOnFirst = () => {\n\t\tselectedItem = 0;\n\t\tselectedIcon = -1;\n\t\tfocusOn(0);\n\t};\n\n\tconst focusOnLast = () => {\n\t\tselectedIcon = -1;\n\t\tconst { length } = getElements();\n\t\tif (length) {\n\t\t\tselectedItem = length - 1;\n\t\t\tfocusOn(length - 1);\n\t\t}\n\t};\n\n\t/**\n\t * Sets the focus on a menu item's icon\n\t * @param index The index of the menu item in the list\n\t * @param iconIndex The index of the menu item's icon (-1 = menu text, not icon)\n\t */\n\tconst focusOnIcon = (index: number, iconIndex: number) => {\n\t\tconst menuItems = getElements();\n\t\t// Menu could have no items\n\t\tif (!menuItems.length) return;\n\n\t\tconst icons = getMenuItemIcons(index);\n\t\t// Defend against possible js runtime error\n\t\tif (icons.length <= iconIndex) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Focus on menu item text, if relevant\n\t\tif (iconIndex === -1) {\n\t\t\tmenuItems[index].focus();\n\t\t\treturn;\n\t\t}\n\n\t\ticons[iconIndex].focus();\n\t};\n\n\t/**\n\t * Simulates mouse events\n\t */\n\tconst clickOnItem = () => {\n\t\tconst elements = getElements();\n\t\tconst selectedItemElement = elements[selectedItem as any];\n\t\t[\"mousedown\", \"click\", \"mouseup\"].forEach((event) => {\n\t\t\tif (selectedIcon > -1) {\n\t\t\t\tconst icons = getMenuItemIcons(selectedItem as any);\n\t\t\t\tconst selectedIconElement = icons[selectedIcon as any];\n\t\t\t\tif (selectedIconElement) {\n\t\t\t\t\tselectedIconElement.dispatchEvent(\n\t\t\t\t\t\tnew MouseEvent(event, {\n\t\t\t\t\t\t\tview: childWin,\n\t\t\t\t\t\t\tbubbles: true,\n\t\t\t\t\t\t\tcancelable: true,\n\t\t\t\t\t\t\tbuttons: 1,\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (selectedItemElement && selectedItemElement.dispatchEvent) {\n\t\t\t\tselectedItemElement.dispatchEvent(\n\t\t\t\t\tnew MouseEvent(event, {\n\t\t\t\t\t\tview: childWin,\n\t\t\t\t\t\tbubbles: true,\n\t\t\t\t\t\tcancelable: true,\n\t\t\t\t\t\tbuttons: 1,\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\t};\n\n\t/**\n\t * Invoked when a user presses on the arrow up key\n\t */\n\tconst onArrowUp = () => {\n\t\tselectedIcon = -1;\n\n\t\t// Set the focus on the previous item\n\t\tselectedItem--;\n\t\tif (selectedItem < 0) {\n\t\t\t// If we are back to the begining\n\t\t\t// set the focus on last item\n\t\t\tfocusOnLast();\n\t\t\treturn;\n\t\t}\n\t\tfocusOn(selectedItem);\n\t};\n\n\t/**\n\t * Invoked when user press the arrow down key\n\t */\n\tconst onArrowDown = () => {\n\t\tselectedIcon = -1;\n\n\t\t// The the focus on the next item\n\t\tselectedItem++;\n\t\t// If we reached the end, then go back to first item\n\t\tif (selectedItem === getElements().length) {\n\t\t\tselectedItem = 0;\n\t\t}\n\t\tfocusOn(selectedItem);\n\t};\n\n\t/**\n\t * Invoked when user press the arrow right key\n\t */\n\tconst onArrowRight = () => {\n\t\tconst menuItems = getElements();\n\t\t// Menu could have no items\n\t\tif (!menuItems.length) return;\n\n\t\tconst icons = getMenuItemIcons(selectedItem);\n\t\tif (icons.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tselectedIcon++;\n\t\tif (selectedIcon === icons.length) {\n\t\t\tselectedIcon = -1;\n\t\t}\n\t\tfocusOnIcon(selectedItem, selectedIcon);\n\t};\n\n\t/**\n\t * Invoked when user press the arrow left key\n\t */\n\tconst onArrowLeft = () => {\n\t\tconst menuItems = getElements();\n\t\t// Menu could have no items\n\t\tif (!menuItems.length) return;\n\n\t\tconst icons = getMenuItemIcons(selectedItem);\n\t\tif (icons.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tselectedIcon--;\n\t\tif (selectedIcon === icons.length) {\n\t\t\tselectedIcon = -1;\n\t\t}\n\t\tfocusOnIcon(selectedItem, selectedIcon);\n\t};\n\n\tconst actionDictionary = {\n\t\tArrowDown: onArrowDown,\n\t\tArrowUp: onArrowUp,\n\t\tArrowLeft: onArrowLeft,\n\t\tArrowRight: onArrowRight,\n\t\tEnter: clickOnItem,\n\t\tHome: focusOnFirst,\n\t\tEnd: focusOnLast,\n\t};\n\n\tchildWin.addEventListener(\"keydown\", (e) => {\n\t\tconst { key } = e as KeyboardEvent;\n\n\t\tif (key in actionDictionary) {\n\t\t\tactionDictionary[key as keyof typeof actionDictionary]?.();\n\t\t\te.preventDefault();\n\t\t}\n\t});\n\n\tchildWin.addEventListener(\"blur\", focusOnFirst);\n\tchildWin.addEventListener(\"focus\", focusOnFirst);\n};\n"]}
|