@vuu-ui/vuu-popups 0.9.2 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/cjs/dialog/useDialog.js.map +1 -1
  2. package/cjs/dialog-header/DialogHeader.js.map +1 -1
  3. package/cjs/menu/ContextMenu.js.map +1 -1
  4. package/cjs/menu/MenuList.js.map +1 -1
  5. package/cjs/menu/context-menu-provider.js.map +1 -1
  6. package/cjs/menu/key-code.js.map +1 -1
  7. package/cjs/menu/use-cascade.js +10 -8
  8. package/cjs/menu/use-cascade.js.map +1 -1
  9. package/cjs/menu/use-items-with-ids-next.js.map +1 -1
  10. package/cjs/menu/use-keyboard-navigation.js.map +1 -1
  11. package/cjs/menu/useContextMenu.js.map +1 -1
  12. package/cjs/menu/utils.js.map +1 -1
  13. package/cjs/notifications/NotificationsCenter.js.map +1 -1
  14. package/cjs/notifications/NotificationsProvider.js +1 -1
  15. package/cjs/notifications/NotificationsProvider.js.map +1 -1
  16. package/cjs/notifications/ToastNotification.js.map +1 -1
  17. package/cjs/popup/Popup.js.map +1 -1
  18. package/cjs/popup/getPositionRelativeToAnchor.js.map +1 -1
  19. package/cjs/popup/popup-service.js +1 -1
  20. package/cjs/popup/popup-service.js.map +1 -1
  21. package/cjs/popup/useAnchoredPosition.js.map +1 -1
  22. package/cjs/popup-menu/PopupMenu.js.map +1 -1
  23. package/cjs/popup-menu/usePopupMenu.js.map +1 -1
  24. package/cjs/portal/Portal.js.map +1 -1
  25. package/cjs/portal-deprecated/render-portal.js.map +1 -1
  26. package/cjs/prompt/Prompt.js.map +1 -1
  27. package/cjs/tooltip/Tooltip.css.js +1 -1
  28. package/cjs/tooltip/Tooltip.js.map +1 -1
  29. package/cjs/tooltip/useTooltip.js.map +1 -1
  30. package/cjs/tooltip/useTooltipAnchoredPosition.js.map +1 -1
  31. package/esm/dialog/useDialog.js.map +1 -1
  32. package/esm/dialog-header/DialogHeader.js.map +1 -1
  33. package/esm/menu/ContextMenu.js.map +1 -1
  34. package/esm/menu/MenuList.js.map +1 -1
  35. package/esm/menu/context-menu-provider.js.map +1 -1
  36. package/esm/menu/key-code.js.map +1 -1
  37. package/esm/menu/use-cascade.js +10 -8
  38. package/esm/menu/use-cascade.js.map +1 -1
  39. package/esm/menu/use-items-with-ids-next.js.map +1 -1
  40. package/esm/menu/use-keyboard-navigation.js.map +1 -1
  41. package/esm/menu/useContextMenu.js.map +1 -1
  42. package/esm/menu/utils.js.map +1 -1
  43. package/esm/notifications/NotificationsCenter.js.map +1 -1
  44. package/esm/notifications/NotificationsProvider.js +1 -1
  45. package/esm/notifications/NotificationsProvider.js.map +1 -1
  46. package/esm/notifications/ToastNotification.js.map +1 -1
  47. package/esm/popup/Popup.js.map +1 -1
  48. package/esm/popup/getPositionRelativeToAnchor.js.map +1 -1
  49. package/esm/popup/popup-service.js +1 -1
  50. package/esm/popup/popup-service.js.map +1 -1
  51. package/esm/popup/useAnchoredPosition.js.map +1 -1
  52. package/esm/popup-menu/PopupMenu.js.map +1 -1
  53. package/esm/popup-menu/usePopupMenu.js.map +1 -1
  54. package/esm/portal/Portal.js.map +1 -1
  55. package/esm/portal-deprecated/render-portal.js.map +1 -1
  56. package/esm/prompt/Prompt.js.map +1 -1
  57. package/esm/tooltip/Tooltip.css.js +1 -1
  58. package/esm/tooltip/Tooltip.js.map +1 -1
  59. package/esm/tooltip/useTooltip.js.map +1 -1
  60. package/esm/tooltip/useTooltipAnchoredPosition.js.map +1 -1
  61. package/package.json +8 -8
  62. package/types/dialog/useDialog.d.ts +2 -2
  63. package/types/dialog-header/DialogHeader.d.ts +1 -1
  64. package/types/menu/ContextMenu.d.ts +1 -2
  65. package/types/menu/MenuList.d.ts +6 -6
  66. package/types/menu/context-menu-provider.d.ts +1 -1
  67. package/types/menu/useContextMenu.d.ts +0 -1
  68. package/types/notifications/NotificationsCenter.d.ts +1 -2
  69. package/types/notifications/NotificationsProvider.d.ts +1 -2
  70. package/types/notifications/ToastNotification.d.ts +1 -2
  71. package/types/popup/Popup.d.ts +1 -1
  72. package/types/popup/getPositionRelativeToAnchor.d.ts +3 -3
  73. package/types/popup-menu/PopupMenu.d.ts +1 -1
  74. package/types/prompt/Prompt.d.ts +1 -1
  75. package/types/tooltip/Tooltip.d.ts +1 -1
  76. package/types/tooltip/useTooltip.d.ts +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"useDialog.js","sources":["../../src/dialog/useDialog.tsx"],"sourcesContent":["import {\n Dialog,\n DialogActions,\n DialogCloseButton,\n DialogContent,\n DialogHeader,\n} from \"@salt-ds/core\";\nimport {\n createContext,\n ReactElement,\n ReactNode,\n useCallback,\n useContext,\n useMemo,\n useState,\n} from \"react\";\n\nexport type DialogState = {\n actions?: ReactElement[];\n content: ReactElement;\n title: string;\n hideCloseButton?: boolean;\n};\n\nexport type SetDialog = (dialogState?: DialogState) => void;\n\nexport type ShowDialog = (\n dialogContent: ReactElement,\n title: string,\n dialogActionButtons?: ReactElement[],\n hideCloseButton?: boolean\n) => void;\n\nexport interface DialogContextProps {\n showDialog: ShowDialog;\n closeDialog: () => void;\n setDialogDispatchers: (\n showDialog: ShowDialog,\n closeDialog: () => void\n ) => void;\n}\n\nexport const useDialog = () => {\n const [dialogState, setDialogState] = useState<DialogState>();\n\n const closeDialog = useCallback(() => {\n setDialogState(undefined);\n }, []);\n\n const handleOpenChange = useCallback(\n (open?: boolean) => {\n if (open !== true) {\n closeDialog();\n }\n },\n [closeDialog]\n );\n\n const dialog = dialogState ? (\n <Dialog open={true} onOpenChange={handleOpenChange}>\n <DialogHeader header={dialogState.title} />\n <DialogContent>{dialogState.content}</DialogContent>\n {dialogState.hideCloseButton !== true ? (\n <DialogCloseButton\n data-embedded\n data-icon=\"close\"\n onClick={closeDialog}\n />\n ) : null}\n {dialogState.actions ? (\n <DialogActions>{dialogState.actions}</DialogActions>\n ) : null}\n </Dialog>\n ) : null;\n\n return {\n dialog,\n setDialogState,\n };\n};\n\nconst defaultShowDialog: ShowDialog = () => {\n console.warn(\"No DialogProvider in place\");\n};\nconst defaultCloseDialog = () => {\n console.warn(\"No DialogProvider in place\");\n};\n\nclass DialogContextObject implements DialogContextProps {\n showDialog = defaultShowDialog;\n closeDialog = defaultCloseDialog;\n setDialogDispatchers(showDialog: ShowDialog, closeDialog: () => void) {\n this.showDialog = showDialog;\n this.closeDialog = closeDialog;\n }\n}\n\nconst DialogContext = createContext<DialogContextProps>(\n new DialogContextObject()\n);\n\nconst DialogHost = ({ context }: { context: DialogContextProps }) => {\n const { dialog, setDialogState } = useDialog();\n const showDialog: ShowDialog = useCallback(\n (dialogContent, title, actionButtons, hideCloseButton) => {\n setDialogState({\n actions: actionButtons,\n content: dialogContent,\n title,\n hideCloseButton,\n });\n },\n [setDialogState]\n );\n const closeDialog = useCallback(() => {\n setDialogState(undefined);\n }, [setDialogState]);\n\n useMemo(() => {\n context.setDialogDispatchers(showDialog, closeDialog);\n }, [closeDialog, context, showDialog]);\n return dialog;\n};\n\nexport const DialogProvider = ({ children }: { children: ReactNode }) => {\n const context = useContext(DialogContext);\n return (\n <DialogContext.Provider value={context}>\n <DialogHost context={context} />\n {children}\n </DialogContext.Provider>\n );\n};\n\nexport const useDialogContext = () => {\n const { closeDialog, showDialog } = useContext(DialogContext);\n return { showDialog, closeDialog };\n};\n"],"names":["useState","useCallback","jsxs","Dialog","jsx","DialogHeader","DialogContent","DialogCloseButton","DialogActions","createContext","useMemo","useContext"],"mappings":"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"}
1
+ {"version":3,"file":"useDialog.js","sources":["../../src/dialog/useDialog.tsx"],"sourcesContent":["import {\n Dialog,\n DialogActions,\n DialogCloseButton,\n DialogContent,\n DialogHeader,\n} from \"@salt-ds/core\";\nimport {\n createContext,\n ReactElement,\n ReactNode,\n useCallback,\n useContext,\n useMemo,\n useState,\n} from \"react\";\n\nexport type DialogState = {\n actions?: ReactElement[];\n content: ReactElement;\n title: string;\n hideCloseButton?: boolean;\n};\n\nexport type SetDialog = (dialogState?: DialogState) => void;\n\nexport type ShowDialog = (\n dialogContent: ReactElement,\n title: string,\n dialogActionButtons?: ReactElement[],\n hideCloseButton?: boolean\n) => void;\n\nexport interface DialogContextProps {\n showDialog: ShowDialog;\n closeDialog: () => void;\n setDialogDispatchers: (\n showDialog: ShowDialog,\n closeDialog: () => void\n ) => void;\n}\n\nexport const useDialog = () => {\n const [dialogState, setDialogState] = useState<DialogState>();\n\n const closeDialog = useCallback(() => {\n setDialogState(undefined);\n }, []);\n\n const handleOpenChange = useCallback(\n (open?: boolean) => {\n if (open !== true) {\n closeDialog();\n }\n },\n [closeDialog]\n );\n\n const dialog = dialogState ? (\n <Dialog open={true} onOpenChange={handleOpenChange}>\n <DialogHeader header={dialogState.title} />\n <DialogContent>{dialogState.content}</DialogContent>\n {dialogState.hideCloseButton !== true ? (\n <DialogCloseButton\n data-embedded\n data-icon=\"close\"\n onClick={closeDialog}\n />\n ) : null}\n {dialogState.actions ? (\n <DialogActions>{dialogState.actions}</DialogActions>\n ) : null}\n </Dialog>\n ) : null;\n\n return {\n dialog,\n setDialogState,\n };\n};\n\nconst defaultShowDialog: ShowDialog = () => {\n console.warn(\"No DialogProvider in place\");\n};\nconst defaultCloseDialog = () => {\n console.warn(\"No DialogProvider in place\");\n};\n\nclass DialogContextObject implements DialogContextProps {\n showDialog = defaultShowDialog;\n closeDialog = defaultCloseDialog;\n setDialogDispatchers(showDialog: ShowDialog, closeDialog: () => void) {\n this.showDialog = showDialog;\n this.closeDialog = closeDialog;\n }\n}\n\nconst DialogContext = createContext<DialogContextProps>(\n new DialogContextObject()\n);\n\nconst DialogHost = ({ context }: { context: DialogContextProps }) => {\n const { dialog, setDialogState } = useDialog();\n const showDialog: ShowDialog = useCallback(\n (dialogContent, title, actionButtons, hideCloseButton) => {\n setDialogState({\n actions: actionButtons,\n content: dialogContent,\n title,\n hideCloseButton,\n });\n },\n [setDialogState]\n );\n const closeDialog = useCallback(() => {\n setDialogState(undefined);\n }, [setDialogState]);\n\n useMemo(() => {\n context.setDialogDispatchers(showDialog, closeDialog);\n }, [closeDialog, context, showDialog]);\n return dialog;\n};\n\nexport const DialogProvider = ({ children }: { children: ReactNode }) => {\n const context = useContext(DialogContext);\n return (\n <DialogContext.Provider value={context}>\n <DialogHost context={context} />\n {children}\n </DialogContext.Provider>\n );\n};\n\nexport const useDialogContext = () => {\n const { closeDialog, showDialog } = useContext(DialogContext);\n return { showDialog, closeDialog };\n};\n"],"names":["useState","useCallback","jsxs","Dialog","jsx","DialogHeader","DialogContent","DialogCloseButton","DialogActions","createContext","useMemo","useContext"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"DialogHeader.js","sources":["../../src/dialog-header/DialogHeader.tsx"],"sourcesContent":["import { Button, Text } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { HTMLAttributes } from \"react\";\n\nimport dialogHeaderCss from \"./DialogHeader.css\";\n\nconst classBase = \"vuuDialogHeader\";\n\nexport interface DialogHeaderProps extends HTMLAttributes<HTMLDivElement> {\n hideCloseButton?: boolean;\n onClose: () => void;\n}\n\nexport const DialogHeader = ({\n hideCloseButton = false,\n title,\n onClose,\n ...htmlAttributes\n}: DialogHeaderProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-dialoh-header\",\n css: dialogHeaderCss,\n window: targetWindow,\n });\n\n return (\n <div {...htmlAttributes} className={classBase}>\n <Text className=\"dialogHeader\">{title}</Text>\n {!hideCloseButton && (\n <Button\n key=\"close\"\n onClick={onClose}\n data-align=\"end\"\n data-icon=\"close\"\n variant=\"secondary\"\n />\n )}\n </div>\n );\n};\n"],"names":["useWindow","useComponentCssInjection","dialogHeaderCss","jsxs","jsx","Text","Button"],"mappings":";;;;;;;;AAOA,MAAM,SAAY,GAAA,iBAAA,CAAA;AAOX,MAAM,eAAe,CAAC;AAAA,EAC3B,eAAkB,GAAA,KAAA;AAAA,EAClB,KAAA;AAAA,EACA,OAAA;AAAA,EACA,GAAG,cAAA;AACL,CAAyB,KAAA;AACvB,EAAA,MAAM,eAAeA,gBAAU,EAAA,CAAA;AAC/B,EAAyBC,+BAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,mBAAA;AAAA,IACR,GAAK,EAAAC,cAAA;AAAA,IACL,MAAQ,EAAA,YAAA;AAAA,GACT,CAAA,CAAA;AAED,EAAA,uBACGC,eAAA,CAAA,KAAA,EAAA,EAAK,GAAG,cAAA,EAAgB,WAAW,SAClC,EAAA,QAAA,EAAA;AAAA,oBAACC,cAAA,CAAAC,SAAA,EAAA,EAAK,SAAU,EAAA,cAAA,EAAgB,QAAM,EAAA,KAAA,EAAA,CAAA;AAAA,IACrC,CAAC,eACA,oBAAAD,cAAA;AAAA,MAACE,WAAA;AAAA,MAAA;AAAA,QAEC,OAAS,EAAA,OAAA;AAAA,QACT,YAAW,EAAA,KAAA;AAAA,QACX,WAAU,EAAA,OAAA;AAAA,QACV,OAAQ,EAAA,WAAA;AAAA,OAAA;AAAA,MAJJ,OAAA;AAAA,KAKN;AAAA,GAEJ,EAAA,CAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"DialogHeader.js","sources":["../../src/dialog-header/DialogHeader.tsx"],"sourcesContent":["import { Button, Text } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { HTMLAttributes } from \"react\";\n\nimport dialogHeaderCss from \"./DialogHeader.css\";\n\nconst classBase = \"vuuDialogHeader\";\n\nexport interface DialogHeaderProps extends HTMLAttributes<HTMLDivElement> {\n hideCloseButton?: boolean;\n onClose: () => void;\n}\n\nexport const DialogHeader = ({\n hideCloseButton = false,\n title,\n onClose,\n ...htmlAttributes\n}: DialogHeaderProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-dialoh-header\",\n css: dialogHeaderCss,\n window: targetWindow,\n });\n\n return (\n <div {...htmlAttributes} className={classBase}>\n <Text className=\"dialogHeader\">{title}</Text>\n {!hideCloseButton && (\n <Button\n key=\"close\"\n onClick={onClose}\n data-align=\"end\"\n data-icon=\"close\"\n variant=\"secondary\"\n />\n )}\n </div>\n );\n};\n"],"names":["useWindow","useComponentCssInjection","dialogHeaderCss","jsxs","jsx","Text","Button"],"mappings":";;;;;;;;AAOA,MAAM,SAAY,GAAA,iBAAA;AAOX,MAAM,eAAe,CAAC;AAAA,EAC3B,eAAkB,GAAA,KAAA;AAAA,EAClB,KAAA;AAAA,EACA,OAAA;AAAA,EACA,GAAG;AACL,CAAyB,KAAA;AACvB,EAAA,MAAM,eAAeA,gBAAU,EAAA;AAC/B,EAAyBC,+BAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,mBAAA;AAAA,IACR,GAAK,EAAAC,cAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAA,uBACGC,eAAA,CAAA,KAAA,EAAA,EAAK,GAAG,cAAA,EAAgB,WAAW,SAClC,EAAA,QAAA,EAAA;AAAA,oBAACC,cAAA,CAAAC,SAAA,EAAA,EAAK,SAAU,EAAA,cAAA,EAAgB,QAAM,EAAA,KAAA,EAAA,CAAA;AAAA,IACrC,CAAC,eACA,oBAAAD,cAAA;AAAA,MAACE,WAAA;AAAA,MAAA;AAAA,QAEC,OAAS,EAAA,OAAA;AAAA,QACT,YAAW,EAAA,KAAA;AAAA,QACX,WAAU,EAAA,OAAA;AAAA,QACV,OAAQ,EAAA;AAAA,OAAA;AAAA,MAJJ;AAAA;AAKN,GAEJ,EAAA,CAAA;AAEJ;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"ContextMenu.js","sources":["../../src/menu/ContextMenu.tsx"],"sourcesContent":["import { useId } from \"@vuu-ui/vuu-utils\";\nimport { useCallback, useRef } from \"react\";\nimport { PopupCloseCallback, PopupComponent } from \"../popup\";\nimport { Portal, PortalProps } from \"../portal\";\nimport { MenuList, MenuListProps } from \"./MenuList\";\nimport { useCascade } from \"./use-cascade\";\nimport { useItemsWithIdsNext } from \"./use-items-with-ids-next\";\nimport { MenuCloseHandler } from \"./use-keyboard-navigation\";\nimport { ContextMenuOptions } from \"./useContextMenu\";\n\nexport interface ContextMenuProps extends Omit<MenuListProps, \"onCloseMenu\"> {\n PortalProps?: Partial<PortalProps>;\n onClose?: PopupCloseCallback;\n position?: { x: number; y: number };\n withPortal?: boolean;\n}\n\nconst noop = () => undefined;\n\nexport const ContextMenu = ({\n PortalProps,\n activatedByKeyboard,\n children: childrenProp,\n className,\n id: idProp,\n onClose = () => undefined,\n position = { x: 0, y: 0 },\n style,\n ...menuListProps\n}: ContextMenuProps) => {\n const id = useId(idProp);\n const closeMenuRef = useRef<(location?: string) => void>(noop);\n const [menus, actions] = useItemsWithIdsNext(childrenProp, id);\n const navigatingWithKeyboard = useRef(activatedByKeyboard);\n const handleMouseEnterItem = useCallback(() => {\n navigatingWithKeyboard.current = false;\n }, []);\n\n const handleActivate = useCallback(\n (menuItemId: string) => {\n const actionId = menuItemId.slice(9);\n const { action, options } = actions[actionId];\n closeMenuRef.current(id);\n onClose({\n type: \"menu-action\",\n menuId: action,\n options: options as ContextMenuOptions,\n });\n },\n [actions, id, onClose],\n );\n\n const {\n closeMenu,\n listItemProps,\n openMenu: onOpenMenu,\n openMenus,\n handleRender,\n } = useCascade({\n // FIXME\n id: `${id}`,\n onActivate: handleActivate,\n onMouseEnterItem: handleMouseEnterItem,\n position,\n });\n closeMenuRef.current = closeMenu;\n\n const handleCloseMenu = useCallback<MenuCloseHandler>(\n (evt, reason) => {\n navigatingWithKeyboard.current = true;\n closeMenu();\n if (reason === \"tab-away\") {\n // TODO we should fire onclose whenever we're closing\n // the root menu, not just on Tab\n onClose({\n event: evt,\n type: \"tab-away\",\n });\n }\n },\n [closeMenu, onClose],\n );\n\n const handleHighlightMenuItem = () => {\n // console.log(`highlight ${idx}`);\n };\n\n const lastMenu = openMenus.length - 1;\n\n const getChildMenuId = (i: number) => {\n if (i >= lastMenu) {\n return undefined;\n } else {\n const { id } = openMenus[i + 1];\n return id;\n }\n };\n\n return (\n <>\n {openMenus.map(({ id: menuId, left, top }, i, all) => {\n const childMenuId = getChildMenuId(i);\n return (\n <Portal {...PortalProps} key={i} onRender={handleRender}>\n <PopupComponent\n anchorElement={{ current: document.body }}\n placement=\"absolute\"\n position={{ left, top }}\n >\n <MenuList\n {...menuListProps}\n activatedByKeyboard={navigatingWithKeyboard.current}\n childMenuShowing={childMenuId}\n className={className}\n id={menuId}\n isRoot={i === 0}\n key={i}\n listItemProps={listItemProps}\n onActivate={handleActivate}\n onHighlightMenuItem={handleHighlightMenuItem}\n onCloseMenu={handleCloseMenu}\n openMenu={onOpenMenu}\n style={style}\n tabIndex={i === all.length - 1 ? 0 : undefined}\n >\n {menus[menuId]}\n </MenuList>\n </PopupComponent>\n </Portal>\n );\n })}\n </>\n );\n};\n\nContextMenu.displayName = \"ContextMenu\";\n"],"names":["PortalProps","useId","useRef","useItemsWithIdsNext","useCallback","useCascade","id","jsx","Fragment","Portal","PopupComponent","createElement","MenuList"],"mappings":"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"}
1
+ {"version":3,"file":"ContextMenu.js","sources":["../../src/menu/ContextMenu.tsx"],"sourcesContent":["import { useId } from \"@vuu-ui/vuu-utils\";\nimport { useCallback, useRef } from \"react\";\nimport { PopupCloseCallback, PopupComponent } from \"../popup\";\nimport { Portal, PortalProps } from \"../portal\";\nimport { MenuList, MenuListProps } from \"./MenuList\";\nimport { useCascade } from \"./use-cascade\";\nimport { useItemsWithIdsNext } from \"./use-items-with-ids-next\";\nimport { MenuCloseHandler } from \"./use-keyboard-navigation\";\nimport { ContextMenuOptions } from \"./useContextMenu\";\n\nexport interface ContextMenuProps extends Omit<MenuListProps, \"onCloseMenu\"> {\n PortalProps?: Partial<PortalProps>;\n onClose?: PopupCloseCallback;\n position?: { x: number; y: number };\n withPortal?: boolean;\n}\n\nconst noop = () => undefined;\n\nexport const ContextMenu = ({\n PortalProps,\n activatedByKeyboard,\n children: childrenProp,\n className,\n id: idProp,\n onClose = () => undefined,\n position = { x: 0, y: 0 },\n style,\n ...menuListProps\n}: ContextMenuProps) => {\n const id = useId(idProp);\n const closeMenuRef = useRef<(location?: string) => void>(noop);\n const [menus, actions] = useItemsWithIdsNext(childrenProp, id);\n const navigatingWithKeyboard = useRef(activatedByKeyboard);\n const handleMouseEnterItem = useCallback(() => {\n navigatingWithKeyboard.current = false;\n }, []);\n\n const handleActivate = useCallback(\n (menuItemId: string) => {\n const actionId = menuItemId.slice(9);\n const { action, options } = actions[actionId];\n closeMenuRef.current(id);\n onClose({\n type: \"menu-action\",\n menuId: action,\n options: options as ContextMenuOptions,\n });\n },\n [actions, id, onClose],\n );\n\n const {\n closeMenu,\n listItemProps,\n openMenu: onOpenMenu,\n openMenus,\n handleRender,\n } = useCascade({\n // FIXME\n id: `${id}`,\n onActivate: handleActivate,\n onMouseEnterItem: handleMouseEnterItem,\n position,\n });\n closeMenuRef.current = closeMenu;\n\n const handleCloseMenu = useCallback<MenuCloseHandler>(\n (evt, reason) => {\n navigatingWithKeyboard.current = true;\n closeMenu();\n if (reason === \"tab-away\") {\n // TODO we should fire onclose whenever we're closing\n // the root menu, not just on Tab\n onClose({\n event: evt,\n type: \"tab-away\",\n });\n }\n },\n [closeMenu, onClose],\n );\n\n const handleHighlightMenuItem = () => {\n // console.log(`highlight ${idx}`);\n };\n\n const lastMenu = openMenus.length - 1;\n\n const getChildMenuId = (i: number) => {\n if (i >= lastMenu) {\n return undefined;\n } else {\n const { id } = openMenus[i + 1];\n return id;\n }\n };\n\n return (\n <>\n {openMenus.map(({ id: menuId, left, top }, i, all) => {\n const childMenuId = getChildMenuId(i);\n return (\n <Portal {...PortalProps} key={i} onRender={handleRender}>\n <PopupComponent\n anchorElement={{ current: document.body }}\n placement=\"absolute\"\n position={{ left, top }}\n >\n <MenuList\n {...menuListProps}\n activatedByKeyboard={navigatingWithKeyboard.current}\n childMenuShowing={childMenuId}\n className={className}\n id={menuId}\n isRoot={i === 0}\n key={i}\n listItemProps={listItemProps}\n onActivate={handleActivate}\n onHighlightMenuItem={handleHighlightMenuItem}\n onCloseMenu={handleCloseMenu}\n openMenu={onOpenMenu}\n style={style}\n tabIndex={i === all.length - 1 ? 0 : undefined}\n >\n {menus[menuId]}\n </MenuList>\n </PopupComponent>\n </Portal>\n );\n })}\n </>\n );\n};\n\nContextMenu.displayName = \"ContextMenu\";\n"],"names":["PortalProps","useId","useRef","useItemsWithIdsNext","useCallback","useCascade","id","jsx","Fragment","Portal","PopupComponent","createElement","MenuList"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"MenuList.js","sources":["../../src/menu/MenuList.tsx"],"sourcesContent":["import cx from \"clsx\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport React, {\n FC,\n HTMLAttributes,\n ReactElement,\n ReactNode,\n useLayoutEffect,\n useMemo,\n useRef,\n} from \"react\";\n//TODO do we want this dependency ?\nimport { useId } from \"@vuu-ui/vuu-utils\";\nimport {\n MenuCloseHandler,\n useKeyboardNavigation,\n} from \"./use-keyboard-navigation\";\n\nimport menuListCss from \"./MenuList.css\";\n\nconst classBase = \"vuuMenuList\";\n\nexport const Separator = () => <li className=\"vuuMenuItem-divider\" />;\n\nexport const isMenuItemGroup = (child: ReactElement) =>\n child.type === MenuItemGroup || !!child.props[\"data-group\"];\n\nexport interface MenuItemGroupProps {\n children:\n | ReactElement<MenuItemProps>[]\n | [ReactElement<MenuItemLabelProps>, ...ReactElement<MenuItemProps>[]];\n label?: string;\n}\n\nexport interface MenuItemProps extends HTMLAttributes<HTMLDivElement> {\n action?: string;\n idx?: number;\n options?: unknown;\n}\n\n// Purely used as markers, props will be extracted\nexport const MenuItemGroup: FC<MenuItemGroupProps> = () => null;\n// eslint-disable-next-line no-unused-vars\nexport const MenuItem = ({\n children,\n idx,\n options,\n ...props\n}: MenuItemProps) => {\n return <div {...props}>{children}</div>;\n};\n\nexport interface MenuItemLabelProps {\n children: ReactNode;\n}\nconst MenuItemLabel = ({ children }: { children: ReactNode }) => (\n <>{children}</>\n);\nMenuItemLabel.displayName = \"MenuItemLabel\";\nMenuItem.Label = MenuItemLabel;\n\nconst getDisplayName = (item: ReactNode) =>\n React.isValidElement(item) &&\n typeof item.type !== \"string\" &&\n \"displayName\" in item.type\n ? item.type.displayName\n : undefined;\n\nexport const isMenuItemLabel = (\n item: ReactNode,\n): item is ReactElement<MenuItemLabelProps> =>\n getDisplayName(item) === \"MenuItemLabel\";\n\nconst hasIcon = (child: ReactElement) => child.props[\"data-icon\"];\n\nexport type MenuOpenHandler = (\n menuItemEl: HTMLElement,\n immediate?: boolean,\n) => void;\nexport interface MenuListProps extends HTMLAttributes<HTMLDivElement> {\n activatedByKeyboard?: boolean;\n children: ReactElement[];\n childMenuShowing?: string;\n defaultHighlightedIdx?: number;\n highlightedIdx?: number;\n isRoot?: boolean;\n listItemProps?: Partial<MenuItemProps>;\n onActivate?: (menuId: string) => void;\n onCloseMenu: MenuCloseHandler;\n openMenu?: MenuOpenHandler;\n onHighlightMenuItem?: (idx: number) => void;\n}\n\nexport const MenuList = ({\n activatedByKeyboard,\n childMenuShowing,\n children,\n className,\n defaultHighlightedIdx,\n highlightedIdx: highlightedIdxProp,\n id: idProp,\n isRoot,\n listItemProps,\n onHighlightMenuItem,\n onActivate,\n onCloseMenu,\n openMenu: onOpenMenu,\n ...props\n}: MenuListProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-menu-list\",\n css: menuListCss,\n window: targetWindow,\n });\n\n const id = useId(idProp);\n const root = useRef<HTMLDivElement>(null);\n\n // The id generation be,ongs in useIttemsWithIds\n const mapIdxToId = useMemo(() => new Map(), []);\n\n const handleActivate = (idx: number) => {\n const el = root.current?.querySelector(`:scope > [data-index='${idx}']`);\n el?.id && onActivate?.(el.id);\n };\n\n const { focusVisible, highlightedIndex, listProps } = useKeyboardNavigation({\n count: React.Children.count(children),\n defaultHighlightedIdx,\n highlightedIndex: highlightedIdxProp,\n onActivate: handleActivate,\n onHighlight: onHighlightMenuItem,\n onOpenMenu,\n onCloseMenu,\n });\n\n const appliedFocusVisible = childMenuShowing == undefined ? focusVisible : -1;\n\n useLayoutEffect(() => {\n if (childMenuShowing === undefined && activatedByKeyboard) {\n root.current?.focus();\n }\n }, [activatedByKeyboard, childMenuShowing]);\n\n const getActiveDescendant = () =>\n highlightedIndex === undefined || highlightedIndex === -1\n ? undefined\n : mapIdxToId.get(highlightedIndex);\n\n function renderContent() {\n const propsCommonToAllListItems = {\n ...listItemProps,\n role: \"menuitem\",\n };\n\n const maybeIcon = (\n childElement: ReactElement,\n withIcon: boolean,\n iconName?: string,\n ) =>\n withIcon\n ? [\n <span\n className=\"vuuIconContainer\"\n data-icon={iconName}\n key=\"icon\"\n />,\n ].concat(childElement)\n : childElement;\n\n function addClonedChild(\n list: ReactElement[],\n child: ReactElement,\n idx: number,\n withIcon: boolean,\n ) {\n const {\n children,\n className,\n \"data-icon\": iconName,\n id: itemId,\n hasSeparator,\n label,\n ...props\n } = child.props;\n const hasSubMenu = isMenuItemGroup(child);\n const subMenuShowing = hasSubMenu && childMenuShowing === itemId;\n const ariaControls = subMenuShowing ? `${id}-${itemId}` : undefined;\n\n const ariaLabel =\n (label ?? typeof children === \"string\") ? children : undefined;\n\n list.push(\n <MenuItem\n {...props}\n {...propsCommonToAllListItems}\n {...getMenuItemProps(\n itemId,\n idx,\n child.key ?? itemId,\n highlightedIndex,\n appliedFocusVisible,\n className,\n hasSeparator,\n )}\n aria-controls={ariaControls}\n aria-haspopup={hasSubMenu || undefined}\n aria-expanded={subMenuShowing || undefined}\n aria-label={ariaLabel}\n >\n {hasSubMenu\n ? maybeIcon(label ?? children, withIcon, iconName)\n : maybeIcon(children, withIcon, iconName)}\n </MenuItem>,\n );\n // mapIdxToId.set(idx, itemId);\n }\n\n const listItems: ReactElement[] = [];\n\n if (children.length > 0) {\n const withIcon = children.some(hasIcon);\n children.forEach((child, idx) => {\n addClonedChild(listItems, child, idx, withIcon);\n });\n }\n\n return listItems;\n }\n\n return (\n <div\n {...props}\n {...listProps}\n aria-activedescendant={getActiveDescendant()}\n className={cx(classBase, className, {\n [`${classBase}-childMenuShowing`]: childMenuShowing !== undefined,\n })}\n data-root={isRoot || undefined}\n id={id}\n ref={root}\n role=\"menu\"\n >\n {renderContent()}\n </div>\n );\n};\n\nconst getMenuItemProps = (\n itemId: string,\n idx: number,\n key: string,\n highlightedIdx: number,\n focusVisible: number,\n className: string,\n hasSeparator: boolean,\n) => ({\n id: `menuitem-${itemId}`,\n key: key ?? idx,\n \"data-index\": idx,\n className: cx(\"vuuMenuItem\", className, {\n \"vuuMenuItem-separator\": hasSeparator,\n vuuHighlighted: idx === highlightedIdx,\n focusVisible: focusVisible === idx,\n }),\n});\n\nMenuList.displayName = \"MenuList\";\n"],"names":["jsx","useWindow","useComponentCssInjection","menuListCss","useId","useRef","useMemo","useKeyboardNavigation","useLayoutEffect","children","className","props"],"mappings":"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"}
1
+ {"version":3,"file":"MenuList.js","sources":["../../src/menu/MenuList.tsx"],"sourcesContent":["import cx from \"clsx\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport React, {\n FC,\n HTMLAttributes,\n ReactElement,\n ReactNode,\n useLayoutEffect,\n useMemo,\n useRef,\n} from \"react\";\n//TODO do we want this dependency ?\nimport { useId } from \"@vuu-ui/vuu-utils\";\nimport {\n MenuCloseHandler,\n useKeyboardNavigation,\n} from \"./use-keyboard-navigation\";\n\nimport menuListCss from \"./MenuList.css\";\n\nconst classBase = \"vuuMenuList\";\n\nexport const Separator = () => <li className=\"vuuMenuItem-divider\" />;\n\nexport const isMenuItemGroup = (child: ReactElement) =>\n child.type === MenuItemGroup || !!child.props[\"data-group\"];\n\nexport interface MenuItemGroupProps {\n children:\n | ReactElement<MenuItemProps>[]\n | [ReactElement<MenuItemLabelProps>, ...ReactElement<MenuItemProps>[]];\n label?: string;\n}\n\nexport interface MenuItemProps extends HTMLAttributes<HTMLDivElement> {\n action?: string;\n idx?: number;\n options?: unknown;\n}\n\n// Purely used as markers, props will be extracted\nexport const MenuItemGroup: FC<MenuItemGroupProps> = () => null;\n// eslint-disable-next-line no-unused-vars\nexport const MenuItem = ({\n children,\n idx,\n options,\n ...props\n}: MenuItemProps) => {\n return <div {...props}>{children}</div>;\n};\n\nexport interface MenuItemLabelProps {\n children: ReactNode;\n}\nconst MenuItemLabel = ({ children }: { children: ReactNode }) => (\n <>{children}</>\n);\nMenuItemLabel.displayName = \"MenuItemLabel\";\nMenuItem.Label = MenuItemLabel;\n\nconst getDisplayName = (item: ReactNode) =>\n React.isValidElement(item) &&\n typeof item.type !== \"string\" &&\n \"displayName\" in item.type\n ? item.type.displayName\n : undefined;\n\nexport const isMenuItemLabel = (\n item: ReactNode,\n): item is ReactElement<MenuItemLabelProps> =>\n getDisplayName(item) === \"MenuItemLabel\";\n\nconst hasIcon = (child: ReactElement) => child.props[\"data-icon\"];\n\nexport type MenuOpenHandler = (\n menuItemEl: HTMLElement,\n immediate?: boolean,\n) => void;\nexport interface MenuListProps extends HTMLAttributes<HTMLDivElement> {\n activatedByKeyboard?: boolean;\n children: ReactElement[];\n childMenuShowing?: string;\n defaultHighlightedIdx?: number;\n highlightedIdx?: number;\n isRoot?: boolean;\n listItemProps?: Partial<MenuItemProps>;\n onActivate?: (menuId: string) => void;\n onCloseMenu: MenuCloseHandler;\n openMenu?: MenuOpenHandler;\n onHighlightMenuItem?: (idx: number) => void;\n}\n\nexport const MenuList = ({\n activatedByKeyboard,\n childMenuShowing,\n children,\n className,\n defaultHighlightedIdx,\n highlightedIdx: highlightedIdxProp,\n id: idProp,\n isRoot,\n listItemProps,\n onHighlightMenuItem,\n onActivate,\n onCloseMenu,\n openMenu: onOpenMenu,\n ...props\n}: MenuListProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-menu-list\",\n css: menuListCss,\n window: targetWindow,\n });\n\n const id = useId(idProp);\n const root = useRef<HTMLDivElement>(null);\n\n // The id generation be,ongs in useIttemsWithIds\n const mapIdxToId = useMemo(() => new Map(), []);\n\n const handleActivate = (idx: number) => {\n const el = root.current?.querySelector(`:scope > [data-index='${idx}']`);\n el?.id && onActivate?.(el.id);\n };\n\n const { focusVisible, highlightedIndex, listProps } = useKeyboardNavigation({\n count: React.Children.count(children),\n defaultHighlightedIdx,\n highlightedIndex: highlightedIdxProp,\n onActivate: handleActivate,\n onHighlight: onHighlightMenuItem,\n onOpenMenu,\n onCloseMenu,\n });\n\n const appliedFocusVisible = childMenuShowing == undefined ? focusVisible : -1;\n\n useLayoutEffect(() => {\n if (childMenuShowing === undefined && activatedByKeyboard) {\n root.current?.focus();\n }\n }, [activatedByKeyboard, childMenuShowing]);\n\n const getActiveDescendant = () =>\n highlightedIndex === undefined || highlightedIndex === -1\n ? undefined\n : mapIdxToId.get(highlightedIndex);\n\n function renderContent() {\n const propsCommonToAllListItems = {\n ...listItemProps,\n role: \"menuitem\",\n };\n\n const maybeIcon = (\n childElement: ReactElement,\n withIcon: boolean,\n iconName?: string,\n ) =>\n withIcon\n ? [\n <span\n className=\"vuuIconContainer\"\n data-icon={iconName}\n key=\"icon\"\n />,\n ].concat(childElement)\n : childElement;\n\n function addClonedChild(\n list: ReactElement[],\n child: ReactElement,\n idx: number,\n withIcon: boolean,\n ) {\n const {\n children,\n className,\n \"data-icon\": iconName,\n id: itemId,\n hasSeparator,\n label,\n ...props\n } = child.props;\n const hasSubMenu = isMenuItemGroup(child);\n const subMenuShowing = hasSubMenu && childMenuShowing === itemId;\n const ariaControls = subMenuShowing ? `${id}-${itemId}` : undefined;\n\n const ariaLabel =\n (label ?? typeof children === \"string\") ? children : undefined;\n\n list.push(\n <MenuItem\n {...props}\n {...propsCommonToAllListItems}\n {...getMenuItemProps(\n itemId,\n idx,\n child.key ?? itemId,\n highlightedIndex,\n appliedFocusVisible,\n className,\n hasSeparator,\n )}\n aria-controls={ariaControls}\n aria-haspopup={hasSubMenu || undefined}\n aria-expanded={subMenuShowing || undefined}\n aria-label={ariaLabel}\n >\n {hasSubMenu\n ? maybeIcon(label ?? children, withIcon, iconName)\n : maybeIcon(children, withIcon, iconName)}\n </MenuItem>,\n );\n // mapIdxToId.set(idx, itemId);\n }\n\n const listItems: ReactElement[] = [];\n\n if (children.length > 0) {\n const withIcon = children.some(hasIcon);\n children.forEach((child, idx) => {\n addClonedChild(listItems, child, idx, withIcon);\n });\n }\n\n return listItems;\n }\n\n return (\n <div\n {...props}\n {...listProps}\n aria-activedescendant={getActiveDescendant()}\n className={cx(classBase, className, {\n [`${classBase}-childMenuShowing`]: childMenuShowing !== undefined,\n })}\n data-root={isRoot || undefined}\n id={id}\n ref={root}\n role=\"menu\"\n >\n {renderContent()}\n </div>\n );\n};\n\nconst getMenuItemProps = (\n itemId: string,\n idx: number,\n key: string,\n highlightedIdx: number,\n focusVisible: number,\n className: string,\n hasSeparator: boolean,\n) => ({\n id: `menuitem-${itemId}`,\n key: key ?? idx,\n \"data-index\": idx,\n className: cx(\"vuuMenuItem\", className, {\n \"vuuMenuItem-separator\": hasSeparator,\n vuuHighlighted: idx === highlightedIdx,\n focusVisible: focusVisible === idx,\n }),\n});\n\nMenuList.displayName = \"MenuList\";\n"],"names":["jsx","useWindow","useComponentCssInjection","menuListCss","useId","useRef","useMemo","useKeyboardNavigation","useLayoutEffect","children","className","props"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"context-menu-provider.js","sources":["../../src/menu/context-menu-provider.tsx"],"sourcesContent":["import type {\n ContextMenuContextType,\n MenuActionHandler,\n MenuBuilder,\n} from \"@vuu-ui/vuu-data-types\";\nimport { createContext, ReactNode, useCallback, useMemo } from \"react\";\n\nexport const ContextMenuContext = createContext<ContextMenuContextType | null>(\n null,\n);\n\nexport interface ContextMenuConfiguration {\n menuActionHandler?: MenuActionHandler;\n menuBuilder: MenuBuilder;\n}\n\nexport interface ContextMenuProviderProps extends ContextMenuConfiguration {\n children: ReactNode;\n label?: string;\n}\n\ninterface ProviderProps extends ContextMenuProviderProps {\n context: ContextMenuContextType | null;\n}\n\nconst Provider = ({\n children,\n context,\n menuActionHandler,\n menuBuilder,\n}: ProviderProps) => {\n const menuBuilders = useMemo(() => {\n if (context?.menuBuilders && menuBuilder) {\n return context.menuBuilders.concat(menuBuilder);\n } else if (menuBuilder) {\n return [menuBuilder];\n } else {\n return context?.menuBuilders || [];\n }\n }, [context, menuBuilder]);\n\n const handleMenuAction = useCallback(\n (reason) => {\n if (menuActionHandler?.(reason)) {\n return true;\n }\n\n if (context?.menuActionHandler?.(reason)) {\n return true;\n }\n },\n [context, menuActionHandler],\n );\n\n return (\n <ContextMenuContext.Provider\n value={{\n menuActionHandler: handleMenuAction,\n menuBuilders,\n }}\n >\n {children}\n </ContextMenuContext.Provider>\n );\n};\n\n// Need an option for local menu to override higher-level menu, rather than extend\nexport const ContextMenuProvider = ({\n children,\n label,\n menuActionHandler,\n menuBuilder,\n}: ContextMenuProviderProps) => {\n return (\n <ContextMenuContext.Consumer>\n {(parentContext) => (\n <Provider\n context={parentContext}\n label={label}\n menuActionHandler={menuActionHandler}\n menuBuilder={menuBuilder}\n >\n {children}\n </Provider>\n )}\n </ContextMenuContext.Consumer>\n );\n};\n"],"names":["createContext","useMemo","useCallback","jsx"],"mappings":";;;;;AAOO,MAAM,kBAAqB,GAAAA,mBAAA;AAAA,EAChC,IAAA;AACF,EAAA;AAgBA,MAAM,WAAW,CAAC;AAAA,EAChB,QAAA;AAAA,EACA,OAAA;AAAA,EACA,iBAAA;AAAA,EACA,WAAA;AACF,CAAqB,KAAA;AACnB,EAAM,MAAA,YAAA,GAAeC,cAAQ,MAAM;AACjC,IAAI,IAAA,OAAA,EAAS,gBAAgB,WAAa,EAAA;AACxC,MAAO,OAAA,OAAA,CAAQ,YAAa,CAAA,MAAA,CAAO,WAAW,CAAA,CAAA;AAAA,eACrC,WAAa,EAAA;AACtB,MAAA,OAAO,CAAC,WAAW,CAAA,CAAA;AAAA,KACd,MAAA;AACL,MAAO,OAAA,OAAA,EAAS,gBAAgB,EAAC,CAAA;AAAA,KACnC;AAAA,GACC,EAAA,CAAC,OAAS,EAAA,WAAW,CAAC,CAAA,CAAA;AAEzB,EAAA,MAAM,gBAAmB,GAAAC,iBAAA;AAAA,IACvB,CAAC,MAAW,KAAA;AACV,MAAI,IAAA,iBAAA,GAAoB,MAAM,CAAG,EAAA;AAC/B,QAAO,OAAA,IAAA,CAAA;AAAA,OACT;AAEA,MAAI,IAAA,OAAA,EAAS,iBAAoB,GAAA,MAAM,CAAG,EAAA;AACxC,QAAO,OAAA,IAAA,CAAA;AAAA,OACT;AAAA,KACF;AAAA,IACA,CAAC,SAAS,iBAAiB,CAAA;AAAA,GAC7B,CAAA;AAEA,EACE,uBAAAC,cAAA;AAAA,IAAC,kBAAmB,CAAA,QAAA;AAAA,IAAnB;AAAA,MACC,KAAO,EAAA;AAAA,QACL,iBAAmB,EAAA,gBAAA;AAAA,QACnB,YAAA;AAAA,OACF;AAAA,MAEC,QAAA;AAAA,KAAA;AAAA,GACH,CAAA;AAEJ,CAAA,CAAA;AAGO,MAAM,sBAAsB,CAAC;AAAA,EAClC,QAAA;AAAA,EACA,KAAA;AAAA,EACA,iBAAA;AAAA,EACA,WAAA;AACF,CAAgC,KAAA;AAC9B,EAAA,uBACGA,cAAA,CAAA,kBAAA,CAAmB,QAAnB,EAAA,EACE,WAAC,aACA,qBAAAA,cAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,OAAS,EAAA,aAAA;AAAA,MACT,KAAA;AAAA,MACA,iBAAA;AAAA,MACA,WAAA;AAAA,MAEC,QAAA;AAAA,KAAA;AAAA,GAGP,EAAA,CAAA,CAAA;AAEJ;;;;;"}
1
+ {"version":3,"file":"context-menu-provider.js","sources":["../../src/menu/context-menu-provider.tsx"],"sourcesContent":["import type {\n ContextMenuContextType,\n MenuActionHandler,\n MenuBuilder,\n} from \"@vuu-ui/vuu-data-types\";\nimport { createContext, ReactNode, useCallback, useMemo } from \"react\";\n\nexport const ContextMenuContext = createContext<ContextMenuContextType | null>(\n null,\n);\n\nexport interface ContextMenuConfiguration {\n menuActionHandler?: MenuActionHandler;\n menuBuilder: MenuBuilder;\n}\n\nexport interface ContextMenuProviderProps extends ContextMenuConfiguration {\n children: ReactNode;\n label?: string;\n}\n\ninterface ProviderProps extends ContextMenuProviderProps {\n context: ContextMenuContextType | null;\n}\n\nconst Provider = ({\n children,\n context,\n menuActionHandler,\n menuBuilder,\n}: ProviderProps) => {\n const menuBuilders = useMemo(() => {\n if (context?.menuBuilders && menuBuilder) {\n return context.menuBuilders.concat(menuBuilder);\n } else if (menuBuilder) {\n return [menuBuilder];\n } else {\n return context?.menuBuilders || [];\n }\n }, [context, menuBuilder]);\n\n const handleMenuAction = useCallback<MenuActionHandler>(\n (reason) => {\n if (menuActionHandler?.(reason)) {\n return true;\n }\n\n if (context?.menuActionHandler?.(reason)) {\n return true;\n }\n },\n [context, menuActionHandler],\n );\n\n return (\n <ContextMenuContext.Provider\n value={{\n menuActionHandler: handleMenuAction,\n menuBuilders,\n }}\n >\n {children}\n </ContextMenuContext.Provider>\n );\n};\n\n// Need an option for local menu to override higher-level menu, rather than extend\nexport const ContextMenuProvider = ({\n children,\n label,\n menuActionHandler,\n menuBuilder,\n}: ContextMenuProviderProps) => {\n return (\n <ContextMenuContext.Consumer>\n {(parentContext) => (\n <Provider\n context={parentContext}\n label={label}\n menuActionHandler={menuActionHandler}\n menuBuilder={menuBuilder}\n >\n {children}\n </Provider>\n )}\n </ContextMenuContext.Consumer>\n );\n};\n"],"names":["createContext","useMemo","useCallback","jsx"],"mappings":";;;;;AAOO,MAAM,kBAAqB,GAAAA,mBAAA;AAAA,EAChC;AACF;AAgBA,MAAM,WAAW,CAAC;AAAA,EAChB,QAAA;AAAA,EACA,OAAA;AAAA,EACA,iBAAA;AAAA,EACA;AACF,CAAqB,KAAA;AACnB,EAAM,MAAA,YAAA,GAAeC,cAAQ,MAAM;AACjC,IAAI,IAAA,OAAA,EAAS,gBAAgB,WAAa,EAAA;AACxC,MAAO,OAAA,OAAA,CAAQ,YAAa,CAAA,MAAA,CAAO,WAAW,CAAA;AAAA,eACrC,WAAa,EAAA;AACtB,MAAA,OAAO,CAAC,WAAW,CAAA;AAAA,KACd,MAAA;AACL,MAAO,OAAA,OAAA,EAAS,gBAAgB,EAAC;AAAA;AACnC,GACC,EAAA,CAAC,OAAS,EAAA,WAAW,CAAC,CAAA;AAEzB,EAAA,MAAM,gBAAmB,GAAAC,iBAAA;AAAA,IACvB,CAAC,MAAW,KAAA;AACV,MAAI,IAAA,iBAAA,GAAoB,MAAM,CAAG,EAAA;AAC/B,QAAO,OAAA,IAAA;AAAA;AAGT,MAAI,IAAA,OAAA,EAAS,iBAAoB,GAAA,MAAM,CAAG,EAAA;AACxC,QAAO,OAAA,IAAA;AAAA;AACT,KACF;AAAA,IACA,CAAC,SAAS,iBAAiB;AAAA,GAC7B;AAEA,EACE,uBAAAC,cAAA;AAAA,IAAC,kBAAmB,CAAA,QAAA;AAAA,IAAnB;AAAA,MACC,KAAO,EAAA;AAAA,QACL,iBAAmB,EAAA,gBAAA;AAAA,QACnB;AAAA,OACF;AAAA,MAEC;AAAA;AAAA,GACH;AAEJ,CAAA;AAGO,MAAM,sBAAsB,CAAC;AAAA,EAClC,QAAA;AAAA,EACA,KAAA;AAAA,EACA,iBAAA;AAAA,EACA;AACF,CAAgC,KAAA;AAC9B,EAAA,uBACGA,cAAA,CAAA,kBAAA,CAAmB,QAAnB,EAAA,EACE,WAAC,aACA,qBAAAA,cAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,OAAS,EAAA,aAAA;AAAA,MACT,KAAA;AAAA,MACA,iBAAA;AAAA,MACA,WAAA;AAAA,MAEC;AAAA;AAAA,GAGP,EAAA,CAAA;AAEJ;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"key-code.js","sources":["../../src/menu/key-code.ts"],"sourcesContent":["function union(set1: Set<string>, ...sets: Set<string>[]) {\n const result = new Set(set1);\n for (const set of sets) {\n for (const element of set) {\n result.add(element);\n }\n }\n return result;\n}\n\nexport const ArrowUp = \"ArrowUp\";\nexport const ArrowDown = \"ArrowDown\";\nexport const ArrowLeft = \"ArrowLeft\";\nexport const Backspace = \"Backspace\";\nexport const ArrowRight = \"ArrowRight\";\nexport const Enter = \"Enter\";\nexport const Escape = \"Escape\";\nexport const Delete = \"Delete\";\n\nconst actionKeys = new Set([Enter, Delete]);\nconst focusKeys = new Set([\"Tab\"]);\n// const navigationKeys = new Set([\"Home\", \"End\", \"ArrowRight\", \"ArrowLeft\",\"ArrowDown\", \"ArrowUp\"]);\nconst arrowLeftRightKeys = new Set([\"ArrowRight\", \"ArrowLeft\"]);\nconst verticalNavigationKeys = new Set([\"Home\", \"End\", \"ArrowDown\", \"ArrowUp\"]);\nconst horizontalNavigationKeys = new Set([\n \"Home\",\n \"End\",\n \"ArrowRight\",\n \"ArrowLeft\",\n]);\nconst functionKeys = new Set([\n \"F1\",\n \"F2\",\n \"F3\",\n \"F4\",\n \"F5\",\n \"F6\",\n \"F7\",\n \"F8\",\n \"F9\",\n \"F10\",\n \"F11\",\n \"F12\",\n]);\nconst specialKeys = union(\n actionKeys,\n horizontalNavigationKeys,\n verticalNavigationKeys,\n arrowLeftRightKeys,\n functionKeys,\n focusKeys\n);\nexport const isCharacterKey = (evt: KeyboardEvent) => {\n if (specialKeys.has(evt.key)) {\n return false;\n }\n if (typeof evt.which === \"number\" && evt.which > 0) {\n return !evt.ctrlKey && !evt.metaKey && !evt.altKey && evt.which !== 8;\n }\n};\n\nexport const isNavigationKey = (\n { key }: { key: string },\n orientation = \"vertical\"\n) => {\n const navigationKeys =\n orientation === \"vertical\"\n ? verticalNavigationKeys\n : horizontalNavigationKeys;\n return navigationKeys.has(key);\n};\n"],"names":[],"mappings":";;AAAA,SAAS,KAAA,CAAM,SAAsB,IAAqB,EAAA;AACxD,EAAM,MAAA,MAAA,GAAS,IAAI,GAAA,CAAI,IAAI,CAAA,CAAA;AAC3B,EAAA,KAAA,MAAW,OAAO,IAAM,EAAA;AACtB,IAAA,KAAA,MAAW,WAAW,GAAK,EAAA;AACzB,MAAA,MAAA,CAAO,IAAI,OAAO,CAAA,CAAA;AAAA,KACpB;AAAA,GACF;AACA,EAAO,OAAA,MAAA,CAAA;AACT,CAAA;AAOO,MAAM,KAAQ,GAAA,QAAA;AAEd,MAAM,MAAS,GAAA,SAAA;AAEtB,MAAM,6BAAiB,IAAA,GAAA,CAAI,CAAC,KAAA,EAAO,MAAM,CAAC,CAAA,CAAA;AAC1C,MAAM,SAAY,mBAAA,IAAI,GAAI,CAAA,CAAC,KAAK,CAAC,CAAA,CAAA;AAEjC,MAAM,qCAAyB,IAAA,GAAA,CAAI,CAAC,YAAA,EAAc,WAAW,CAAC,CAAA,CAAA;AAC9D,MAAM,sBAAA,uBAA6B,GAAI,CAAA,CAAC,QAAQ,KAAO,EAAA,WAAA,EAAa,SAAS,CAAC,CAAA,CAAA;AAC9E,MAAM,wBAAA,uBAA+B,GAAI,CAAA;AAAA,EACvC,MAAA;AAAA,EACA,KAAA;AAAA,EACA,YAAA;AAAA,EACA,WAAA;AACF,CAAC,CAAA,CAAA;AACD,MAAM,YAAA,uBAAmB,GAAI,CAAA;AAAA,EAC3B,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AACF,CAAC,CAAA,CAAA;AACmB,KAAA;AAAA,EAClB,UAAA;AAAA,EACA,wBAAA;AAAA,EACA,sBAAA;AAAA,EACA,kBAAA;AAAA,EACA,YAAA;AAAA,EACA,SAAA;AACF,EAAA;AAUO,MAAM,kBAAkB,CAC7B,EAAE,GAAI,EAAA,EACN,cAAc,UACX,KAAA;AACH,EAAM,MAAA,cAAA,GACJ,WAAgB,KAAA,UAAA,GACZ,sBACA,GAAA,wBAAA,CAAA;AACN,EAAO,OAAA,cAAA,CAAe,IAAI,GAAG,CAAA,CAAA;AAC/B;;;;;;"}
1
+ {"version":3,"file":"key-code.js","sources":["../../src/menu/key-code.ts"],"sourcesContent":["function union(set1: Set<string>, ...sets: Set<string>[]) {\n const result = new Set(set1);\n for (const set of sets) {\n for (const element of set) {\n result.add(element);\n }\n }\n return result;\n}\n\nexport const ArrowUp = \"ArrowUp\";\nexport const ArrowDown = \"ArrowDown\";\nexport const ArrowLeft = \"ArrowLeft\";\nexport const Backspace = \"Backspace\";\nexport const ArrowRight = \"ArrowRight\";\nexport const Enter = \"Enter\";\nexport const Escape = \"Escape\";\nexport const Delete = \"Delete\";\n\nconst actionKeys = new Set([Enter, Delete]);\nconst focusKeys = new Set([\"Tab\"]);\n// const navigationKeys = new Set([\"Home\", \"End\", \"ArrowRight\", \"ArrowLeft\",\"ArrowDown\", \"ArrowUp\"]);\nconst arrowLeftRightKeys = new Set([\"ArrowRight\", \"ArrowLeft\"]);\nconst verticalNavigationKeys = new Set([\"Home\", \"End\", \"ArrowDown\", \"ArrowUp\"]);\nconst horizontalNavigationKeys = new Set([\n \"Home\",\n \"End\",\n \"ArrowRight\",\n \"ArrowLeft\",\n]);\nconst functionKeys = new Set([\n \"F1\",\n \"F2\",\n \"F3\",\n \"F4\",\n \"F5\",\n \"F6\",\n \"F7\",\n \"F8\",\n \"F9\",\n \"F10\",\n \"F11\",\n \"F12\",\n]);\nconst specialKeys = union(\n actionKeys,\n horizontalNavigationKeys,\n verticalNavigationKeys,\n arrowLeftRightKeys,\n functionKeys,\n focusKeys\n);\nexport const isCharacterKey = (evt: KeyboardEvent) => {\n if (specialKeys.has(evt.key)) {\n return false;\n }\n if (typeof evt.which === \"number\" && evt.which > 0) {\n return !evt.ctrlKey && !evt.metaKey && !evt.altKey && evt.which !== 8;\n }\n};\n\nexport const isNavigationKey = (\n { key }: { key: string },\n orientation = \"vertical\"\n) => {\n const navigationKeys =\n orientation === \"vertical\"\n ? verticalNavigationKeys\n : horizontalNavigationKeys;\n return navigationKeys.has(key);\n};\n"],"names":[],"mappings":";;AAAA,SAAS,KAAA,CAAM,SAAsB,IAAqB,EAAA;AACxD,EAAM,MAAA,MAAA,GAAS,IAAI,GAAA,CAAI,IAAI,CAAA;AAC3B,EAAA,KAAA,MAAW,OAAO,IAAM,EAAA;AACtB,IAAA,KAAA,MAAW,WAAW,GAAK,EAAA;AACzB,MAAA,MAAA,CAAO,IAAI,OAAO,CAAA;AAAA;AACpB;AAEF,EAAO,OAAA,MAAA;AACT;AAOO,MAAM,KAAQ,GAAA;AAEd,MAAM,MAAS,GAAA;AAEtB,MAAM,6BAAiB,IAAA,GAAA,CAAI,CAAC,KAAA,EAAO,MAAM,CAAC,CAAA;AAC1C,MAAM,SAAY,mBAAA,IAAI,GAAI,CAAA,CAAC,KAAK,CAAC,CAAA;AAEjC,MAAM,qCAAyB,IAAA,GAAA,CAAI,CAAC,YAAA,EAAc,WAAW,CAAC,CAAA;AAC9D,MAAM,sBAAA,uBAA6B,GAAI,CAAA,CAAC,QAAQ,KAAO,EAAA,WAAA,EAAa,SAAS,CAAC,CAAA;AAC9E,MAAM,wBAAA,uBAA+B,GAAI,CAAA;AAAA,EACvC,MAAA;AAAA,EACA,KAAA;AAAA,EACA,YAAA;AAAA,EACA;AACF,CAAC,CAAA;AACD,MAAM,YAAA,uBAAmB,GAAI,CAAA;AAAA,EAC3B,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA;AACF,CAAC,CAAA;AACmB,KAAA;AAAA,EAClB,UAAA;AAAA,EACA,wBAAA;AAAA,EACA,sBAAA;AAAA,EACA,kBAAA;AAAA,EACA,YAAA;AAAA,EACA;AACF;AAUO,MAAM,kBAAkB,CAC7B,EAAE,GAAI,EAAA,EACN,cAAc,UACX,KAAA;AACH,EAAM,MAAA,cAAA,GACJ,WAAgB,KAAA,UAAA,GACZ,sBACA,GAAA,wBAAA;AACN,EAAO,OAAA,cAAA,CAAe,IAAI,GAAG,CAAA;AAC/B;;;;;;"}
@@ -88,14 +88,16 @@ const useCascade = ({
88
88
  setOpenMenus([{ id: rootId, left: posX, top: posY }]);
89
89
  } else {
90
90
  menuState.current[hostMenuId] = "popup-open";
91
- const el = document.getElementById(itemId);
92
- if (el !== null) {
93
- const { left, top } = getPosition(el, openMenus.current);
94
- setOpenMenus(
95
- openMenus.current.concat({ id: targetMenuId, left, top })
96
- );
97
- } else {
98
- throw Error(`openMenu no menuItem ${itemId}`);
91
+ if (itemId) {
92
+ const el = document.getElementById(itemId);
93
+ if (el !== null) {
94
+ const { left, top } = getPosition(el, openMenus.current);
95
+ setOpenMenus(
96
+ openMenus.current.concat({ id: targetMenuId, left, top })
97
+ );
98
+ } else {
99
+ throw Error(`openMenu no menuItem ${itemId}`);
100
+ }
99
101
  }
100
102
  }
101
103
  },
@@ -1 +1 @@
1
- {"version":3,"file":"use-cascade.js","sources":["../../src/menu/use-cascade.ts"],"sourcesContent":["import {\n MouseEvent,\n SyntheticEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { closestListItem } from \"./list-dom-utils\";\nimport { MenuItemProps, MenuOpenHandler } from \"./MenuList\";\n// import {mousePosition} from './aim/utils';\n// import {aiming} from './aim/aim';\n\nconst nudge = (\n menus: RuntimeMenuDescriptor[],\n distance: number,\n pos: \"left\" | \"top\"\n) => {\n return menus.map((m, i) =>\n i === menus.length - 1\n ? {\n ...m,\n [pos]: m[pos] - distance,\n }\n : m\n );\n};\nconst nudgeLeft = (menus: RuntimeMenuDescriptor[], distance: number) =>\n nudge(menus, distance, \"left\");\nconst nudgeUp = (menus: RuntimeMenuDescriptor[], distance: number) =>\n nudge(menus, distance, \"top\");\n\nconst flipSides = (id: string, menus: RuntimeMenuDescriptor[]) => {\n const [parentMenu, menu] = menus.slice(-2);\n const el = document.getElementById(`${id}-${menu.id}`);\n if (el === null) {\n throw Error(`useCascade.flipSides element with id ${menu.id} not found`);\n }\n const { width } = el.getBoundingClientRect();\n return menus.map((m) =>\n m === menu\n ? {\n ...m,\n left: parentMenu.left - (width - 2),\n }\n : m\n );\n};\n\n// const closedNode = (el: HTMLElement) =>\n// el.ariaHasPopup === \"true\" && el.ariaExpanded !== \"true\";\nconst getPosition = (el: HTMLElement, openMenus: RuntimeMenuDescriptor[]) => {\n const [{ left, top: menuTop }] = openMenus.slice(-1);\n // const {top, right, bottom, left} = el.getBoundingClientRect();\n // this will not work for MenuList within window, we need the\n // const {offsetLeft: left, offsetTop: menuTop} = el.closest('.vuuMenuList');\n const { offsetWidth: width, offsetTop: top } = el;\n return { left: left + width, top: top + menuTop };\n};\n\nexport type RuntimeMenuDescriptor = {\n id: string;\n left: number;\n top: number;\n};\n\n/** menuitem-vuu-1-0 vuu-1 */\nexport const getHostMenuId = (id: string, rootId: string) => {\n const pos = id.lastIndexOf(\"-\");\n if (id.startsWith(\"menuitem\")) {\n return pos > -1 ? id.slice(9, pos) : rootId;\n } else {\n return pos > -1 ? id.slice(0, pos) : rootId;\n }\n};\n\nconst getTargetMenuId = (id: string) => id.slice(9);\n\nconst getMenuItemDetails = (\n { ariaExpanded, ariaHasPopup, id }: HTMLElement,\n rootId: string\n) => {\n if (id.startsWith(\"menuitem\")) {\n return {\n hostMenuId: getHostMenuId(id, rootId),\n targetMenuId: getTargetMenuId(id),\n menuItemId: id,\n isGroup: ariaHasPopup === \"true\",\n isOpen: ariaExpanded === \"true\",\n };\n } else {\n throw Error(`getMenuItemDetails #${id} is not a menuitem`);\n }\n};\n\nexport interface CascadeHookProps {\n id: string;\n onActivate: (menuId: string) => void;\n onMouseEnterItem: (evt: MouseEvent, itemId: string) => void;\n position: { x: number; y: number };\n}\n\nexport interface CascadeHooksResult {\n closeMenu: () => void;\n handleRender: () => void;\n listItemProps: Partial<MenuItemProps>;\n openMenu: MenuOpenHandler;\n openMenus: RuntimeMenuDescriptor[];\n}\n\ntype MenuStatus = \"no-popup\" | \"popup-open\" | \"pending-close\" | \"popup-pending\";\ntype MenuState = { [key: string]: MenuStatus };\n\nexport const useCascade = ({\n id: rootId,\n onActivate,\n onMouseEnterItem,\n position: { x: posX, y: posY },\n}: CascadeHookProps): CascadeHooksResult => {\n const [, forceRefresh] = useState({});\n const openMenus = useRef<RuntimeMenuDescriptor[]>([\n { id: rootId, left: posX, top: posY },\n ]);\n\n const menuIsOpen = useCallback(\n (menuId: string) =>\n openMenus.current.findIndex((menu) => menu.id === menuId) !== -1,\n []\n );\n\n const getOpenMenuStatus = useCallback((menuId: string) => {\n const state = menuState.current[menuId];\n if (state === undefined) {\n throw Error(`getOpenMenuState no entry for menu ${menuId}`);\n }\n return state;\n }, []);\n\n const setOpenMenus = useCallback((menus: RuntimeMenuDescriptor[]) => {\n openMenus.current = menus;\n forceRefresh({});\n }, []);\n\n const menuOpenPendingTimeout = useRef<number | undefined>();\n const menuClosePendingTimeout = useRef<number | undefined>();\n const menuState = useRef<MenuState>({ [rootId]: \"no-popup\" });\n // const prevLevel = useRef(0);\n\n // const prevAim = useRef({mousePos: null, distance: true});\n\n const openMenu = useCallback(\n (hostMenuId = rootId, targetMenuId: string, itemId = null) => {\n if (hostMenuId === rootId && itemId === null) {\n setOpenMenus([{ id: rootId, left: posX, top: posY }]);\n } else {\n menuState.current[hostMenuId] = \"popup-open\";\n const el = document.getElementById(itemId) as HTMLElement;\n if (el !== null) {\n const { left, top } = getPosition(el, openMenus.current);\n setOpenMenus(\n openMenus.current.concat({ id: targetMenuId, left, top })\n );\n } else {\n throw Error(`openMenu no menuItem ${itemId}`);\n }\n }\n },\n [rootId, posX, posY, setOpenMenus]\n );\n\n const closeMenu = useCallback(\n (menuId?: string) => {\n if (menuId === rootId) {\n setOpenMenus([]);\n } else {\n const menus = openMenus.current.slice();\n const lastMenu = menus.pop() as RuntimeMenuDescriptor;\n menuState.current[lastMenu.id] = \"no-popup\";\n const parentMenu = menus.at(-1);\n if (parentMenu) {\n menuState.current[parentMenu.id] = \"no-popup\";\n }\n setOpenMenus(menus);\n }\n },\n [rootId, setOpenMenus]\n );\n\n const closeMenus = useCallback(\n (menuItemId) => {\n const menus = openMenus.current.slice();\n const menuItemMenuId = menuItemId.slice(9);\n let { id: lastMenuId } = menus.at(-1) as RuntimeMenuDescriptor;\n while (menus.length > 1 && !menuItemMenuId.startsWith(lastMenuId)) {\n const parentMenuId = getHostMenuId(lastMenuId, rootId);\n menus.pop();\n menuState.current[lastMenuId] = \"no-popup\";\n menuState.current[parentMenuId] = \"no-popup\";\n ({ id: lastMenuId } = menus[menus.length - 1]);\n }\n if (menus.length < openMenus.current.length) {\n setOpenMenus(menus);\n }\n },\n [rootId, setOpenMenus]\n );\n\n const clearAnyScheduledOpenTasks = useCallback(() => {\n if (menuOpenPendingTimeout.current) {\n clearTimeout(menuOpenPendingTimeout.current);\n menuOpenPendingTimeout.current = undefined;\n }\n }, []);\n\n const scheduleOpen = useCallback(\n (\n hostMenuId: string,\n targetMenuId: string,\n menuItemId: string,\n delay = 300\n ) => {\n clearAnyScheduledOpenTasks();\n // do we need to set target state to pending-open ?s\n\n menuOpenPendingTimeout.current = window.setTimeout(() => {\n // console.log(\n // `scheduleOpen<timeout> opening menu ${targetMenuId} from menu ${hostMenuId} via menuitem ${menuItemId}`\n // );\n closeMenus(menuItemId);\n menuState.current[hostMenuId] = \"popup-open\";\n menuState.current[targetMenuId] = \"no-popup\";\n openMenu(hostMenuId, targetMenuId, menuItemId);\n }, delay);\n },\n [clearAnyScheduledOpenTasks, closeMenus, openMenu]\n );\n\n const scheduleClose = useCallback(\n (hostMenuId: string, openMenuId: string, itemId: string) => {\n // console.log(\n // `scheduleClose openMenuId ${openMenuId} from parent menu ${hostMenuId} itemId ${itemId}`\n // );\n menuState.current[openMenuId] = \"pending-close\";\n menuClosePendingTimeout.current = window.setTimeout(() => {\n // console.log(`call closeMenus from scheduleClose`);\n closeMenus(itemId);\n }, 400);\n },\n [closeMenus]\n );\n\n const handleRender = useCallback(() => {\n const { current: menus } = openMenus;\n const menu = menus.at(-1);\n const el = menu ? document.getElementById(menu.id) : undefined;\n if (el) {\n const { right, bottom } = el.getBoundingClientRect();\n const { clientHeight, clientWidth } = document.body;\n if (right > clientWidth) {\n const newMenus =\n menus.length > 1\n ? flipSides(rootId, menus)\n : nudgeLeft(menus, right - clientWidth);\n setOpenMenus(newMenus);\n } else if (bottom > clientHeight) {\n const newMenus = nudgeUp(menus, bottom - clientHeight);\n setOpenMenus(newMenus);\n }\n\n if (typeof el.tabIndex === \"number\") {\n el.focus();\n }\n }\n }, [rootId, setOpenMenus]);\n\n // TODO introduce a delay parameter that allows click to requeat an immediate render\n const triggerChildMenu = useCallback<MenuOpenHandler>(\n (menuItemEl, immediate = false) => {\n const { hostMenuId, targetMenuId, menuItemId, isGroup, isOpen } =\n getMenuItemDetails(menuItemEl, rootId);\n const {\n current: { [hostMenuId]: state },\n } = menuState;\n\n const delay = immediate ? 0 : undefined;\n\n // console.log(\n // `%ctriggerChildMenu\n // rootId ${rootId}\n // menuItem ${menuItemId}\n // host menu: ${hostMenuId}\n // target menu: ${targetMenuId}\n // item index: ${menuItemId}\n // state ${state}\n // isGroup ${isGroup} isOpen ${isOpen}\n // openMenus: ${JSON.stringify(openMenus.current)}\n // full state='${JSON.stringify(menuState.current)}`,\n // \"color: green; font-weight: bold;\"\n // );\n\n if (state === \"no-popup\" && isGroup) {\n menuState.current[hostMenuId] = \"popup-pending\";\n scheduleOpen(hostMenuId, targetMenuId, menuItemId, delay);\n } else if (state === \"popup-pending\" && !isGroup) {\n menuState.current[hostMenuId] = \"no-popup\";\n clearTimeout(menuOpenPendingTimeout.current);\n menuOpenPendingTimeout.current = undefined;\n } else if (state === \"popup-pending\" && isGroup) {\n clearTimeout(menuOpenPendingTimeout.current);\n scheduleOpen(hostMenuId, targetMenuId, menuItemId, delay);\n } else if (state === \"popup-open\") {\n if (menuIsOpen(targetMenuId)) {\n const menuStatus = getOpenMenuStatus(targetMenuId);\n // Close any child menus of the target menu. This can happen if we have\n // opened child menus, then moused out of the menu entirely, to re-enter\n // at a higher level\n closeMenus(menuItemId);\n\n switch (menuStatus) {\n case \"pending-close\":\n // cancel the close\n clearTimeout(menuClosePendingTimeout.current);\n menuClosePendingTimeout.current = undefined;\n menuState.current[targetMenuId] = \"no-popup\";\n clearAnyScheduledOpenTasks();\n break;\n default:\n }\n } else {\n // TODO review the below, suspectb it's over complicating things\n const [parentOfLastOpenedMenu, lastOpenedMenu] =\n openMenus.current.slice(-2);\n if (\n parentOfLastOpenedMenu.id === hostMenuId &&\n menuState.current[lastOpenedMenu.id] !== \"pending-close\" /*&&\n sameLevel*/\n ) {\n scheduleClose(hostMenuId, lastOpenedMenu.id, menuItemId);\n if (isGroup && !isOpen) {\n scheduleOpen(hostMenuId, targetMenuId, menuItemId, delay);\n }\n } else if (\n parentOfLastOpenedMenu.id === hostMenuId &&\n isGroup &&\n menuItemId !== lastOpenedMenu.id &&\n menuState.current[lastOpenedMenu.id] === \"pending-close\"\n ) {\n // if there is already an item queued for opening cancel it\n scheduleOpen(hostMenuId, targetMenuId, menuItemId, delay);\n } else if (isGroup) {\n // closeMenus(menuId, itemId);\n scheduleOpen(hostMenuId, targetMenuId, menuItemId, delay);\n } else if (\n !(\n (menuState.current[lastOpenedMenu.id] === \"pending-close\") /*&&\n sameLevel*/\n )\n ) {\n closeMenus(menuItemId);\n }\n }\n }\n\n if (state === \"pending-close\") {\n clearAnyScheduledOpenTasks();\n clearTimeout(menuClosePendingTimeout.current);\n menuClosePendingTimeout.current = undefined;\n menuState.current[hostMenuId] = \"popup-open\";\n }\n },\n [\n clearAnyScheduledOpenTasks,\n closeMenus,\n getOpenMenuStatus,\n menuIsOpen,\n rootId,\n scheduleClose,\n scheduleOpen,\n ]\n );\n\n const listItemProps: Partial<MenuItemProps> = useMemo(\n () => ({\n onMouseEnter: (evt: MouseEvent) => {\n const menuItemEl = closestListItem(evt.target as HTMLElement);\n triggerChildMenu(menuItemEl);\n onMouseEnterItem(evt, menuItemEl.id);\n },\n\n onClick: (evt: SyntheticEvent) => {\n const listItemEl = closestListItem(evt.target as HTMLElement);\n const { isGroup, menuItemId } = getMenuItemDetails(listItemEl, rootId);\n if (isGroup) {\n triggerChildMenu(listItemEl);\n } else {\n onActivate(menuItemId);\n }\n },\n }),\n [onActivate, onMouseEnterItem, rootId, triggerChildMenu]\n );\n\n return {\n closeMenu,\n handleRender,\n listItemProps,\n openMenu: triggerChildMenu,\n openMenus: openMenus.current,\n };\n};\n"],"names":["useState","useRef","useCallback","useMemo","closestListItem"],"mappings":"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"}
1
+ {"version":3,"file":"use-cascade.js","sources":["../../src/menu/use-cascade.ts"],"sourcesContent":["import {\n MouseEvent,\n SyntheticEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { closestListItem } from \"./list-dom-utils\";\nimport { MenuItemProps, MenuOpenHandler } from \"./MenuList\";\n// import {mousePosition} from './aim/utils';\n// import {aiming} from './aim/aim';\n\nconst nudge = (\n menus: RuntimeMenuDescriptor[],\n distance: number,\n pos: \"left\" | \"top\",\n) => {\n return menus.map((m, i) =>\n i === menus.length - 1\n ? {\n ...m,\n [pos]: m[pos] - distance,\n }\n : m,\n );\n};\nconst nudgeLeft = (menus: RuntimeMenuDescriptor[], distance: number) =>\n nudge(menus, distance, \"left\");\nconst nudgeUp = (menus: RuntimeMenuDescriptor[], distance: number) =>\n nudge(menus, distance, \"top\");\n\nconst flipSides = (id: string, menus: RuntimeMenuDescriptor[]) => {\n const [parentMenu, menu] = menus.slice(-2);\n const el = document.getElementById(`${id}-${menu.id}`);\n if (el === null) {\n throw Error(`useCascade.flipSides element with id ${menu.id} not found`);\n }\n const { width } = el.getBoundingClientRect();\n return menus.map((m) =>\n m === menu\n ? {\n ...m,\n left: parentMenu.left - (width - 2),\n }\n : m,\n );\n};\n\n// const closedNode = (el: HTMLElement) =>\n// el.ariaHasPopup === \"true\" && el.ariaExpanded !== \"true\";\nconst getPosition = (el: HTMLElement, openMenus: RuntimeMenuDescriptor[]) => {\n const [{ left, top: menuTop }] = openMenus.slice(-1);\n // const {top, right, bottom, left} = el.getBoundingClientRect();\n // this will not work for MenuList within window, we need the\n // const {offsetLeft: left, offsetTop: menuTop} = el.closest('.vuuMenuList');\n const { offsetWidth: width, offsetTop: top } = el;\n return { left: left + width, top: top + menuTop };\n};\n\nexport type RuntimeMenuDescriptor = {\n id: string;\n left: number;\n top: number;\n};\n\n/** menuitem-vuu-1-0 vuu-1 */\nexport const getHostMenuId = (id: string, rootId: string) => {\n const pos = id.lastIndexOf(\"-\");\n if (id.startsWith(\"menuitem\")) {\n return pos > -1 ? id.slice(9, pos) : rootId;\n } else {\n return pos > -1 ? id.slice(0, pos) : rootId;\n }\n};\n\nconst getTargetMenuId = (id: string) => id.slice(9);\n\nconst getMenuItemDetails = (\n { ariaExpanded, ariaHasPopup, id }: HTMLElement,\n rootId: string,\n) => {\n if (id.startsWith(\"menuitem\")) {\n return {\n hostMenuId: getHostMenuId(id, rootId),\n targetMenuId: getTargetMenuId(id),\n menuItemId: id,\n isGroup: ariaHasPopup === \"true\",\n isOpen: ariaExpanded === \"true\",\n };\n } else {\n throw Error(`getMenuItemDetails #${id} is not a menuitem`);\n }\n};\n\nexport interface CascadeHookProps {\n id: string;\n onActivate: (menuId: string) => void;\n onMouseEnterItem: (evt: MouseEvent, itemId: string) => void;\n position: { x: number; y: number };\n}\n\nexport interface CascadeHooksResult {\n closeMenu: () => void;\n handleRender: () => void;\n listItemProps: Partial<MenuItemProps>;\n openMenu: MenuOpenHandler;\n openMenus: RuntimeMenuDescriptor[];\n}\n\ntype MenuStatus = \"no-popup\" | \"popup-open\" | \"pending-close\" | \"popup-pending\";\ntype MenuState = { [key: string]: MenuStatus };\n\nexport const useCascade = ({\n id: rootId,\n onActivate,\n onMouseEnterItem,\n position: { x: posX, y: posY },\n}: CascadeHookProps): CascadeHooksResult => {\n const [, forceRefresh] = useState({});\n const openMenus = useRef<RuntimeMenuDescriptor[]>([\n { id: rootId, left: posX, top: posY },\n ]);\n\n const menuIsOpen = useCallback(\n (menuId: string) =>\n openMenus.current.findIndex((menu) => menu.id === menuId) !== -1,\n [],\n );\n\n const getOpenMenuStatus = useCallback((menuId: string) => {\n const state = menuState.current[menuId];\n if (state === undefined) {\n throw Error(`getOpenMenuState no entry for menu ${menuId}`);\n }\n return state;\n }, []);\n\n const setOpenMenus = useCallback((menus: RuntimeMenuDescriptor[]) => {\n openMenus.current = menus;\n forceRefresh({});\n }, []);\n\n const menuOpenPendingTimeout = useRef<number | undefined>();\n const menuClosePendingTimeout = useRef<number | undefined>();\n const menuState = useRef<MenuState>({ [rootId]: \"no-popup\" });\n // const prevLevel = useRef(0);\n\n // const prevAim = useRef({mousePos: null, distance: true});\n\n const openMenu = useCallback(\n (\n hostMenuId = rootId,\n targetMenuId: string,\n itemId: string | null = null,\n ) => {\n if (hostMenuId === rootId && itemId === null) {\n setOpenMenus([{ id: rootId, left: posX, top: posY }]);\n } else {\n menuState.current[hostMenuId] = \"popup-open\";\n if (itemId) {\n const el = document.getElementById(itemId) as HTMLElement;\n if (el !== null) {\n const { left, top } = getPosition(el, openMenus.current);\n setOpenMenus(\n openMenus.current.concat({ id: targetMenuId, left, top }),\n );\n } else {\n throw Error(`openMenu no menuItem ${itemId}`);\n }\n }\n }\n },\n [rootId, posX, posY, setOpenMenus],\n );\n\n const closeMenu = useCallback(\n (menuId?: string) => {\n if (menuId === rootId) {\n setOpenMenus([]);\n } else {\n const menus = openMenus.current.slice();\n const lastMenu = menus.pop() as RuntimeMenuDescriptor;\n menuState.current[lastMenu.id] = \"no-popup\";\n const parentMenu = menus.at(-1);\n if (parentMenu) {\n menuState.current[parentMenu.id] = \"no-popup\";\n }\n setOpenMenus(menus);\n }\n },\n [rootId, setOpenMenus],\n );\n\n const closeMenus = useCallback(\n (menuItemId: string) => {\n const menus = openMenus.current.slice();\n const menuItemMenuId = menuItemId.slice(9);\n let { id: lastMenuId } = menus.at(-1) as RuntimeMenuDescriptor;\n while (menus.length > 1 && !menuItemMenuId.startsWith(lastMenuId)) {\n const parentMenuId = getHostMenuId(lastMenuId, rootId);\n menus.pop();\n menuState.current[lastMenuId] = \"no-popup\";\n menuState.current[parentMenuId] = \"no-popup\";\n ({ id: lastMenuId } = menus[menus.length - 1]);\n }\n if (menus.length < openMenus.current.length) {\n setOpenMenus(menus);\n }\n },\n [rootId, setOpenMenus],\n );\n\n const clearAnyScheduledOpenTasks = useCallback(() => {\n if (menuOpenPendingTimeout.current) {\n clearTimeout(menuOpenPendingTimeout.current);\n menuOpenPendingTimeout.current = undefined;\n }\n }, []);\n\n const scheduleOpen = useCallback(\n (\n hostMenuId: string,\n targetMenuId: string,\n menuItemId: string,\n delay = 300,\n ) => {\n clearAnyScheduledOpenTasks();\n // do we need to set target state to pending-open ?s\n\n menuOpenPendingTimeout.current = window.setTimeout(() => {\n // console.log(\n // `scheduleOpen<timeout> opening menu ${targetMenuId} from menu ${hostMenuId} via menuitem ${menuItemId}`\n // );\n closeMenus(menuItemId);\n menuState.current[hostMenuId] = \"popup-open\";\n menuState.current[targetMenuId] = \"no-popup\";\n openMenu(hostMenuId, targetMenuId, menuItemId);\n }, delay);\n },\n [clearAnyScheduledOpenTasks, closeMenus, openMenu],\n );\n\n const scheduleClose = useCallback(\n (hostMenuId: string, openMenuId: string, itemId: string) => {\n // console.log(\n // `scheduleClose openMenuId ${openMenuId} from parent menu ${hostMenuId} itemId ${itemId}`\n // );\n menuState.current[openMenuId] = \"pending-close\";\n menuClosePendingTimeout.current = window.setTimeout(() => {\n // console.log(`call closeMenus from scheduleClose`);\n closeMenus(itemId);\n }, 400);\n },\n [closeMenus],\n );\n\n const handleRender = useCallback(() => {\n const { current: menus } = openMenus;\n const menu = menus.at(-1);\n const el = menu ? document.getElementById(menu.id) : undefined;\n if (el) {\n const { right, bottom } = el.getBoundingClientRect();\n const { clientHeight, clientWidth } = document.body;\n if (right > clientWidth) {\n const newMenus =\n menus.length > 1\n ? flipSides(rootId, menus)\n : nudgeLeft(menus, right - clientWidth);\n setOpenMenus(newMenus);\n } else if (bottom > clientHeight) {\n const newMenus = nudgeUp(menus, bottom - clientHeight);\n setOpenMenus(newMenus);\n }\n\n if (typeof el.tabIndex === \"number\") {\n el.focus();\n }\n }\n }, [rootId, setOpenMenus]);\n\n // TODO introduce a delay parameter that allows click to requeat an immediate render\n const triggerChildMenu = useCallback<MenuOpenHandler>(\n (menuItemEl, immediate = false) => {\n const { hostMenuId, targetMenuId, menuItemId, isGroup, isOpen } =\n getMenuItemDetails(menuItemEl, rootId);\n const {\n current: { [hostMenuId]: state },\n } = menuState;\n\n const delay = immediate ? 0 : undefined;\n\n // console.log(\n // `%ctriggerChildMenu\n // rootId ${rootId}\n // menuItem ${menuItemId}\n // host menu: ${hostMenuId}\n // target menu: ${targetMenuId}\n // item index: ${menuItemId}\n // state ${state}\n // isGroup ${isGroup} isOpen ${isOpen}\n // openMenus: ${JSON.stringify(openMenus.current)}\n // full state='${JSON.stringify(menuState.current)}`,\n // \"color: green; font-weight: bold;\"\n // );\n\n if (state === \"no-popup\" && isGroup) {\n menuState.current[hostMenuId] = \"popup-pending\";\n scheduleOpen(hostMenuId, targetMenuId, menuItemId, delay);\n } else if (state === \"popup-pending\" && !isGroup) {\n menuState.current[hostMenuId] = \"no-popup\";\n clearTimeout(menuOpenPendingTimeout.current);\n menuOpenPendingTimeout.current = undefined;\n } else if (state === \"popup-pending\" && isGroup) {\n clearTimeout(menuOpenPendingTimeout.current);\n scheduleOpen(hostMenuId, targetMenuId, menuItemId, delay);\n } else if (state === \"popup-open\") {\n if (menuIsOpen(targetMenuId)) {\n const menuStatus = getOpenMenuStatus(targetMenuId);\n // Close any child menus of the target menu. This can happen if we have\n // opened child menus, then moused out of the menu entirely, to re-enter\n // at a higher level\n closeMenus(menuItemId);\n\n switch (menuStatus) {\n case \"pending-close\":\n // cancel the close\n clearTimeout(menuClosePendingTimeout.current);\n menuClosePendingTimeout.current = undefined;\n menuState.current[targetMenuId] = \"no-popup\";\n clearAnyScheduledOpenTasks();\n break;\n default:\n }\n } else {\n // TODO review the below, suspectb it's over complicating things\n const [parentOfLastOpenedMenu, lastOpenedMenu] =\n openMenus.current.slice(-2);\n if (\n parentOfLastOpenedMenu.id === hostMenuId &&\n menuState.current[lastOpenedMenu.id] !== \"pending-close\" /*&&\n sameLevel*/\n ) {\n scheduleClose(hostMenuId, lastOpenedMenu.id, menuItemId);\n if (isGroup && !isOpen) {\n scheduleOpen(hostMenuId, targetMenuId, menuItemId, delay);\n }\n } else if (\n parentOfLastOpenedMenu.id === hostMenuId &&\n isGroup &&\n menuItemId !== lastOpenedMenu.id &&\n menuState.current[lastOpenedMenu.id] === \"pending-close\"\n ) {\n // if there is already an item queued for opening cancel it\n scheduleOpen(hostMenuId, targetMenuId, menuItemId, delay);\n } else if (isGroup) {\n // closeMenus(menuId, itemId);\n scheduleOpen(hostMenuId, targetMenuId, menuItemId, delay);\n } else if (\n !(\n (menuState.current[lastOpenedMenu.id] === \"pending-close\") /*&&\n sameLevel*/\n )\n ) {\n closeMenus(menuItemId);\n }\n }\n }\n\n if (state === \"pending-close\") {\n clearAnyScheduledOpenTasks();\n clearTimeout(menuClosePendingTimeout.current);\n menuClosePendingTimeout.current = undefined;\n menuState.current[hostMenuId] = \"popup-open\";\n }\n },\n [\n clearAnyScheduledOpenTasks,\n closeMenus,\n getOpenMenuStatus,\n menuIsOpen,\n rootId,\n scheduleClose,\n scheduleOpen,\n ],\n );\n\n const listItemProps: Partial<MenuItemProps> = useMemo(\n () => ({\n onMouseEnter: (evt: MouseEvent) => {\n const menuItemEl = closestListItem(evt.target as HTMLElement);\n triggerChildMenu(menuItemEl);\n onMouseEnterItem(evt, menuItemEl.id);\n },\n\n onClick: (evt: SyntheticEvent) => {\n const listItemEl = closestListItem(evt.target as HTMLElement);\n const { isGroup, menuItemId } = getMenuItemDetails(listItemEl, rootId);\n if (isGroup) {\n triggerChildMenu(listItemEl);\n } else {\n onActivate(menuItemId);\n }\n },\n }),\n [onActivate, onMouseEnterItem, rootId, triggerChildMenu],\n );\n\n return {\n closeMenu,\n handleRender,\n listItemProps,\n openMenu: triggerChildMenu,\n openMenus: openMenus.current,\n };\n};\n"],"names":["useState","useRef","useCallback","useMemo","closestListItem"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-items-with-ids-next.js","sources":["../../src/menu/use-items-with-ids-next.ts"],"sourcesContent":["import React, { ReactElement, ReactNode, useCallback, useMemo } from \"react\";\nimport { isMenuItemLabel, isMenuItemGroup, Separator } from \"./MenuList\";\n\ntype Menus = { [key: string]: ReactElement[] };\ntype Actions = { [key: string]: { action: string; options?: unknown } };\n\nconst getLabelFromChildren = (children: ReactNode) => {\n if (Array.isArray(children) && isMenuItemLabel(children[0])) {\n return children[0];\n }\n};\n\nconst assignId = (\n child: ReactElement,\n path: string,\n group: boolean,\n hasSeparator = false\n) => {\n const {\n props: { children },\n } = child;\n // If we have a leaf MenuItem, any children will be label etc\n // if we have a GroupMenuItem, firet item mat be Label\n return {\n childWithId: React.cloneElement(child, {\n hasSeparator,\n id: `${path}`,\n key: path,\n children: group ? getLabelFromChildren(children) : children,\n }),\n grandChildren: group ? children : undefined,\n };\n};\n\nexport const useItemsWithIdsNext = (\n childrenProp: ReactElement[],\n rootId: string\n): [Menus, Actions] => {\n const normalizeChildren = useCallback(() => {\n const collectChildren = (\n children: ReactElement[],\n path = rootId,\n menus: Menus = {},\n actions: Actions = {}\n ) => {\n const list: ReactElement[] = (menus[path] = []);\n let idx = 0;\n let hasSeparator = false;\n\n React.Children.forEach(children, (child) => {\n if (isMenuItemLabel(child)) {\n // do nothing\n } else if (child.type === Separator) {\n hasSeparator = true;\n } else {\n const hasChildItems = isMenuItemGroup(child);\n const childPath = `${path}-${idx}`;\n const {\n props: { action, options },\n } = child;\n\n const { childWithId, grandChildren } = assignId(\n child,\n childPath,\n hasChildItems,\n hasSeparator\n );\n list.push(childWithId);\n if (grandChildren) {\n collectChildren(grandChildren, childPath, menus, actions);\n } else {\n actions[childPath] = { action, options };\n }\n idx += 1;\n hasSeparator = false;\n }\n });\n return [menus, actions];\n };\n\n return collectChildren(childrenProp);\n }, [rootId, childrenProp]);\n\n const [menus, actions] = useMemo(\n () => normalizeChildren(),\n [normalizeChildren]\n );\n\n return [menus, actions] as [Menus, Actions];\n};\n"],"names":["isMenuItemLabel","useCallback","menus","actions","Separator","isMenuItemGroup","useMemo"],"mappings":"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"}
1
+ {"version":3,"file":"use-items-with-ids-next.js","sources":["../../src/menu/use-items-with-ids-next.ts"],"sourcesContent":["import React, { ReactElement, ReactNode, useCallback, useMemo } from \"react\";\nimport { isMenuItemLabel, isMenuItemGroup, Separator } from \"./MenuList\";\n\ntype Menus = { [key: string]: ReactElement[] };\ntype Actions = { [key: string]: { action: string; options?: unknown } };\n\nconst getLabelFromChildren = (children: ReactNode) => {\n if (Array.isArray(children) && isMenuItemLabel(children[0])) {\n return children[0];\n }\n};\n\nconst assignId = (\n child: ReactElement,\n path: string,\n group: boolean,\n hasSeparator = false\n) => {\n const {\n props: { children },\n } = child;\n // If we have a leaf MenuItem, any children will be label etc\n // if we have a GroupMenuItem, firet item mat be Label\n return {\n childWithId: React.cloneElement(child, {\n hasSeparator,\n id: `${path}`,\n key: path,\n children: group ? getLabelFromChildren(children) : children,\n }),\n grandChildren: group ? children : undefined,\n };\n};\n\nexport const useItemsWithIdsNext = (\n childrenProp: ReactElement[],\n rootId: string\n): [Menus, Actions] => {\n const normalizeChildren = useCallback(() => {\n const collectChildren = (\n children: ReactElement[],\n path = rootId,\n menus: Menus = {},\n actions: Actions = {}\n ) => {\n const list: ReactElement[] = (menus[path] = []);\n let idx = 0;\n let hasSeparator = false;\n\n React.Children.forEach(children, (child) => {\n if (isMenuItemLabel(child)) {\n // do nothing\n } else if (child.type === Separator) {\n hasSeparator = true;\n } else {\n const hasChildItems = isMenuItemGroup(child);\n const childPath = `${path}-${idx}`;\n const {\n props: { action, options },\n } = child;\n\n const { childWithId, grandChildren } = assignId(\n child,\n childPath,\n hasChildItems,\n hasSeparator\n );\n list.push(childWithId);\n if (grandChildren) {\n collectChildren(grandChildren, childPath, menus, actions);\n } else {\n actions[childPath] = { action, options };\n }\n idx += 1;\n hasSeparator = false;\n }\n });\n return [menus, actions];\n };\n\n return collectChildren(childrenProp);\n }, [rootId, childrenProp]);\n\n const [menus, actions] = useMemo(\n () => normalizeChildren(),\n [normalizeChildren]\n );\n\n return [menus, actions] as [Menus, Actions];\n};\n"],"names":["isMenuItemLabel","useCallback","menus","actions","Separator","isMenuItemGroup","useMemo"],"mappings":";;;;;AAMA,MAAM,oBAAA,GAAuB,CAAC,QAAwB,KAAA;AACpD,EAAI,IAAA,KAAA,CAAM,QAAQ,QAAQ,CAAA,IAAKA,yBAAgB,QAAS,CAAA,CAAC,CAAC,CAAG,EAAA;AAC3D,IAAA,OAAO,SAAS,CAAC,CAAA;AAAA;AAErB,CAAA;AAEA,MAAM,WAAW,CACf,KAAA,EACA,IACA,EAAA,KAAA,EACA,eAAe,KACZ,KAAA;AACH,EAAM,MAAA;AAAA,IACJ,KAAA,EAAO,EAAE,QAAS;AAAA,GAChB,GAAA,KAAA;AAGJ,EAAO,OAAA;AAAA,IACL,WAAA,EAAa,KAAM,CAAA,YAAA,CAAa,KAAO,EAAA;AAAA,MACrC,YAAA;AAAA,MACA,EAAA,EAAI,GAAG,IAAI,CAAA,CAAA;AAAA,MACX,GAAK,EAAA,IAAA;AAAA,MACL,QAAU,EAAA,KAAA,GAAQ,oBAAqB,CAAA,QAAQ,CAAI,GAAA;AAAA,KACpD,CAAA;AAAA,IACD,aAAA,EAAe,QAAQ,QAAW,GAAA,KAAA;AAAA,GACpC;AACF,CAAA;AAEa,MAAA,mBAAA,GAAsB,CACjC,YAAA,EACA,MACqB,KAAA;AACrB,EAAM,MAAA,iBAAA,GAAoBC,kBAAY,MAAM;AAC1C,IAAM,MAAA,eAAA,GAAkB,CACtB,QAAA,EACA,IAAO,GAAA,MAAA,EACPC,SAAe,EAAC,EAChBC,QAAmB,GAAA,EAChB,KAAA;AACH,MAAA,MAAM,IAAwBD,GAAAA,MAAAA,CAAM,IAAI,CAAA,GAAI,EAAC;AAC7C,MAAA,IAAI,GAAM,GAAA,CAAA;AACV,MAAA,IAAI,YAAe,GAAA,KAAA;AAEnB,MAAA,KAAA,CAAM,QAAS,CAAA,OAAA,CAAQ,QAAU,EAAA,CAAC,KAAU,KAAA;AAC1C,QAAI,IAAAF,wBAAA,CAAgB,KAAK,CAAG,EAAA,CAE5B,MAAA,IAAW,KAAM,CAAA,IAAA,KAASI,kBAAW,EAAA;AACnC,UAAe,YAAA,GAAA,IAAA;AAAA,SACV,MAAA;AACL,UAAM,MAAA,aAAA,GAAgBC,yBAAgB,KAAK,CAAA;AAC3C,UAAA,MAAM,SAAY,GAAA,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,GAAG,CAAA,CAAA;AAChC,UAAM,MAAA;AAAA,YACJ,KAAA,EAAO,EAAE,MAAA,EAAQ,OAAQ;AAAA,WACvB,GAAA,KAAA;AAEJ,UAAM,MAAA,EAAE,WAAa,EAAA,aAAA,EAAkB,GAAA,QAAA;AAAA,YACrC,KAAA;AAAA,YACA,SAAA;AAAA,YACA,aAAA;AAAA,YACA;AAAA,WACF;AACA,UAAA,IAAA,CAAK,KAAK,WAAW,CAAA;AACrB,UAAA,IAAI,aAAe,EAAA;AACjB,YAAgB,eAAA,CAAA,aAAA,EAAe,SAAWH,EAAAA,MAAAA,EAAOC,QAAO,CAAA;AAAA,WACnD,MAAA;AACL,YAAAA,QAAQ,CAAA,SAAS,CAAI,GAAA,EAAE,QAAQ,OAAQ,EAAA;AAAA;AAEzC,UAAO,GAAA,IAAA,CAAA;AACP,UAAe,YAAA,GAAA,KAAA;AAAA;AACjB,OACD,CAAA;AACD,MAAO,OAAA,CAACD,QAAOC,QAAO,CAAA;AAAA,KACxB;AAEA,IAAA,OAAO,gBAAgB,YAAY,CAAA;AAAA,GAClC,EAAA,CAAC,MAAQ,EAAA,YAAY,CAAC,CAAA;AAEzB,EAAM,MAAA,CAAC,KAAO,EAAA,OAAO,CAAI,GAAAG,aAAA;AAAA,IACvB,MAAM,iBAAkB,EAAA;AAAA,IACxB,CAAC,iBAAiB;AAAA,GACpB;AAEA,EAAO,OAAA,CAAC,OAAO,OAAO,CAAA;AACxB;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-keyboard-navigation.js","sources":["../../src/menu/use-keyboard-navigation.ts"],"sourcesContent":["import {\n FocusEvent,\n KeyboardEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { hasPopup, isRoot } from \"./utils\";\nimport { isNavigationKey } from \"./key-code\";\nimport { isValidNumber } from \"@vuu-ui/vuu-utils\";\nimport { MenuOpenHandler } from \"./MenuList\";\n\nexport type MenuCloseReason = \"tab-away\" | \"close-child-menu\";\n\nexport type MenuCloseHandler = (\n evt: KeyboardEvent,\n reason: MenuCloseReason,\n) => void;\n\nexport interface KeyboardNavigationProps {\n autoHighlightFirstItem?: boolean;\n count: number;\n defaultHighlightedIdx?: number;\n highlightedIndex?: number;\n onActivate: (idx: number) => void;\n onHighlight?: (idx: number) => void;\n onCloseMenu: MenuCloseHandler;\n onOpenMenu?: MenuOpenHandler;\n}\n\nexport interface KeyboardHookListProps {\n // onBlur: (evt: FocusEvent) => void;\n onFocus: (evt: FocusEvent) => void;\n onKeyDown: (evt: KeyboardEvent) => void;\n onMouseDownCapture: () => void;\n onMouseMove: () => void;\n onMouseLeave: () => void;\n}\n\nexport interface NavigationHookResult {\n focusVisible: number;\n controlledHighlighting: boolean;\n highlightedIndex: number;\n setHighlightedIndex: (idx: number) => void;\n // keyboardNavigation: RefObject<boolean>;\n listProps: KeyboardHookListProps;\n setIgnoreFocus: (ignoreFocus: boolean) => void;\n}\n\n// we need a way to set highlightedIdx when selection changes\nexport const useKeyboardNavigation = ({\n autoHighlightFirstItem = false,\n count,\n defaultHighlightedIdx,\n highlightedIndex: highlightedIndexProp,\n onActivate,\n onHighlight,\n onCloseMenu,\n onOpenMenu,\n}: KeyboardNavigationProps): NavigationHookResult => {\n if (\n isValidNumber(highlightedIndexProp) &&\n isValidNumber(defaultHighlightedIdx)\n ) {\n throw Error(\n \"useKeyboardNavigation do not pass values for both highlightedIndex and defaultHighlightedIdx\",\n );\n }\n\n const controlledHighlighting = isValidNumber(highlightedIndexProp);\n const highlightedIndexRef = useRef(\n defaultHighlightedIdx ??\n highlightedIndexProp ??\n (autoHighlightFirstItem ? 0 : -1),\n );\n const [, forceRender] = useState<unknown>(null);\n\n const setHighlightedIdx = useCallback(\n (idx) => {\n highlightedIndexRef.current = idx;\n onHighlight?.(idx);\n forceRender({});\n },\n [onHighlight],\n );\n\n const setHighlightedIndex = useCallback(\n (idx) => {\n if (idx !== highlightedIndexRef.current) {\n if (!controlledHighlighting) {\n setHighlightedIdx(idx);\n }\n }\n },\n [controlledHighlighting, setHighlightedIdx],\n );\n\n // does this belong here or should it be a method passed in?\n const keyBoardNavigation = useRef(true);\n const ignoreFocus = useRef(false);\n const setIgnoreFocus = (value: boolean) => (ignoreFocus.current = value);\n\n const highlightedIndex = controlledHighlighting\n ? highlightedIndexProp\n : highlightedIndexRef.current;\n\n const navigateChildItems = useCallback(\n (e: KeyboardEvent) => {\n const nextIdx = nextItemIdx(count, e.key, highlightedIndexRef.current);\n if (nextIdx !== highlightedIndexRef.current) {\n setHighlightedIndex(nextIdx);\n }\n },\n [count, setHighlightedIndex],\n );\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (isNavigationKey(e)) {\n e.preventDefault();\n e.stopPropagation();\n keyBoardNavigation.current = true;\n navigateChildItems(e);\n } else if (\n (e.key === \"ArrowRight\" || e.key === \"Enter\") &&\n hasPopup(e.target as HTMLElement, highlightedIndex)\n ) {\n const menuEl = e.target as HTMLElement;\n const menuItemEl = menuEl.querySelector(\n `:scope > [data-index='${highlightedIndex}']`,\n ) as HTMLElement;\n\n if (menuItemEl) {\n onOpenMenu?.(menuItemEl, true);\n }\n } else if (e.key === \"ArrowLeft\" && !isRoot(e.target as HTMLElement)) {\n onCloseMenu(e, \"close-child-menu\");\n } else if (e.key === \"Enter\") {\n e.preventDefault();\n e.stopPropagation();\n onActivate && onActivate(highlightedIndex);\n } else if (e.key === \"Tab\") {\n onCloseMenu(e, \"tab-away\");\n }\n },\n [highlightedIndex, navigateChildItems, onActivate, onCloseMenu, onOpenMenu],\n );\n\n const listProps: KeyboardHookListProps = useMemo(\n () => ({\n onFocus: () => {\n if (highlightedIndex === -1) {\n setHighlightedIdx(0);\n }\n },\n onKeyDown: handleKeyDown,\n onMouseDownCapture: () => {\n keyBoardNavigation.current = false;\n setIgnoreFocus(true);\n },\n\n // onMouseEnter would seem less expensive but it misses some cases\n onMouseMove: () => {\n if (keyBoardNavigation.current) {\n keyBoardNavigation.current = false;\n }\n },\n onMouseLeave: () => {\n keyBoardNavigation.current = true;\n setIgnoreFocus(false);\n setHighlightedIndex(-1);\n },\n }),\n [handleKeyDown, highlightedIndex, setHighlightedIdx, setHighlightedIndex],\n );\n\n return {\n focusVisible: keyBoardNavigation.current ? highlightedIndex : -1,\n controlledHighlighting,\n highlightedIndex,\n setHighlightedIndex: setHighlightedIndex,\n listProps,\n setIgnoreFocus,\n };\n};\n\n// need to be able to accommodate disabled items\nfunction nextItemIdx(count: number, key: string, idx: number) {\n if (key === \"ArrowUp\") {\n if (idx > 0) {\n return idx - 1;\n } else {\n return idx;\n }\n } else {\n if (idx === null) {\n return 0;\n } else if (idx === count - 1) {\n return idx;\n } else {\n return idx + 1;\n }\n }\n}\n"],"names":["isValidNumber","useRef","useState","useCallback","isNavigationKey","hasPopup","isRoot","useMemo"],"mappings":"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"}
1
+ {"version":3,"file":"use-keyboard-navigation.js","sources":["../../src/menu/use-keyboard-navigation.ts"],"sourcesContent":["import {\n FocusEvent,\n KeyboardEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { hasPopup, isRoot } from \"./utils\";\nimport { isNavigationKey } from \"./key-code\";\nimport { isValidNumber } from \"@vuu-ui/vuu-utils\";\nimport { MenuOpenHandler } from \"./MenuList\";\n\nexport type MenuCloseReason = \"tab-away\" | \"close-child-menu\";\n\nexport type MenuCloseHandler = (\n evt: KeyboardEvent,\n reason: MenuCloseReason,\n) => void;\n\nexport interface KeyboardNavigationProps {\n autoHighlightFirstItem?: boolean;\n count: number;\n defaultHighlightedIdx?: number;\n highlightedIndex?: number;\n onActivate: (idx: number) => void;\n onHighlight?: (idx: number) => void;\n onCloseMenu: MenuCloseHandler;\n onOpenMenu?: MenuOpenHandler;\n}\n\nexport interface KeyboardHookListProps {\n // onBlur: (evt: FocusEvent) => void;\n onFocus: (evt: FocusEvent) => void;\n onKeyDown: (evt: KeyboardEvent) => void;\n onMouseDownCapture: () => void;\n onMouseMove: () => void;\n onMouseLeave: () => void;\n}\n\nexport interface NavigationHookResult {\n focusVisible: number;\n controlledHighlighting: boolean;\n highlightedIndex: number;\n setHighlightedIndex: (idx: number) => void;\n // keyboardNavigation: RefObject<boolean>;\n listProps: KeyboardHookListProps;\n setIgnoreFocus: (ignoreFocus: boolean) => void;\n}\n\n// we need a way to set highlightedIdx when selection changes\nexport const useKeyboardNavigation = ({\n autoHighlightFirstItem = false,\n count,\n defaultHighlightedIdx,\n highlightedIndex: highlightedIndexProp,\n onActivate,\n onHighlight,\n onCloseMenu,\n onOpenMenu,\n}: KeyboardNavigationProps): NavigationHookResult => {\n if (\n isValidNumber(highlightedIndexProp) &&\n isValidNumber(defaultHighlightedIdx)\n ) {\n throw Error(\n \"useKeyboardNavigation do not pass values for both highlightedIndex and defaultHighlightedIdx\",\n );\n }\n\n const controlledHighlighting = isValidNumber(highlightedIndexProp);\n const highlightedIndexRef = useRef(\n defaultHighlightedIdx ??\n highlightedIndexProp ??\n (autoHighlightFirstItem ? 0 : -1),\n );\n const [, forceRender] = useState<unknown>(null);\n\n const setHighlightedIdx = useCallback(\n (idx: number) => {\n highlightedIndexRef.current = idx;\n onHighlight?.(idx);\n forceRender({});\n },\n [onHighlight],\n );\n\n const setHighlightedIndex = useCallback(\n (idx: number) => {\n if (idx !== highlightedIndexRef.current) {\n if (!controlledHighlighting) {\n setHighlightedIdx(idx);\n }\n }\n },\n [controlledHighlighting, setHighlightedIdx],\n );\n\n // does this belong here or should it be a method passed in?\n const keyBoardNavigation = useRef(true);\n const ignoreFocus = useRef(false);\n const setIgnoreFocus = (value: boolean) => (ignoreFocus.current = value);\n\n const highlightedIndex = controlledHighlighting\n ? highlightedIndexProp\n : highlightedIndexRef.current;\n\n const navigateChildItems = useCallback(\n (e: KeyboardEvent) => {\n const nextIdx = nextItemIdx(count, e.key, highlightedIndexRef.current);\n if (nextIdx !== highlightedIndexRef.current) {\n setHighlightedIndex(nextIdx);\n }\n },\n [count, setHighlightedIndex],\n );\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (isNavigationKey(e)) {\n e.preventDefault();\n e.stopPropagation();\n keyBoardNavigation.current = true;\n navigateChildItems(e);\n } else if (\n (e.key === \"ArrowRight\" || e.key === \"Enter\") &&\n hasPopup(e.target as HTMLElement, highlightedIndex)\n ) {\n const menuEl = e.target as HTMLElement;\n const menuItemEl = menuEl.querySelector(\n `:scope > [data-index='${highlightedIndex}']`,\n ) as HTMLElement;\n\n if (menuItemEl) {\n onOpenMenu?.(menuItemEl, true);\n }\n } else if (e.key === \"ArrowLeft\" && !isRoot(e.target as HTMLElement)) {\n onCloseMenu(e, \"close-child-menu\");\n } else if (e.key === \"Enter\") {\n e.preventDefault();\n e.stopPropagation();\n onActivate && onActivate(highlightedIndex);\n } else if (e.key === \"Tab\") {\n onCloseMenu(e, \"tab-away\");\n }\n },\n [highlightedIndex, navigateChildItems, onActivate, onCloseMenu, onOpenMenu],\n );\n\n const listProps: KeyboardHookListProps = useMemo(\n () => ({\n onFocus: () => {\n if (highlightedIndex === -1) {\n setHighlightedIdx(0);\n }\n },\n onKeyDown: handleKeyDown,\n onMouseDownCapture: () => {\n keyBoardNavigation.current = false;\n setIgnoreFocus(true);\n },\n\n // onMouseEnter would seem less expensive but it misses some cases\n onMouseMove: () => {\n if (keyBoardNavigation.current) {\n keyBoardNavigation.current = false;\n }\n },\n onMouseLeave: () => {\n keyBoardNavigation.current = true;\n setIgnoreFocus(false);\n setHighlightedIndex(-1);\n },\n }),\n [handleKeyDown, highlightedIndex, setHighlightedIdx, setHighlightedIndex],\n );\n\n return {\n focusVisible: keyBoardNavigation.current ? highlightedIndex : -1,\n controlledHighlighting,\n highlightedIndex,\n setHighlightedIndex: setHighlightedIndex,\n listProps,\n setIgnoreFocus,\n };\n};\n\n// need to be able to accommodate disabled items\nfunction nextItemIdx(count: number, key: string, idx: number) {\n if (key === \"ArrowUp\") {\n if (idx > 0) {\n return idx - 1;\n } else {\n return idx;\n }\n } else {\n if (idx === null) {\n return 0;\n } else if (idx === count - 1) {\n return idx;\n } else {\n return idx + 1;\n }\n }\n}\n"],"names":["isValidNumber","useRef","useState","useCallback","isNavigationKey","hasPopup","isRoot","useMemo"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"useContextMenu.js","sources":["../../src/menu/useContextMenu.tsx"],"sourcesContent":["import {\n ContextMenuItemDescriptor,\n MenuActionHandler,\n MenuBuilder,\n} from \"@vuu-ui/vuu-data-types\";\nimport { ColumnDescriptor } from \"@vuu-ui/vuu-table-types\";\nimport {\n isGroupMenuItemDescriptor,\n useThemeAttributes,\n} from \"@vuu-ui/vuu-utils\";\nimport { cloneElement, useCallback, useContext, useMemo } from \"react\";\nimport {\n MenuActionClosePopup,\n PopupCloseReason,\n PopupService,\n reasonIsMenuAction,\n} from \"../popup\";\nimport { ContextMenu, ContextMenuProps } from \"./ContextMenu\";\nimport { MenuItem, MenuItemGroup } from \"./MenuList\";\nimport { ContextMenuContext } from \"./context-menu-provider\";\n\nexport type ContextMenuOptions = {\n [key: string]: unknown;\n columns?: ColumnDescriptor[];\n contextMenu?: JSX.Element;\n ContextMenuProps?: Partial<ContextMenuProps> & {\n className?: string;\n };\n controlledComponentId?: string;\n};\n\nexport type EventLike = {\n clientX: number;\n clientY: number;\n preventDefault?: () => void;\n stopPropagation?: () => void;\n};\n\nexport type ShowContextMenu = (\n e: EventLike,\n location: string,\n options: ContextMenuOptions,\n) => void;\n\n// The argument allows a top-level menuBuilder to operate outside the Context\nexport const useContextMenu = (\n menuBuilder?: MenuBuilder,\n menuActionHandler?: MenuActionHandler,\n): [ShowContextMenu, () => void] => {\n const ctx = useContext(ContextMenuContext);\n\n const [themeClass, densityClass, dataMode] = useThemeAttributes();\n const themeAttributes = useMemo(\n () => ({\n themeClass,\n densityClass,\n dataMode,\n }),\n [dataMode, densityClass, themeClass],\n );\n\n const buildMenuOptions = useCallback(\n (menuBuilders: MenuBuilder[], location, options) => {\n let results: ContextMenuItemDescriptor[] = [];\n for (const menuBuilder of menuBuilders) {\n // Maybe we should leave the concatenation to the menuBuilder, then it can control menuItem order\n results = results.concat(menuBuilder(location, options));\n }\n return results;\n },\n [],\n );\n\n const handleShowContextMenu = useCallback<ShowContextMenu>(\n (e, location, { ContextMenuProps, contextMenu, ...options }) => {\n e.stopPropagation?.();\n e.preventDefault?.();\n\n if (contextMenu) {\n return showContextMenuComponent(\n {\n x: e.clientX,\n y: e.clientY,\n },\n contextMenu,\n );\n }\n\n const menuBuilders: MenuBuilder[] = [];\n if (menuBuilder) {\n menuBuilders.push(menuBuilder);\n }\n if (\n ctx &&\n Array.isArray(ctx?.menuBuilders) &&\n ctx.menuBuilders.length > 0\n ) {\n menuBuilders.push(...ctx.menuBuilders);\n }\n\n if (menuBuilders.length > 0) {\n const menuItemDescriptors = buildMenuOptions(\n menuBuilders,\n location,\n options,\n );\n\n // const menuHandler = menuActionHandler ?? ctx?.menuActionHandler;\n const menuHandler: MenuActionHandler = (\n action: MenuActionClosePopup,\n ) => {\n if (menuActionHandler?.(action) === true) {\n return true;\n } else {\n return ctx?.menuActionHandler(action);\n }\n };\n\n if (menuItemDescriptors.length && menuHandler) {\n // because showPopup is going to be used to render the context menu, it will not\n // have access to the ContextMenuContext. Pass the theme attributes here\n showContextMenu(e, menuItemDescriptors, menuHandler, {\n PortalProps: {\n themeAttributes,\n },\n ...ContextMenuProps,\n });\n }\n } else {\n console.warn(\n \"useContextMenu, no menuBuilders configured. These should be supplied via the ContextMenuProvider(s)\",\n );\n }\n },\n [buildMenuOptions, ctx, menuActionHandler, menuBuilder, themeAttributes],\n );\n\n const hideContextMenu = useCallback(() => {\n console.log(\"hide context menu\");\n }, []);\n\n return [handleShowContextMenu, hideContextMenu];\n};\n\nconst NO_OPTIONS = {};\n\nconst showContextMenuComponent = (\n position: { x: number; y: number },\n contextMenu: JSX.Element,\n) => {\n PopupService.showPopup({\n focus: true,\n left: 0,\n top: 0,\n component: cloneElement(contextMenu, { position }),\n });\n};\n\nconst showContextMenu = (\n e: EventLike,\n menuDescriptors: ContextMenuItemDescriptor[],\n handleContextMenuAction: MenuActionHandler,\n {\n position: positionProp,\n ...contextMenuProps\n }: ContextMenuOptions[\"ContextMenuProps\"] = NO_OPTIONS,\n) => {\n const menuItems = (menuDescriptors: ContextMenuItemDescriptor[]) => {\n const fromDescriptor = (menuItem: ContextMenuItemDescriptor, i: number) =>\n isGroupMenuItemDescriptor(menuItem) ? (\n <MenuItemGroup key={i} label={menuItem.label}>\n {menuItem.children.map(fromDescriptor)}\n </MenuItemGroup>\n ) : (\n <MenuItem\n key={i}\n action={menuItem.action}\n className={menuItem.className}\n data-icon={menuItem.icon}\n options={menuItem.options}\n >\n {menuItem.label}\n </MenuItem>\n );\n\n return menuDescriptors.map(fromDescriptor);\n };\n\n const handleClose = (reason?: PopupCloseReason) => {\n if (reasonIsMenuAction(reason)) {\n if (reason?.closedBy === \"popup-service\") {\n return;\n }\n handleContextMenuAction(reason);\n // TODO this results in onClose being called twice on component\n // cant simply be removed, some refactoring work needed\n PopupService.hidePopup(reason);\n }\n contextMenuProps?.onClose?.(reason);\n };\n\n const position = positionProp ?? {\n x: e.clientX,\n y: e.clientY,\n };\n\n const component = (\n <ContextMenu\n {...contextMenuProps}\n onClose={handleClose}\n position={position}\n >\n {menuItems(menuDescriptors)}\n </ContextMenu>\n );\n PopupService.showPopup({ left: 0, top: 0, component, focus: true });\n};\n"],"names":["useContext","ContextMenuContext","useThemeAttributes","useMemo","useCallback","menuBuilder","ContextMenuProps","PopupService","cloneElement","menuDescriptors","isGroupMenuItemDescriptor","jsx","MenuItemGroup","MenuItem","reasonIsMenuAction","ContextMenu"],"mappings":"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"}
1
+ {"version":3,"file":"useContextMenu.js","sources":["../../src/menu/useContextMenu.tsx"],"sourcesContent":["import {\n ContextMenuItemDescriptor,\n MenuActionHandler,\n MenuBuilder,\n} from \"@vuu-ui/vuu-data-types\";\nimport { ColumnDescriptor } from \"@vuu-ui/vuu-table-types\";\nimport {\n isGroupMenuItemDescriptor,\n useThemeAttributes,\n} from \"@vuu-ui/vuu-utils\";\nimport { cloneElement, useCallback, useContext, useMemo } from \"react\";\nimport {\n MenuActionClosePopup,\n PopupCloseReason,\n PopupService,\n reasonIsMenuAction,\n} from \"../popup\";\nimport { ContextMenu, ContextMenuProps } from \"./ContextMenu\";\nimport { MenuItem, MenuItemGroup } from \"./MenuList\";\nimport { ContextMenuContext } from \"./context-menu-provider\";\n\nexport type ContextMenuOptions = {\n [key: string]: unknown;\n columns?: ColumnDescriptor[];\n contextMenu?: JSX.Element;\n ContextMenuProps?: Partial<ContextMenuProps> & {\n className?: string;\n };\n controlledComponentId?: string;\n};\n\nexport type EventLike = {\n clientX: number;\n clientY: number;\n preventDefault?: () => void;\n stopPropagation?: () => void;\n};\n\nexport type ShowContextMenu = (\n e: EventLike,\n location: string,\n options: ContextMenuOptions,\n) => void;\n\n// The argument allows a top-level menuBuilder to operate outside the Context\nexport const useContextMenu = (\n menuBuilder?: MenuBuilder,\n menuActionHandler?: MenuActionHandler,\n): [ShowContextMenu, () => void] => {\n const ctx = useContext(ContextMenuContext);\n\n const [themeClass, densityClass, dataMode] = useThemeAttributes();\n const themeAttributes = useMemo(\n () => ({\n themeClass,\n densityClass,\n dataMode,\n }),\n [dataMode, densityClass, themeClass],\n );\n\n const buildMenuOptions = useCallback(\n (menuBuilders: MenuBuilder[], location: string, options: unknown) => {\n let results: ContextMenuItemDescriptor[] = [];\n for (const menuBuilder of menuBuilders) {\n // Maybe we should leave the concatenation to the menuBuilder, then it can control menuItem order\n results = results.concat(menuBuilder(location, options));\n }\n return results;\n },\n [],\n );\n\n const handleShowContextMenu = useCallback<ShowContextMenu>(\n (e, location, { ContextMenuProps, contextMenu, ...options }) => {\n e.stopPropagation?.();\n e.preventDefault?.();\n\n if (contextMenu) {\n return showContextMenuComponent(\n {\n x: e.clientX,\n y: e.clientY,\n },\n contextMenu,\n );\n }\n\n const menuBuilders: MenuBuilder[] = [];\n if (menuBuilder) {\n menuBuilders.push(menuBuilder);\n }\n if (\n ctx &&\n Array.isArray(ctx?.menuBuilders) &&\n ctx.menuBuilders.length > 0\n ) {\n menuBuilders.push(...ctx.menuBuilders);\n }\n\n if (menuBuilders.length > 0) {\n const menuItemDescriptors = buildMenuOptions(\n menuBuilders,\n location,\n options,\n );\n\n // const menuHandler = menuActionHandler ?? ctx?.menuActionHandler;\n const menuHandler: MenuActionHandler = (\n action: MenuActionClosePopup,\n ) => {\n if (menuActionHandler?.(action) === true) {\n return true;\n } else {\n return ctx?.menuActionHandler(action);\n }\n };\n\n if (menuItemDescriptors.length && menuHandler) {\n // because showPopup is going to be used to render the context menu, it will not\n // have access to the ContextMenuContext. Pass the theme attributes here\n showContextMenu(e, menuItemDescriptors, menuHandler, {\n PortalProps: {\n themeAttributes,\n },\n ...ContextMenuProps,\n });\n }\n } else {\n console.warn(\n \"useContextMenu, no menuBuilders configured. These should be supplied via the ContextMenuProvider(s)\",\n );\n }\n },\n [buildMenuOptions, ctx, menuActionHandler, menuBuilder, themeAttributes],\n );\n\n const hideContextMenu = useCallback(() => {\n console.log(\"hide context menu\");\n }, []);\n\n return [handleShowContextMenu, hideContextMenu];\n};\n\nconst NO_OPTIONS = {};\n\nconst showContextMenuComponent = (\n position: { x: number; y: number },\n contextMenu: JSX.Element,\n) => {\n PopupService.showPopup({\n focus: true,\n left: 0,\n top: 0,\n component: cloneElement(contextMenu, { position }),\n });\n};\n\nconst showContextMenu = (\n e: EventLike,\n menuDescriptors: ContextMenuItemDescriptor[],\n handleContextMenuAction: MenuActionHandler,\n {\n position: positionProp,\n ...contextMenuProps\n }: ContextMenuOptions[\"ContextMenuProps\"] = NO_OPTIONS,\n) => {\n const menuItems = (menuDescriptors: ContextMenuItemDescriptor[]) => {\n const fromDescriptor = (menuItem: ContextMenuItemDescriptor, i: number) =>\n isGroupMenuItemDescriptor(menuItem) ? (\n <MenuItemGroup key={i} label={menuItem.label}>\n {menuItem.children.map(fromDescriptor)}\n </MenuItemGroup>\n ) : (\n <MenuItem\n key={i}\n action={menuItem.action}\n className={menuItem.className}\n data-icon={menuItem.icon}\n options={menuItem.options}\n >\n {menuItem.label}\n </MenuItem>\n );\n\n return menuDescriptors.map(fromDescriptor);\n };\n\n const handleClose = (reason?: PopupCloseReason) => {\n if (reasonIsMenuAction(reason)) {\n if (reason?.closedBy === \"popup-service\") {\n return;\n }\n handleContextMenuAction(reason);\n // TODO this results in onClose being called twice on component\n // cant simply be removed, some refactoring work needed\n PopupService.hidePopup(reason);\n }\n contextMenuProps?.onClose?.(reason);\n };\n\n const position = positionProp ?? {\n x: e.clientX,\n y: e.clientY,\n };\n\n const component = (\n <ContextMenu\n {...contextMenuProps}\n onClose={handleClose}\n position={position}\n >\n {menuItems(menuDescriptors)}\n </ContextMenu>\n );\n PopupService.showPopup({ left: 0, top: 0, component, focus: true });\n};\n"],"names":["useContext","ContextMenuContext","useThemeAttributes","useMemo","useCallback","menuBuilder","ContextMenuProps","PopupService","cloneElement","menuDescriptors","isGroupMenuItemDescriptor","jsx","MenuItemGroup","MenuItem","reasonIsMenuAction","ContextMenu"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../../src/menu/utils.ts"],"sourcesContent":["export const isRoot = (el: HTMLElement) =>\n el.closest(`[data-root='true']`) !== null;\n\nexport const hasPopup = (el: HTMLElement, idx: number) =>\n (el.ariaHasPopup === \"true\" && el.dataset?.idx === `${idx}`) ||\n el.querySelector(`:scope > [data-index='${idx}'][aria-haspopup='true']`) !==\n null;\n"],"names":[],"mappings":";;AAAO,MAAM,SAAS,CAAC,EAAA,KACrB,EAAG,CAAA,OAAA,CAAQ,oBAAoB,CAAM,KAAA,KAAA;AAEhC,MAAM,WAAW,CAAC,EAAA,EAAiB,QACvC,EAAG,CAAA,YAAA,KAAiB,UAAU,EAAG,CAAA,OAAA,EAAS,GAAQ,KAAA,CAAA,EAAG,GAAG,CACzD,CAAA,IAAA,EAAA,CAAG,cAAc,CAAyB,sBAAA,EAAA,GAAG,0BAA0B,CACrE,KAAA;;;;;"}
1
+ {"version":3,"file":"utils.js","sources":["../../src/menu/utils.ts"],"sourcesContent":["export const isRoot = (el: HTMLElement) =>\n el.closest(`[data-root='true']`) !== null;\n\nexport const hasPopup = (el: HTMLElement, idx: number) =>\n (el.ariaHasPopup === \"true\" && el.dataset?.idx === `${idx}`) ||\n el.querySelector(`:scope > [data-index='${idx}'][aria-haspopup='true']`) !==\n null;\n"],"names":[],"mappings":";;AAAO,MAAM,SAAS,CAAC,EAAA,KACrB,EAAG,CAAA,OAAA,CAAQ,oBAAoB,CAAM,KAAA;AAEhC,MAAM,WAAW,CAAC,EAAA,EAAiB,QACvC,EAAG,CAAA,YAAA,KAAiB,UAAU,EAAG,CAAA,OAAA,EAAS,GAAQ,KAAA,CAAA,EAAG,GAAG,CACzD,CAAA,IAAA,EAAA,CAAG,cAAc,CAAyB,sBAAA,EAAA,GAAG,0BAA0B,CACrE,KAAA;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"NotificationsCenter.js","sources":["../../src/notifications/NotificationsCenter.tsx"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport { NotificationsContext } from \"./NotificationsProvider\";\nimport { getUniqueId } from \"@vuu-ui/vuu-utils\";\nimport { ToastNotification } from \"./ToastNotification\";\nimport { Notification } from \"./notificationTypes\";\n\nexport interface NotificationsCenterProps {\n notificationsContext: NotificationsContext;\n}\n\n// animation times in milliseconds\nconst toastOffsetTop = 60;\nconst toastDisplayDuration = 6000;\nconst horizontalTransitionDuration = 1000;\n\n// toast size in pixels\nconst toastHeight = 56;\nconst toastContainerContentGap = 10;\n// rightPadding is used together with the toastWidth to compute the toast position\n// at the beginning and at the end of the animation\n\nexport const NotificationsCenter = ({\n notificationsContext,\n}: NotificationsCenterProps) => {\n const [notifications, setNotifications] = useState<Notification[]>([]);\n\n useMemo(() => {\n notificationsContext.setNotify((notification) => {\n const newNotification: Notification = {\n ...notification,\n id: getUniqueId(),\n };\n setNotifications((prev) => prev.concat(newNotification));\n setTimeout(\n () => {\n setNotifications((prev) => prev.filter((n) => n !== newNotification));\n },\n toastDisplayDuration + horizontalTransitionDuration * 2,\n );\n });\n }, [notificationsContext]);\n\n return (\n <>\n {notifications.map((notification, i) => (\n <ToastNotification\n top={toastOffsetTop + (toastHeight + toastContainerContentGap) * i}\n notification={notification}\n key={notification.id}\n />\n ))}\n </>\n );\n};\n"],"names":["useState","useMemo","getUniqueId","jsx","Fragment","ToastNotification"],"mappings":";;;;;;;AAWA,MAAM,cAAiB,GAAA,EAAA,CAAA;AACvB,MAAM,oBAAuB,GAAA,GAAA,CAAA;AAC7B,MAAM,4BAA+B,GAAA,GAAA,CAAA;AAGrC,MAAM,WAAc,GAAA,EAAA,CAAA;AACpB,MAAM,wBAA2B,GAAA,EAAA,CAAA;AAI1B,MAAM,sBAAsB,CAAC;AAAA,EAClC,oBAAA;AACF,CAAgC,KAAA;AAC9B,EAAA,MAAM,CAAC,aAAe,EAAA,gBAAgB,CAAI,GAAAA,cAAA,CAAyB,EAAE,CAAA,CAAA;AAErE,EAAAC,aAAA,CAAQ,MAAM;AACZ,IAAqB,oBAAA,CAAA,SAAA,CAAU,CAAC,YAAiB,KAAA;AAC/C,MAAA,MAAM,eAAgC,GAAA;AAAA,QACpC,GAAG,YAAA;AAAA,QACH,IAAIC,oBAAY,EAAA;AAAA,OAClB,CAAA;AACA,MAAA,gBAAA,CAAiB,CAAC,IAAA,KAAS,IAAK,CAAA,MAAA,CAAO,eAAe,CAAC,CAAA,CAAA;AACvD,MAAA,UAAA;AAAA,QACE,MAAM;AACJ,UAAiB,gBAAA,CAAA,CAAC,SAAS,IAAK,CAAA,MAAA,CAAO,CAAC,CAAM,KAAA,CAAA,KAAM,eAAe,CAAC,CAAA,CAAA;AAAA,SACtE;AAAA,QACA,uBAAuB,4BAA+B,GAAA,CAAA;AAAA,OACxD,CAAA;AAAA,KACD,CAAA,CAAA;AAAA,GACH,EAAG,CAAC,oBAAoB,CAAC,CAAA,CAAA;AAEzB,EAAA,uBAEKC,cAAA,CAAAC,mBAAA,EAAA,EAAA,QAAA,EAAA,aAAA,CAAc,GAAI,CAAA,CAAC,cAAc,CAChC,qBAAAD,cAAA;AAAA,IAACE,mCAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,cAAkB,GAAA,CAAA,WAAA,GAAc,wBAA4B,IAAA,CAAA;AAAA,MACjE,YAAA;AAAA,KAAA;AAAA,IACK,YAAa,CAAA,EAAA;AAAA,GAErB,CACH,EAAA,CAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"NotificationsCenter.js","sources":["../../src/notifications/NotificationsCenter.tsx"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport { NotificationsContext } from \"./NotificationsProvider\";\nimport { getUniqueId } from \"@vuu-ui/vuu-utils\";\nimport { ToastNotification } from \"./ToastNotification\";\nimport { Notification } from \"./notificationTypes\";\n\nexport interface NotificationsCenterProps {\n notificationsContext: NotificationsContext;\n}\n\n// animation times in milliseconds\nconst toastOffsetTop = 60;\nconst toastDisplayDuration = 6000;\nconst horizontalTransitionDuration = 1000;\n\n// toast size in pixels\nconst toastHeight = 56;\nconst toastContainerContentGap = 10;\n// rightPadding is used together with the toastWidth to compute the toast position\n// at the beginning and at the end of the animation\n\nexport const NotificationsCenter = ({\n notificationsContext,\n}: NotificationsCenterProps) => {\n const [notifications, setNotifications] = useState<Notification[]>([]);\n\n useMemo(() => {\n notificationsContext.setNotify((notification) => {\n const newNotification: Notification = {\n ...notification,\n id: getUniqueId(),\n };\n setNotifications((prev) => prev.concat(newNotification));\n setTimeout(\n () => {\n setNotifications((prev) => prev.filter((n) => n !== newNotification));\n },\n toastDisplayDuration + horizontalTransitionDuration * 2,\n );\n });\n }, [notificationsContext]);\n\n return (\n <>\n {notifications.map((notification, i) => (\n <ToastNotification\n top={toastOffsetTop + (toastHeight + toastContainerContentGap) * i}\n notification={notification}\n key={notification.id}\n />\n ))}\n </>\n );\n};\n"],"names":["useState","useMemo","getUniqueId","jsx","Fragment","ToastNotification"],"mappings":";;;;;;;AAWA,MAAM,cAAiB,GAAA,EAAA;AACvB,MAAM,oBAAuB,GAAA,GAAA;AAC7B,MAAM,4BAA+B,GAAA,GAAA;AAGrC,MAAM,WAAc,GAAA,EAAA;AACpB,MAAM,wBAA2B,GAAA,EAAA;AAI1B,MAAM,sBAAsB,CAAC;AAAA,EAClC;AACF,CAAgC,KAAA;AAC9B,EAAA,MAAM,CAAC,aAAe,EAAA,gBAAgB,CAAI,GAAAA,cAAA,CAAyB,EAAE,CAAA;AAErE,EAAAC,aAAA,CAAQ,MAAM;AACZ,IAAqB,oBAAA,CAAA,SAAA,CAAU,CAAC,YAAiB,KAAA;AAC/C,MAAA,MAAM,eAAgC,GAAA;AAAA,QACpC,GAAG,YAAA;AAAA,QACH,IAAIC,oBAAY;AAAA,OAClB;AACA,MAAA,gBAAA,CAAiB,CAAC,IAAA,KAAS,IAAK,CAAA,MAAA,CAAO,eAAe,CAAC,CAAA;AACvD,MAAA,UAAA;AAAA,QACE,MAAM;AACJ,UAAiB,gBAAA,CAAA,CAAC,SAAS,IAAK,CAAA,MAAA,CAAO,CAAC,CAAM,KAAA,CAAA,KAAM,eAAe,CAAC,CAAA;AAAA,SACtE;AAAA,QACA,uBAAuB,4BAA+B,GAAA;AAAA,OACxD;AAAA,KACD,CAAA;AAAA,GACH,EAAG,CAAC,oBAAoB,CAAC,CAAA;AAEzB,EAAA,uBAEKC,cAAA,CAAAC,mBAAA,EAAA,EAAA,QAAA,EAAA,aAAA,CAAc,GAAI,CAAA,CAAC,cAAc,CAChC,qBAAAD,cAAA;AAAA,IAACE,mCAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,cAAkB,GAAA,CAAA,WAAA,GAAc,wBAA4B,IAAA,CAAA;AAAA,MACjE;AAAA,KAAA;AAAA,IACK,YAAa,CAAA;AAAA,GAErB,CACH,EAAA,CAAA;AAEJ;;;;"}
@@ -13,7 +13,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
13
13
  var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
14
14
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
15
15
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
16
- var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
16
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
17
17
  var _notify;
18
18
  class NotificationsContextObject {
19
19
  constructor() {
@@ -1 +1 @@
1
- {"version":3,"file":"NotificationsProvider.js","sources":["../../src/notifications/NotificationsProvider.tsx"],"sourcesContent":["import React, { useContext } from \"react\";\nimport { NotificationsCenter } from \"./NotificationsCenter\";\nimport { Notification } from \"./notificationTypes\";\n\nexport type DispatchNotification = (\n notification: Omit<Notification, \"id\">\n) => void;\n\nexport type NotificationsContext = {\n notify: DispatchNotification;\n setNotify: (dispatcher: DispatchNotification) => void;\n};\n\n/*\n The Context is not exposed outside this module, only the notify\n prop can be accessed via the useNotifications hook.\n The NotificationsCenter receives the full context object and\n sets the notify method. State management around dispatched\n notifications is handled entirely within the NotificationsCenter,\n avoiding rerendering our children when notifications are \n dispatched.\n*/\nclass NotificationsContextObject implements NotificationsContext {\n #notify: DispatchNotification = () =>\n console.log(\"have you forgotten to provide a NotificationsCenter?\");\n // We want the public notify method to be stable, setNotify call should not trigger re-renders\n notify: DispatchNotification = (notification) => this.#notify(notification);\n setNotify = (dispatcher: DispatchNotification) => {\n this.#notify = dispatcher;\n };\n}\n\nconst NotificationsContext = React.createContext<NotificationsContext>(\n new NotificationsContextObject()\n);\n\nexport const NotificationsProvider = (props: {\n children: JSX.Element | JSX.Element[];\n}) => {\n const context = useContext(NotificationsContext);\n return (\n <NotificationsContext.Provider value={context}>\n <NotificationsCenter notificationsContext={context} />\n {props.children}\n </NotificationsContext.Provider>\n );\n};\n\nexport const useNotifications = () => {\n const { notify } = useContext(NotificationsContext);\n return notify;\n};\n"],"names":["useContext","jsxs","jsx","NotificationsCenter"],"mappings":";;;;;;;;;;;;;;;;AAAA,IAAA,OAAA,CAAA;AAsBA,MAAM,0BAA2D,CAAA;AAAA,EAAjE,WAAA,GAAA;AACE,IAAgC,YAAA,CAAA,IAAA,EAAA,OAAA,EAAA,MAC9B,OAAQ,CAAA,GAAA,CAAI,sDAAsD,CAAA,CAAA,CAAA;AAEpE;AAAA,IAAA,aAAA,CAAA,IAAA,EAAA,QAAA,EAA+B,CAAC,YAAA,KAAiB,YAAK,CAAA,IAAA,EAAA,OAAA,CAAA,CAAL,IAAa,CAAA,IAAA,EAAA,YAAA,CAAA,CAAA,CAAA;AAC9D,IAAA,aAAA,CAAA,IAAA,EAAA,WAAA,EAAY,CAAC,UAAqC,KAAA;AAChD,MAAA,YAAA,CAAA,IAAA,EAAK,OAAU,EAAA,UAAA,CAAA,CAAA;AAAA,KACjB,CAAA,CAAA;AAAA,GAAA;AACF,CAAA;AAPE,OAAA,GAAA,IAAA,OAAA,EAAA,CAAA;AASF,MAAM,uBAAuB,KAAM,CAAA,aAAA;AAAA,EACjC,IAAI,0BAA2B,EAAA;AACjC,CAAA,CAAA;AAEa,MAAA,qBAAA,GAAwB,CAAC,KAEhC,KAAA;AACJ,EAAM,MAAA,OAAA,GAAUA,iBAAW,oBAAoB,CAAA,CAAA;AAC/C,EAAA,uBACGC,eAAA,CAAA,oBAAA,CAAqB,QAArB,EAAA,EAA8B,OAAO,OACpC,EAAA,QAAA,EAAA;AAAA,oBAACC,cAAA,CAAAC,uCAAA,EAAA,EAAoB,sBAAsB,OAAS,EAAA,CAAA;AAAA,IACnD,KAAM,CAAA,QAAA;AAAA,GACT,EAAA,CAAA,CAAA;AAEJ,EAAA;AAEO,MAAM,mBAAmB,MAAM;AACpC,EAAA,MAAM,EAAE,MAAA,EAAW,GAAAH,gBAAA,CAAW,oBAAoB,CAAA,CAAA;AAClD,EAAO,OAAA,MAAA,CAAA;AACT;;;;;"}
1
+ {"version":3,"file":"NotificationsProvider.js","sources":["../../src/notifications/NotificationsProvider.tsx"],"sourcesContent":["import React, { useContext } from \"react\";\nimport { NotificationsCenter } from \"./NotificationsCenter\";\nimport { Notification } from \"./notificationTypes\";\n\nexport type DispatchNotification = (\n notification: Omit<Notification, \"id\">\n) => void;\n\nexport type NotificationsContext = {\n notify: DispatchNotification;\n setNotify: (dispatcher: DispatchNotification) => void;\n};\n\n/*\n The Context is not exposed outside this module, only the notify\n prop can be accessed via the useNotifications hook.\n The NotificationsCenter receives the full context object and\n sets the notify method. State management around dispatched\n notifications is handled entirely within the NotificationsCenter,\n avoiding rerendering our children when notifications are \n dispatched.\n*/\nclass NotificationsContextObject implements NotificationsContext {\n #notify: DispatchNotification = () =>\n console.log(\"have you forgotten to provide a NotificationsCenter?\");\n // We want the public notify method to be stable, setNotify call should not trigger re-renders\n notify: DispatchNotification = (notification) => this.#notify(notification);\n setNotify = (dispatcher: DispatchNotification) => {\n this.#notify = dispatcher;\n };\n}\n\nconst NotificationsContext = React.createContext<NotificationsContext>(\n new NotificationsContextObject()\n);\n\nexport const NotificationsProvider = (props: {\n children: JSX.Element | JSX.Element[];\n}) => {\n const context = useContext(NotificationsContext);\n return (\n <NotificationsContext.Provider value={context}>\n <NotificationsCenter notificationsContext={context} />\n {props.children}\n </NotificationsContext.Provider>\n );\n};\n\nexport const useNotifications = () => {\n const { notify } = useContext(NotificationsContext);\n return notify;\n};\n"],"names":["useContext","jsxs","jsx","NotificationsCenter"],"mappings":";;;;;;;;;;;;;;;;AAAA,IAAA,OAAA;AAsBA,MAAM,0BAA2D,CAAA;AAAA,EAAjE,WAAA,GAAA;AACE,IAAgC,YAAA,CAAA,IAAA,EAAA,OAAA,EAAA,MAC9B,OAAQ,CAAA,GAAA,CAAI,sDAAsD,CAAA,CAAA;AAEpE;AAAA,IAAA,aAAA,CAAA,IAAA,EAAA,QAAA,EAA+B,CAAC,YAAA,KAAiB,YAAK,CAAA,IAAA,EAAA,OAAA,CAAA,CAAL,IAAa,CAAA,IAAA,EAAA,YAAA,CAAA,CAAA;AAC9D,IAAA,aAAA,CAAA,IAAA,EAAA,WAAA,EAAY,CAAC,UAAqC,KAAA;AAChD,MAAA,YAAA,CAAA,IAAA,EAAK,OAAU,EAAA,UAAA,CAAA;AAAA,KACjB,CAAA;AAAA;AACF;AAPE,OAAA,GAAA,IAAA,OAAA,EAAA;AASF,MAAM,uBAAuB,KAAM,CAAA,aAAA;AAAA,EACjC,IAAI,0BAA2B;AACjC,CAAA;AAEa,MAAA,qBAAA,GAAwB,CAAC,KAEhC,KAAA;AACJ,EAAM,MAAA,OAAA,GAAUA,iBAAW,oBAAoB,CAAA;AAC/C,EAAA,uBACGC,eAAA,CAAA,oBAAA,CAAqB,QAArB,EAAA,EAA8B,OAAO,OACpC,EAAA,QAAA,EAAA;AAAA,oBAACC,cAAA,CAAAC,uCAAA,EAAA,EAAoB,sBAAsB,OAAS,EAAA,CAAA;AAAA,IACnD,KAAM,CAAA;AAAA,GACT,EAAA,CAAA;AAEJ;AAEO,MAAM,mBAAmB,MAAM;AACpC,EAAA,MAAM,EAAE,MAAA,EAAW,GAAAH,gBAAA,CAAW,oBAAoB,CAAA;AAClD,EAAO,OAAA,MAAA;AACT;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"ToastNotification.js","sources":["../../src/notifications/ToastNotification.tsx"],"sourcesContent":["import { Icon } from \"@vuu-ui/vuu-ui-controls\";\nimport cx from \"clsx\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { useEffect, useState } from \"react\";\nimport { Portal } from \"../portal\";\nimport type { Notification } from \"./notificationTypes\";\n\nimport toastNotificationCss from \"./ToastNotification.css\";\n\nconst toastWidth = 300;\nconst toastContainerRightPadding = 50;\nconst toastDisplayDuration = 6000;\nconst horizontalTransitionDuration = 1000;\nconst toastHeight = 56;\nconst verticalTransitionDuration = 300;\n\nexport type ToastNotificationProps = {\n top: number;\n notification: Notification;\n animated?: boolean;\n};\n\nconst classBase = \"vuuToastNotification\";\n\nconst icon = {\n error: \"error\",\n info: \"info-circle\",\n success: \"tick\",\n warning: \"warn-triangle\",\n};\n\nexport const ToastNotification = (props: ToastNotificationProps) => {\n const { top, notification, animated = true } = props;\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-toast-notification\",\n css: toastNotificationCss,\n window: targetWindow,\n });\n\n const [right, setRight] = useState(-toastWidth - toastContainerRightPadding);\n\n useEffect(() => {\n setTimeout(() => setRight(toastContainerRightPadding));\n\n if (animated) {\n setTimeout(\n () => setRight(-toastWidth - toastContainerRightPadding),\n toastDisplayDuration + horizontalTransitionDuration,\n );\n }\n }, [animated]);\n\n return (\n <Portal>\n <div\n className={cx(classBase, `${classBase}-${notification.type}`)}\n style={{\n height: toastHeight,\n right,\n width: toastWidth,\n top,\n transition: animated\n ? `right ${horizontalTransitionDuration}ms, top ${verticalTransitionDuration}ms `\n : \"none\",\n }}\n >\n <Icon name={icon[notification.type]} />\n <div className={`${classBase}-toastContent`}>\n <strong className={`${classBase}-toastHeader`}>\n {notification.header}\n </strong>\n <div>{notification.body}</div>\n </div>\n </div>\n </Portal>\n );\n};\n"],"names":["useWindow","useComponentCssInjection","toastNotificationCss","useState","useEffect","Portal","jsxs","jsx","Icon"],"mappings":";;;;;;;;;;;AAUA,MAAM,UAAa,GAAA,GAAA,CAAA;AACnB,MAAM,0BAA6B,GAAA,EAAA,CAAA;AACnC,MAAM,oBAAuB,GAAA,GAAA,CAAA;AAC7B,MAAM,4BAA+B,GAAA,GAAA,CAAA;AACrC,MAAM,WAAc,GAAA,EAAA,CAAA;AACpB,MAAM,0BAA6B,GAAA,GAAA,CAAA;AAQnC,MAAM,SAAY,GAAA,sBAAA,CAAA;AAElB,MAAM,IAAO,GAAA;AAAA,EACX,KAAO,EAAA,OAAA;AAAA,EACP,IAAM,EAAA,aAAA;AAAA,EACN,OAAS,EAAA,MAAA;AAAA,EACT,OAAS,EAAA,eAAA;AACX,CAAA,CAAA;AAEa,MAAA,iBAAA,GAAoB,CAAC,KAAkC,KAAA;AAClE,EAAA,MAAM,EAAE,GAAA,EAAK,YAAc,EAAA,QAAA,GAAW,MAAS,GAAA,KAAA,CAAA;AAC/C,EAAA,MAAM,eAAeA,gBAAU,EAAA,CAAA;AAC/B,EAAyBC,+BAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,wBAAA;AAAA,IACR,GAAK,EAAAC,mBAAA;AAAA,IACL,MAAQ,EAAA,YAAA;AAAA,GACT,CAAA,CAAA;AAED,EAAA,MAAM,CAAC,KAAO,EAAA,QAAQ,IAAIC,cAAS,CAAA,CAAC,aAAa,0BAA0B,CAAA,CAAA;AAE3E,EAAAC,eAAA,CAAU,MAAM;AACd,IAAW,UAAA,CAAA,MAAM,QAAS,CAAA,0BAA0B,CAAC,CAAA,CAAA;AAErD,IAAA,IAAI,QAAU,EAAA;AACZ,MAAA,UAAA;AAAA,QACE,MAAM,QAAA,CAAS,CAAC,UAAA,GAAa,0BAA0B,CAAA;AAAA,QACvD,oBAAuB,GAAA,4BAAA;AAAA,OACzB,CAAA;AAAA,KACF;AAAA,GACF,EAAG,CAAC,QAAQ,CAAC,CAAA,CAAA;AAEb,EAAA,sCACGC,aACC,EAAA,EAAA,QAAA,kBAAAC,eAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,GAAG,SAAW,EAAA,CAAA,EAAG,SAAS,CAAI,CAAA,EAAA,YAAA,CAAa,IAAI,CAAE,CAAA,CAAA;AAAA,MAC5D,KAAO,EAAA;AAAA,QACL,MAAQ,EAAA,WAAA;AAAA,QACR,KAAA;AAAA,QACA,KAAO,EAAA,UAAA;AAAA,QACP,GAAA;AAAA,QACA,YAAY,QACR,GAAA,CAAA,MAAA,EAAS,4BAA4B,CAAA,QAAA,EAAW,0BAA0B,CAC1E,GAAA,CAAA,GAAA,MAAA;AAAA,OACN;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAAC,cAAA,CAACC,kBAAK,EAAA,EAAA,IAAA,EAAM,IAAK,CAAA,YAAA,CAAa,IAAI,CAAG,EAAA,CAAA;AAAA,wBACpCF,eAAA,CAAA,KAAA,EAAA,EAAI,SAAW,EAAA,CAAA,EAAG,SAAS,CAC1B,aAAA,CAAA,EAAA,QAAA,EAAA;AAAA,0BAAAC,cAAA,CAAC,YAAO,SAAW,EAAA,CAAA,EAAG,SAAS,CAAA,YAAA,CAAA,EAC5B,uBAAa,MAChB,EAAA,CAAA;AAAA,0BACAA,cAAA,CAAC,KAAK,EAAA,EAAA,QAAA,EAAA,YAAA,CAAa,IAAK,EAAA,CAAA;AAAA,SAC1B,EAAA,CAAA;AAAA,OAAA;AAAA,KAAA;AAAA,GAEJ,EAAA,CAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"ToastNotification.js","sources":["../../src/notifications/ToastNotification.tsx"],"sourcesContent":["import { Icon } from \"@vuu-ui/vuu-ui-controls\";\nimport cx from \"clsx\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { useEffect, useState } from \"react\";\nimport { Portal } from \"../portal\";\nimport type { Notification } from \"./notificationTypes\";\n\nimport toastNotificationCss from \"./ToastNotification.css\";\n\nconst toastWidth = 300;\nconst toastContainerRightPadding = 50;\nconst toastDisplayDuration = 6000;\nconst horizontalTransitionDuration = 1000;\nconst toastHeight = 56;\nconst verticalTransitionDuration = 300;\n\nexport type ToastNotificationProps = {\n top: number;\n notification: Notification;\n animated?: boolean;\n};\n\nconst classBase = \"vuuToastNotification\";\n\nconst icon = {\n error: \"error\",\n info: \"info-circle\",\n success: \"tick\",\n warning: \"warn-triangle\",\n};\n\nexport const ToastNotification = (props: ToastNotificationProps) => {\n const { top, notification, animated = true } = props;\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-toast-notification\",\n css: toastNotificationCss,\n window: targetWindow,\n });\n\n const [right, setRight] = useState(-toastWidth - toastContainerRightPadding);\n\n useEffect(() => {\n setTimeout(() => setRight(toastContainerRightPadding));\n\n if (animated) {\n setTimeout(\n () => setRight(-toastWidth - toastContainerRightPadding),\n toastDisplayDuration + horizontalTransitionDuration,\n );\n }\n }, [animated]);\n\n return (\n <Portal>\n <div\n className={cx(classBase, `${classBase}-${notification.type}`)}\n style={{\n height: toastHeight,\n right,\n width: toastWidth,\n top,\n transition: animated\n ? `right ${horizontalTransitionDuration}ms, top ${verticalTransitionDuration}ms `\n : \"none\",\n }}\n >\n <Icon name={icon[notification.type]} />\n <div className={`${classBase}-toastContent`}>\n <strong className={`${classBase}-toastHeader`}>\n {notification.header}\n </strong>\n <div>{notification.body}</div>\n </div>\n </div>\n </Portal>\n );\n};\n"],"names":["useWindow","useComponentCssInjection","toastNotificationCss","useState","useEffect","Portal","jsxs","jsx","Icon"],"mappings":";;;;;;;;;;;AAUA,MAAM,UAAa,GAAA,GAAA;AACnB,MAAM,0BAA6B,GAAA,EAAA;AACnC,MAAM,oBAAuB,GAAA,GAAA;AAC7B,MAAM,4BAA+B,GAAA,GAAA;AACrC,MAAM,WAAc,GAAA,EAAA;AACpB,MAAM,0BAA6B,GAAA,GAAA;AAQnC,MAAM,SAAY,GAAA,sBAAA;AAElB,MAAM,IAAO,GAAA;AAAA,EACX,KAAO,EAAA,OAAA;AAAA,EACP,IAAM,EAAA,aAAA;AAAA,EACN,OAAS,EAAA,MAAA;AAAA,EACT,OAAS,EAAA;AACX,CAAA;AAEa,MAAA,iBAAA,GAAoB,CAAC,KAAkC,KAAA;AAClE,EAAA,MAAM,EAAE,GAAA,EAAK,YAAc,EAAA,QAAA,GAAW,MAAS,GAAA,KAAA;AAC/C,EAAA,MAAM,eAAeA,gBAAU,EAAA;AAC/B,EAAyBC,+BAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,wBAAA;AAAA,IACR,GAAK,EAAAC,mBAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAA,MAAM,CAAC,KAAO,EAAA,QAAQ,IAAIC,cAAS,CAAA,CAAC,aAAa,0BAA0B,CAAA;AAE3E,EAAAC,eAAA,CAAU,MAAM;AACd,IAAW,UAAA,CAAA,MAAM,QAAS,CAAA,0BAA0B,CAAC,CAAA;AAErD,IAAA,IAAI,QAAU,EAAA;AACZ,MAAA,UAAA;AAAA,QACE,MAAM,QAAA,CAAS,CAAC,UAAA,GAAa,0BAA0B,CAAA;AAAA,QACvD,oBAAuB,GAAA;AAAA,OACzB;AAAA;AACF,GACF,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,EAAA,sCACGC,aACC,EAAA,EAAA,QAAA,kBAAAC,eAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,GAAG,SAAW,EAAA,CAAA,EAAG,SAAS,CAAI,CAAA,EAAA,YAAA,CAAa,IAAI,CAAE,CAAA,CAAA;AAAA,MAC5D,KAAO,EAAA;AAAA,QACL,MAAQ,EAAA,WAAA;AAAA,QACR,KAAA;AAAA,QACA,KAAO,EAAA,UAAA;AAAA,QACP,GAAA;AAAA,QACA,YAAY,QACR,GAAA,CAAA,MAAA,EAAS,4BAA4B,CAAA,QAAA,EAAW,0BAA0B,CAC1E,GAAA,CAAA,GAAA;AAAA,OACN;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAAC,cAAA,CAACC,kBAAK,EAAA,EAAA,IAAA,EAAM,IAAK,CAAA,YAAA,CAAa,IAAI,CAAG,EAAA,CAAA;AAAA,wBACpCF,eAAA,CAAA,KAAA,EAAA,EAAI,SAAW,EAAA,CAAA,EAAG,SAAS,CAC1B,aAAA,CAAA,EAAA,QAAA,EAAA;AAAA,0BAAAC,cAAA,CAAC,YAAO,SAAW,EAAA,CAAA,EAAG,SAAS,CAAA,YAAA,CAAA,EAC5B,uBAAa,MAChB,EAAA,CAAA;AAAA,0BACAA,cAAA,CAAC,KAAK,EAAA,EAAA,QAAA,EAAA,YAAA,CAAa,IAAK,EAAA;AAAA,SAC1B,EAAA;AAAA;AAAA;AAAA,GAEJ,EAAA,CAAA;AAEJ;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"Popup.js","sources":["../../src/popup/Popup.tsx"],"sourcesContent":["import cx from \"clsx\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { HTMLAttributes, RefObject } from \"react\";\nimport { useAnchoredPosition } from \"./useAnchoredPosition\";\nimport { Position } from \"./getPositionRelativeToAnchor\";\n\nimport popupCss from \"./Popup.css\";\n\nexport type PopupPlacement =\n | \"absolute\"\n | \"auto\"\n | \"below\"\n | \"below-center\"\n | \"below-right\"\n | \"below-full-width\"\n | \"center\"\n | \"right\";\n\nexport interface PopupComponentProps extends HTMLAttributes<HTMLDivElement> {\n anchorElement: RefObject<HTMLElement>;\n // TODO this is repeated in Position\n minWidth?: number | string;\n offsetLeft?: number;\n offsetTop?: number;\n placement: PopupPlacement;\n position?: Position;\n}\n\nexport const PopupComponent = ({\n children,\n className,\n anchorElement,\n minWidth,\n offsetLeft,\n offsetTop,\n placement,\n position: positionProp,\n}: PopupComponentProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-popup\",\n css: popupCss,\n window: targetWindow,\n });\n\n const { popupRef, position } = useAnchoredPosition({\n anchorElement,\n minWidth,\n offsetLeft,\n offsetTop,\n placement,\n position: positionProp,\n });\n return position === undefined ? null : (\n <div className={cx(`vuuPortal`, className)} ref={popupRef} style={position}>\n {children}\n </div>\n );\n};\n"],"names":["useWindow","useComponentCssInjection","popupCss","useAnchoredPosition","jsx"],"mappings":";;;;;;;;;AA6BO,MAAM,iBAAiB,CAAC;AAAA,EAC7B,QAAA;AAAA,EACA,SAAA;AAAA,EACA,aAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAU,EAAA,YAAA;AACZ,CAA2B,KAAA;AACzB,EAAA,MAAM,eAAeA,gBAAU,EAAA,CAAA;AAC/B,EAAyBC,+BAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,WAAA;AAAA,IACR,GAAK,EAAAC,KAAA;AAAA,IACL,MAAQ,EAAA,YAAA;AAAA,GACT,CAAA,CAAA;AAED,EAAA,MAAM,EAAE,QAAA,EAAU,QAAS,EAAA,GAAIC,uCAAoB,CAAA;AAAA,IACjD,aAAA;AAAA,IACA,QAAA;AAAA,IACA,UAAA;AAAA,IACA,SAAA;AAAA,IACA,SAAA;AAAA,IACA,QAAU,EAAA,YAAA;AAAA,GACX,CAAA,CAAA;AACD,EAAA,OAAO,QAAa,KAAA,KAAA,CAAA,GAAY,IAC9B,mBAAAC,cAAA,CAAC,SAAI,SAAW,EAAA,EAAA,CAAG,CAAa,SAAA,CAAA,EAAA,SAAS,CAAG,EAAA,GAAA,EAAK,QAAU,EAAA,KAAA,EAAO,UAC/D,QACH,EAAA,CAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"Popup.js","sources":["../../src/popup/Popup.tsx"],"sourcesContent":["import cx from \"clsx\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { HTMLAttributes, RefObject } from \"react\";\nimport { useAnchoredPosition } from \"./useAnchoredPosition\";\nimport { Position } from \"./getPositionRelativeToAnchor\";\n\nimport popupCss from \"./Popup.css\";\n\nexport type PopupPlacement =\n | \"absolute\"\n | \"auto\"\n | \"below\"\n | \"below-center\"\n | \"below-right\"\n | \"below-full-width\"\n | \"center\"\n | \"right\";\n\nexport interface PopupComponentProps extends HTMLAttributes<HTMLDivElement> {\n anchorElement: RefObject<HTMLElement>;\n // TODO this is repeated in Position\n minWidth?: number | string;\n offsetLeft?: number;\n offsetTop?: number;\n placement: PopupPlacement;\n position?: Position;\n}\n\nexport const PopupComponent = ({\n children,\n className,\n anchorElement,\n minWidth,\n offsetLeft,\n offsetTop,\n placement,\n position: positionProp,\n}: PopupComponentProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-popup\",\n css: popupCss,\n window: targetWindow,\n });\n\n const { popupRef, position } = useAnchoredPosition({\n anchorElement,\n minWidth,\n offsetLeft,\n offsetTop,\n placement,\n position: positionProp,\n });\n return position === undefined ? null : (\n <div className={cx(`vuuPortal`, className)} ref={popupRef} style={position}>\n {children}\n </div>\n );\n};\n"],"names":["useWindow","useComponentCssInjection","popupCss","useAnchoredPosition","jsx"],"mappings":";;;;;;;;;AA6BO,MAAM,iBAAiB,CAAC;AAAA,EAC7B,QAAA;AAAA,EACA,SAAA;AAAA,EACA,aAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAU,EAAA;AACZ,CAA2B,KAAA;AACzB,EAAA,MAAM,eAAeA,gBAAU,EAAA;AAC/B,EAAyBC,+BAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,WAAA;AAAA,IACR,GAAK,EAAAC,KAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAA,MAAM,EAAE,QAAA,EAAU,QAAS,EAAA,GAAIC,uCAAoB,CAAA;AAAA,IACjD,aAAA;AAAA,IACA,QAAA;AAAA,IACA,UAAA;AAAA,IACA,SAAA;AAAA,IACA,SAAA;AAAA,IACA,QAAU,EAAA;AAAA,GACX,CAAA;AACD,EAAA,OAAO,QAAa,KAAA,KAAA,CAAA,GAAY,IAC9B,mBAAAC,cAAA,CAAC,SAAI,SAAW,EAAA,EAAA,CAAG,CAAa,SAAA,CAAA,EAAA,SAAS,CAAG,EAAA,GAAA,EAAK,QAAU,EAAA,KAAA,EAAO,UAC/D,QACH,EAAA,CAAA;AAEJ;;;;"}