@vuu-ui/vuu-popups 0.13.14 → 0.13.16

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 (31) hide show
  1. package/cjs/dialog/useDialog.js.map +1 -1
  2. package/cjs/dialog-header/DialogHeader.js.map +1 -1
  3. package/cjs/notifications/NotificationsCenter.js.map +1 -1
  4. package/cjs/notifications/NotificationsProvider.js.map +1 -1
  5. package/cjs/notifications/ToastNotification.js.map +1 -1
  6. package/cjs/popup/Popup.js.map +1 -1
  7. package/cjs/popup/getPositionRelativeToAnchor.js.map +1 -1
  8. package/cjs/popup/useAnchoredPosition.js.map +1 -1
  9. package/cjs/popup-menu/PopupMenu.js.map +1 -1
  10. package/cjs/popup-menu/usePopupMenu.js.map +1 -1
  11. package/cjs/portal/Portal.js.map +1 -1
  12. package/cjs/prompt/Prompt.js.map +1 -1
  13. package/cjs/tooltip/Tooltip.js.map +1 -1
  14. package/cjs/tooltip/useTooltip.js.map +1 -1
  15. package/cjs/tooltip/useTooltipAnchoredPosition.js.map +1 -1
  16. package/esm/dialog/useDialog.js.map +1 -1
  17. package/esm/dialog-header/DialogHeader.js.map +1 -1
  18. package/esm/notifications/NotificationsCenter.js.map +1 -1
  19. package/esm/notifications/NotificationsProvider.js.map +1 -1
  20. package/esm/notifications/ToastNotification.js.map +1 -1
  21. package/esm/popup/Popup.js.map +1 -1
  22. package/esm/popup/getPositionRelativeToAnchor.js.map +1 -1
  23. package/esm/popup/useAnchoredPosition.js.map +1 -1
  24. package/esm/popup-menu/PopupMenu.js.map +1 -1
  25. package/esm/popup-menu/usePopupMenu.js.map +1 -1
  26. package/esm/portal/Portal.js.map +1 -1
  27. package/esm/prompt/Prompt.js.map +1 -1
  28. package/esm/tooltip/Tooltip.js.map +1 -1
  29. package/esm/tooltip/useTooltip.js.map +1 -1
  30. package/esm/tooltip/useTooltipAnchoredPosition.js.map +1 -1
  31. package/package.json +6 -6
@@ -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":["../../../../packages/vuu-popups/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;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
+ {"version":3,"file":"DialogHeader.js","sources":["../../../../packages/vuu-popups/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":"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;;;;"}
1
+ {"version":3,"file":"NotificationsCenter.js","sources":["../../../../packages/vuu-popups/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;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"NotificationsProvider.js","sources":["../../src/notifications/NotificationsProvider.tsx"],"sourcesContent":["import React, { ReactElement, 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: ReactElement | ReactElement[];\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
+ {"version":3,"file":"NotificationsProvider.js","sources":["../../../../packages/vuu-popups/src/notifications/NotificationsProvider.tsx"],"sourcesContent":["import React, { ReactElement, 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: ReactElement | ReactElement[];\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;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
+ {"version":3,"file":"ToastNotification.js","sources":["../../../../packages/vuu-popups/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 | null>;\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;;;;"}
1
+ {"version":3,"file":"Popup.js","sources":["../../../../packages/vuu-popups/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 | null>;\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;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"getPositionRelativeToAnchor.js","sources":["../../src/popup/getPositionRelativeToAnchor.ts"],"sourcesContent":["import { PopupPlacement } from \"./Popup\";\n\nexport type Visibility = \"hidden\" | \"visible\";\n\nexport type Position = {\n left: number;\n minWidth?: number | string;\n top: number;\n visibility?: Visibility;\n width?: number;\n};\n\nexport const getPositionRelativeToAnchor = (\n anchorElement: HTMLElement,\n placement: PopupPlacement,\n offsetLeft: number,\n offsetTop: number,\n minWidth?: number | string,\n dimensions?: { height: number; width: number }\n): {\n left: number;\n minWidth?: number | string;\n top: number;\n visibility?: Visibility;\n width?: number;\n} => {\n const { bottom, height, left, right, top, width } =\n anchorElement.getBoundingClientRect();\n switch (placement) {\n case \"below\":\n return { left: left + offsetLeft, top: bottom + offsetTop };\n case \"right\":\n return { left: right + offsetLeft, top: top + offsetTop };\n case \"below-center\":\n return { left: left + width / 2 + offsetLeft, top: bottom + offsetTop };\n case \"below-right\":\n return { left: left, minWidth, top: bottom + offsetTop };\n case \"below-full-width\":\n return {\n left: left + offsetLeft,\n minWidth,\n top: bottom + offsetTop,\n width,\n };\n case \"center\":\n if (dimensions) {\n return {\n left: width / 2 - dimensions.width / 2 + offsetLeft,\n top: height / 2 - dimensions.height / 2 + offsetTop,\n visibility: \"visible\",\n };\n } else {\n return {\n left: width / 2 + offsetLeft,\n top: height / 2 + offsetTop,\n visibility: \"hidden\",\n };\n }\n default:\n throw Error(\n `Popup getPositionRelativeToAnchor non-supported placement value ${placement}`\n );\n }\n};\n"],"names":[],"mappings":";;AAYO,MAAM,8BAA8B,CACzC,aAAA,EACA,WACA,UACA,EAAA,SAAA,EACA,UACA,UAOG,KAAA;AACH,EAAM,MAAA,EAAE,QAAQ,MAAQ,EAAA,IAAA,EAAM,OAAO,GAAK,EAAA,KAAA,EACxC,GAAA,aAAA,CAAc,qBAAsB,EAAA;AACtC,EAAA,QAAQ,SAAW;AAAA,IACjB,KAAK,OAAA;AACH,MAAA,OAAO,EAAE,IAAM,EAAA,IAAA,GAAO,UAAY,EAAA,GAAA,EAAK,SAAS,SAAU,EAAA;AAAA,IAC5D,KAAK,OAAA;AACH,MAAA,OAAO,EAAE,IAAM,EAAA,KAAA,GAAQ,UAAY,EAAA,GAAA,EAAK,MAAM,SAAU,EAAA;AAAA,IAC1D,KAAK,cAAA;AACH,MAAO,OAAA,EAAE,MAAM,IAAO,GAAA,KAAA,GAAQ,IAAI,UAAY,EAAA,GAAA,EAAK,SAAS,SAAU,EAAA;AAAA,IACxE,KAAK,aAAA;AACH,MAAA,OAAO,EAAE,IAAA,EAAY,QAAU,EAAA,GAAA,EAAK,SAAS,SAAU,EAAA;AAAA,IACzD,KAAK,kBAAA;AACH,MAAO,OAAA;AAAA,QACL,MAAM,IAAO,GAAA,UAAA;AAAA,QACb,QAAA;AAAA,QACA,KAAK,MAAS,GAAA,SAAA;AAAA,QACd;AAAA,OACF;AAAA,IACF,KAAK,QAAA;AACH,MAAA,IAAI,UAAY,EAAA;AACd,QAAO,OAAA;AAAA,UACL,IAAM,EAAA,KAAA,GAAQ,CAAI,GAAA,UAAA,CAAW,QAAQ,CAAI,GAAA,UAAA;AAAA,UACzC,GAAK,EAAA,MAAA,GAAS,CAAI,GAAA,UAAA,CAAW,SAAS,CAAI,GAAA,SAAA;AAAA,UAC1C,UAAY,EAAA;AAAA,SACd;AAAA,OACK,MAAA;AACL,QAAO,OAAA;AAAA,UACL,IAAA,EAAM,QAAQ,CAAI,GAAA,UAAA;AAAA,UAClB,GAAA,EAAK,SAAS,CAAI,GAAA,SAAA;AAAA,UAClB,UAAY,EAAA;AAAA,SACd;AAAA;AACF,IACF;AACE,MAAM,MAAA,KAAA;AAAA,QACJ,mEAAmE,SAAS,CAAA;AAAA,OAC9E;AAAA;AAEN;;;;"}
1
+ {"version":3,"file":"getPositionRelativeToAnchor.js","sources":["../../../../packages/vuu-popups/src/popup/getPositionRelativeToAnchor.ts"],"sourcesContent":["import { PopupPlacement } from \"./Popup\";\n\nexport type Visibility = \"hidden\" | \"visible\";\n\nexport type Position = {\n left: number;\n minWidth?: number | string;\n top: number;\n visibility?: Visibility;\n width?: number;\n};\n\nexport const getPositionRelativeToAnchor = (\n anchorElement: HTMLElement,\n placement: PopupPlacement,\n offsetLeft: number,\n offsetTop: number,\n minWidth?: number | string,\n dimensions?: { height: number; width: number }\n): {\n left: number;\n minWidth?: number | string;\n top: number;\n visibility?: Visibility;\n width?: number;\n} => {\n const { bottom, height, left, right, top, width } =\n anchorElement.getBoundingClientRect();\n switch (placement) {\n case \"below\":\n return { left: left + offsetLeft, top: bottom + offsetTop };\n case \"right\":\n return { left: right + offsetLeft, top: top + offsetTop };\n case \"below-center\":\n return { left: left + width / 2 + offsetLeft, top: bottom + offsetTop };\n case \"below-right\":\n return { left: left, minWidth, top: bottom + offsetTop };\n case \"below-full-width\":\n return {\n left: left + offsetLeft,\n minWidth,\n top: bottom + offsetTop,\n width,\n };\n case \"center\":\n if (dimensions) {\n return {\n left: width / 2 - dimensions.width / 2 + offsetLeft,\n top: height / 2 - dimensions.height / 2 + offsetTop,\n visibility: \"visible\",\n };\n } else {\n return {\n left: width / 2 + offsetLeft,\n top: height / 2 + offsetTop,\n visibility: \"hidden\",\n };\n }\n default:\n throw Error(\n `Popup getPositionRelativeToAnchor non-supported placement value ${placement}`\n );\n }\n};\n"],"names":[],"mappings":";;AAYO,MAAM,8BAA8B,CACzC,aAAA,EACA,WACA,UACA,EAAA,SAAA,EACA,UACA,UAOG,KAAA;AACH,EAAM,MAAA,EAAE,QAAQ,MAAQ,EAAA,IAAA,EAAM,OAAO,GAAK,EAAA,KAAA,EACxC,GAAA,aAAA,CAAc,qBAAsB,EAAA;AACtC,EAAA,QAAQ,SAAW;AAAA,IACjB,KAAK,OAAA;AACH,MAAA,OAAO,EAAE,IAAM,EAAA,IAAA,GAAO,UAAY,EAAA,GAAA,EAAK,SAAS,SAAU,EAAA;AAAA,IAC5D,KAAK,OAAA;AACH,MAAA,OAAO,EAAE,IAAM,EAAA,KAAA,GAAQ,UAAY,EAAA,GAAA,EAAK,MAAM,SAAU,EAAA;AAAA,IAC1D,KAAK,cAAA;AACH,MAAO,OAAA,EAAE,MAAM,IAAO,GAAA,KAAA,GAAQ,IAAI,UAAY,EAAA,GAAA,EAAK,SAAS,SAAU,EAAA;AAAA,IACxE,KAAK,aAAA;AACH,MAAA,OAAO,EAAE,IAAA,EAAY,QAAU,EAAA,GAAA,EAAK,SAAS,SAAU,EAAA;AAAA,IACzD,KAAK,kBAAA;AACH,MAAO,OAAA;AAAA,QACL,MAAM,IAAO,GAAA,UAAA;AAAA,QACb,QAAA;AAAA,QACA,KAAK,MAAS,GAAA,SAAA;AAAA,QACd;AAAA,OACF;AAAA,IACF,KAAK,QAAA;AACH,MAAA,IAAI,UAAY,EAAA;AACd,QAAO,OAAA;AAAA,UACL,IAAM,EAAA,KAAA,GAAQ,CAAI,GAAA,UAAA,CAAW,QAAQ,CAAI,GAAA,UAAA;AAAA,UACzC,GAAK,EAAA,MAAA,GAAS,CAAI,GAAA,UAAA,CAAW,SAAS,CAAI,GAAA,SAAA;AAAA,UAC1C,UAAY,EAAA;AAAA,SACd;AAAA,OACK,MAAA;AACL,QAAO,OAAA;AAAA,UACL,IAAA,EAAM,QAAQ,CAAI,GAAA,UAAA;AAAA,UAClB,GAAA,EAAK,SAAS,CAAI,GAAA,SAAA;AAAA,UAClB,UAAY,EAAA;AAAA,SACd;AAAA;AACF,IACF;AACE,MAAM,MAAA,KAAA;AAAA,QACJ,mEAAmE,SAAS,CAAA;AAAA,OAC9E;AAAA;AAEN;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"useAnchoredPosition.js","sources":["../../src/popup/useAnchoredPosition.ts"],"sourcesContent":["import { useCallback, useLayoutEffect, useRef, useState } from \"react\";\nimport {\n getPositionRelativeToAnchor,\n Position,\n} from \"./getPositionRelativeToAnchor\";\nimport { PopupComponentProps } from \"./Popup\";\n\nexport type AnchoredPositionHookProps = Pick<\n PopupComponentProps,\n | \"anchorElement\"\n | \"minWidth\"\n | \"offsetLeft\"\n | \"offsetTop\"\n | \"placement\"\n | \"position\"\n>;\n\nexport const useAnchoredPosition = ({\n anchorElement,\n minWidth,\n offsetLeft = 0,\n offsetTop = 0,\n placement,\n position: positionProp,\n}: AnchoredPositionHookProps) => {\n const popupRef = useRef<HTMLElement | null>(null);\n const [position, setPosition] = useState<Position | undefined>(positionProp);\n\n // maybe better as useMemo ?\n useLayoutEffect(() => {\n if (placement === \"absolute\" && positionProp) {\n setPosition(positionProp);\n } else if (anchorElement.current && placement !== \"auto\") {\n const dimensions =\n popupRef.current === null\n ? undefined\n : popupRef.current.getBoundingClientRect();\n const position = getPositionRelativeToAnchor(\n anchorElement.current,\n placement,\n offsetLeft,\n offsetTop,\n minWidth,\n dimensions\n );\n setPosition(position);\n }\n }, [anchorElement, minWidth, offsetLeft, offsetTop, placement, positionProp]);\n\n const popupCallbackRef = useCallback(\n (el: HTMLDivElement | null) => {\n popupRef.current = el;\n if (el && placement === \"center\" && anchorElement.current) {\n const { height, width } = el.getBoundingClientRect();\n setPosition(\n getPositionRelativeToAnchor(\n anchorElement.current,\n placement,\n offsetLeft,\n offsetTop,\n undefined,\n { height, width }\n )\n );\n }\n },\n [anchorElement, offsetLeft, offsetTop, placement]\n );\n\n return {\n position,\n popupRef: placement === \"center\" ? popupCallbackRef : undefined,\n };\n};\n"],"names":["useRef","useState","useLayoutEffect","position","getPositionRelativeToAnchor","useCallback"],"mappings":";;;;;AAiBO,MAAM,sBAAsB,CAAC;AAAA,EAClC,aAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAa,GAAA,CAAA;AAAA,EACb,SAAY,GAAA,CAAA;AAAA,EACZ,SAAA;AAAA,EACA,QAAU,EAAA;AACZ,CAAiC,KAAA;AAC/B,EAAM,MAAA,QAAA,GAAWA,aAA2B,IAAI,CAAA;AAChD,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIC,eAA+B,YAAY,CAAA;AAG3E,EAAAC,qBAAA,CAAgB,MAAM;AACpB,IAAI,IAAA,SAAA,KAAc,cAAc,YAAc,EAAA;AAC5C,MAAA,WAAA,CAAY,YAAY,CAAA;AAAA,KACf,MAAA,IAAA,aAAA,CAAc,OAAW,IAAA,SAAA,KAAc,MAAQ,EAAA;AACxD,MAAA,MAAM,aACJ,QAAS,CAAA,OAAA,KAAY,OACjB,KACA,CAAA,GAAA,QAAA,CAAS,QAAQ,qBAAsB,EAAA;AAC7C,MAAA,MAAMC,SAAW,GAAAC,uDAAA;AAAA,QACf,aAAc,CAAA,OAAA;AAAA,QACd,SAAA;AAAA,QACA,UAAA;AAAA,QACA,SAAA;AAAA,QACA,QAAA;AAAA,QACA;AAAA,OACF;AACA,MAAA,WAAA,CAAYD,SAAQ,CAAA;AAAA;AACtB,GACF,EAAG,CAAC,aAAe,EAAA,QAAA,EAAU,YAAY,SAAW,EAAA,SAAA,EAAW,YAAY,CAAC,CAAA;AAE5E,EAAA,MAAM,gBAAmB,GAAAE,iBAAA;AAAA,IACvB,CAAC,EAA8B,KAAA;AAC7B,MAAA,QAAA,CAAS,OAAU,GAAA,EAAA;AACnB,MAAA,IAAI,EAAM,IAAA,SAAA,KAAc,QAAY,IAAA,aAAA,CAAc,OAAS,EAAA;AACzD,QAAA,MAAM,EAAE,MAAA,EAAQ,KAAM,EAAA,GAAI,GAAG,qBAAsB,EAAA;AACnD,QAAA,WAAA;AAAA,UACED,uDAAA;AAAA,YACE,aAAc,CAAA,OAAA;AAAA,YACd,SAAA;AAAA,YACA,UAAA;AAAA,YACA,SAAA;AAAA,YACA,KAAA,CAAA;AAAA,YACA,EAAE,QAAQ,KAAM;AAAA;AAClB,SACF;AAAA;AACF,KACF;AAAA,IACA,CAAC,aAAA,EAAe,UAAY,EAAA,SAAA,EAAW,SAAS;AAAA,GAClD;AAEA,EAAO,OAAA;AAAA,IACL,QAAA;AAAA,IACA,QAAA,EAAU,SAAc,KAAA,QAAA,GAAW,gBAAmB,GAAA,KAAA;AAAA,GACxD;AACF;;;;"}
1
+ {"version":3,"file":"useAnchoredPosition.js","sources":["../../../../packages/vuu-popups/src/popup/useAnchoredPosition.ts"],"sourcesContent":["import { useCallback, useLayoutEffect, useRef, useState } from \"react\";\nimport {\n getPositionRelativeToAnchor,\n Position,\n} from \"./getPositionRelativeToAnchor\";\nimport { PopupComponentProps } from \"./Popup\";\n\nexport type AnchoredPositionHookProps = Pick<\n PopupComponentProps,\n | \"anchorElement\"\n | \"minWidth\"\n | \"offsetLeft\"\n | \"offsetTop\"\n | \"placement\"\n | \"position\"\n>;\n\nexport const useAnchoredPosition = ({\n anchorElement,\n minWidth,\n offsetLeft = 0,\n offsetTop = 0,\n placement,\n position: positionProp,\n}: AnchoredPositionHookProps) => {\n const popupRef = useRef<HTMLElement | null>(null);\n const [position, setPosition] = useState<Position | undefined>(positionProp);\n\n // maybe better as useMemo ?\n useLayoutEffect(() => {\n if (placement === \"absolute\" && positionProp) {\n setPosition(positionProp);\n } else if (anchorElement.current && placement !== \"auto\") {\n const dimensions =\n popupRef.current === null\n ? undefined\n : popupRef.current.getBoundingClientRect();\n const position = getPositionRelativeToAnchor(\n anchorElement.current,\n placement,\n offsetLeft,\n offsetTop,\n minWidth,\n dimensions\n );\n setPosition(position);\n }\n }, [anchorElement, minWidth, offsetLeft, offsetTop, placement, positionProp]);\n\n const popupCallbackRef = useCallback(\n (el: HTMLDivElement | null) => {\n popupRef.current = el;\n if (el && placement === \"center\" && anchorElement.current) {\n const { height, width } = el.getBoundingClientRect();\n setPosition(\n getPositionRelativeToAnchor(\n anchorElement.current,\n placement,\n offsetLeft,\n offsetTop,\n undefined,\n { height, width }\n )\n );\n }\n },\n [anchorElement, offsetLeft, offsetTop, placement]\n );\n\n return {\n position,\n popupRef: placement === \"center\" ? popupCallbackRef : undefined,\n };\n};\n"],"names":["useRef","useState","useLayoutEffect","position","getPositionRelativeToAnchor","useCallback"],"mappings":";;;;;AAiBO,MAAM,sBAAsB,CAAC;AAAA,EAClC,aAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAa,GAAA,CAAA;AAAA,EACb,SAAY,GAAA,CAAA;AAAA,EACZ,SAAA;AAAA,EACA,QAAU,EAAA;AACZ,CAAiC,KAAA;AAC/B,EAAM,MAAA,QAAA,GAAWA,aAA2B,IAAI,CAAA;AAChD,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIC,eAA+B,YAAY,CAAA;AAG3E,EAAAC,qBAAA,CAAgB,MAAM;AACpB,IAAI,IAAA,SAAA,KAAc,cAAc,YAAc,EAAA;AAC5C,MAAA,WAAA,CAAY,YAAY,CAAA;AAAA,KACf,MAAA,IAAA,aAAA,CAAc,OAAW,IAAA,SAAA,KAAc,MAAQ,EAAA;AACxD,MAAA,MAAM,aACJ,QAAS,CAAA,OAAA,KAAY,OACjB,KACA,CAAA,GAAA,QAAA,CAAS,QAAQ,qBAAsB,EAAA;AAC7C,MAAA,MAAMC,SAAW,GAAAC,uDAAA;AAAA,QACf,aAAc,CAAA,OAAA;AAAA,QACd,SAAA;AAAA,QACA,UAAA;AAAA,QACA,SAAA;AAAA,QACA,QAAA;AAAA,QACA;AAAA,OACF;AACA,MAAA,WAAA,CAAYD,SAAQ,CAAA;AAAA;AACtB,GACF,EAAG,CAAC,aAAe,EAAA,QAAA,EAAU,YAAY,SAAW,EAAA,SAAA,EAAW,YAAY,CAAC,CAAA;AAE5E,EAAA,MAAM,gBAAmB,GAAAE,iBAAA;AAAA,IACvB,CAAC,EAA8B,KAAA;AAC7B,MAAA,QAAA,CAAS,OAAU,GAAA,EAAA;AACnB,MAAA,IAAI,EAAM,IAAA,SAAA,KAAc,QAAY,IAAA,aAAA,CAAc,OAAS,EAAA;AACzD,QAAA,MAAM,EAAE,MAAA,EAAQ,KAAM,EAAA,GAAI,GAAG,qBAAsB,EAAA;AACnD,QAAA,WAAA;AAAA,UACED,uDAAA;AAAA,YACE,aAAc,CAAA,OAAA;AAAA,YACd,SAAA;AAAA,YACA,UAAA;AAAA,YACA,SAAA;AAAA,YACA,KAAA,CAAA;AAAA,YACA,EAAE,QAAQ,KAAM;AAAA;AAClB,SACF;AAAA;AACF,KACF;AAAA,IACA,CAAC,aAAA,EAAe,UAAY,EAAA,SAAA,EAAW,SAAS;AAAA,GAClD;AAEA,EAAO,OAAA;AAAA,IACL,QAAA;AAAA,IACA,QAAA,EAAU,SAAc,KAAA,QAAA,GAAW,gBAAmB,GAAA,KAAA;AAAA,GACxD;AACF;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"PopupMenu.js","sources":["../../src/popup-menu/PopupMenu.tsx"],"sourcesContent":["import { Button, ButtonProps } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { MenuActionHandler, MenuBuilder } from \"@vuu-ui/vuu-context-menu\";\nimport { Icon, IconButton } from \"@vuu-ui/vuu-ui-controls\";\nimport { useId } from \"@vuu-ui/vuu-utils\";\nimport cx from \"clsx\";\nimport { HTMLAttributes, KeyboardEvent, RefObject } from \"react\";\nimport { PopupPlacement } from \"../popup/Popup\";\nimport { usePopupMenu } from \"./usePopupMenu\";\n\nimport popupMenuCss from \"./PopupMenu.css\";\n\nconst classBase = \"vuuPopupMenu\";\n\nexport type TabAwayClosePopup = {\n closedBy?: string;\n type: \"tab-away\";\n event: KeyboardEvent;\n};\n\nexport type ClickAwayClosePopup = {\n closedBy?: string;\n type: \"click-away\";\n mouseEvt: MouseEvent;\n};\n\nexport type EscapeClosePopup = {\n closedBy?: string;\n event: KeyboardEvent;\n type: \"escape\";\n};\n\nexport type MenuActionClosePopup = {\n closedBy?: string;\n menuId: string;\n options: unknown;\n type: \"menu-action\";\n};\n\nexport type PopupCloseReason =\n | ClickAwayClosePopup\n | EscapeClosePopup\n | MenuActionClosePopup\n | TabAwayClosePopup;\n\nexport type MenuCloseHandler = (reason?: PopupCloseReason) => void;\n\nexport interface PopupMenuProps extends HTMLAttributes<HTMLButtonElement> {\n anchorElement?: RefObject<HTMLElement | null>;\n disabled?: boolean;\n icon?: string;\n label?: string;\n menuActionHandler?: MenuActionHandler;\n menuBuilder?: MenuBuilder;\n menuClassName?: string;\n menuLocation?: string;\n menuOptions?: { [key: string]: unknown };\n onMenuClose?: MenuCloseHandler;\n onMenuOpen?: () => void;\n popupPlacement?: PopupPlacement;\n variant?: ButtonProps[\"variant\"];\n}\n\nexport const PopupMenu = ({\n anchorElement,\n className,\n disabled = false,\n label,\n icon = label ? \"chevron-down\" : \"more-vert\",\n id: idProp,\n menuActionHandler,\n menuBuilder,\n menuClassName,\n menuLocation = \"header\",\n menuOptions,\n onMenuClose,\n onMenuOpen,\n popupPlacement = \"below-right\",\n tabIndex = 0,\n variant = \"secondary\",\n ...htmlAttributes\n}: PopupMenuProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-popup-menu\",\n css: popupMenuCss,\n window: targetWindow,\n });\n\n const id = useId(idProp);\n\n const { ariaAttributes, buttonProps, menuOpen, rootRef } = usePopupMenu({\n anchorElement,\n id,\n menuActionHandler,\n menuBuilder,\n menuClassName,\n menuLocation,\n onMenuClose,\n onMenuOpen,\n menuOptions,\n popupPlacement,\n tabIndex,\n });\n\n if (label) {\n return (\n <Button\n {...htmlAttributes}\n {...ariaAttributes}\n {...buttonProps}\n className={cx(classBase, className, `${classBase}-withCaption`, {\n \"saltButton-active\": menuOpen,\n })}\n disabled={disabled}\n ref={rootRef}\n variant=\"secondary\"\n >\n {icon ? <Icon name={icon} /> : null}\n {label}\n </Button>\n );\n } else if (icon) {\n return (\n <IconButton\n {...htmlAttributes}\n {...ariaAttributes}\n {...buttonProps}\n className={cx(classBase, className, {\n \"saltButton-active\": menuOpen,\n })}\n disabled={disabled}\n icon={icon}\n ref={rootRef}\n variant={variant}\n />\n );\n } else {\n console.error(\"PopupMenu must have a label or an icon (or both)\");\n return null;\n }\n};\n"],"names":["useWindow","useComponentCssInjection","popupMenuCss","useId","usePopupMenu","jsxs","Button","jsx","Icon","IconButton"],"mappings":";;;;;;;;;;;;AAaA,MAAM,SAAY,GAAA,cAAA;AAmDX,MAAM,YAAY,CAAC;AAAA,EACxB,aAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAW,GAAA,KAAA;AAAA,EACX,KAAA;AAAA,EACA,IAAA,GAAO,QAAQ,cAAiB,GAAA,WAAA;AAAA,EAChC,EAAI,EAAA,MAAA;AAAA,EACJ,iBAAA;AAAA,EACA,WAAA;AAAA,EACA,aAAA;AAAA,EACA,YAAe,GAAA,QAAA;AAAA,EACf,WAAA;AAAA,EACA,WAAA;AAAA,EACA,UAAA;AAAA,EACA,cAAiB,GAAA,aAAA;AAAA,EACjB,QAAW,GAAA,CAAA;AAAA,EACX,OAAU,GAAA,WAAA;AAAA,EACV,GAAG;AACL,CAAsB,KAAA;AACpB,EAAA,MAAM,eAAeA,gBAAU,EAAA;AAC/B,EAAyBC,+BAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,gBAAA;AAAA,IACR,GAAK,EAAAC,WAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAM,MAAA,EAAA,GAAKC,eAAM,MAAM,CAAA;AAEvB,EAAA,MAAM,EAAE,cAAgB,EAAA,WAAA,EAAa,QAAU,EAAA,OAAA,KAAYC,yBAAa,CAAA;AAAA,IACtE,aAAA;AAAA,IACA,EAAA;AAAA,IACA,iBAAA;AAAA,IACA,WAAA;AAAA,IACA,aAAA;AAAA,IACA,YAAA;AAAA,IACA,WAAA;AAAA,IACA,UAAA;AAAA,IACA,WAAA;AAAA,IACA,cAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,IAAI,KAAO,EAAA;AACT,IACE,uBAAAC,eAAA;AAAA,MAACC,WAAA;AAAA,MAAA;AAAA,QACE,GAAG,cAAA;AAAA,QACH,GAAG,cAAA;AAAA,QACH,GAAG,WAAA;AAAA,QACJ,WAAW,EAAG,CAAA,SAAA,EAAW,SAAW,EAAA,CAAA,EAAG,SAAS,CAAgB,YAAA,CAAA,EAAA;AAAA,UAC9D,mBAAqB,EAAA;AAAA,SACtB,CAAA;AAAA,QACD,QAAA;AAAA,QACA,GAAK,EAAA,OAAA;AAAA,QACL,OAAQ,EAAA,WAAA;AAAA,QAEP,QAAA,EAAA;AAAA,UAAA,IAAA,mBAAQC,cAAA,CAAAC,kBAAA,EAAA,EAAK,IAAM,EAAA,IAAA,EAAM,CAAK,GAAA,IAAA;AAAA,UAC9B;AAAA;AAAA;AAAA,KACH;AAAA,aAEO,IAAM,EAAA;AACf,IACE,uBAAAD,cAAA;AAAA,MAACE,wBAAA;AAAA,MAAA;AAAA,QACE,GAAG,cAAA;AAAA,QACH,GAAG,cAAA;AAAA,QACH,GAAG,WAAA;AAAA,QACJ,SAAA,EAAW,EAAG,CAAA,SAAA,EAAW,SAAW,EAAA;AAAA,UAClC,mBAAqB,EAAA;AAAA,SACtB,CAAA;AAAA,QACD,QAAA;AAAA,QACA,IAAA;AAAA,QACA,GAAK,EAAA,OAAA;AAAA,QACL;AAAA;AAAA,KACF;AAAA,GAEG,MAAA;AACL,IAAA,OAAA,CAAQ,MAAM,kDAAkD,CAAA;AAChE,IAAO,OAAA,IAAA;AAAA;AAEX;;;;"}
1
+ {"version":3,"file":"PopupMenu.js","sources":["../../../../packages/vuu-popups/src/popup-menu/PopupMenu.tsx"],"sourcesContent":["import { Button, ButtonProps } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { MenuActionHandler, MenuBuilder } from \"@vuu-ui/vuu-context-menu\";\nimport { Icon, IconButton } from \"@vuu-ui/vuu-ui-controls\";\nimport { useId } from \"@vuu-ui/vuu-utils\";\nimport cx from \"clsx\";\nimport { HTMLAttributes, KeyboardEvent, RefObject } from \"react\";\nimport { PopupPlacement } from \"../popup/Popup\";\nimport { usePopupMenu } from \"./usePopupMenu\";\n\nimport popupMenuCss from \"./PopupMenu.css\";\n\nconst classBase = \"vuuPopupMenu\";\n\nexport type TabAwayClosePopup = {\n closedBy?: string;\n type: \"tab-away\";\n event: KeyboardEvent;\n};\n\nexport type ClickAwayClosePopup = {\n closedBy?: string;\n type: \"click-away\";\n mouseEvt: MouseEvent;\n};\n\nexport type EscapeClosePopup = {\n closedBy?: string;\n event: KeyboardEvent;\n type: \"escape\";\n};\n\nexport type MenuActionClosePopup = {\n closedBy?: string;\n menuId: string;\n options: unknown;\n type: \"menu-action\";\n};\n\nexport type PopupCloseReason =\n | ClickAwayClosePopup\n | EscapeClosePopup\n | MenuActionClosePopup\n | TabAwayClosePopup;\n\nexport type MenuCloseHandler = (reason?: PopupCloseReason) => void;\n\nexport interface PopupMenuProps extends HTMLAttributes<HTMLButtonElement> {\n anchorElement?: RefObject<HTMLElement | null>;\n disabled?: boolean;\n icon?: string;\n label?: string;\n menuActionHandler?: MenuActionHandler;\n menuBuilder?: MenuBuilder;\n menuClassName?: string;\n menuLocation?: string;\n menuOptions?: { [key: string]: unknown };\n onMenuClose?: MenuCloseHandler;\n onMenuOpen?: () => void;\n popupPlacement?: PopupPlacement;\n variant?: ButtonProps[\"variant\"];\n}\n\nexport const PopupMenu = ({\n anchorElement,\n className,\n disabled = false,\n label,\n icon = label ? \"chevron-down\" : \"more-vert\",\n id: idProp,\n menuActionHandler,\n menuBuilder,\n menuClassName,\n menuLocation = \"header\",\n menuOptions,\n onMenuClose,\n onMenuOpen,\n popupPlacement = \"below-right\",\n tabIndex = 0,\n variant = \"secondary\",\n ...htmlAttributes\n}: PopupMenuProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-popup-menu\",\n css: popupMenuCss,\n window: targetWindow,\n });\n\n const id = useId(idProp);\n\n const { ariaAttributes, buttonProps, menuOpen, rootRef } = usePopupMenu({\n anchorElement,\n id,\n menuActionHandler,\n menuBuilder,\n menuClassName,\n menuLocation,\n onMenuClose,\n onMenuOpen,\n menuOptions,\n popupPlacement,\n tabIndex,\n });\n\n if (label) {\n return (\n <Button\n {...htmlAttributes}\n {...ariaAttributes}\n {...buttonProps}\n className={cx(classBase, className, `${classBase}-withCaption`, {\n \"saltButton-active\": menuOpen,\n })}\n disabled={disabled}\n ref={rootRef}\n variant=\"secondary\"\n >\n {icon ? <Icon name={icon} /> : null}\n {label}\n </Button>\n );\n } else if (icon) {\n return (\n <IconButton\n {...htmlAttributes}\n {...ariaAttributes}\n {...buttonProps}\n className={cx(classBase, className, {\n \"saltButton-active\": menuOpen,\n })}\n disabled={disabled}\n icon={icon}\n ref={rootRef}\n variant={variant}\n />\n );\n } else {\n console.error(\"PopupMenu must have a label or an icon (or both)\");\n return null;\n }\n};\n"],"names":["useWindow","useComponentCssInjection","popupMenuCss","useId","usePopupMenu","jsxs","Button","jsx","Icon","IconButton"],"mappings":";;;;;;;;;;;;AAaA,MAAM,SAAY,GAAA,cAAA;AAmDX,MAAM,YAAY,CAAC;AAAA,EACxB,aAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAW,GAAA,KAAA;AAAA,EACX,KAAA;AAAA,EACA,IAAA,GAAO,QAAQ,cAAiB,GAAA,WAAA;AAAA,EAChC,EAAI,EAAA,MAAA;AAAA,EACJ,iBAAA;AAAA,EACA,WAAA;AAAA,EACA,aAAA;AAAA,EACA,YAAe,GAAA,QAAA;AAAA,EACf,WAAA;AAAA,EACA,WAAA;AAAA,EACA,UAAA;AAAA,EACA,cAAiB,GAAA,aAAA;AAAA,EACjB,QAAW,GAAA,CAAA;AAAA,EACX,OAAU,GAAA,WAAA;AAAA,EACV,GAAG;AACL,CAAsB,KAAA;AACpB,EAAA,MAAM,eAAeA,gBAAU,EAAA;AAC/B,EAAyBC,+BAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,gBAAA;AAAA,IACR,GAAK,EAAAC,WAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAM,MAAA,EAAA,GAAKC,eAAM,MAAM,CAAA;AAEvB,EAAA,MAAM,EAAE,cAAgB,EAAA,WAAA,EAAa,QAAU,EAAA,OAAA,KAAYC,yBAAa,CAAA;AAAA,IACtE,aAAA;AAAA,IACA,EAAA;AAAA,IACA,iBAAA;AAAA,IACA,WAAA;AAAA,IACA,aAAA;AAAA,IACA,YAAA;AAAA,IACA,WAAA;AAAA,IACA,UAAA;AAAA,IACA,WAAA;AAAA,IACA,cAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,IAAI,KAAO,EAAA;AACT,IACE,uBAAAC,eAAA;AAAA,MAACC,WAAA;AAAA,MAAA;AAAA,QACE,GAAG,cAAA;AAAA,QACH,GAAG,cAAA;AAAA,QACH,GAAG,WAAA;AAAA,QACJ,WAAW,EAAG,CAAA,SAAA,EAAW,SAAW,EAAA,CAAA,EAAG,SAAS,CAAgB,YAAA,CAAA,EAAA;AAAA,UAC9D,mBAAqB,EAAA;AAAA,SACtB,CAAA;AAAA,QACD,QAAA;AAAA,QACA,GAAK,EAAA,OAAA;AAAA,QACL,OAAQ,EAAA,WAAA;AAAA,QAEP,QAAA,EAAA;AAAA,UAAA,IAAA,mBAAQC,cAAA,CAAAC,kBAAA,EAAA,EAAK,IAAM,EAAA,IAAA,EAAM,CAAK,GAAA,IAAA;AAAA,UAC9B;AAAA;AAAA;AAAA,KACH;AAAA,aAEO,IAAM,EAAA;AACf,IACE,uBAAAD,cAAA;AAAA,MAACE,wBAAA;AAAA,MAAA;AAAA,QACE,GAAG,cAAA;AAAA,QACH,GAAG,cAAA;AAAA,QACH,GAAG,WAAA;AAAA,QACJ,SAAA,EAAW,EAAG,CAAA,SAAA,EAAW,SAAW,EAAA;AAAA,UAClC,mBAAqB,EAAA;AAAA,SACtB,CAAA;AAAA,QACD,QAAA;AAAA,QACA,IAAA;AAAA,QACA,GAAK,EAAA,OAAA;AAAA,QACL;AAAA;AAAA,KACF;AAAA,GAEG,MAAA;AACL,IAAA,OAAA,CAAQ,MAAM,kDAAkD,CAAA;AAChE,IAAO,OAAA,IAAA;AAAA;AAEX;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"usePopupMenu.js","sources":["../../src/popup-menu/usePopupMenu.ts"],"sourcesContent":["import {\n AriaAttributes,\n MouseEvent,\n useCallback,\n useRef,\n useState,\n} from \"react\";\nimport { PopupMenuProps } from \"./PopupMenu\";\nimport { getPositionRelativeToAnchor } from \"../popup/getPositionRelativeToAnchor\";\nimport { PopupPlacement } from \"../popup/Popup\";\nimport { useContextMenu } from \"@vuu-ui/vuu-context-menu\";\n\nexport interface PopupMenuHookProps\n extends Pick<\n PopupMenuProps,\n | \"anchorElement\"\n | \"menuActionHandler\"\n | \"menuBuilder\"\n | \"menuClassName\"\n | \"menuOptions\"\n | \"onMenuClose\"\n | \"onMenuOpen\"\n > {\n id: string;\n menuLocation: string;\n popupPlacement: PopupPlacement;\n tabIndex: number;\n}\n\nexport const usePopupMenu = ({\n anchorElement,\n id,\n menuActionHandler,\n menuBuilder,\n menuLocation,\n menuOptions,\n onMenuClose,\n onMenuOpen,\n popupPlacement,\n tabIndex,\n}: PopupMenuHookProps) => {\n const [menuOpen, _setMenuOpen] = useState(false);\n const suppressShowMenuRef = useRef(false);\n const rootRef = useRef<HTMLButtonElement>(null);\n\n const setMenuOpen = useCallback(\n (isOpen: boolean) => {\n _setMenuOpen(isOpen);\n if (isOpen) {\n onMenuOpen?.();\n }\n },\n [onMenuOpen],\n );\n\n const showContextMenu = useContextMenu(menuBuilder, menuActionHandler);\n\n const handleMenuOpenChange = useCallback(\n (isOpen: boolean) => {\n if (isOpen === false) {\n setMenuOpen(false);\n onMenuClose?.();\n }\n // // If user has clicked the MenuButton whilst menu is open, we want to close it.\n // // The PopupService will close it for us as a 'click-away' event. We don't want\n // // that click on the button to re-open it.\n // if (reasonIsClickAway(reason)) {\n // const target = reason.mouseEvt.target as HTMLElement;\n // if (target === rootRef.current) {\n // suppressShowMenuRef.current = true;\n // }\n // onMenuClose?.(reason);\n // } else {\n // requestAnimationFrame(() => {\n // onMenuClose?.(reason);\n // if (tabIndex !== -1 && reason?.type !== \"tab-away\") {\n // rootRef.current?.focus();\n // }\n // });\n // }\n },\n [onMenuClose, setMenuOpen],\n );\n\n const showMenu = useCallback(\n (e: MouseEvent<HTMLElement>) => {\n if (suppressShowMenuRef.current) {\n suppressShowMenuRef.current = false;\n } else {\n const anchorEl = anchorElement?.current ?? rootRef.current;\n if (anchorEl) {\n const {\n left: x,\n top: y,\n // width,\n } = getPositionRelativeToAnchor(anchorEl, popupPlacement, 0, 0);\n setMenuOpen(true);\n\n showContextMenu(e, menuLocation, menuOptions, {\n // className: menuClassName,\n // id: `${id}-menu`,\n onOpenChange: handleMenuOpenChange,\n x,\n y,\n // style: { width: width ? width - 2 : undefined },\n });\n }\n }\n },\n [\n anchorElement,\n popupPlacement,\n setMenuOpen,\n showContextMenu,\n menuLocation,\n menuOptions,\n handleMenuOpenChange,\n ],\n );\n\n const ariaAttributes: AriaAttributes = {\n \"aria-controls\": menuOpen ? `${id}-menu` : undefined,\n \"aria-expanded\": menuOpen,\n \"aria-haspopup\": \"menu\",\n };\n\n const buttonProps = {\n id,\n onClick: showMenu,\n tabIndex,\n };\n\n return { ariaAttributes, buttonProps, menuOpen, rootRef };\n};\n"],"names":["useState","useRef","useCallback","useContextMenu","getPositionRelativeToAnchor"],"mappings":";;;;;;AA6BO,MAAM,eAAe,CAAC;AAAA,EAC3B,aAAA;AAAA,EACA,EAAA;AAAA,EACA,iBAAA;AAAA,EACA,WAAA;AAAA,EACA,YAAA;AAAA,EACA,WAAA;AAAA,EACA,WAAA;AAAA,EACA,UAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF,CAA0B,KAAA;AACxB,EAAA,MAAM,CAAC,QAAA,EAAU,YAAY,CAAA,GAAIA,eAAS,KAAK,CAAA;AAC/C,EAAM,MAAA,mBAAA,GAAsBC,aAAO,KAAK,CAAA;AACxC,EAAM,MAAA,OAAA,GAAUA,aAA0B,IAAI,CAAA;AAE9C,EAAA,MAAM,WAAc,GAAAC,iBAAA;AAAA,IAClB,CAAC,MAAoB,KAAA;AACnB,MAAA,YAAA,CAAa,MAAM,CAAA;AACnB,MAAA,IAAI,MAAQ,EAAA;AACV,QAAa,UAAA,IAAA;AAAA;AACf,KACF;AAAA,IACA,CAAC,UAAU;AAAA,GACb;AAEA,EAAM,MAAA,eAAA,GAAkBC,6BAAe,CAAA,WAAA,EAAa,iBAAiB,CAAA;AAErE,EAAA,MAAM,oBAAuB,GAAAD,iBAAA;AAAA,IAC3B,CAAC,MAAoB,KAAA;AACnB,MAAA,IAAI,WAAW,KAAO,EAAA;AACpB,QAAA,WAAA,CAAY,KAAK,CAAA;AACjB,QAAc,WAAA,IAAA;AAAA;AAChB,KAkBF;AAAA,IACA,CAAC,aAAa,WAAW;AAAA,GAC3B;AAEA,EAAA,MAAM,QAAW,GAAAA,iBAAA;AAAA,IACf,CAAC,CAA+B,KAAA;AAC9B,MAAA,IAAI,oBAAoB,OAAS,EAAA;AAC/B,QAAA,mBAAA,CAAoB,OAAU,GAAA,KAAA;AAAA,OACzB,MAAA;AACL,QAAM,MAAA,QAAA,GAAW,aAAe,EAAA,OAAA,IAAW,OAAQ,CAAA,OAAA;AACnD,QAAA,IAAI,QAAU,EAAA;AACZ,UAAM,MAAA;AAAA,YACJ,IAAM,EAAA,CAAA;AAAA,YACN,GAAK,EAAA;AAAA;AAAA,WAEH,GAAAE,uDAAA,CAA4B,QAAU,EAAA,cAAA,EAAgB,GAAG,CAAC,CAAA;AAC9D,UAAA,WAAA,CAAY,IAAI,CAAA;AAEhB,UAAgB,eAAA,CAAA,CAAA,EAAG,cAAc,WAAa,EAAA;AAAA;AAAA;AAAA,YAG5C,YAAc,EAAA,oBAAA;AAAA,YACd,CAAA;AAAA,YACA;AAAA;AAAA,WAED,CAAA;AAAA;AACH;AACF,KACF;AAAA,IACA;AAAA,MACE,aAAA;AAAA,MACA,cAAA;AAAA,MACA,WAAA;AAAA,MACA,eAAA;AAAA,MACA,YAAA;AAAA,MACA,WAAA;AAAA,MACA;AAAA;AACF,GACF;AAEA,EAAA,MAAM,cAAiC,GAAA;AAAA,IACrC,eAAiB,EAAA,QAAA,GAAW,CAAG,EAAA,EAAE,CAAU,KAAA,CAAA,GAAA,KAAA,CAAA;AAAA,IAC3C,eAAiB,EAAA,QAAA;AAAA,IACjB,eAAiB,EAAA;AAAA,GACnB;AAEA,EAAA,MAAM,WAAc,GAAA;AAAA,IAClB,EAAA;AAAA,IACA,OAAS,EAAA,QAAA;AAAA,IACT;AAAA,GACF;AAEA,EAAA,OAAO,EAAE,cAAA,EAAgB,WAAa,EAAA,QAAA,EAAU,OAAQ,EAAA;AAC1D;;;;"}
1
+ {"version":3,"file":"usePopupMenu.js","sources":["../../../../packages/vuu-popups/src/popup-menu/usePopupMenu.ts"],"sourcesContent":["import {\n AriaAttributes,\n MouseEvent,\n useCallback,\n useRef,\n useState,\n} from \"react\";\nimport { PopupMenuProps } from \"./PopupMenu\";\nimport { getPositionRelativeToAnchor } from \"../popup/getPositionRelativeToAnchor\";\nimport { PopupPlacement } from \"../popup/Popup\";\nimport { useContextMenu } from \"@vuu-ui/vuu-context-menu\";\n\nexport interface PopupMenuHookProps\n extends Pick<\n PopupMenuProps,\n | \"anchorElement\"\n | \"menuActionHandler\"\n | \"menuBuilder\"\n | \"menuClassName\"\n | \"menuOptions\"\n | \"onMenuClose\"\n | \"onMenuOpen\"\n > {\n id: string;\n menuLocation: string;\n popupPlacement: PopupPlacement;\n tabIndex: number;\n}\n\nexport const usePopupMenu = ({\n anchorElement,\n id,\n menuActionHandler,\n menuBuilder,\n menuLocation,\n menuOptions,\n onMenuClose,\n onMenuOpen,\n popupPlacement,\n tabIndex,\n}: PopupMenuHookProps) => {\n const [menuOpen, _setMenuOpen] = useState(false);\n const suppressShowMenuRef = useRef(false);\n const rootRef = useRef<HTMLButtonElement>(null);\n\n const setMenuOpen = useCallback(\n (isOpen: boolean) => {\n _setMenuOpen(isOpen);\n if (isOpen) {\n onMenuOpen?.();\n }\n },\n [onMenuOpen],\n );\n\n const showContextMenu = useContextMenu(menuBuilder, menuActionHandler);\n\n const handleMenuOpenChange = useCallback(\n (isOpen: boolean) => {\n if (isOpen === false) {\n setMenuOpen(false);\n onMenuClose?.();\n }\n // // If user has clicked the MenuButton whilst menu is open, we want to close it.\n // // The PopupService will close it for us as a 'click-away' event. We don't want\n // // that click on the button to re-open it.\n // if (reasonIsClickAway(reason)) {\n // const target = reason.mouseEvt.target as HTMLElement;\n // if (target === rootRef.current) {\n // suppressShowMenuRef.current = true;\n // }\n // onMenuClose?.(reason);\n // } else {\n // requestAnimationFrame(() => {\n // onMenuClose?.(reason);\n // if (tabIndex !== -1 && reason?.type !== \"tab-away\") {\n // rootRef.current?.focus();\n // }\n // });\n // }\n },\n [onMenuClose, setMenuOpen],\n );\n\n const showMenu = useCallback(\n (e: MouseEvent<HTMLElement>) => {\n if (suppressShowMenuRef.current) {\n suppressShowMenuRef.current = false;\n } else {\n const anchorEl = anchorElement?.current ?? rootRef.current;\n if (anchorEl) {\n const {\n left: x,\n top: y,\n // width,\n } = getPositionRelativeToAnchor(anchorEl, popupPlacement, 0, 0);\n setMenuOpen(true);\n\n showContextMenu(e, menuLocation, menuOptions, {\n // className: menuClassName,\n // id: `${id}-menu`,\n onOpenChange: handleMenuOpenChange,\n x,\n y,\n // style: { width: width ? width - 2 : undefined },\n });\n }\n }\n },\n [\n anchorElement,\n popupPlacement,\n setMenuOpen,\n showContextMenu,\n menuLocation,\n menuOptions,\n handleMenuOpenChange,\n ],\n );\n\n const ariaAttributes: AriaAttributes = {\n \"aria-controls\": menuOpen ? `${id}-menu` : undefined,\n \"aria-expanded\": menuOpen,\n \"aria-haspopup\": \"menu\",\n };\n\n const buttonProps = {\n id,\n onClick: showMenu,\n tabIndex,\n };\n\n return { ariaAttributes, buttonProps, menuOpen, rootRef };\n};\n"],"names":["useState","useRef","useCallback","useContextMenu","getPositionRelativeToAnchor"],"mappings":";;;;;;AA6BO,MAAM,eAAe,CAAC;AAAA,EAC3B,aAAA;AAAA,EACA,EAAA;AAAA,EACA,iBAAA;AAAA,EACA,WAAA;AAAA,EACA,YAAA;AAAA,EACA,WAAA;AAAA,EACA,WAAA;AAAA,EACA,UAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF,CAA0B,KAAA;AACxB,EAAA,MAAM,CAAC,QAAA,EAAU,YAAY,CAAA,GAAIA,eAAS,KAAK,CAAA;AAC/C,EAAM,MAAA,mBAAA,GAAsBC,aAAO,KAAK,CAAA;AACxC,EAAM,MAAA,OAAA,GAAUA,aAA0B,IAAI,CAAA;AAE9C,EAAA,MAAM,WAAc,GAAAC,iBAAA;AAAA,IAClB,CAAC,MAAoB,KAAA;AACnB,MAAA,YAAA,CAAa,MAAM,CAAA;AACnB,MAAA,IAAI,MAAQ,EAAA;AACV,QAAa,UAAA,IAAA;AAAA;AACf,KACF;AAAA,IACA,CAAC,UAAU;AAAA,GACb;AAEA,EAAM,MAAA,eAAA,GAAkBC,6BAAe,CAAA,WAAA,EAAa,iBAAiB,CAAA;AAErE,EAAA,MAAM,oBAAuB,GAAAD,iBAAA;AAAA,IAC3B,CAAC,MAAoB,KAAA;AACnB,MAAA,IAAI,WAAW,KAAO,EAAA;AACpB,QAAA,WAAA,CAAY,KAAK,CAAA;AACjB,QAAc,WAAA,IAAA;AAAA;AAChB,KAkBF;AAAA,IACA,CAAC,aAAa,WAAW;AAAA,GAC3B;AAEA,EAAA,MAAM,QAAW,GAAAA,iBAAA;AAAA,IACf,CAAC,CAA+B,KAAA;AAC9B,MAAA,IAAI,oBAAoB,OAAS,EAAA;AAC/B,QAAA,mBAAA,CAAoB,OAAU,GAAA,KAAA;AAAA,OACzB,MAAA;AACL,QAAM,MAAA,QAAA,GAAW,aAAe,EAAA,OAAA,IAAW,OAAQ,CAAA,OAAA;AACnD,QAAA,IAAI,QAAU,EAAA;AACZ,UAAM,MAAA;AAAA,YACJ,IAAM,EAAA,CAAA;AAAA,YACN,GAAK,EAAA;AAAA;AAAA,WAEH,GAAAE,uDAAA,CAA4B,QAAU,EAAA,cAAA,EAAgB,GAAG,CAAC,CAAA;AAC9D,UAAA,WAAA,CAAY,IAAI,CAAA;AAEhB,UAAgB,eAAA,CAAA,CAAA,EAAG,cAAc,WAAa,EAAA;AAAA;AAAA;AAAA,YAG5C,YAAc,EAAA,oBAAA;AAAA,YACd,CAAA;AAAA,YACA;AAAA;AAAA,WAED,CAAA;AAAA;AACH;AACF,KACF;AAAA,IACA;AAAA,MACE,aAAA;AAAA,MACA,cAAA;AAAA,MACA,WAAA;AAAA,MACA,eAAA;AAAA,MACA,YAAA;AAAA,MACA,WAAA;AAAA,MACA;AAAA;AACF,GACF;AAEA,EAAA,MAAM,cAAiC,GAAA;AAAA,IACrC,eAAiB,EAAA,QAAA,GAAW,CAAG,EAAA,EAAE,CAAU,KAAA,CAAA,GAAA,KAAA,CAAA;AAAA,IAC3C,eAAiB,EAAA,QAAA;AAAA,IACjB,eAAiB,EAAA;AAAA,GACnB;AAEA,EAAA,MAAM,WAAc,GAAA;AAAA,IAClB,EAAA;AAAA,IACA,OAAS,EAAA,QAAA;AAAA,IACT;AAAA,GACF;AAEA,EAAA,OAAO,EAAE,cAAA,EAAgB,WAAa,EAAA,QAAA,EAAU,OAAQ,EAAA;AAC1D;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"Portal.js","sources":["../../src/portal/Portal.tsx"],"sourcesContent":["import { ThemeAttributes, useThemeAttributes } from \"@vuu-ui/vuu-utils\";\nimport { ReactNode, useLayoutEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\n\nimport portalCss from \"./Portal.css\";\n\nexport interface PortalProps {\n /**\n * The children to render into the `container`.\n */\n children?: ReactNode;\n /**\n * An HTML element, component instance, or function that returns either.\n * The `container` will have the portal children appended to it.\n *\n * By default, it uses the body of the top-level document object,\n * so it's simply `document.body` most of the time.\n */\n container?: Element | (() => Element | null) | null;\n /**\n * Id of element into which portal will be rendered. If this node does not exist on the document,\n * it will be created for you. If more than one value is provided, the first element found will\n * be used.\n */\n id?: string | string[];\n /**\n * Callback invoked immediately after render (in layoutEffect). Can be\n * used to check position vis-a-vis viewport and adjust if out of bounds\n */\n onRender?: () => void;\n /**\n * Allow conditional rendering of this Portal, if false, will render nothing.\n * Defaults to true\n */\n open?: boolean;\n /**\n * ThemeAttributes can be passed in for cases where ContextMenu is\n * rendered via popup-service showPopup, outside the Context hierarchy.\n */\n themeAttributes?: ThemeAttributes;\n}\n\nfunction getContainer(container: PortalProps[\"container\"]) {\n return typeof container === \"function\" ? container() : container;\n}\n\nconst DEFAULT_ID = [\"vuu-dialog-portal-root\", \"vuu-portal-root\"];\n\nconst getFirstAvailableElementById = (id: string | string[]) => {\n if (Array.isArray(id)) {\n for (const i of id) {\n const element = document.getElementById(i);\n if (element) {\n return element;\n }\n }\n } else {\n return document.getElementById(id);\n }\n return null;\n};\n\n/**\n * Portals provide a first-class way to render children into a DOM node\n * that exists outside the DOM hierarchy of the parent component.\n */\nexport const Portal = ({\n children,\n container: containerProp = document.body,\n id = DEFAULT_ID,\n onRender,\n open = true,\n themeAttributes,\n}: PortalProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-portal\",\n css: portalCss,\n window: targetWindow,\n });\n\n const [mounted, setMounted] = useState(false);\n const portalRef = useRef<HTMLElement | null>(null);\n const container = getContainer(containerProp) ?? document.body;\n const [themeClass, densityClass, dataMode] =\n useThemeAttributes(themeAttributes);\n\n useLayoutEffect(() => {\n const root = getFirstAvailableElementById(id);\n if (root) {\n portalRef.current = root;\n } else {\n portalRef.current = document.createElement(\"div\");\n portalRef.current.id =\n typeof id === \"string\"\n ? id\n : id.length > 0\n ? (id.at(-1) as string)\n : \"vuu-portal-root\";\n }\n const el = portalRef.current;\n if (!container.contains(el)) {\n container.appendChild(el);\n }\n el.classList.add(themeClass, densityClass);\n el.dataset.mode = dataMode;\n setMounted(true);\n }, [id, container, themeClass, densityClass, dataMode]);\n\n useLayoutEffect(() => {\n requestAnimationFrame(() => {\n onRender?.();\n });\n }, [onRender]);\n\n if (open && mounted && portalRef.current && children) {\n return createPortal(children, portalRef.current);\n }\n\n return null;\n};\n"],"names":["useWindow","useComponentCssInjection","portalCss","useState","useRef","useThemeAttributes","useLayoutEffect","createPortal"],"mappings":"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"}
1
+ {"version":3,"file":"Portal.js","sources":["../../../../packages/vuu-popups/src/portal/Portal.tsx"],"sourcesContent":["import { ThemeAttributes, useThemeAttributes } from \"@vuu-ui/vuu-utils\";\nimport { ReactNode, useLayoutEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\n\nimport portalCss from \"./Portal.css\";\n\nexport interface PortalProps {\n /**\n * The children to render into the `container`.\n */\n children?: ReactNode;\n /**\n * An HTML element, component instance, or function that returns either.\n * The `container` will have the portal children appended to it.\n *\n * By default, it uses the body of the top-level document object,\n * so it's simply `document.body` most of the time.\n */\n container?: Element | (() => Element | null) | null;\n /**\n * Id of element into which portal will be rendered. If this node does not exist on the document,\n * it will be created for you. If more than one value is provided, the first element found will\n * be used.\n */\n id?: string | string[];\n /**\n * Callback invoked immediately after render (in layoutEffect). Can be\n * used to check position vis-a-vis viewport and adjust if out of bounds\n */\n onRender?: () => void;\n /**\n * Allow conditional rendering of this Portal, if false, will render nothing.\n * Defaults to true\n */\n open?: boolean;\n /**\n * ThemeAttributes can be passed in for cases where ContextMenu is\n * rendered via popup-service showPopup, outside the Context hierarchy.\n */\n themeAttributes?: ThemeAttributes;\n}\n\nfunction getContainer(container: PortalProps[\"container\"]) {\n return typeof container === \"function\" ? container() : container;\n}\n\nconst DEFAULT_ID = [\"vuu-dialog-portal-root\", \"vuu-portal-root\"];\n\nconst getFirstAvailableElementById = (id: string | string[]) => {\n if (Array.isArray(id)) {\n for (const i of id) {\n const element = document.getElementById(i);\n if (element) {\n return element;\n }\n }\n } else {\n return document.getElementById(id);\n }\n return null;\n};\n\n/**\n * Portals provide a first-class way to render children into a DOM node\n * that exists outside the DOM hierarchy of the parent component.\n */\nexport const Portal = ({\n children,\n container: containerProp = document.body,\n id = DEFAULT_ID,\n onRender,\n open = true,\n themeAttributes,\n}: PortalProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-portal\",\n css: portalCss,\n window: targetWindow,\n });\n\n const [mounted, setMounted] = useState(false);\n const portalRef = useRef<HTMLElement | null>(null);\n const container = getContainer(containerProp) ?? document.body;\n const [themeClass, densityClass, dataMode] =\n useThemeAttributes(themeAttributes);\n\n useLayoutEffect(() => {\n const root = getFirstAvailableElementById(id);\n if (root) {\n portalRef.current = root;\n } else {\n portalRef.current = document.createElement(\"div\");\n portalRef.current.id =\n typeof id === \"string\"\n ? id\n : id.length > 0\n ? (id.at(-1) as string)\n : \"vuu-portal-root\";\n }\n const el = portalRef.current;\n if (!container.contains(el)) {\n container.appendChild(el);\n }\n el.classList.add(themeClass, densityClass);\n el.dataset.mode = dataMode;\n setMounted(true);\n }, [id, container, themeClass, densityClass, dataMode]);\n\n useLayoutEffect(() => {\n requestAnimationFrame(() => {\n onRender?.();\n });\n }, [onRender]);\n\n if (open && mounted && portalRef.current && children) {\n return createPortal(children, portalRef.current);\n }\n\n return null;\n};\n"],"names":["useWindow","useComponentCssInjection","portalCss","useState","useRef","useThemeAttributes","useLayoutEffect","createPortal"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Prompt.js","sources":["../../src/prompt/Prompt.tsx"],"sourcesContent":["import { useThemeAttributes } from \"@vuu-ui/vuu-utils\";\nimport { Button } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport cx from \"clsx\";\nimport { HTMLAttributes, useLayoutEffect, useRef } from \"react\";\nimport { PopupComponentProps, useAnchoredPosition } from \"../popup\";\n\nimport propmtCss from \"./Prompt.css\";\n\nconst classBase = \"vuuPrompt\";\n\nconst AnchorBody = { current: document.body };\n\nconst EMPTY_PROPS = {};\n\nexport interface PromptProps extends HTMLAttributes<HTMLDialogElement> {\n PopupProps?: Partial<PopupComponentProps>;\n cancelButtonLabel?: string;\n confirmButtonLabel?: string;\n onCancel: () => void;\n onConfirm: () => void;\n icon?: string;\n text: string;\n variant?: \"warn\" | \"error\" | \"info\";\n}\n\nexport const Prompt = ({\n PopupProps = EMPTY_PROPS,\n cancelButtonLabel = \"Cancel\",\n confirmButtonLabel = \"Confirm\",\n icon,\n onCancel,\n onConfirm,\n style,\n text,\n title,\n variant = \"info\",\n ...htmlAttributes\n}: PromptProps) => {\n const {\n anchorElement = AnchorBody,\n offsetLeft = 0,\n offsetTop = 0,\n placement = \"below\",\n } = PopupProps;\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-prompt\",\n css: propmtCss,\n window: targetWindow,\n });\n\n const [themeClass, _, dataMode] = useThemeAttributes();\n const { position } = useAnchoredPosition({\n anchorElement,\n offsetLeft,\n offsetTop,\n placement,\n });\n const rootRef = useRef<HTMLDialogElement>(null);\n const confirmRef = useRef<HTMLButtonElement>(null);\n\n useLayoutEffect(() => {\n if (rootRef.current) {\n rootRef.current.showModal();\n if (confirmRef.current) {\n confirmRef.current.focus();\n }\n if (placement.endsWith(\"center\")) {\n const { width } = rootRef.current.getBoundingClientRect();\n rootRef.current.style.marginLeft = `-${width / 2}px`;\n }\n }\n }, [placement]);\n\n return (\n <dialog\n {...htmlAttributes}\n className={cx(classBase, `${classBase}-${variant}`, themeClass)}\n data-mode={dataMode}\n ref={rootRef}\n style={{ ...style, ...position }}\n >\n <form className={`${classBase}-form`}>\n <div className={`${classBase}-header`} data-icon={icon}>\n {title}\n </div>\n <div className={`${classBase}-text`}>{text}</div>\n <div className={`${classBase}-buttonBar`}>\n <Button onClick={onCancel} variant=\"secondary\">\n {cancelButtonLabel}\n </Button>\n <Button onClick={onConfirm} ref={confirmRef} value=\"default\">\n {confirmButtonLabel}\n </Button>\n </div>\n </form>\n </dialog>\n );\n};\n"],"names":["useWindow","useComponentCssInjection","propmtCss","useThemeAttributes","useAnchoredPosition","useRef","useLayoutEffect","jsx","jsxs","Button"],"mappings":"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"}
1
+ {"version":3,"file":"Prompt.js","sources":["../../../../packages/vuu-popups/src/prompt/Prompt.tsx"],"sourcesContent":["import { useThemeAttributes } from \"@vuu-ui/vuu-utils\";\nimport { Button } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport cx from \"clsx\";\nimport { HTMLAttributes, useLayoutEffect, useRef } from \"react\";\nimport { PopupComponentProps, useAnchoredPosition } from \"../popup\";\n\nimport propmtCss from \"./Prompt.css\";\n\nconst classBase = \"vuuPrompt\";\n\nconst AnchorBody = { current: document.body };\n\nconst EMPTY_PROPS = {};\n\nexport interface PromptProps extends HTMLAttributes<HTMLDialogElement> {\n PopupProps?: Partial<PopupComponentProps>;\n cancelButtonLabel?: string;\n confirmButtonLabel?: string;\n onCancel: () => void;\n onConfirm: () => void;\n icon?: string;\n text: string;\n variant?: \"warn\" | \"error\" | \"info\";\n}\n\nexport const Prompt = ({\n PopupProps = EMPTY_PROPS,\n cancelButtonLabel = \"Cancel\",\n confirmButtonLabel = \"Confirm\",\n icon,\n onCancel,\n onConfirm,\n style,\n text,\n title,\n variant = \"info\",\n ...htmlAttributes\n}: PromptProps) => {\n const {\n anchorElement = AnchorBody,\n offsetLeft = 0,\n offsetTop = 0,\n placement = \"below\",\n } = PopupProps;\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-prompt\",\n css: propmtCss,\n window: targetWindow,\n });\n\n const [themeClass, _, dataMode] = useThemeAttributes();\n const { position } = useAnchoredPosition({\n anchorElement,\n offsetLeft,\n offsetTop,\n placement,\n });\n const rootRef = useRef<HTMLDialogElement>(null);\n const confirmRef = useRef<HTMLButtonElement>(null);\n\n useLayoutEffect(() => {\n if (rootRef.current) {\n rootRef.current.showModal();\n if (confirmRef.current) {\n confirmRef.current.focus();\n }\n if (placement.endsWith(\"center\")) {\n const { width } = rootRef.current.getBoundingClientRect();\n rootRef.current.style.marginLeft = `-${width / 2}px`;\n }\n }\n }, [placement]);\n\n return (\n <dialog\n {...htmlAttributes}\n className={cx(classBase, `${classBase}-${variant}`, themeClass)}\n data-mode={dataMode}\n ref={rootRef}\n style={{ ...style, ...position }}\n >\n <form className={`${classBase}-form`}>\n <div className={`${classBase}-header`} data-icon={icon}>\n {title}\n </div>\n <div className={`${classBase}-text`}>{text}</div>\n <div className={`${classBase}-buttonBar`}>\n <Button onClick={onCancel} variant=\"secondary\">\n {cancelButtonLabel}\n </Button>\n <Button onClick={onConfirm} ref={confirmRef} value=\"default\">\n {confirmButtonLabel}\n </Button>\n </div>\n </form>\n </dialog>\n );\n};\n"],"names":["useWindow","useComponentCssInjection","propmtCss","useThemeAttributes","useAnchoredPosition","useRef","useLayoutEffect","jsx","jsxs","Button"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Tooltip.js","sources":["../../src/tooltip/Tooltip.tsx"],"sourcesContent":["import { CSSProperties, MouseEventHandler, ReactNode, RefObject } from \"react\";\nimport { Portal } from \"../portal\";\nimport {\n TooltipPlacement,\n useTooltipAnchoredPosition,\n} from \"./useTooltipAnchoredPosition\";\nimport cx from \"clsx\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\n\nimport tooltipCss from \"./Tooltip.css\";\n\nconst classBase = \"vuuTooltip\";\n\nexport type TooltipStatus = \"warning\" | \"error\" | \"info\";\nexport interface TooltipProps {\n anchorElement: RefObject<HTMLElement | null>;\n children: ReactNode;\n className?: string;\n id?: string;\n onMouseEnter: MouseEventHandler;\n onMouseLeave: MouseEventHandler;\n placement: TooltipPlacement | TooltipPlacement[];\n status?: TooltipStatus;\n style?: CSSProperties;\n}\n\nexport const Tooltip = ({\n anchorElement,\n children,\n className,\n id,\n onMouseEnter,\n onMouseLeave,\n placement: placementProp,\n status,\n style: styleProp,\n}: TooltipProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-tooltip\",\n css: tooltipCss,\n window: targetWindow,\n });\n\n const ref = useTooltipAnchoredPosition({\n anchorElement,\n placement: placementProp,\n });\n return (\n <Portal>\n <div\n className={cx(classBase, className, \"vuuHidden\", {\n [`${classBase}-error`]: status === \"error\",\n })}\n id={id}\n ref={ref}\n style={{ ...styleProp, left: 0, top: 0 }}\n >\n <span\n className={`${classBase}-content`}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n {children}\n </span>\n </div>\n </Portal>\n );\n};\n"],"names":["useWindow","useComponentCssInjection","tooltipCss","useTooltipAnchoredPosition","Portal","jsx"],"mappings":";;;;;;;;;;AAYA,MAAM,SAAY,GAAA,YAAA;AAeX,MAAM,UAAU,CAAC;AAAA,EACtB,aAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,EAAA;AAAA,EACA,YAAA;AAAA,EACA,YAAA;AAAA,EACA,SAAW,EAAA,aAAA;AAAA,EACX,MAAA;AAAA,EACA,KAAO,EAAA;AACT,CAAoB,KAAA;AAClB,EAAA,MAAM,eAAeA,gBAAU,EAAA;AAC/B,EAAyBC,+BAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,aAAA;AAAA,IACR,GAAK,EAAAC,SAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAA,MAAM,MAAMC,qDAA2B,CAAA;AAAA,IACrC,aAAA;AAAA,IACA,SAAW,EAAA;AAAA,GACZ,CAAA;AACD,EAAA,sCACGC,aACC,EAAA,EAAA,QAAA,kBAAAC,cAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAW,EAAA,EAAA,CAAG,SAAW,EAAA,SAAA,EAAW,WAAa,EAAA;AAAA,QAC/C,CAAC,CAAA,EAAG,SAAS,CAAA,MAAA,CAAQ,GAAG,MAAW,KAAA;AAAA,OACpC,CAAA;AAAA,MACD,EAAA;AAAA,MACA,GAAA;AAAA,MACA,OAAO,EAAE,GAAG,WAAW,IAAM,EAAA,CAAA,EAAG,KAAK,CAAE,EAAA;AAAA,MAEvC,QAAA,kBAAAA,cAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,SAAA,EAAW,GAAG,SAAS,CAAA,QAAA,CAAA;AAAA,UACvB,YAAA;AAAA,UACA,YAAA;AAAA,UAEC;AAAA;AAAA;AACH;AAAA,GAEJ,EAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"Tooltip.js","sources":["../../../../packages/vuu-popups/src/tooltip/Tooltip.tsx"],"sourcesContent":["import { CSSProperties, MouseEventHandler, ReactNode, RefObject } from \"react\";\nimport { Portal } from \"../portal\";\nimport {\n TooltipPlacement,\n useTooltipAnchoredPosition,\n} from \"./useTooltipAnchoredPosition\";\nimport cx from \"clsx\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\n\nimport tooltipCss from \"./Tooltip.css\";\n\nconst classBase = \"vuuTooltip\";\n\nexport type TooltipStatus = \"warning\" | \"error\" | \"info\";\nexport interface TooltipProps {\n anchorElement: RefObject<HTMLElement | null>;\n children: ReactNode;\n className?: string;\n id?: string;\n onMouseEnter: MouseEventHandler;\n onMouseLeave: MouseEventHandler;\n placement: TooltipPlacement | TooltipPlacement[];\n status?: TooltipStatus;\n style?: CSSProperties;\n}\n\nexport const Tooltip = ({\n anchorElement,\n children,\n className,\n id,\n onMouseEnter,\n onMouseLeave,\n placement: placementProp,\n status,\n style: styleProp,\n}: TooltipProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-tooltip\",\n css: tooltipCss,\n window: targetWindow,\n });\n\n const ref = useTooltipAnchoredPosition({\n anchorElement,\n placement: placementProp,\n });\n return (\n <Portal>\n <div\n className={cx(classBase, className, \"vuuHidden\", {\n [`${classBase}-error`]: status === \"error\",\n })}\n id={id}\n ref={ref}\n style={{ ...styleProp, left: 0, top: 0 }}\n >\n <span\n className={`${classBase}-content`}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n {children}\n </span>\n </div>\n </Portal>\n );\n};\n"],"names":["useWindow","useComponentCssInjection","tooltipCss","useTooltipAnchoredPosition","Portal","jsx"],"mappings":";;;;;;;;;;AAYA,MAAM,SAAY,GAAA,YAAA;AAeX,MAAM,UAAU,CAAC;AAAA,EACtB,aAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,EAAA;AAAA,EACA,YAAA;AAAA,EACA,YAAA;AAAA,EACA,SAAW,EAAA,aAAA;AAAA,EACX,MAAA;AAAA,EACA,KAAO,EAAA;AACT,CAAoB,KAAA;AAClB,EAAA,MAAM,eAAeA,gBAAU,EAAA;AAC/B,EAAyBC,+BAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,aAAA;AAAA,IACR,GAAK,EAAAC,SAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAA,MAAM,MAAMC,qDAA2B,CAAA;AAAA,IACrC,aAAA;AAAA,IACA,SAAW,EAAA;AAAA,GACZ,CAAA;AACD,EAAA,sCACGC,aACC,EAAA,EAAA,QAAA,kBAAAC,cAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAW,EAAA,EAAA,CAAG,SAAW,EAAA,SAAA,EAAW,WAAa,EAAA;AAAA,QAC/C,CAAC,CAAA,EAAG,SAAS,CAAA,MAAA,CAAQ,GAAG,MAAW,KAAA;AAAA,OACpC,CAAA;AAAA,MACD,EAAA;AAAA,MACA,GAAA;AAAA,MACA,OAAO,EAAE,GAAG,WAAW,IAAM,EAAA,CAAA,EAAG,KAAK,CAAE,EAAA;AAAA,MAEvC,QAAA,kBAAAA,cAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,SAAA,EAAW,GAAG,SAAS,CAAA,QAAA,CAAA;AAAA,UACvB,YAAA;AAAA,UACA,YAAA;AAAA,UAEC;AAAA;AAAA;AACH;AAAA,GAEJ,EAAA,CAAA;AAEJ;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"useTooltip.js","sources":["../../src/tooltip/useTooltip.ts"],"sourcesContent":["import { queryClosest, useId } from \"@vuu-ui/vuu-utils\";\nimport { MouseEvent, ReactNode, useCallback, useRef, useState } from \"react\";\nimport { TooltipProps } from \"./Tooltip\";\nimport { TooltipPlacement } from \"./useTooltipAnchoredPosition\";\n\nexport interface TooltipHookProps {\n anchorQuery?: string;\n id: string;\n placement?: TooltipPlacement | TooltipPlacement[];\n tooltipContent: ReactNode;\n}\n\nexport const useTooltip = ({\n anchorQuery = \"*\",\n id: idProp,\n placement = [\"right\", \"above\", \"below\"],\n tooltipContent,\n}: TooltipHookProps) => {\n const hideTooltipRef = useRef<() => void>(undefined);\n const isHoveringRef = useRef(false);\n const anchorElementRef = useRef<HTMLElement | null>(null);\n const mouseEnterTimerRef = useRef<number | undefined>(undefined);\n const mouseLeaveTimerRef = useRef<number | undefined>(undefined);\n const [tooltipProps, setTooltipProps] = useState<TooltipProps | undefined>();\n\n const id = useId(idProp);\n\n const escapeListener = useCallback((evt: KeyboardEvent) => {\n if (evt.key === \"Escape\") {\n hideTooltipRef.current?.();\n }\n }, []);\n\n hideTooltipRef.current = useCallback(() => {\n setTooltipProps(undefined);\n document.removeEventListener(\"keydown\", escapeListener);\n }, [escapeListener]);\n\n const handleMouseEnterTooltip = useCallback(() => {\n window.clearTimeout(mouseLeaveTimerRef.current);\n }, []);\n\n const handleMouseLeaveTooltip = useCallback(() => {\n hideTooltipRef.current?.();\n }, []);\n\n const hideTooltip = useCallback((defer = 0) => {\n if (mouseEnterTimerRef.current) {\n window.clearTimeout(mouseEnterTimerRef.current);\n mouseEnterTimerRef.current = undefined;\n } else if (hideTooltipRef.current) {\n if (defer === 0) {\n hideTooltipRef.current();\n } else {\n mouseLeaveTimerRef.current = window.setTimeout(\n hideTooltipRef.current,\n defer,\n );\n }\n }\n }, []);\n\n const showTooltip = useCallback(\n (ref = anchorElementRef) => {\n const { current: anchorEl } = ref;\n if (anchorEl) {\n setTooltipProps({\n anchorElement: ref,\n children: tooltipContent,\n id: `${id}-tooltip`,\n onMouseEnter: handleMouseEnterTooltip,\n onMouseLeave: handleMouseLeaveTooltip,\n placement: placement,\n });\n // register ESC listener\n document.addEventListener(\"keydown\", escapeListener);\n }\n mouseEnterTimerRef.current = undefined;\n hideTooltip(isHoveringRef.current ? 3000 : 1000);\n },\n [\n escapeListener,\n handleMouseEnterTooltip,\n handleMouseLeaveTooltip,\n hideTooltip,\n id,\n placement,\n tooltipContent,\n ],\n );\n\n const handleMouseEnter = useCallback(\n (evt: MouseEvent) => {\n isHoveringRef.current = true;\n const el = queryClosest(evt.target, anchorQuery);\n if (el) {\n console.log(`el ${el.classList}`);\n anchorElementRef.current = el;\n mouseEnterTimerRef.current = window.setTimeout(showTooltip, 800);\n }\n },\n [anchorQuery, showTooltip],\n );\n\n const handleMouseLeave = useCallback(() => {\n isHoveringRef.current = false;\n hideTooltip(200);\n }, [hideTooltip]);\n\n const anchorProps = {\n \"aria-describedby\": `${id}-tooltip`,\n onMouseEnter: handleMouseEnter,\n onMouseLeave: handleMouseLeave,\n };\n\n return {\n anchorProps,\n hideTooltip,\n showTooltip,\n tooltipProps,\n };\n};\n"],"names":["useRef","useState","useId","useCallback","queryClosest"],"mappings":"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"}
1
+ {"version":3,"file":"useTooltip.js","sources":["../../../../packages/vuu-popups/src/tooltip/useTooltip.ts"],"sourcesContent":["import { queryClosest, useId } from \"@vuu-ui/vuu-utils\";\nimport { MouseEvent, ReactNode, useCallback, useRef, useState } from \"react\";\nimport { TooltipProps } from \"./Tooltip\";\nimport { TooltipPlacement } from \"./useTooltipAnchoredPosition\";\n\nexport interface TooltipHookProps {\n anchorQuery?: string;\n id: string;\n placement?: TooltipPlacement | TooltipPlacement[];\n tooltipContent: ReactNode;\n}\n\nexport const useTooltip = ({\n anchorQuery = \"*\",\n id: idProp,\n placement = [\"right\", \"above\", \"below\"],\n tooltipContent,\n}: TooltipHookProps) => {\n const hideTooltipRef = useRef<() => void>(undefined);\n const isHoveringRef = useRef(false);\n const anchorElementRef = useRef<HTMLElement | null>(null);\n const mouseEnterTimerRef = useRef<number | undefined>(undefined);\n const mouseLeaveTimerRef = useRef<number | undefined>(undefined);\n const [tooltipProps, setTooltipProps] = useState<TooltipProps | undefined>();\n\n const id = useId(idProp);\n\n const escapeListener = useCallback((evt: KeyboardEvent) => {\n if (evt.key === \"Escape\") {\n hideTooltipRef.current?.();\n }\n }, []);\n\n hideTooltipRef.current = useCallback(() => {\n setTooltipProps(undefined);\n document.removeEventListener(\"keydown\", escapeListener);\n }, [escapeListener]);\n\n const handleMouseEnterTooltip = useCallback(() => {\n window.clearTimeout(mouseLeaveTimerRef.current);\n }, []);\n\n const handleMouseLeaveTooltip = useCallback(() => {\n hideTooltipRef.current?.();\n }, []);\n\n const hideTooltip = useCallback((defer = 0) => {\n if (mouseEnterTimerRef.current) {\n window.clearTimeout(mouseEnterTimerRef.current);\n mouseEnterTimerRef.current = undefined;\n } else if (hideTooltipRef.current) {\n if (defer === 0) {\n hideTooltipRef.current();\n } else {\n mouseLeaveTimerRef.current = window.setTimeout(\n hideTooltipRef.current,\n defer,\n );\n }\n }\n }, []);\n\n const showTooltip = useCallback(\n (ref = anchorElementRef) => {\n const { current: anchorEl } = ref;\n if (anchorEl) {\n setTooltipProps({\n anchorElement: ref,\n children: tooltipContent,\n id: `${id}-tooltip`,\n onMouseEnter: handleMouseEnterTooltip,\n onMouseLeave: handleMouseLeaveTooltip,\n placement: placement,\n });\n // register ESC listener\n document.addEventListener(\"keydown\", escapeListener);\n }\n mouseEnterTimerRef.current = undefined;\n hideTooltip(isHoveringRef.current ? 3000 : 1000);\n },\n [\n escapeListener,\n handleMouseEnterTooltip,\n handleMouseLeaveTooltip,\n hideTooltip,\n id,\n placement,\n tooltipContent,\n ],\n );\n\n const handleMouseEnter = useCallback(\n (evt: MouseEvent) => {\n isHoveringRef.current = true;\n const el = queryClosest(evt.target, anchorQuery);\n if (el) {\n console.log(`el ${el.classList}`);\n anchorElementRef.current = el;\n mouseEnterTimerRef.current = window.setTimeout(showTooltip, 800);\n }\n },\n [anchorQuery, showTooltip],\n );\n\n const handleMouseLeave = useCallback(() => {\n isHoveringRef.current = false;\n hideTooltip(200);\n }, [hideTooltip]);\n\n const anchorProps = {\n \"aria-describedby\": `${id}-tooltip`,\n onMouseEnter: handleMouseEnter,\n onMouseLeave: handleMouseLeave,\n };\n\n return {\n anchorProps,\n hideTooltip,\n showTooltip,\n tooltipProps,\n };\n};\n"],"names":["useRef","useState","useId","useCallback","queryClosest"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"useTooltipAnchoredPosition.js","sources":["../../src/tooltip/useTooltipAnchoredPosition.ts"],"sourcesContent":["// TODO merge with Popup\n\nimport { RefCallback, RefObject, useCallback } from \"react\";\n\nexport type TooltipPlacement = \"above\" | \"right\" | \"below\" | \"left\";\n\nconst pointerSize = 12;\nexport interface TooltipAnchoredPositionHookProps {\n anchorElement: RefObject<HTMLElement | null>;\n placement: TooltipPlacement | TooltipPlacement[];\n}\n\nconst roomAbove = (anchor: DOMRect, tooltip: DOMRect) =>\n tooltip.height + pointerSize < anchor.top;\nconst roomLeft = (anchor: DOMRect, tooltip: DOMRect) =>\n tooltip.width + pointerSize < anchor.left;\nconst roomRight = (anchor: DOMRect, tooltip: DOMRect) =>\n anchor.right + tooltip.width + pointerSize < document.body.clientWidth;\nconst roomBelow = (anchor: DOMRect, tooltip: DOMRect) =>\n document.body.clientHeight - anchor.bottom > tooltip.height + pointerSize;\n\nconst roomAvailableAtPlacement = (\n placement: TooltipPlacement,\n anchor: DOMRect,\n tooltip: DOMRect,\n) => {\n switch (placement) {\n case \"above\":\n return roomAbove(anchor, tooltip);\n case \"left\":\n return roomLeft(anchor, tooltip);\n case \"below\":\n return roomBelow(anchor, tooltip);\n case \"right\":\n return roomRight(anchor, tooltip);\n default:\n throw Error(\"invalid tooltip placement\");\n }\n};\n\ntype Position = { left: number; top: number };\ntype Positioner = (anchorRect: DOMRect, tooltipRect: DOMRect) => Position;\n\nconst positionAbove: Positioner = (anchor, tooltip) => ({\n left: anchor.left - (tooltip.width - anchor.width) / 2,\n top: anchor.top - (tooltip.height + pointerSize),\n});\n\nconst positionBelow: Positioner = (anchor, tooltip) => ({\n left: anchor.left - (tooltip.width - anchor.width) / 2,\n top: anchor.bottom + pointerSize,\n});\nconst positionLeft: Positioner = (anchor, tooltip) => ({\n left: anchor.left - pointerSize - tooltip.width,\n top: anchor.top - (tooltip.height - anchor.height) / 2,\n});\n\nconst positionRight: Positioner = (anchor, tooltip) => ({\n left: anchor.right + pointerSize,\n top: anchor.top - (tooltip.height - anchor.height) / 2,\n});\n\nconst positionAtPlacement = (\n placement: TooltipPlacement,\n anchor: DOMRect,\n tooltip: DOMRect,\n) => {\n switch (placement) {\n case \"above\":\n return positionAbove(anchor, tooltip);\n case \"left\":\n return positionLeft(anchor, tooltip);\n case \"below\":\n return positionBelow(anchor, tooltip);\n case \"right\":\n return positionRight(anchor, tooltip);\n default:\n throw Error(\"invalid tooltip placement\");\n }\n};\n\nconst keepWithinTheScreen = (\n { height, width }: DOMRect,\n position: Position,\n) => {\n const { clientWidth, clientHeight } = document.body;\n let { left, top } = position;\n if (left + width > clientWidth) {\n left -= left + width - clientWidth;\n }\n if (left < 0) {\n left = 0;\n }\n if (top + height > clientHeight) {\n top -= top + height - clientHeight;\n }\n if (top < 0) {\n top = 0;\n }\n\n return { left, top };\n};\n\nconst toCSSText = ({ left, top }: Position) =>\n `left:${left}px;top:${top}px;opacity:1;`;\n\nconst getNextPlacement = (\n placement: TooltipPlacement | TooltipPlacement[],\n): [TooltipPlacement | undefined, TooltipPlacement[]] => {\n if (Array.isArray(placement)) {\n if (placement.length === 0) {\n return [undefined, placement];\n } else {\n return [placement[0], placement.slice(1)];\n }\n } else {\n return [placement, []];\n }\n};\n\nexport const useTooltipAnchoredPosition = ({\n anchorElement,\n placement,\n}: TooltipAnchoredPositionHookProps) => {\n const ref = useCallback<RefCallback<HTMLDivElement>>(\n (el) => {\n if (el && anchorElement.current) {\n const anchorRect = anchorElement.current.getBoundingClientRect();\n const tooltipRect = el.getBoundingClientRect();\n let nextPlacement: TooltipPlacement | undefined;\n let placements: TooltipPlacement | TooltipPlacement[] = placement;\n [nextPlacement = \"right\", placements] = getNextPlacement(placements);\n do {\n if (\n roomAvailableAtPlacement(nextPlacement, anchorRect, tooltipRect)\n ) {\n el.style.cssText = toCSSText(\n keepWithinTheScreen(\n tooltipRect,\n positionAtPlacement(nextPlacement, anchorRect, tooltipRect),\n ),\n );\n el.dataset.align = nextPlacement;\n return;\n }\n [nextPlacement, placements] = getNextPlacement(placements);\n } while (nextPlacement);\n }\n el?.classList.remove(\"vuuHidden\");\n },\n [anchorElement, placement],\n );\n return ref;\n};\n"],"names":["useCallback"],"mappings":"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"}
1
+ {"version":3,"file":"useTooltipAnchoredPosition.js","sources":["../../../../packages/vuu-popups/src/tooltip/useTooltipAnchoredPosition.ts"],"sourcesContent":["// TODO merge with Popup\n\nimport { RefCallback, RefObject, useCallback } from \"react\";\n\nexport type TooltipPlacement = \"above\" | \"right\" | \"below\" | \"left\";\n\nconst pointerSize = 12;\nexport interface TooltipAnchoredPositionHookProps {\n anchorElement: RefObject<HTMLElement | null>;\n placement: TooltipPlacement | TooltipPlacement[];\n}\n\nconst roomAbove = (anchor: DOMRect, tooltip: DOMRect) =>\n tooltip.height + pointerSize < anchor.top;\nconst roomLeft = (anchor: DOMRect, tooltip: DOMRect) =>\n tooltip.width + pointerSize < anchor.left;\nconst roomRight = (anchor: DOMRect, tooltip: DOMRect) =>\n anchor.right + tooltip.width + pointerSize < document.body.clientWidth;\nconst roomBelow = (anchor: DOMRect, tooltip: DOMRect) =>\n document.body.clientHeight - anchor.bottom > tooltip.height + pointerSize;\n\nconst roomAvailableAtPlacement = (\n placement: TooltipPlacement,\n anchor: DOMRect,\n tooltip: DOMRect,\n) => {\n switch (placement) {\n case \"above\":\n return roomAbove(anchor, tooltip);\n case \"left\":\n return roomLeft(anchor, tooltip);\n case \"below\":\n return roomBelow(anchor, tooltip);\n case \"right\":\n return roomRight(anchor, tooltip);\n default:\n throw Error(\"invalid tooltip placement\");\n }\n};\n\ntype Position = { left: number; top: number };\ntype Positioner = (anchorRect: DOMRect, tooltipRect: DOMRect) => Position;\n\nconst positionAbove: Positioner = (anchor, tooltip) => ({\n left: anchor.left - (tooltip.width - anchor.width) / 2,\n top: anchor.top - (tooltip.height + pointerSize),\n});\n\nconst positionBelow: Positioner = (anchor, tooltip) => ({\n left: anchor.left - (tooltip.width - anchor.width) / 2,\n top: anchor.bottom + pointerSize,\n});\nconst positionLeft: Positioner = (anchor, tooltip) => ({\n left: anchor.left - pointerSize - tooltip.width,\n top: anchor.top - (tooltip.height - anchor.height) / 2,\n});\n\nconst positionRight: Positioner = (anchor, tooltip) => ({\n left: anchor.right + pointerSize,\n top: anchor.top - (tooltip.height - anchor.height) / 2,\n});\n\nconst positionAtPlacement = (\n placement: TooltipPlacement,\n anchor: DOMRect,\n tooltip: DOMRect,\n) => {\n switch (placement) {\n case \"above\":\n return positionAbove(anchor, tooltip);\n case \"left\":\n return positionLeft(anchor, tooltip);\n case \"below\":\n return positionBelow(anchor, tooltip);\n case \"right\":\n return positionRight(anchor, tooltip);\n default:\n throw Error(\"invalid tooltip placement\");\n }\n};\n\nconst keepWithinTheScreen = (\n { height, width }: DOMRect,\n position: Position,\n) => {\n const { clientWidth, clientHeight } = document.body;\n let { left, top } = position;\n if (left + width > clientWidth) {\n left -= left + width - clientWidth;\n }\n if (left < 0) {\n left = 0;\n }\n if (top + height > clientHeight) {\n top -= top + height - clientHeight;\n }\n if (top < 0) {\n top = 0;\n }\n\n return { left, top };\n};\n\nconst toCSSText = ({ left, top }: Position) =>\n `left:${left}px;top:${top}px;opacity:1;`;\n\nconst getNextPlacement = (\n placement: TooltipPlacement | TooltipPlacement[],\n): [TooltipPlacement | undefined, TooltipPlacement[]] => {\n if (Array.isArray(placement)) {\n if (placement.length === 0) {\n return [undefined, placement];\n } else {\n return [placement[0], placement.slice(1)];\n }\n } else {\n return [placement, []];\n }\n};\n\nexport const useTooltipAnchoredPosition = ({\n anchorElement,\n placement,\n}: TooltipAnchoredPositionHookProps) => {\n const ref = useCallback<RefCallback<HTMLDivElement>>(\n (el) => {\n if (el && anchorElement.current) {\n const anchorRect = anchorElement.current.getBoundingClientRect();\n const tooltipRect = el.getBoundingClientRect();\n let nextPlacement: TooltipPlacement | undefined;\n let placements: TooltipPlacement | TooltipPlacement[] = placement;\n [nextPlacement = \"right\", placements] = getNextPlacement(placements);\n do {\n if (\n roomAvailableAtPlacement(nextPlacement, anchorRect, tooltipRect)\n ) {\n el.style.cssText = toCSSText(\n keepWithinTheScreen(\n tooltipRect,\n positionAtPlacement(nextPlacement, anchorRect, tooltipRect),\n ),\n );\n el.dataset.align = nextPlacement;\n return;\n }\n [nextPlacement, placements] = getNextPlacement(placements);\n } while (nextPlacement);\n }\n el?.classList.remove(\"vuuHidden\");\n },\n [anchorElement, placement],\n );\n return ref;\n};\n"],"names":["useCallback"],"mappings":"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"}
@@ -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":[],"mappings":"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"}
1
+ {"version":3,"file":"useDialog.js","sources":["../../../../packages/vuu-popups/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":[],"mappings":";;;;;;;AA0CO,MAAM,YAAY,MAAM;AAC7B,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,QAAsB,EAAA;AAE5D,EAAM,MAAA,WAAA,GAAc,YAAY,MAAM;AACpC,IAAA,cAAA,CAAe,KAAS,CAAA,CAAA;AAAA,GAC1B,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,gBAAmB,GAAA,WAAA;AAAA,IACvB,CAAC,IAAmB,KAAA;AAClB,MAAA,IAAI,SAAS,IAAM,EAAA;AACjB,QAAY,WAAA,EAAA;AAAA;AACd,KACF;AAAA,IACA,CAAC,WAAW;AAAA,GACd;AAEA,EAAA,MAAM,SAAS,WACb,mBAAA,IAAA,CAAC,UAAO,IAAM,EAAA,IAAA,EAAM,cAAc,gBAChC,EAAA,QAAA,EAAA;AAAA,oBAAC,GAAA,CAAA,YAAA,EAAA,EAAa,MAAQ,EAAA,WAAA,CAAY,KAAO,EAAA,CAAA;AAAA,oBACzC,GAAA,CAAC,aAAe,EAAA,EAAA,QAAA,EAAA,WAAA,CAAY,OAAQ,EAAA,CAAA;AAAA,IACnC,WAAA,CAAY,oBAAoB,IAC/B,mBAAA,GAAA;AAAA,MAAC,iBAAA;AAAA,MAAA;AAAA,QACC,eAAa,EAAA,IAAA;AAAA,QACb,WAAU,EAAA,OAAA;AAAA,QACV,OAAS,EAAA;AAAA;AAAA,KAET,GAAA,IAAA;AAAA,IACH,YAAY,OACX,mBAAA,GAAA,CAAC,aAAe,EAAA,EAAA,QAAA,EAAA,WAAA,CAAY,SAAQ,CAClC,GAAA;AAAA,GAAA,EACN,CACE,GAAA,IAAA;AAEJ,EAAO,OAAA;AAAA,IACL,MAAA;AAAA,IACA;AAAA,GACF;AACF;AAEA,MAAM,oBAAgC,MAAM;AAC1C,EAAA,OAAA,CAAQ,KAAK,4BAA4B,CAAA;AAC3C,CAAA;AACA,MAAM,qBAAqB,MAAM;AAC/B,EAAA,OAAA,CAAQ,KAAK,4BAA4B,CAAA;AAC3C,CAAA;AAEA,MAAM,mBAAkD,CAAA;AAAA,EAAxD,WAAA,GAAA;AACE,IAAa,aAAA,CAAA,IAAA,EAAA,YAAA,EAAA,iBAAA,CAAA;AACb,IAAc,aAAA,CAAA,IAAA,EAAA,aAAA,EAAA,kBAAA,CAAA;AAAA;AAAA,EACd,oBAAA,CAAqB,YAAwB,WAAyB,EAAA;AACpE,IAAA,IAAA,CAAK,UAAa,GAAA,UAAA;AAClB,IAAA,IAAA,CAAK,WAAc,GAAA,WAAA;AAAA;AAEvB;AAEA,MAAM,aAAgB,GAAA,aAAA;AAAA,EACpB,IAAI,mBAAoB;AAC1B,CAAA;AAEA,MAAM,UAAa,GAAA,CAAC,EAAE,OAAA,EAA+C,KAAA;AACnE,EAAA,MAAM,EAAE,MAAA,EAAQ,cAAe,EAAA,GAAI,SAAU,EAAA;AAC7C,EAAA,MAAM,UAAyB,GAAA,WAAA;AAAA,IAC7B,CAAC,aAAA,EAAe,KAAO,EAAA,aAAA,EAAe,eAAoB,KAAA;AACxD,MAAe,cAAA,CAAA;AAAA,QACb,OAAS,EAAA,aAAA;AAAA,QACT,OAAS,EAAA,aAAA;AAAA,QACT,KAAA;AAAA,QACA;AAAA,OACD,CAAA;AAAA,KACH;AAAA,IACA,CAAC,cAAc;AAAA,GACjB;AACA,EAAM,MAAA,WAAA,GAAc,YAAY,MAAM;AACpC,IAAA,cAAA,CAAe,KAAS,CAAA,CAAA;AAAA,GAC1B,EAAG,CAAC,cAAc,CAAC,CAAA;AAEnB,EAAA,OAAA,CAAQ,MAAM;AACZ,IAAQ,OAAA,CAAA,oBAAA,CAAqB,YAAY,WAAW,CAAA;AAAA,GACnD,EAAA,CAAC,WAAa,EAAA,OAAA,EAAS,UAAU,CAAC,CAAA;AACrC,EAAO,OAAA,MAAA;AACT,CAAA;AAEO,MAAM,cAAiB,GAAA,CAAC,EAAE,QAAA,EAAwC,KAAA;AACvE,EAAM,MAAA,OAAA,GAAU,WAAW,aAAa,CAAA;AACxC,EAAA,uBACG,IAAA,CAAA,aAAA,CAAc,QAAd,EAAA,EAAuB,OAAO,OAC7B,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,cAAW,OAAkB,EAAA,CAAA;AAAA,IAC7B;AAAA,GACH,EAAA,CAAA;AAEJ;AAEO,MAAM,mBAAmB,MAAM;AACpC,EAAA,MAAM,EAAE,WAAA,EAAa,UAAW,EAAA,GAAI,WAAW,aAAa,CAAA;AAC5D,EAAO,OAAA,EAAE,YAAY,WAAY,EAAA;AACnC;;;;"}
@@ -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":[],"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,eAAe,SAAU,EAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,mBAAA;AAAA,IACR,GAAK,EAAA,eAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAA,uBACG,IAAA,CAAA,KAAA,EAAA,EAAK,GAAG,cAAA,EAAgB,WAAW,SAClC,EAAA,QAAA,EAAA;AAAA,oBAAC,GAAA,CAAA,IAAA,EAAA,EAAK,SAAU,EAAA,cAAA,EAAgB,QAAM,EAAA,KAAA,EAAA,CAAA;AAAA,IACrC,CAAC,eACA,oBAAA,GAAA;AAAA,MAAC,MAAA;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
+ {"version":3,"file":"DialogHeader.js","sources":["../../../../packages/vuu-popups/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":[],"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,eAAe,SAAU,EAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,mBAAA;AAAA,IACR,GAAK,EAAA,eAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAA,uBACG,IAAA,CAAA,KAAA,EAAA,EAAK,GAAG,cAAA,EAAgB,WAAW,SAClC,EAAA,QAAA,EAAA;AAAA,oBAAC,GAAA,CAAA,IAAA,EAAA,EAAK,SAAU,EAAA,cAAA,EAAgB,QAAM,EAAA,KAAA,EAAA,CAAA;AAAA,IACrC,CAAC,eACA,oBAAA,GAAA;AAAA,MAAC,MAAA;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":"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":[],"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,GAAA,QAAA,CAAyB,EAAE,CAAA;AAErE,EAAA,OAAA,CAAQ,MAAM;AACZ,IAAqB,oBAAA,CAAA,SAAA,CAAU,CAAC,YAAiB,KAAA;AAC/C,MAAA,MAAM,eAAgC,GAAA;AAAA,QACpC,GAAG,YAAA;AAAA,QACH,IAAI,WAAY;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,uBAEK,GAAA,CAAA,QAAA,EAAA,EAAA,QAAA,EAAA,aAAA,CAAc,GAAI,CAAA,CAAC,cAAc,CAChC,qBAAA,GAAA;AAAA,IAAC,iBAAA;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;;;;"}
1
+ {"version":3,"file":"NotificationsCenter.js","sources":["../../../../packages/vuu-popups/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":[],"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,GAAA,QAAA,CAAyB,EAAE,CAAA;AAErE,EAAA,OAAA,CAAQ,MAAM;AACZ,IAAqB,oBAAA,CAAA,SAAA,CAAU,CAAC,YAAiB,KAAA;AAC/C,MAAA,MAAM,eAAgC,GAAA;AAAA,QACpC,GAAG,YAAA;AAAA,QACH,IAAI,WAAY;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,uBAEK,GAAA,CAAA,QAAA,EAAA,EAAA,QAAA,EAAA,aAAA,CAAc,GAAI,CAAA,CAAC,cAAc,CAChC,qBAAA,GAAA;AAAA,IAAC,iBAAA;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;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"NotificationsProvider.js","sources":["../../src/notifications/NotificationsProvider.tsx"],"sourcesContent":["import React, { ReactElement, 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: ReactElement | ReactElement[];\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":[],"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,GAAU,WAAW,oBAAoB,CAAA;AAC/C,EAAA,uBACG,IAAA,CAAA,oBAAA,CAAqB,QAArB,EAAA,EAA8B,OAAO,OACpC,EAAA,QAAA,EAAA;AAAA,oBAAC,GAAA,CAAA,mBAAA,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,GAAA,UAAA,CAAW,oBAAoB,CAAA;AAClD,EAAO,OAAA,MAAA;AACT;;;;"}
1
+ {"version":3,"file":"NotificationsProvider.js","sources":["../../../../packages/vuu-popups/src/notifications/NotificationsProvider.tsx"],"sourcesContent":["import React, { ReactElement, 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: ReactElement | ReactElement[];\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":[],"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,GAAU,WAAW,oBAAoB,CAAA;AAC/C,EAAA,uBACG,IAAA,CAAA,oBAAA,CAAqB,QAArB,EAAA,EAA8B,OAAO,OACpC,EAAA,QAAA,EAAA;AAAA,oBAAC,GAAA,CAAA,mBAAA,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,GAAA,UAAA,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":[],"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,eAAe,SAAU,EAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,wBAAA;AAAA,IACR,GAAK,EAAA,oBAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAA,MAAM,CAAC,KAAO,EAAA,QAAQ,IAAI,QAAS,CAAA,CAAC,aAAa,0BAA0B,CAAA;AAE3E,EAAA,SAAA,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,2BACG,MACC,EAAA,EAAA,QAAA,kBAAA,IAAA;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,wBAAA,GAAA,CAAC,IAAK,EAAA,EAAA,IAAA,EAAM,IAAK,CAAA,YAAA,CAAa,IAAI,CAAG,EAAA,CAAA;AAAA,wBACpC,IAAA,CAAA,KAAA,EAAA,EAAI,SAAW,EAAA,CAAA,EAAG,SAAS,CAC1B,aAAA,CAAA,EAAA,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,YAAO,SAAW,EAAA,CAAA,EAAG,SAAS,CAAA,YAAA,CAAA,EAC5B,uBAAa,MAChB,EAAA,CAAA;AAAA,0BACA,GAAA,CAAC,KAAK,EAAA,EAAA,QAAA,EAAA,YAAA,CAAa,IAAK,EAAA;AAAA,SAC1B,EAAA;AAAA;AAAA;AAAA,GAEJ,EAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"ToastNotification.js","sources":["../../../../packages/vuu-popups/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":[],"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,eAAe,SAAU,EAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,wBAAA;AAAA,IACR,GAAK,EAAA,oBAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAA,MAAM,CAAC,KAAO,EAAA,QAAQ,IAAI,QAAS,CAAA,CAAC,aAAa,0BAA0B,CAAA;AAE3E,EAAA,SAAA,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,2BACG,MACC,EAAA,EAAA,QAAA,kBAAA,IAAA;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,wBAAA,GAAA,CAAC,IAAK,EAAA,EAAA,IAAA,EAAM,IAAK,CAAA,YAAA,CAAa,IAAI,CAAG,EAAA,CAAA;AAAA,wBACpC,IAAA,CAAA,KAAA,EAAA,EAAI,SAAW,EAAA,CAAA,EAAG,SAAS,CAC1B,aAAA,CAAA,EAAA,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,YAAO,SAAW,EAAA,CAAA,EAAG,SAAS,CAAA,YAAA,CAAA,EAC5B,uBAAa,MAChB,EAAA,CAAA;AAAA,0BACA,GAAA,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 | null>;\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":[],"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,eAAe,SAAU,EAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,WAAA;AAAA,IACR,GAAK,EAAA,QAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAA,MAAM,EAAE,QAAA,EAAU,QAAS,EAAA,GAAI,mBAAoB,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,mBAAA,GAAA,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;;;;"}
1
+ {"version":3,"file":"Popup.js","sources":["../../../../packages/vuu-popups/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 | null>;\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":[],"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,eAAe,SAAU,EAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,WAAA;AAAA,IACR,GAAK,EAAA,QAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAA,MAAM,EAAE,QAAA,EAAU,QAAS,EAAA,GAAI,mBAAoB,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,mBAAA,GAAA,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;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"getPositionRelativeToAnchor.js","sources":["../../src/popup/getPositionRelativeToAnchor.ts"],"sourcesContent":["import { PopupPlacement } from \"./Popup\";\n\nexport type Visibility = \"hidden\" | \"visible\";\n\nexport type Position = {\n left: number;\n minWidth?: number | string;\n top: number;\n visibility?: Visibility;\n width?: number;\n};\n\nexport const getPositionRelativeToAnchor = (\n anchorElement: HTMLElement,\n placement: PopupPlacement,\n offsetLeft: number,\n offsetTop: number,\n minWidth?: number | string,\n dimensions?: { height: number; width: number }\n): {\n left: number;\n minWidth?: number | string;\n top: number;\n visibility?: Visibility;\n width?: number;\n} => {\n const { bottom, height, left, right, top, width } =\n anchorElement.getBoundingClientRect();\n switch (placement) {\n case \"below\":\n return { left: left + offsetLeft, top: bottom + offsetTop };\n case \"right\":\n return { left: right + offsetLeft, top: top + offsetTop };\n case \"below-center\":\n return { left: left + width / 2 + offsetLeft, top: bottom + offsetTop };\n case \"below-right\":\n return { left: left, minWidth, top: bottom + offsetTop };\n case \"below-full-width\":\n return {\n left: left + offsetLeft,\n minWidth,\n top: bottom + offsetTop,\n width,\n };\n case \"center\":\n if (dimensions) {\n return {\n left: width / 2 - dimensions.width / 2 + offsetLeft,\n top: height / 2 - dimensions.height / 2 + offsetTop,\n visibility: \"visible\",\n };\n } else {\n return {\n left: width / 2 + offsetLeft,\n top: height / 2 + offsetTop,\n visibility: \"hidden\",\n };\n }\n default:\n throw Error(\n `Popup getPositionRelativeToAnchor non-supported placement value ${placement}`\n );\n }\n};\n"],"names":[],"mappings":"AAYO,MAAM,8BAA8B,CACzC,aAAA,EACA,WACA,UACA,EAAA,SAAA,EACA,UACA,UAOG,KAAA;AACH,EAAM,MAAA,EAAE,QAAQ,MAAQ,EAAA,IAAA,EAAM,OAAO,GAAK,EAAA,KAAA,EACxC,GAAA,aAAA,CAAc,qBAAsB,EAAA;AACtC,EAAA,QAAQ,SAAW;AAAA,IACjB,KAAK,OAAA;AACH,MAAA,OAAO,EAAE,IAAM,EAAA,IAAA,GAAO,UAAY,EAAA,GAAA,EAAK,SAAS,SAAU,EAAA;AAAA,IAC5D,KAAK,OAAA;AACH,MAAA,OAAO,EAAE,IAAM,EAAA,KAAA,GAAQ,UAAY,EAAA,GAAA,EAAK,MAAM,SAAU,EAAA;AAAA,IAC1D,KAAK,cAAA;AACH,MAAO,OAAA,EAAE,MAAM,IAAO,GAAA,KAAA,GAAQ,IAAI,UAAY,EAAA,GAAA,EAAK,SAAS,SAAU,EAAA;AAAA,IACxE,KAAK,aAAA;AACH,MAAA,OAAO,EAAE,IAAA,EAAY,QAAU,EAAA,GAAA,EAAK,SAAS,SAAU,EAAA;AAAA,IACzD,KAAK,kBAAA;AACH,MAAO,OAAA;AAAA,QACL,MAAM,IAAO,GAAA,UAAA;AAAA,QACb,QAAA;AAAA,QACA,KAAK,MAAS,GAAA,SAAA;AAAA,QACd;AAAA,OACF;AAAA,IACF,KAAK,QAAA;AACH,MAAA,IAAI,UAAY,EAAA;AACd,QAAO,OAAA;AAAA,UACL,IAAM,EAAA,KAAA,GAAQ,CAAI,GAAA,UAAA,CAAW,QAAQ,CAAI,GAAA,UAAA;AAAA,UACzC,GAAK,EAAA,MAAA,GAAS,CAAI,GAAA,UAAA,CAAW,SAAS,CAAI,GAAA,SAAA;AAAA,UAC1C,UAAY,EAAA;AAAA,SACd;AAAA,OACK,MAAA;AACL,QAAO,OAAA;AAAA,UACL,IAAA,EAAM,QAAQ,CAAI,GAAA,UAAA;AAAA,UAClB,GAAA,EAAK,SAAS,CAAI,GAAA,SAAA;AAAA,UAClB,UAAY,EAAA;AAAA,SACd;AAAA;AACF,IACF;AACE,MAAM,MAAA,KAAA;AAAA,QACJ,mEAAmE,SAAS,CAAA;AAAA,OAC9E;AAAA;AAEN;;;;"}
1
+ {"version":3,"file":"getPositionRelativeToAnchor.js","sources":["../../../../packages/vuu-popups/src/popup/getPositionRelativeToAnchor.ts"],"sourcesContent":["import { PopupPlacement } from \"./Popup\";\n\nexport type Visibility = \"hidden\" | \"visible\";\n\nexport type Position = {\n left: number;\n minWidth?: number | string;\n top: number;\n visibility?: Visibility;\n width?: number;\n};\n\nexport const getPositionRelativeToAnchor = (\n anchorElement: HTMLElement,\n placement: PopupPlacement,\n offsetLeft: number,\n offsetTop: number,\n minWidth?: number | string,\n dimensions?: { height: number; width: number }\n): {\n left: number;\n minWidth?: number | string;\n top: number;\n visibility?: Visibility;\n width?: number;\n} => {\n const { bottom, height, left, right, top, width } =\n anchorElement.getBoundingClientRect();\n switch (placement) {\n case \"below\":\n return { left: left + offsetLeft, top: bottom + offsetTop };\n case \"right\":\n return { left: right + offsetLeft, top: top + offsetTop };\n case \"below-center\":\n return { left: left + width / 2 + offsetLeft, top: bottom + offsetTop };\n case \"below-right\":\n return { left: left, minWidth, top: bottom + offsetTop };\n case \"below-full-width\":\n return {\n left: left + offsetLeft,\n minWidth,\n top: bottom + offsetTop,\n width,\n };\n case \"center\":\n if (dimensions) {\n return {\n left: width / 2 - dimensions.width / 2 + offsetLeft,\n top: height / 2 - dimensions.height / 2 + offsetTop,\n visibility: \"visible\",\n };\n } else {\n return {\n left: width / 2 + offsetLeft,\n top: height / 2 + offsetTop,\n visibility: \"hidden\",\n };\n }\n default:\n throw Error(\n `Popup getPositionRelativeToAnchor non-supported placement value ${placement}`\n );\n }\n};\n"],"names":[],"mappings":"AAYO,MAAM,8BAA8B,CACzC,aAAA,EACA,WACA,UACA,EAAA,SAAA,EACA,UACA,UAOG,KAAA;AACH,EAAM,MAAA,EAAE,QAAQ,MAAQ,EAAA,IAAA,EAAM,OAAO,GAAK,EAAA,KAAA,EACxC,GAAA,aAAA,CAAc,qBAAsB,EAAA;AACtC,EAAA,QAAQ,SAAW;AAAA,IACjB,KAAK,OAAA;AACH,MAAA,OAAO,EAAE,IAAM,EAAA,IAAA,GAAO,UAAY,EAAA,GAAA,EAAK,SAAS,SAAU,EAAA;AAAA,IAC5D,KAAK,OAAA;AACH,MAAA,OAAO,EAAE,IAAM,EAAA,KAAA,GAAQ,UAAY,EAAA,GAAA,EAAK,MAAM,SAAU,EAAA;AAAA,IAC1D,KAAK,cAAA;AACH,MAAO,OAAA,EAAE,MAAM,IAAO,GAAA,KAAA,GAAQ,IAAI,UAAY,EAAA,GAAA,EAAK,SAAS,SAAU,EAAA;AAAA,IACxE,KAAK,aAAA;AACH,MAAA,OAAO,EAAE,IAAA,EAAY,QAAU,EAAA,GAAA,EAAK,SAAS,SAAU,EAAA;AAAA,IACzD,KAAK,kBAAA;AACH,MAAO,OAAA;AAAA,QACL,MAAM,IAAO,GAAA,UAAA;AAAA,QACb,QAAA;AAAA,QACA,KAAK,MAAS,GAAA,SAAA;AAAA,QACd;AAAA,OACF;AAAA,IACF,KAAK,QAAA;AACH,MAAA,IAAI,UAAY,EAAA;AACd,QAAO,OAAA;AAAA,UACL,IAAM,EAAA,KAAA,GAAQ,CAAI,GAAA,UAAA,CAAW,QAAQ,CAAI,GAAA,UAAA;AAAA,UACzC,GAAK,EAAA,MAAA,GAAS,CAAI,GAAA,UAAA,CAAW,SAAS,CAAI,GAAA,SAAA;AAAA,UAC1C,UAAY,EAAA;AAAA,SACd;AAAA,OACK,MAAA;AACL,QAAO,OAAA;AAAA,UACL,IAAA,EAAM,QAAQ,CAAI,GAAA,UAAA;AAAA,UAClB,GAAA,EAAK,SAAS,CAAI,GAAA,SAAA;AAAA,UAClB,UAAY,EAAA;AAAA,SACd;AAAA;AACF,IACF;AACE,MAAM,MAAA,KAAA;AAAA,QACJ,mEAAmE,SAAS,CAAA;AAAA,OAC9E;AAAA;AAEN;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"useAnchoredPosition.js","sources":["../../src/popup/useAnchoredPosition.ts"],"sourcesContent":["import { useCallback, useLayoutEffect, useRef, useState } from \"react\";\nimport {\n getPositionRelativeToAnchor,\n Position,\n} from \"./getPositionRelativeToAnchor\";\nimport { PopupComponentProps } from \"./Popup\";\n\nexport type AnchoredPositionHookProps = Pick<\n PopupComponentProps,\n | \"anchorElement\"\n | \"minWidth\"\n | \"offsetLeft\"\n | \"offsetTop\"\n | \"placement\"\n | \"position\"\n>;\n\nexport const useAnchoredPosition = ({\n anchorElement,\n minWidth,\n offsetLeft = 0,\n offsetTop = 0,\n placement,\n position: positionProp,\n}: AnchoredPositionHookProps) => {\n const popupRef = useRef<HTMLElement | null>(null);\n const [position, setPosition] = useState<Position | undefined>(positionProp);\n\n // maybe better as useMemo ?\n useLayoutEffect(() => {\n if (placement === \"absolute\" && positionProp) {\n setPosition(positionProp);\n } else if (anchorElement.current && placement !== \"auto\") {\n const dimensions =\n popupRef.current === null\n ? undefined\n : popupRef.current.getBoundingClientRect();\n const position = getPositionRelativeToAnchor(\n anchorElement.current,\n placement,\n offsetLeft,\n offsetTop,\n minWidth,\n dimensions\n );\n setPosition(position);\n }\n }, [anchorElement, minWidth, offsetLeft, offsetTop, placement, positionProp]);\n\n const popupCallbackRef = useCallback(\n (el: HTMLDivElement | null) => {\n popupRef.current = el;\n if (el && placement === \"center\" && anchorElement.current) {\n const { height, width } = el.getBoundingClientRect();\n setPosition(\n getPositionRelativeToAnchor(\n anchorElement.current,\n placement,\n offsetLeft,\n offsetTop,\n undefined,\n { height, width }\n )\n );\n }\n },\n [anchorElement, offsetLeft, offsetTop, placement]\n );\n\n return {\n position,\n popupRef: placement === \"center\" ? popupCallbackRef : undefined,\n };\n};\n"],"names":["position"],"mappings":";;;AAiBO,MAAM,sBAAsB,CAAC;AAAA,EAClC,aAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAa,GAAA,CAAA;AAAA,EACb,SAAY,GAAA,CAAA;AAAA,EACZ,SAAA;AAAA,EACA,QAAU,EAAA;AACZ,CAAiC,KAAA;AAC/B,EAAM,MAAA,QAAA,GAAW,OAA2B,IAAI,CAAA;AAChD,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAA+B,YAAY,CAAA;AAG3E,EAAA,eAAA,CAAgB,MAAM;AACpB,IAAI,IAAA,SAAA,KAAc,cAAc,YAAc,EAAA;AAC5C,MAAA,WAAA,CAAY,YAAY,CAAA;AAAA,KACf,MAAA,IAAA,aAAA,CAAc,OAAW,IAAA,SAAA,KAAc,MAAQ,EAAA;AACxD,MAAA,MAAM,aACJ,QAAS,CAAA,OAAA,KAAY,OACjB,KACA,CAAA,GAAA,QAAA,CAAS,QAAQ,qBAAsB,EAAA;AAC7C,MAAA,MAAMA,SAAW,GAAA,2BAAA;AAAA,QACf,aAAc,CAAA,OAAA;AAAA,QACd,SAAA;AAAA,QACA,UAAA;AAAA,QACA,SAAA;AAAA,QACA,QAAA;AAAA,QACA;AAAA,OACF;AACA,MAAA,WAAA,CAAYA,SAAQ,CAAA;AAAA;AACtB,GACF,EAAG,CAAC,aAAe,EAAA,QAAA,EAAU,YAAY,SAAW,EAAA,SAAA,EAAW,YAAY,CAAC,CAAA;AAE5E,EAAA,MAAM,gBAAmB,GAAA,WAAA;AAAA,IACvB,CAAC,EAA8B,KAAA;AAC7B,MAAA,QAAA,CAAS,OAAU,GAAA,EAAA;AACnB,MAAA,IAAI,EAAM,IAAA,SAAA,KAAc,QAAY,IAAA,aAAA,CAAc,OAAS,EAAA;AACzD,QAAA,MAAM,EAAE,MAAA,EAAQ,KAAM,EAAA,GAAI,GAAG,qBAAsB,EAAA;AACnD,QAAA,WAAA;AAAA,UACE,2BAAA;AAAA,YACE,aAAc,CAAA,OAAA;AAAA,YACd,SAAA;AAAA,YACA,UAAA;AAAA,YACA,SAAA;AAAA,YACA,KAAA,CAAA;AAAA,YACA,EAAE,QAAQ,KAAM;AAAA;AAClB,SACF;AAAA;AACF,KACF;AAAA,IACA,CAAC,aAAA,EAAe,UAAY,EAAA,SAAA,EAAW,SAAS;AAAA,GAClD;AAEA,EAAO,OAAA;AAAA,IACL,QAAA;AAAA,IACA,QAAA,EAAU,SAAc,KAAA,QAAA,GAAW,gBAAmB,GAAA,KAAA;AAAA,GACxD;AACF;;;;"}
1
+ {"version":3,"file":"useAnchoredPosition.js","sources":["../../../../packages/vuu-popups/src/popup/useAnchoredPosition.ts"],"sourcesContent":["import { useCallback, useLayoutEffect, useRef, useState } from \"react\";\nimport {\n getPositionRelativeToAnchor,\n Position,\n} from \"./getPositionRelativeToAnchor\";\nimport { PopupComponentProps } from \"./Popup\";\n\nexport type AnchoredPositionHookProps = Pick<\n PopupComponentProps,\n | \"anchorElement\"\n | \"minWidth\"\n | \"offsetLeft\"\n | \"offsetTop\"\n | \"placement\"\n | \"position\"\n>;\n\nexport const useAnchoredPosition = ({\n anchorElement,\n minWidth,\n offsetLeft = 0,\n offsetTop = 0,\n placement,\n position: positionProp,\n}: AnchoredPositionHookProps) => {\n const popupRef = useRef<HTMLElement | null>(null);\n const [position, setPosition] = useState<Position | undefined>(positionProp);\n\n // maybe better as useMemo ?\n useLayoutEffect(() => {\n if (placement === \"absolute\" && positionProp) {\n setPosition(positionProp);\n } else if (anchorElement.current && placement !== \"auto\") {\n const dimensions =\n popupRef.current === null\n ? undefined\n : popupRef.current.getBoundingClientRect();\n const position = getPositionRelativeToAnchor(\n anchorElement.current,\n placement,\n offsetLeft,\n offsetTop,\n minWidth,\n dimensions\n );\n setPosition(position);\n }\n }, [anchorElement, minWidth, offsetLeft, offsetTop, placement, positionProp]);\n\n const popupCallbackRef = useCallback(\n (el: HTMLDivElement | null) => {\n popupRef.current = el;\n if (el && placement === \"center\" && anchorElement.current) {\n const { height, width } = el.getBoundingClientRect();\n setPosition(\n getPositionRelativeToAnchor(\n anchorElement.current,\n placement,\n offsetLeft,\n offsetTop,\n undefined,\n { height, width }\n )\n );\n }\n },\n [anchorElement, offsetLeft, offsetTop, placement]\n );\n\n return {\n position,\n popupRef: placement === \"center\" ? popupCallbackRef : undefined,\n };\n};\n"],"names":["position"],"mappings":";;;AAiBO,MAAM,sBAAsB,CAAC;AAAA,EAClC,aAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAa,GAAA,CAAA;AAAA,EACb,SAAY,GAAA,CAAA;AAAA,EACZ,SAAA;AAAA,EACA,QAAU,EAAA;AACZ,CAAiC,KAAA;AAC/B,EAAM,MAAA,QAAA,GAAW,OAA2B,IAAI,CAAA;AAChD,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAA+B,YAAY,CAAA;AAG3E,EAAA,eAAA,CAAgB,MAAM;AACpB,IAAI,IAAA,SAAA,KAAc,cAAc,YAAc,EAAA;AAC5C,MAAA,WAAA,CAAY,YAAY,CAAA;AAAA,KACf,MAAA,IAAA,aAAA,CAAc,OAAW,IAAA,SAAA,KAAc,MAAQ,EAAA;AACxD,MAAA,MAAM,aACJ,QAAS,CAAA,OAAA,KAAY,OACjB,KACA,CAAA,GAAA,QAAA,CAAS,QAAQ,qBAAsB,EAAA;AAC7C,MAAA,MAAMA,SAAW,GAAA,2BAAA;AAAA,QACf,aAAc,CAAA,OAAA;AAAA,QACd,SAAA;AAAA,QACA,UAAA;AAAA,QACA,SAAA;AAAA,QACA,QAAA;AAAA,QACA;AAAA,OACF;AACA,MAAA,WAAA,CAAYA,SAAQ,CAAA;AAAA;AACtB,GACF,EAAG,CAAC,aAAe,EAAA,QAAA,EAAU,YAAY,SAAW,EAAA,SAAA,EAAW,YAAY,CAAC,CAAA;AAE5E,EAAA,MAAM,gBAAmB,GAAA,WAAA;AAAA,IACvB,CAAC,EAA8B,KAAA;AAC7B,MAAA,QAAA,CAAS,OAAU,GAAA,EAAA;AACnB,MAAA,IAAI,EAAM,IAAA,SAAA,KAAc,QAAY,IAAA,aAAA,CAAc,OAAS,EAAA;AACzD,QAAA,MAAM,EAAE,MAAA,EAAQ,KAAM,EAAA,GAAI,GAAG,qBAAsB,EAAA;AACnD,QAAA,WAAA;AAAA,UACE,2BAAA;AAAA,YACE,aAAc,CAAA,OAAA;AAAA,YACd,SAAA;AAAA,YACA,UAAA;AAAA,YACA,SAAA;AAAA,YACA,KAAA,CAAA;AAAA,YACA,EAAE,QAAQ,KAAM;AAAA;AAClB,SACF;AAAA;AACF,KACF;AAAA,IACA,CAAC,aAAA,EAAe,UAAY,EAAA,SAAA,EAAW,SAAS;AAAA,GAClD;AAEA,EAAO,OAAA;AAAA,IACL,QAAA;AAAA,IACA,QAAA,EAAU,SAAc,KAAA,QAAA,GAAW,gBAAmB,GAAA,KAAA;AAAA,GACxD;AACF;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"PopupMenu.js","sources":["../../src/popup-menu/PopupMenu.tsx"],"sourcesContent":["import { Button, ButtonProps } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { MenuActionHandler, MenuBuilder } from \"@vuu-ui/vuu-context-menu\";\nimport { Icon, IconButton } from \"@vuu-ui/vuu-ui-controls\";\nimport { useId } from \"@vuu-ui/vuu-utils\";\nimport cx from \"clsx\";\nimport { HTMLAttributes, KeyboardEvent, RefObject } from \"react\";\nimport { PopupPlacement } from \"../popup/Popup\";\nimport { usePopupMenu } from \"./usePopupMenu\";\n\nimport popupMenuCss from \"./PopupMenu.css\";\n\nconst classBase = \"vuuPopupMenu\";\n\nexport type TabAwayClosePopup = {\n closedBy?: string;\n type: \"tab-away\";\n event: KeyboardEvent;\n};\n\nexport type ClickAwayClosePopup = {\n closedBy?: string;\n type: \"click-away\";\n mouseEvt: MouseEvent;\n};\n\nexport type EscapeClosePopup = {\n closedBy?: string;\n event: KeyboardEvent;\n type: \"escape\";\n};\n\nexport type MenuActionClosePopup = {\n closedBy?: string;\n menuId: string;\n options: unknown;\n type: \"menu-action\";\n};\n\nexport type PopupCloseReason =\n | ClickAwayClosePopup\n | EscapeClosePopup\n | MenuActionClosePopup\n | TabAwayClosePopup;\n\nexport type MenuCloseHandler = (reason?: PopupCloseReason) => void;\n\nexport interface PopupMenuProps extends HTMLAttributes<HTMLButtonElement> {\n anchorElement?: RefObject<HTMLElement | null>;\n disabled?: boolean;\n icon?: string;\n label?: string;\n menuActionHandler?: MenuActionHandler;\n menuBuilder?: MenuBuilder;\n menuClassName?: string;\n menuLocation?: string;\n menuOptions?: { [key: string]: unknown };\n onMenuClose?: MenuCloseHandler;\n onMenuOpen?: () => void;\n popupPlacement?: PopupPlacement;\n variant?: ButtonProps[\"variant\"];\n}\n\nexport const PopupMenu = ({\n anchorElement,\n className,\n disabled = false,\n label,\n icon = label ? \"chevron-down\" : \"more-vert\",\n id: idProp,\n menuActionHandler,\n menuBuilder,\n menuClassName,\n menuLocation = \"header\",\n menuOptions,\n onMenuClose,\n onMenuOpen,\n popupPlacement = \"below-right\",\n tabIndex = 0,\n variant = \"secondary\",\n ...htmlAttributes\n}: PopupMenuProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-popup-menu\",\n css: popupMenuCss,\n window: targetWindow,\n });\n\n const id = useId(idProp);\n\n const { ariaAttributes, buttonProps, menuOpen, rootRef } = usePopupMenu({\n anchorElement,\n id,\n menuActionHandler,\n menuBuilder,\n menuClassName,\n menuLocation,\n onMenuClose,\n onMenuOpen,\n menuOptions,\n popupPlacement,\n tabIndex,\n });\n\n if (label) {\n return (\n <Button\n {...htmlAttributes}\n {...ariaAttributes}\n {...buttonProps}\n className={cx(classBase, className, `${classBase}-withCaption`, {\n \"saltButton-active\": menuOpen,\n })}\n disabled={disabled}\n ref={rootRef}\n variant=\"secondary\"\n >\n {icon ? <Icon name={icon} /> : null}\n {label}\n </Button>\n );\n } else if (icon) {\n return (\n <IconButton\n {...htmlAttributes}\n {...ariaAttributes}\n {...buttonProps}\n className={cx(classBase, className, {\n \"saltButton-active\": menuOpen,\n })}\n disabled={disabled}\n icon={icon}\n ref={rootRef}\n variant={variant}\n />\n );\n } else {\n console.error(\"PopupMenu must have a label or an icon (or both)\");\n return null;\n }\n};\n"],"names":[],"mappings":";;;;;;;;;;AAaA,MAAM,SAAY,GAAA,cAAA;AAmDX,MAAM,YAAY,CAAC;AAAA,EACxB,aAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAW,GAAA,KAAA;AAAA,EACX,KAAA;AAAA,EACA,IAAA,GAAO,QAAQ,cAAiB,GAAA,WAAA;AAAA,EAChC,EAAI,EAAA,MAAA;AAAA,EACJ,iBAAA;AAAA,EACA,WAAA;AAAA,EACA,aAAA;AAAA,EACA,YAAe,GAAA,QAAA;AAAA,EACf,WAAA;AAAA,EACA,WAAA;AAAA,EACA,UAAA;AAAA,EACA,cAAiB,GAAA,aAAA;AAAA,EACjB,QAAW,GAAA,CAAA;AAAA,EACX,OAAU,GAAA,WAAA;AAAA,EACV,GAAG;AACL,CAAsB,KAAA;AACpB,EAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,gBAAA;AAAA,IACR,GAAK,EAAA,YAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAM,MAAA,EAAA,GAAK,MAAM,MAAM,CAAA;AAEvB,EAAA,MAAM,EAAE,cAAgB,EAAA,WAAA,EAAa,QAAU,EAAA,OAAA,KAAY,YAAa,CAAA;AAAA,IACtE,aAAA;AAAA,IACA,EAAA;AAAA,IACA,iBAAA;AAAA,IACA,WAAA;AAAA,IACA,aAAA;AAAA,IACA,YAAA;AAAA,IACA,WAAA;AAAA,IACA,UAAA;AAAA,IACA,WAAA;AAAA,IACA,cAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,IAAI,KAAO,EAAA;AACT,IACE,uBAAA,IAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACE,GAAG,cAAA;AAAA,QACH,GAAG,cAAA;AAAA,QACH,GAAG,WAAA;AAAA,QACJ,WAAW,EAAG,CAAA,SAAA,EAAW,SAAW,EAAA,CAAA,EAAG,SAAS,CAAgB,YAAA,CAAA,EAAA;AAAA,UAC9D,mBAAqB,EAAA;AAAA,SACtB,CAAA;AAAA,QACD,QAAA;AAAA,QACA,GAAK,EAAA,OAAA;AAAA,QACL,OAAQ,EAAA,WAAA;AAAA,QAEP,QAAA,EAAA;AAAA,UAAA,IAAA,mBAAQ,GAAA,CAAA,IAAA,EAAA,EAAK,IAAM,EAAA,IAAA,EAAM,CAAK,GAAA,IAAA;AAAA,UAC9B;AAAA;AAAA;AAAA,KACH;AAAA,aAEO,IAAM,EAAA;AACf,IACE,uBAAA,GAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACE,GAAG,cAAA;AAAA,QACH,GAAG,cAAA;AAAA,QACH,GAAG,WAAA;AAAA,QACJ,SAAA,EAAW,EAAG,CAAA,SAAA,EAAW,SAAW,EAAA;AAAA,UAClC,mBAAqB,EAAA;AAAA,SACtB,CAAA;AAAA,QACD,QAAA;AAAA,QACA,IAAA;AAAA,QACA,GAAK,EAAA,OAAA;AAAA,QACL;AAAA;AAAA,KACF;AAAA,GAEG,MAAA;AACL,IAAA,OAAA,CAAQ,MAAM,kDAAkD,CAAA;AAChE,IAAO,OAAA,IAAA;AAAA;AAEX;;;;"}
1
+ {"version":3,"file":"PopupMenu.js","sources":["../../../../packages/vuu-popups/src/popup-menu/PopupMenu.tsx"],"sourcesContent":["import { Button, ButtonProps } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { MenuActionHandler, MenuBuilder } from \"@vuu-ui/vuu-context-menu\";\nimport { Icon, IconButton } from \"@vuu-ui/vuu-ui-controls\";\nimport { useId } from \"@vuu-ui/vuu-utils\";\nimport cx from \"clsx\";\nimport { HTMLAttributes, KeyboardEvent, RefObject } from \"react\";\nimport { PopupPlacement } from \"../popup/Popup\";\nimport { usePopupMenu } from \"./usePopupMenu\";\n\nimport popupMenuCss from \"./PopupMenu.css\";\n\nconst classBase = \"vuuPopupMenu\";\n\nexport type TabAwayClosePopup = {\n closedBy?: string;\n type: \"tab-away\";\n event: KeyboardEvent;\n};\n\nexport type ClickAwayClosePopup = {\n closedBy?: string;\n type: \"click-away\";\n mouseEvt: MouseEvent;\n};\n\nexport type EscapeClosePopup = {\n closedBy?: string;\n event: KeyboardEvent;\n type: \"escape\";\n};\n\nexport type MenuActionClosePopup = {\n closedBy?: string;\n menuId: string;\n options: unknown;\n type: \"menu-action\";\n};\n\nexport type PopupCloseReason =\n | ClickAwayClosePopup\n | EscapeClosePopup\n | MenuActionClosePopup\n | TabAwayClosePopup;\n\nexport type MenuCloseHandler = (reason?: PopupCloseReason) => void;\n\nexport interface PopupMenuProps extends HTMLAttributes<HTMLButtonElement> {\n anchorElement?: RefObject<HTMLElement | null>;\n disabled?: boolean;\n icon?: string;\n label?: string;\n menuActionHandler?: MenuActionHandler;\n menuBuilder?: MenuBuilder;\n menuClassName?: string;\n menuLocation?: string;\n menuOptions?: { [key: string]: unknown };\n onMenuClose?: MenuCloseHandler;\n onMenuOpen?: () => void;\n popupPlacement?: PopupPlacement;\n variant?: ButtonProps[\"variant\"];\n}\n\nexport const PopupMenu = ({\n anchorElement,\n className,\n disabled = false,\n label,\n icon = label ? \"chevron-down\" : \"more-vert\",\n id: idProp,\n menuActionHandler,\n menuBuilder,\n menuClassName,\n menuLocation = \"header\",\n menuOptions,\n onMenuClose,\n onMenuOpen,\n popupPlacement = \"below-right\",\n tabIndex = 0,\n variant = \"secondary\",\n ...htmlAttributes\n}: PopupMenuProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-popup-menu\",\n css: popupMenuCss,\n window: targetWindow,\n });\n\n const id = useId(idProp);\n\n const { ariaAttributes, buttonProps, menuOpen, rootRef } = usePopupMenu({\n anchorElement,\n id,\n menuActionHandler,\n menuBuilder,\n menuClassName,\n menuLocation,\n onMenuClose,\n onMenuOpen,\n menuOptions,\n popupPlacement,\n tabIndex,\n });\n\n if (label) {\n return (\n <Button\n {...htmlAttributes}\n {...ariaAttributes}\n {...buttonProps}\n className={cx(classBase, className, `${classBase}-withCaption`, {\n \"saltButton-active\": menuOpen,\n })}\n disabled={disabled}\n ref={rootRef}\n variant=\"secondary\"\n >\n {icon ? <Icon name={icon} /> : null}\n {label}\n </Button>\n );\n } else if (icon) {\n return (\n <IconButton\n {...htmlAttributes}\n {...ariaAttributes}\n {...buttonProps}\n className={cx(classBase, className, {\n \"saltButton-active\": menuOpen,\n })}\n disabled={disabled}\n icon={icon}\n ref={rootRef}\n variant={variant}\n />\n );\n } else {\n console.error(\"PopupMenu must have a label or an icon (or both)\");\n return null;\n }\n};\n"],"names":[],"mappings":";;;;;;;;;;AAaA,MAAM,SAAY,GAAA,cAAA;AAmDX,MAAM,YAAY,CAAC;AAAA,EACxB,aAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAW,GAAA,KAAA;AAAA,EACX,KAAA;AAAA,EACA,IAAA,GAAO,QAAQ,cAAiB,GAAA,WAAA;AAAA,EAChC,EAAI,EAAA,MAAA;AAAA,EACJ,iBAAA;AAAA,EACA,WAAA;AAAA,EACA,aAAA;AAAA,EACA,YAAe,GAAA,QAAA;AAAA,EACf,WAAA;AAAA,EACA,WAAA;AAAA,EACA,UAAA;AAAA,EACA,cAAiB,GAAA,aAAA;AAAA,EACjB,QAAW,GAAA,CAAA;AAAA,EACX,OAAU,GAAA,WAAA;AAAA,EACV,GAAG;AACL,CAAsB,KAAA;AACpB,EAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,gBAAA;AAAA,IACR,GAAK,EAAA,YAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAM,MAAA,EAAA,GAAK,MAAM,MAAM,CAAA;AAEvB,EAAA,MAAM,EAAE,cAAgB,EAAA,WAAA,EAAa,QAAU,EAAA,OAAA,KAAY,YAAa,CAAA;AAAA,IACtE,aAAA;AAAA,IACA,EAAA;AAAA,IACA,iBAAA;AAAA,IACA,WAAA;AAAA,IACA,aAAA;AAAA,IACA,YAAA;AAAA,IACA,WAAA;AAAA,IACA,UAAA;AAAA,IACA,WAAA;AAAA,IACA,cAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,IAAI,KAAO,EAAA;AACT,IACE,uBAAA,IAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACE,GAAG,cAAA;AAAA,QACH,GAAG,cAAA;AAAA,QACH,GAAG,WAAA;AAAA,QACJ,WAAW,EAAG,CAAA,SAAA,EAAW,SAAW,EAAA,CAAA,EAAG,SAAS,CAAgB,YAAA,CAAA,EAAA;AAAA,UAC9D,mBAAqB,EAAA;AAAA,SACtB,CAAA;AAAA,QACD,QAAA;AAAA,QACA,GAAK,EAAA,OAAA;AAAA,QACL,OAAQ,EAAA,WAAA;AAAA,QAEP,QAAA,EAAA;AAAA,UAAA,IAAA,mBAAQ,GAAA,CAAA,IAAA,EAAA,EAAK,IAAM,EAAA,IAAA,EAAM,CAAK,GAAA,IAAA;AAAA,UAC9B;AAAA;AAAA;AAAA,KACH;AAAA,aAEO,IAAM,EAAA;AACf,IACE,uBAAA,GAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACE,GAAG,cAAA;AAAA,QACH,GAAG,cAAA;AAAA,QACH,GAAG,WAAA;AAAA,QACJ,SAAA,EAAW,EAAG,CAAA,SAAA,EAAW,SAAW,EAAA;AAAA,UAClC,mBAAqB,EAAA;AAAA,SACtB,CAAA;AAAA,QACD,QAAA;AAAA,QACA,IAAA;AAAA,QACA,GAAK,EAAA,OAAA;AAAA,QACL;AAAA;AAAA,KACF;AAAA,GAEG,MAAA;AACL,IAAA,OAAA,CAAQ,MAAM,kDAAkD,CAAA;AAChE,IAAO,OAAA,IAAA;AAAA;AAEX;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"usePopupMenu.js","sources":["../../src/popup-menu/usePopupMenu.ts"],"sourcesContent":["import {\n AriaAttributes,\n MouseEvent,\n useCallback,\n useRef,\n useState,\n} from \"react\";\nimport { PopupMenuProps } from \"./PopupMenu\";\nimport { getPositionRelativeToAnchor } from \"../popup/getPositionRelativeToAnchor\";\nimport { PopupPlacement } from \"../popup/Popup\";\nimport { useContextMenu } from \"@vuu-ui/vuu-context-menu\";\n\nexport interface PopupMenuHookProps\n extends Pick<\n PopupMenuProps,\n | \"anchorElement\"\n | \"menuActionHandler\"\n | \"menuBuilder\"\n | \"menuClassName\"\n | \"menuOptions\"\n | \"onMenuClose\"\n | \"onMenuOpen\"\n > {\n id: string;\n menuLocation: string;\n popupPlacement: PopupPlacement;\n tabIndex: number;\n}\n\nexport const usePopupMenu = ({\n anchorElement,\n id,\n menuActionHandler,\n menuBuilder,\n menuLocation,\n menuOptions,\n onMenuClose,\n onMenuOpen,\n popupPlacement,\n tabIndex,\n}: PopupMenuHookProps) => {\n const [menuOpen, _setMenuOpen] = useState(false);\n const suppressShowMenuRef = useRef(false);\n const rootRef = useRef<HTMLButtonElement>(null);\n\n const setMenuOpen = useCallback(\n (isOpen: boolean) => {\n _setMenuOpen(isOpen);\n if (isOpen) {\n onMenuOpen?.();\n }\n },\n [onMenuOpen],\n );\n\n const showContextMenu = useContextMenu(menuBuilder, menuActionHandler);\n\n const handleMenuOpenChange = useCallback(\n (isOpen: boolean) => {\n if (isOpen === false) {\n setMenuOpen(false);\n onMenuClose?.();\n }\n // // If user has clicked the MenuButton whilst menu is open, we want to close it.\n // // The PopupService will close it for us as a 'click-away' event. We don't want\n // // that click on the button to re-open it.\n // if (reasonIsClickAway(reason)) {\n // const target = reason.mouseEvt.target as HTMLElement;\n // if (target === rootRef.current) {\n // suppressShowMenuRef.current = true;\n // }\n // onMenuClose?.(reason);\n // } else {\n // requestAnimationFrame(() => {\n // onMenuClose?.(reason);\n // if (tabIndex !== -1 && reason?.type !== \"tab-away\") {\n // rootRef.current?.focus();\n // }\n // });\n // }\n },\n [onMenuClose, setMenuOpen],\n );\n\n const showMenu = useCallback(\n (e: MouseEvent<HTMLElement>) => {\n if (suppressShowMenuRef.current) {\n suppressShowMenuRef.current = false;\n } else {\n const anchorEl = anchorElement?.current ?? rootRef.current;\n if (anchorEl) {\n const {\n left: x,\n top: y,\n // width,\n } = getPositionRelativeToAnchor(anchorEl, popupPlacement, 0, 0);\n setMenuOpen(true);\n\n showContextMenu(e, menuLocation, menuOptions, {\n // className: menuClassName,\n // id: `${id}-menu`,\n onOpenChange: handleMenuOpenChange,\n x,\n y,\n // style: { width: width ? width - 2 : undefined },\n });\n }\n }\n },\n [\n anchorElement,\n popupPlacement,\n setMenuOpen,\n showContextMenu,\n menuLocation,\n menuOptions,\n handleMenuOpenChange,\n ],\n );\n\n const ariaAttributes: AriaAttributes = {\n \"aria-controls\": menuOpen ? `${id}-menu` : undefined,\n \"aria-expanded\": menuOpen,\n \"aria-haspopup\": \"menu\",\n };\n\n const buttonProps = {\n id,\n onClick: showMenu,\n tabIndex,\n };\n\n return { ariaAttributes, buttonProps, menuOpen, rootRef };\n};\n"],"names":[],"mappings":";;;;AA6BO,MAAM,eAAe,CAAC;AAAA,EAC3B,aAAA;AAAA,EACA,EAAA;AAAA,EACA,iBAAA;AAAA,EACA,WAAA;AAAA,EACA,YAAA;AAAA,EACA,WAAA;AAAA,EACA,WAAA;AAAA,EACA,UAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF,CAA0B,KAAA;AACxB,EAAA,MAAM,CAAC,QAAA,EAAU,YAAY,CAAA,GAAI,SAAS,KAAK,CAAA;AAC/C,EAAM,MAAA,mBAAA,GAAsB,OAAO,KAAK,CAAA;AACxC,EAAM,MAAA,OAAA,GAAU,OAA0B,IAAI,CAAA;AAE9C,EAAA,MAAM,WAAc,GAAA,WAAA;AAAA,IAClB,CAAC,MAAoB,KAAA;AACnB,MAAA,YAAA,CAAa,MAAM,CAAA;AACnB,MAAA,IAAI,MAAQ,EAAA;AACV,QAAa,UAAA,IAAA;AAAA;AACf,KACF;AAAA,IACA,CAAC,UAAU;AAAA,GACb;AAEA,EAAM,MAAA,eAAA,GAAkB,cAAe,CAAA,WAAA,EAAa,iBAAiB,CAAA;AAErE,EAAA,MAAM,oBAAuB,GAAA,WAAA;AAAA,IAC3B,CAAC,MAAoB,KAAA;AACnB,MAAA,IAAI,WAAW,KAAO,EAAA;AACpB,QAAA,WAAA,CAAY,KAAK,CAAA;AACjB,QAAc,WAAA,IAAA;AAAA;AAChB,KAkBF;AAAA,IACA,CAAC,aAAa,WAAW;AAAA,GAC3B;AAEA,EAAA,MAAM,QAAW,GAAA,WAAA;AAAA,IACf,CAAC,CAA+B,KAAA;AAC9B,MAAA,IAAI,oBAAoB,OAAS,EAAA;AAC/B,QAAA,mBAAA,CAAoB,OAAU,GAAA,KAAA;AAAA,OACzB,MAAA;AACL,QAAM,MAAA,QAAA,GAAW,aAAe,EAAA,OAAA,IAAW,OAAQ,CAAA,OAAA;AACnD,QAAA,IAAI,QAAU,EAAA;AACZ,UAAM,MAAA;AAAA,YACJ,IAAM,EAAA,CAAA;AAAA,YACN,GAAK,EAAA;AAAA;AAAA,WAEH,GAAA,2BAAA,CAA4B,QAAU,EAAA,cAAA,EAAgB,GAAG,CAAC,CAAA;AAC9D,UAAA,WAAA,CAAY,IAAI,CAAA;AAEhB,UAAgB,eAAA,CAAA,CAAA,EAAG,cAAc,WAAa,EAAA;AAAA;AAAA;AAAA,YAG5C,YAAc,EAAA,oBAAA;AAAA,YACd,CAAA;AAAA,YACA;AAAA;AAAA,WAED,CAAA;AAAA;AACH;AACF,KACF;AAAA,IACA;AAAA,MACE,aAAA;AAAA,MACA,cAAA;AAAA,MACA,WAAA;AAAA,MACA,eAAA;AAAA,MACA,YAAA;AAAA,MACA,WAAA;AAAA,MACA;AAAA;AACF,GACF;AAEA,EAAA,MAAM,cAAiC,GAAA;AAAA,IACrC,eAAiB,EAAA,QAAA,GAAW,CAAG,EAAA,EAAE,CAAU,KAAA,CAAA,GAAA,KAAA,CAAA;AAAA,IAC3C,eAAiB,EAAA,QAAA;AAAA,IACjB,eAAiB,EAAA;AAAA,GACnB;AAEA,EAAA,MAAM,WAAc,GAAA;AAAA,IAClB,EAAA;AAAA,IACA,OAAS,EAAA,QAAA;AAAA,IACT;AAAA,GACF;AAEA,EAAA,OAAO,EAAE,cAAA,EAAgB,WAAa,EAAA,QAAA,EAAU,OAAQ,EAAA;AAC1D;;;;"}
1
+ {"version":3,"file":"usePopupMenu.js","sources":["../../../../packages/vuu-popups/src/popup-menu/usePopupMenu.ts"],"sourcesContent":["import {\n AriaAttributes,\n MouseEvent,\n useCallback,\n useRef,\n useState,\n} from \"react\";\nimport { PopupMenuProps } from \"./PopupMenu\";\nimport { getPositionRelativeToAnchor } from \"../popup/getPositionRelativeToAnchor\";\nimport { PopupPlacement } from \"../popup/Popup\";\nimport { useContextMenu } from \"@vuu-ui/vuu-context-menu\";\n\nexport interface PopupMenuHookProps\n extends Pick<\n PopupMenuProps,\n | \"anchorElement\"\n | \"menuActionHandler\"\n | \"menuBuilder\"\n | \"menuClassName\"\n | \"menuOptions\"\n | \"onMenuClose\"\n | \"onMenuOpen\"\n > {\n id: string;\n menuLocation: string;\n popupPlacement: PopupPlacement;\n tabIndex: number;\n}\n\nexport const usePopupMenu = ({\n anchorElement,\n id,\n menuActionHandler,\n menuBuilder,\n menuLocation,\n menuOptions,\n onMenuClose,\n onMenuOpen,\n popupPlacement,\n tabIndex,\n}: PopupMenuHookProps) => {\n const [menuOpen, _setMenuOpen] = useState(false);\n const suppressShowMenuRef = useRef(false);\n const rootRef = useRef<HTMLButtonElement>(null);\n\n const setMenuOpen = useCallback(\n (isOpen: boolean) => {\n _setMenuOpen(isOpen);\n if (isOpen) {\n onMenuOpen?.();\n }\n },\n [onMenuOpen],\n );\n\n const showContextMenu = useContextMenu(menuBuilder, menuActionHandler);\n\n const handleMenuOpenChange = useCallback(\n (isOpen: boolean) => {\n if (isOpen === false) {\n setMenuOpen(false);\n onMenuClose?.();\n }\n // // If user has clicked the MenuButton whilst menu is open, we want to close it.\n // // The PopupService will close it for us as a 'click-away' event. We don't want\n // // that click on the button to re-open it.\n // if (reasonIsClickAway(reason)) {\n // const target = reason.mouseEvt.target as HTMLElement;\n // if (target === rootRef.current) {\n // suppressShowMenuRef.current = true;\n // }\n // onMenuClose?.(reason);\n // } else {\n // requestAnimationFrame(() => {\n // onMenuClose?.(reason);\n // if (tabIndex !== -1 && reason?.type !== \"tab-away\") {\n // rootRef.current?.focus();\n // }\n // });\n // }\n },\n [onMenuClose, setMenuOpen],\n );\n\n const showMenu = useCallback(\n (e: MouseEvent<HTMLElement>) => {\n if (suppressShowMenuRef.current) {\n suppressShowMenuRef.current = false;\n } else {\n const anchorEl = anchorElement?.current ?? rootRef.current;\n if (anchorEl) {\n const {\n left: x,\n top: y,\n // width,\n } = getPositionRelativeToAnchor(anchorEl, popupPlacement, 0, 0);\n setMenuOpen(true);\n\n showContextMenu(e, menuLocation, menuOptions, {\n // className: menuClassName,\n // id: `${id}-menu`,\n onOpenChange: handleMenuOpenChange,\n x,\n y,\n // style: { width: width ? width - 2 : undefined },\n });\n }\n }\n },\n [\n anchorElement,\n popupPlacement,\n setMenuOpen,\n showContextMenu,\n menuLocation,\n menuOptions,\n handleMenuOpenChange,\n ],\n );\n\n const ariaAttributes: AriaAttributes = {\n \"aria-controls\": menuOpen ? `${id}-menu` : undefined,\n \"aria-expanded\": menuOpen,\n \"aria-haspopup\": \"menu\",\n };\n\n const buttonProps = {\n id,\n onClick: showMenu,\n tabIndex,\n };\n\n return { ariaAttributes, buttonProps, menuOpen, rootRef };\n};\n"],"names":[],"mappings":";;;;AA6BO,MAAM,eAAe,CAAC;AAAA,EAC3B,aAAA;AAAA,EACA,EAAA;AAAA,EACA,iBAAA;AAAA,EACA,WAAA;AAAA,EACA,YAAA;AAAA,EACA,WAAA;AAAA,EACA,WAAA;AAAA,EACA,UAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF,CAA0B,KAAA;AACxB,EAAA,MAAM,CAAC,QAAA,EAAU,YAAY,CAAA,GAAI,SAAS,KAAK,CAAA;AAC/C,EAAM,MAAA,mBAAA,GAAsB,OAAO,KAAK,CAAA;AACxC,EAAM,MAAA,OAAA,GAAU,OAA0B,IAAI,CAAA;AAE9C,EAAA,MAAM,WAAc,GAAA,WAAA;AAAA,IAClB,CAAC,MAAoB,KAAA;AACnB,MAAA,YAAA,CAAa,MAAM,CAAA;AACnB,MAAA,IAAI,MAAQ,EAAA;AACV,QAAa,UAAA,IAAA;AAAA;AACf,KACF;AAAA,IACA,CAAC,UAAU;AAAA,GACb;AAEA,EAAM,MAAA,eAAA,GAAkB,cAAe,CAAA,WAAA,EAAa,iBAAiB,CAAA;AAErE,EAAA,MAAM,oBAAuB,GAAA,WAAA;AAAA,IAC3B,CAAC,MAAoB,KAAA;AACnB,MAAA,IAAI,WAAW,KAAO,EAAA;AACpB,QAAA,WAAA,CAAY,KAAK,CAAA;AACjB,QAAc,WAAA,IAAA;AAAA;AAChB,KAkBF;AAAA,IACA,CAAC,aAAa,WAAW;AAAA,GAC3B;AAEA,EAAA,MAAM,QAAW,GAAA,WAAA;AAAA,IACf,CAAC,CAA+B,KAAA;AAC9B,MAAA,IAAI,oBAAoB,OAAS,EAAA;AAC/B,QAAA,mBAAA,CAAoB,OAAU,GAAA,KAAA;AAAA,OACzB,MAAA;AACL,QAAM,MAAA,QAAA,GAAW,aAAe,EAAA,OAAA,IAAW,OAAQ,CAAA,OAAA;AACnD,QAAA,IAAI,QAAU,EAAA;AACZ,UAAM,MAAA;AAAA,YACJ,IAAM,EAAA,CAAA;AAAA,YACN,GAAK,EAAA;AAAA;AAAA,WAEH,GAAA,2BAAA,CAA4B,QAAU,EAAA,cAAA,EAAgB,GAAG,CAAC,CAAA;AAC9D,UAAA,WAAA,CAAY,IAAI,CAAA;AAEhB,UAAgB,eAAA,CAAA,CAAA,EAAG,cAAc,WAAa,EAAA;AAAA;AAAA;AAAA,YAG5C,YAAc,EAAA,oBAAA;AAAA,YACd,CAAA;AAAA,YACA;AAAA;AAAA,WAED,CAAA;AAAA;AACH;AACF,KACF;AAAA,IACA;AAAA,MACE,aAAA;AAAA,MACA,cAAA;AAAA,MACA,WAAA;AAAA,MACA,eAAA;AAAA,MACA,YAAA;AAAA,MACA,WAAA;AAAA,MACA;AAAA;AACF,GACF;AAEA,EAAA,MAAM,cAAiC,GAAA;AAAA,IACrC,eAAiB,EAAA,QAAA,GAAW,CAAG,EAAA,EAAE,CAAU,KAAA,CAAA,GAAA,KAAA,CAAA;AAAA,IAC3C,eAAiB,EAAA,QAAA;AAAA,IACjB,eAAiB,EAAA;AAAA,GACnB;AAEA,EAAA,MAAM,WAAc,GAAA;AAAA,IAClB,EAAA;AAAA,IACA,OAAS,EAAA,QAAA;AAAA,IACT;AAAA,GACF;AAEA,EAAA,OAAO,EAAE,cAAA,EAAgB,WAAa,EAAA,QAAA,EAAU,OAAQ,EAAA;AAC1D;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"Portal.js","sources":["../../src/portal/Portal.tsx"],"sourcesContent":["import { ThemeAttributes, useThemeAttributes } from \"@vuu-ui/vuu-utils\";\nimport { ReactNode, useLayoutEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\n\nimport portalCss from \"./Portal.css\";\n\nexport interface PortalProps {\n /**\n * The children to render into the `container`.\n */\n children?: ReactNode;\n /**\n * An HTML element, component instance, or function that returns either.\n * The `container` will have the portal children appended to it.\n *\n * By default, it uses the body of the top-level document object,\n * so it's simply `document.body` most of the time.\n */\n container?: Element | (() => Element | null) | null;\n /**\n * Id of element into which portal will be rendered. If this node does not exist on the document,\n * it will be created for you. If more than one value is provided, the first element found will\n * be used.\n */\n id?: string | string[];\n /**\n * Callback invoked immediately after render (in layoutEffect). Can be\n * used to check position vis-a-vis viewport and adjust if out of bounds\n */\n onRender?: () => void;\n /**\n * Allow conditional rendering of this Portal, if false, will render nothing.\n * Defaults to true\n */\n open?: boolean;\n /**\n * ThemeAttributes can be passed in for cases where ContextMenu is\n * rendered via popup-service showPopup, outside the Context hierarchy.\n */\n themeAttributes?: ThemeAttributes;\n}\n\nfunction getContainer(container: PortalProps[\"container\"]) {\n return typeof container === \"function\" ? container() : container;\n}\n\nconst DEFAULT_ID = [\"vuu-dialog-portal-root\", \"vuu-portal-root\"];\n\nconst getFirstAvailableElementById = (id: string | string[]) => {\n if (Array.isArray(id)) {\n for (const i of id) {\n const element = document.getElementById(i);\n if (element) {\n return element;\n }\n }\n } else {\n return document.getElementById(id);\n }\n return null;\n};\n\n/**\n * Portals provide a first-class way to render children into a DOM node\n * that exists outside the DOM hierarchy of the parent component.\n */\nexport const Portal = ({\n children,\n container: containerProp = document.body,\n id = DEFAULT_ID,\n onRender,\n open = true,\n themeAttributes,\n}: PortalProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-portal\",\n css: portalCss,\n window: targetWindow,\n });\n\n const [mounted, setMounted] = useState(false);\n const portalRef = useRef<HTMLElement | null>(null);\n const container = getContainer(containerProp) ?? document.body;\n const [themeClass, densityClass, dataMode] =\n useThemeAttributes(themeAttributes);\n\n useLayoutEffect(() => {\n const root = getFirstAvailableElementById(id);\n if (root) {\n portalRef.current = root;\n } else {\n portalRef.current = document.createElement(\"div\");\n portalRef.current.id =\n typeof id === \"string\"\n ? id\n : id.length > 0\n ? (id.at(-1) as string)\n : \"vuu-portal-root\";\n }\n const el = portalRef.current;\n if (!container.contains(el)) {\n container.appendChild(el);\n }\n el.classList.add(themeClass, densityClass);\n el.dataset.mode = dataMode;\n setMounted(true);\n }, [id, container, themeClass, densityClass, dataMode]);\n\n useLayoutEffect(() => {\n requestAnimationFrame(() => {\n onRender?.();\n });\n }, [onRender]);\n\n if (open && mounted && portalRef.current && children) {\n return createPortal(children, portalRef.current);\n }\n\n return null;\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Portal.js","sources":["../../../../packages/vuu-popups/src/portal/Portal.tsx"],"sourcesContent":["import { ThemeAttributes, useThemeAttributes } from \"@vuu-ui/vuu-utils\";\nimport { ReactNode, useLayoutEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\n\nimport portalCss from \"./Portal.css\";\n\nexport interface PortalProps {\n /**\n * The children to render into the `container`.\n */\n children?: ReactNode;\n /**\n * An HTML element, component instance, or function that returns either.\n * The `container` will have the portal children appended to it.\n *\n * By default, it uses the body of the top-level document object,\n * so it's simply `document.body` most of the time.\n */\n container?: Element | (() => Element | null) | null;\n /**\n * Id of element into which portal will be rendered. If this node does not exist on the document,\n * it will be created for you. If more than one value is provided, the first element found will\n * be used.\n */\n id?: string | string[];\n /**\n * Callback invoked immediately after render (in layoutEffect). Can be\n * used to check position vis-a-vis viewport and adjust if out of bounds\n */\n onRender?: () => void;\n /**\n * Allow conditional rendering of this Portal, if false, will render nothing.\n * Defaults to true\n */\n open?: boolean;\n /**\n * ThemeAttributes can be passed in for cases where ContextMenu is\n * rendered via popup-service showPopup, outside the Context hierarchy.\n */\n themeAttributes?: ThemeAttributes;\n}\n\nfunction getContainer(container: PortalProps[\"container\"]) {\n return typeof container === \"function\" ? container() : container;\n}\n\nconst DEFAULT_ID = [\"vuu-dialog-portal-root\", \"vuu-portal-root\"];\n\nconst getFirstAvailableElementById = (id: string | string[]) => {\n if (Array.isArray(id)) {\n for (const i of id) {\n const element = document.getElementById(i);\n if (element) {\n return element;\n }\n }\n } else {\n return document.getElementById(id);\n }\n return null;\n};\n\n/**\n * Portals provide a first-class way to render children into a DOM node\n * that exists outside the DOM hierarchy of the parent component.\n */\nexport const Portal = ({\n children,\n container: containerProp = document.body,\n id = DEFAULT_ID,\n onRender,\n open = true,\n themeAttributes,\n}: PortalProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-portal\",\n css: portalCss,\n window: targetWindow,\n });\n\n const [mounted, setMounted] = useState(false);\n const portalRef = useRef<HTMLElement | null>(null);\n const container = getContainer(containerProp) ?? document.body;\n const [themeClass, densityClass, dataMode] =\n useThemeAttributes(themeAttributes);\n\n useLayoutEffect(() => {\n const root = getFirstAvailableElementById(id);\n if (root) {\n portalRef.current = root;\n } else {\n portalRef.current = document.createElement(\"div\");\n portalRef.current.id =\n typeof id === \"string\"\n ? id\n : id.length > 0\n ? (id.at(-1) as string)\n : \"vuu-portal-root\";\n }\n const el = portalRef.current;\n if (!container.contains(el)) {\n container.appendChild(el);\n }\n el.classList.add(themeClass, densityClass);\n el.dataset.mode = dataMode;\n setMounted(true);\n }, [id, container, themeClass, densityClass, dataMode]);\n\n useLayoutEffect(() => {\n requestAnimationFrame(() => {\n onRender?.();\n });\n }, [onRender]);\n\n if (open && mounted && portalRef.current && children) {\n return createPortal(children, portalRef.current);\n }\n\n return null;\n};\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Prompt.js","sources":["../../src/prompt/Prompt.tsx"],"sourcesContent":["import { useThemeAttributes } from \"@vuu-ui/vuu-utils\";\nimport { Button } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport cx from \"clsx\";\nimport { HTMLAttributes, useLayoutEffect, useRef } from \"react\";\nimport { PopupComponentProps, useAnchoredPosition } from \"../popup\";\n\nimport propmtCss from \"./Prompt.css\";\n\nconst classBase = \"vuuPrompt\";\n\nconst AnchorBody = { current: document.body };\n\nconst EMPTY_PROPS = {};\n\nexport interface PromptProps extends HTMLAttributes<HTMLDialogElement> {\n PopupProps?: Partial<PopupComponentProps>;\n cancelButtonLabel?: string;\n confirmButtonLabel?: string;\n onCancel: () => void;\n onConfirm: () => void;\n icon?: string;\n text: string;\n variant?: \"warn\" | \"error\" | \"info\";\n}\n\nexport const Prompt = ({\n PopupProps = EMPTY_PROPS,\n cancelButtonLabel = \"Cancel\",\n confirmButtonLabel = \"Confirm\",\n icon,\n onCancel,\n onConfirm,\n style,\n text,\n title,\n variant = \"info\",\n ...htmlAttributes\n}: PromptProps) => {\n const {\n anchorElement = AnchorBody,\n offsetLeft = 0,\n offsetTop = 0,\n placement = \"below\",\n } = PopupProps;\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-prompt\",\n css: propmtCss,\n window: targetWindow,\n });\n\n const [themeClass, _, dataMode] = useThemeAttributes();\n const { position } = useAnchoredPosition({\n anchorElement,\n offsetLeft,\n offsetTop,\n placement,\n });\n const rootRef = useRef<HTMLDialogElement>(null);\n const confirmRef = useRef<HTMLButtonElement>(null);\n\n useLayoutEffect(() => {\n if (rootRef.current) {\n rootRef.current.showModal();\n if (confirmRef.current) {\n confirmRef.current.focus();\n }\n if (placement.endsWith(\"center\")) {\n const { width } = rootRef.current.getBoundingClientRect();\n rootRef.current.style.marginLeft = `-${width / 2}px`;\n }\n }\n }, [placement]);\n\n return (\n <dialog\n {...htmlAttributes}\n className={cx(classBase, `${classBase}-${variant}`, themeClass)}\n data-mode={dataMode}\n ref={rootRef}\n style={{ ...style, ...position }}\n >\n <form className={`${classBase}-form`}>\n <div className={`${classBase}-header`} data-icon={icon}>\n {title}\n </div>\n <div className={`${classBase}-text`}>{text}</div>\n <div className={`${classBase}-buttonBar`}>\n <Button onClick={onCancel} variant=\"secondary\">\n {cancelButtonLabel}\n </Button>\n <Button onClick={onConfirm} ref={confirmRef} value=\"default\">\n {confirmButtonLabel}\n </Button>\n </div>\n </form>\n </dialog>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Prompt.js","sources":["../../../../packages/vuu-popups/src/prompt/Prompt.tsx"],"sourcesContent":["import { useThemeAttributes } from \"@vuu-ui/vuu-utils\";\nimport { Button } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport cx from \"clsx\";\nimport { HTMLAttributes, useLayoutEffect, useRef } from \"react\";\nimport { PopupComponentProps, useAnchoredPosition } from \"../popup\";\n\nimport propmtCss from \"./Prompt.css\";\n\nconst classBase = \"vuuPrompt\";\n\nconst AnchorBody = { current: document.body };\n\nconst EMPTY_PROPS = {};\n\nexport interface PromptProps extends HTMLAttributes<HTMLDialogElement> {\n PopupProps?: Partial<PopupComponentProps>;\n cancelButtonLabel?: string;\n confirmButtonLabel?: string;\n onCancel: () => void;\n onConfirm: () => void;\n icon?: string;\n text: string;\n variant?: \"warn\" | \"error\" | \"info\";\n}\n\nexport const Prompt = ({\n PopupProps = EMPTY_PROPS,\n cancelButtonLabel = \"Cancel\",\n confirmButtonLabel = \"Confirm\",\n icon,\n onCancel,\n onConfirm,\n style,\n text,\n title,\n variant = \"info\",\n ...htmlAttributes\n}: PromptProps) => {\n const {\n anchorElement = AnchorBody,\n offsetLeft = 0,\n offsetTop = 0,\n placement = \"below\",\n } = PopupProps;\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-prompt\",\n css: propmtCss,\n window: targetWindow,\n });\n\n const [themeClass, _, dataMode] = useThemeAttributes();\n const { position } = useAnchoredPosition({\n anchorElement,\n offsetLeft,\n offsetTop,\n placement,\n });\n const rootRef = useRef<HTMLDialogElement>(null);\n const confirmRef = useRef<HTMLButtonElement>(null);\n\n useLayoutEffect(() => {\n if (rootRef.current) {\n rootRef.current.showModal();\n if (confirmRef.current) {\n confirmRef.current.focus();\n }\n if (placement.endsWith(\"center\")) {\n const { width } = rootRef.current.getBoundingClientRect();\n rootRef.current.style.marginLeft = `-${width / 2}px`;\n }\n }\n }, [placement]);\n\n return (\n <dialog\n {...htmlAttributes}\n className={cx(classBase, `${classBase}-${variant}`, themeClass)}\n data-mode={dataMode}\n ref={rootRef}\n style={{ ...style, ...position }}\n >\n <form className={`${classBase}-form`}>\n <div className={`${classBase}-header`} data-icon={icon}>\n {title}\n </div>\n <div className={`${classBase}-text`}>{text}</div>\n <div className={`${classBase}-buttonBar`}>\n <Button onClick={onCancel} variant=\"secondary\">\n {cancelButtonLabel}\n </Button>\n <Button onClick={onConfirm} ref={confirmRef} value=\"default\">\n {confirmButtonLabel}\n </Button>\n </div>\n </form>\n </dialog>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Tooltip.js","sources":["../../src/tooltip/Tooltip.tsx"],"sourcesContent":["import { CSSProperties, MouseEventHandler, ReactNode, RefObject } from \"react\";\nimport { Portal } from \"../portal\";\nimport {\n TooltipPlacement,\n useTooltipAnchoredPosition,\n} from \"./useTooltipAnchoredPosition\";\nimport cx from \"clsx\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\n\nimport tooltipCss from \"./Tooltip.css\";\n\nconst classBase = \"vuuTooltip\";\n\nexport type TooltipStatus = \"warning\" | \"error\" | \"info\";\nexport interface TooltipProps {\n anchorElement: RefObject<HTMLElement | null>;\n children: ReactNode;\n className?: string;\n id?: string;\n onMouseEnter: MouseEventHandler;\n onMouseLeave: MouseEventHandler;\n placement: TooltipPlacement | TooltipPlacement[];\n status?: TooltipStatus;\n style?: CSSProperties;\n}\n\nexport const Tooltip = ({\n anchorElement,\n children,\n className,\n id,\n onMouseEnter,\n onMouseLeave,\n placement: placementProp,\n status,\n style: styleProp,\n}: TooltipProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-tooltip\",\n css: tooltipCss,\n window: targetWindow,\n });\n\n const ref = useTooltipAnchoredPosition({\n anchorElement,\n placement: placementProp,\n });\n return (\n <Portal>\n <div\n className={cx(classBase, className, \"vuuHidden\", {\n [`${classBase}-error`]: status === \"error\",\n })}\n id={id}\n ref={ref}\n style={{ ...styleProp, left: 0, top: 0 }}\n >\n <span\n className={`${classBase}-content`}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n {children}\n </span>\n </div>\n </Portal>\n );\n};\n"],"names":[],"mappings":";;;;;;;;AAYA,MAAM,SAAY,GAAA,YAAA;AAeX,MAAM,UAAU,CAAC;AAAA,EACtB,aAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,EAAA;AAAA,EACA,YAAA;AAAA,EACA,YAAA;AAAA,EACA,SAAW,EAAA,aAAA;AAAA,EACX,MAAA;AAAA,EACA,KAAO,EAAA;AACT,CAAoB,KAAA;AAClB,EAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,aAAA;AAAA,IACR,GAAK,EAAA,UAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAA,MAAM,MAAM,0BAA2B,CAAA;AAAA,IACrC,aAAA;AAAA,IACA,SAAW,EAAA;AAAA,GACZ,CAAA;AACD,EAAA,2BACG,MACC,EAAA,EAAA,QAAA,kBAAA,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAW,EAAA,EAAA,CAAG,SAAW,EAAA,SAAA,EAAW,WAAa,EAAA;AAAA,QAC/C,CAAC,CAAA,EAAG,SAAS,CAAA,MAAA,CAAQ,GAAG,MAAW,KAAA;AAAA,OACpC,CAAA;AAAA,MACD,EAAA;AAAA,MACA,GAAA;AAAA,MACA,OAAO,EAAE,GAAG,WAAW,IAAM,EAAA,CAAA,EAAG,KAAK,CAAE,EAAA;AAAA,MAEvC,QAAA,kBAAA,GAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,SAAA,EAAW,GAAG,SAAS,CAAA,QAAA,CAAA;AAAA,UACvB,YAAA;AAAA,UACA,YAAA;AAAA,UAEC;AAAA;AAAA;AACH;AAAA,GAEJ,EAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"Tooltip.js","sources":["../../../../packages/vuu-popups/src/tooltip/Tooltip.tsx"],"sourcesContent":["import { CSSProperties, MouseEventHandler, ReactNode, RefObject } from \"react\";\nimport { Portal } from \"../portal\";\nimport {\n TooltipPlacement,\n useTooltipAnchoredPosition,\n} from \"./useTooltipAnchoredPosition\";\nimport cx from \"clsx\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\n\nimport tooltipCss from \"./Tooltip.css\";\n\nconst classBase = \"vuuTooltip\";\n\nexport type TooltipStatus = \"warning\" | \"error\" | \"info\";\nexport interface TooltipProps {\n anchorElement: RefObject<HTMLElement | null>;\n children: ReactNode;\n className?: string;\n id?: string;\n onMouseEnter: MouseEventHandler;\n onMouseLeave: MouseEventHandler;\n placement: TooltipPlacement | TooltipPlacement[];\n status?: TooltipStatus;\n style?: CSSProperties;\n}\n\nexport const Tooltip = ({\n anchorElement,\n children,\n className,\n id,\n onMouseEnter,\n onMouseLeave,\n placement: placementProp,\n status,\n style: styleProp,\n}: TooltipProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-tooltip\",\n css: tooltipCss,\n window: targetWindow,\n });\n\n const ref = useTooltipAnchoredPosition({\n anchorElement,\n placement: placementProp,\n });\n return (\n <Portal>\n <div\n className={cx(classBase, className, \"vuuHidden\", {\n [`${classBase}-error`]: status === \"error\",\n })}\n id={id}\n ref={ref}\n style={{ ...styleProp, left: 0, top: 0 }}\n >\n <span\n className={`${classBase}-content`}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n {children}\n </span>\n </div>\n </Portal>\n );\n};\n"],"names":[],"mappings":";;;;;;;;AAYA,MAAM,SAAY,GAAA,YAAA;AAeX,MAAM,UAAU,CAAC;AAAA,EACtB,aAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,EAAA;AAAA,EACA,YAAA;AAAA,EACA,YAAA;AAAA,EACA,SAAW,EAAA,aAAA;AAAA,EACX,MAAA;AAAA,EACA,KAAO,EAAA;AACT,CAAoB,KAAA;AAClB,EAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,aAAA;AAAA,IACR,GAAK,EAAA,UAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAA,MAAM,MAAM,0BAA2B,CAAA;AAAA,IACrC,aAAA;AAAA,IACA,SAAW,EAAA;AAAA,GACZ,CAAA;AACD,EAAA,2BACG,MACC,EAAA,EAAA,QAAA,kBAAA,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAW,EAAA,EAAA,CAAG,SAAW,EAAA,SAAA,EAAW,WAAa,EAAA;AAAA,QAC/C,CAAC,CAAA,EAAG,SAAS,CAAA,MAAA,CAAQ,GAAG,MAAW,KAAA;AAAA,OACpC,CAAA;AAAA,MACD,EAAA;AAAA,MACA,GAAA;AAAA,MACA,OAAO,EAAE,GAAG,WAAW,IAAM,EAAA,CAAA,EAAG,KAAK,CAAE,EAAA;AAAA,MAEvC,QAAA,kBAAA,GAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,SAAA,EAAW,GAAG,SAAS,CAAA,QAAA,CAAA;AAAA,UACvB,YAAA;AAAA,UACA,YAAA;AAAA,UAEC;AAAA;AAAA;AACH;AAAA,GAEJ,EAAA,CAAA;AAEJ;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"useTooltip.js","sources":["../../src/tooltip/useTooltip.ts"],"sourcesContent":["import { queryClosest, useId } from \"@vuu-ui/vuu-utils\";\nimport { MouseEvent, ReactNode, useCallback, useRef, useState } from \"react\";\nimport { TooltipProps } from \"./Tooltip\";\nimport { TooltipPlacement } from \"./useTooltipAnchoredPosition\";\n\nexport interface TooltipHookProps {\n anchorQuery?: string;\n id: string;\n placement?: TooltipPlacement | TooltipPlacement[];\n tooltipContent: ReactNode;\n}\n\nexport const useTooltip = ({\n anchorQuery = \"*\",\n id: idProp,\n placement = [\"right\", \"above\", \"below\"],\n tooltipContent,\n}: TooltipHookProps) => {\n const hideTooltipRef = useRef<() => void>(undefined);\n const isHoveringRef = useRef(false);\n const anchorElementRef = useRef<HTMLElement | null>(null);\n const mouseEnterTimerRef = useRef<number | undefined>(undefined);\n const mouseLeaveTimerRef = useRef<number | undefined>(undefined);\n const [tooltipProps, setTooltipProps] = useState<TooltipProps | undefined>();\n\n const id = useId(idProp);\n\n const escapeListener = useCallback((evt: KeyboardEvent) => {\n if (evt.key === \"Escape\") {\n hideTooltipRef.current?.();\n }\n }, []);\n\n hideTooltipRef.current = useCallback(() => {\n setTooltipProps(undefined);\n document.removeEventListener(\"keydown\", escapeListener);\n }, [escapeListener]);\n\n const handleMouseEnterTooltip = useCallback(() => {\n window.clearTimeout(mouseLeaveTimerRef.current);\n }, []);\n\n const handleMouseLeaveTooltip = useCallback(() => {\n hideTooltipRef.current?.();\n }, []);\n\n const hideTooltip = useCallback((defer = 0) => {\n if (mouseEnterTimerRef.current) {\n window.clearTimeout(mouseEnterTimerRef.current);\n mouseEnterTimerRef.current = undefined;\n } else if (hideTooltipRef.current) {\n if (defer === 0) {\n hideTooltipRef.current();\n } else {\n mouseLeaveTimerRef.current = window.setTimeout(\n hideTooltipRef.current,\n defer,\n );\n }\n }\n }, []);\n\n const showTooltip = useCallback(\n (ref = anchorElementRef) => {\n const { current: anchorEl } = ref;\n if (anchorEl) {\n setTooltipProps({\n anchorElement: ref,\n children: tooltipContent,\n id: `${id}-tooltip`,\n onMouseEnter: handleMouseEnterTooltip,\n onMouseLeave: handleMouseLeaveTooltip,\n placement: placement,\n });\n // register ESC listener\n document.addEventListener(\"keydown\", escapeListener);\n }\n mouseEnterTimerRef.current = undefined;\n hideTooltip(isHoveringRef.current ? 3000 : 1000);\n },\n [\n escapeListener,\n handleMouseEnterTooltip,\n handleMouseLeaveTooltip,\n hideTooltip,\n id,\n placement,\n tooltipContent,\n ],\n );\n\n const handleMouseEnter = useCallback(\n (evt: MouseEvent) => {\n isHoveringRef.current = true;\n const el = queryClosest(evt.target, anchorQuery);\n if (el) {\n console.log(`el ${el.classList}`);\n anchorElementRef.current = el;\n mouseEnterTimerRef.current = window.setTimeout(showTooltip, 800);\n }\n },\n [anchorQuery, showTooltip],\n );\n\n const handleMouseLeave = useCallback(() => {\n isHoveringRef.current = false;\n hideTooltip(200);\n }, [hideTooltip]);\n\n const anchorProps = {\n \"aria-describedby\": `${id}-tooltip`,\n onMouseEnter: handleMouseEnter,\n onMouseLeave: handleMouseLeave,\n };\n\n return {\n anchorProps,\n hideTooltip,\n showTooltip,\n tooltipProps,\n };\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useTooltip.js","sources":["../../../../packages/vuu-popups/src/tooltip/useTooltip.ts"],"sourcesContent":["import { queryClosest, useId } from \"@vuu-ui/vuu-utils\";\nimport { MouseEvent, ReactNode, useCallback, useRef, useState } from \"react\";\nimport { TooltipProps } from \"./Tooltip\";\nimport { TooltipPlacement } from \"./useTooltipAnchoredPosition\";\n\nexport interface TooltipHookProps {\n anchorQuery?: string;\n id: string;\n placement?: TooltipPlacement | TooltipPlacement[];\n tooltipContent: ReactNode;\n}\n\nexport const useTooltip = ({\n anchorQuery = \"*\",\n id: idProp,\n placement = [\"right\", \"above\", \"below\"],\n tooltipContent,\n}: TooltipHookProps) => {\n const hideTooltipRef = useRef<() => void>(undefined);\n const isHoveringRef = useRef(false);\n const anchorElementRef = useRef<HTMLElement | null>(null);\n const mouseEnterTimerRef = useRef<number | undefined>(undefined);\n const mouseLeaveTimerRef = useRef<number | undefined>(undefined);\n const [tooltipProps, setTooltipProps] = useState<TooltipProps | undefined>();\n\n const id = useId(idProp);\n\n const escapeListener = useCallback((evt: KeyboardEvent) => {\n if (evt.key === \"Escape\") {\n hideTooltipRef.current?.();\n }\n }, []);\n\n hideTooltipRef.current = useCallback(() => {\n setTooltipProps(undefined);\n document.removeEventListener(\"keydown\", escapeListener);\n }, [escapeListener]);\n\n const handleMouseEnterTooltip = useCallback(() => {\n window.clearTimeout(mouseLeaveTimerRef.current);\n }, []);\n\n const handleMouseLeaveTooltip = useCallback(() => {\n hideTooltipRef.current?.();\n }, []);\n\n const hideTooltip = useCallback((defer = 0) => {\n if (mouseEnterTimerRef.current) {\n window.clearTimeout(mouseEnterTimerRef.current);\n mouseEnterTimerRef.current = undefined;\n } else if (hideTooltipRef.current) {\n if (defer === 0) {\n hideTooltipRef.current();\n } else {\n mouseLeaveTimerRef.current = window.setTimeout(\n hideTooltipRef.current,\n defer,\n );\n }\n }\n }, []);\n\n const showTooltip = useCallback(\n (ref = anchorElementRef) => {\n const { current: anchorEl } = ref;\n if (anchorEl) {\n setTooltipProps({\n anchorElement: ref,\n children: tooltipContent,\n id: `${id}-tooltip`,\n onMouseEnter: handleMouseEnterTooltip,\n onMouseLeave: handleMouseLeaveTooltip,\n placement: placement,\n });\n // register ESC listener\n document.addEventListener(\"keydown\", escapeListener);\n }\n mouseEnterTimerRef.current = undefined;\n hideTooltip(isHoveringRef.current ? 3000 : 1000);\n },\n [\n escapeListener,\n handleMouseEnterTooltip,\n handleMouseLeaveTooltip,\n hideTooltip,\n id,\n placement,\n tooltipContent,\n ],\n );\n\n const handleMouseEnter = useCallback(\n (evt: MouseEvent) => {\n isHoveringRef.current = true;\n const el = queryClosest(evt.target, anchorQuery);\n if (el) {\n console.log(`el ${el.classList}`);\n anchorElementRef.current = el;\n mouseEnterTimerRef.current = window.setTimeout(showTooltip, 800);\n }\n },\n [anchorQuery, showTooltip],\n );\n\n const handleMouseLeave = useCallback(() => {\n isHoveringRef.current = false;\n hideTooltip(200);\n }, [hideTooltip]);\n\n const anchorProps = {\n \"aria-describedby\": `${id}-tooltip`,\n onMouseEnter: handleMouseEnter,\n onMouseLeave: handleMouseLeave,\n };\n\n return {\n anchorProps,\n hideTooltip,\n showTooltip,\n tooltipProps,\n };\n};\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"useTooltipAnchoredPosition.js","sources":["../../src/tooltip/useTooltipAnchoredPosition.ts"],"sourcesContent":["// TODO merge with Popup\n\nimport { RefCallback, RefObject, useCallback } from \"react\";\n\nexport type TooltipPlacement = \"above\" | \"right\" | \"below\" | \"left\";\n\nconst pointerSize = 12;\nexport interface TooltipAnchoredPositionHookProps {\n anchorElement: RefObject<HTMLElement | null>;\n placement: TooltipPlacement | TooltipPlacement[];\n}\n\nconst roomAbove = (anchor: DOMRect, tooltip: DOMRect) =>\n tooltip.height + pointerSize < anchor.top;\nconst roomLeft = (anchor: DOMRect, tooltip: DOMRect) =>\n tooltip.width + pointerSize < anchor.left;\nconst roomRight = (anchor: DOMRect, tooltip: DOMRect) =>\n anchor.right + tooltip.width + pointerSize < document.body.clientWidth;\nconst roomBelow = (anchor: DOMRect, tooltip: DOMRect) =>\n document.body.clientHeight - anchor.bottom > tooltip.height + pointerSize;\n\nconst roomAvailableAtPlacement = (\n placement: TooltipPlacement,\n anchor: DOMRect,\n tooltip: DOMRect,\n) => {\n switch (placement) {\n case \"above\":\n return roomAbove(anchor, tooltip);\n case \"left\":\n return roomLeft(anchor, tooltip);\n case \"below\":\n return roomBelow(anchor, tooltip);\n case \"right\":\n return roomRight(anchor, tooltip);\n default:\n throw Error(\"invalid tooltip placement\");\n }\n};\n\ntype Position = { left: number; top: number };\ntype Positioner = (anchorRect: DOMRect, tooltipRect: DOMRect) => Position;\n\nconst positionAbove: Positioner = (anchor, tooltip) => ({\n left: anchor.left - (tooltip.width - anchor.width) / 2,\n top: anchor.top - (tooltip.height + pointerSize),\n});\n\nconst positionBelow: Positioner = (anchor, tooltip) => ({\n left: anchor.left - (tooltip.width - anchor.width) / 2,\n top: anchor.bottom + pointerSize,\n});\nconst positionLeft: Positioner = (anchor, tooltip) => ({\n left: anchor.left - pointerSize - tooltip.width,\n top: anchor.top - (tooltip.height - anchor.height) / 2,\n});\n\nconst positionRight: Positioner = (anchor, tooltip) => ({\n left: anchor.right + pointerSize,\n top: anchor.top - (tooltip.height - anchor.height) / 2,\n});\n\nconst positionAtPlacement = (\n placement: TooltipPlacement,\n anchor: DOMRect,\n tooltip: DOMRect,\n) => {\n switch (placement) {\n case \"above\":\n return positionAbove(anchor, tooltip);\n case \"left\":\n return positionLeft(anchor, tooltip);\n case \"below\":\n return positionBelow(anchor, tooltip);\n case \"right\":\n return positionRight(anchor, tooltip);\n default:\n throw Error(\"invalid tooltip placement\");\n }\n};\n\nconst keepWithinTheScreen = (\n { height, width }: DOMRect,\n position: Position,\n) => {\n const { clientWidth, clientHeight } = document.body;\n let { left, top } = position;\n if (left + width > clientWidth) {\n left -= left + width - clientWidth;\n }\n if (left < 0) {\n left = 0;\n }\n if (top + height > clientHeight) {\n top -= top + height - clientHeight;\n }\n if (top < 0) {\n top = 0;\n }\n\n return { left, top };\n};\n\nconst toCSSText = ({ left, top }: Position) =>\n `left:${left}px;top:${top}px;opacity:1;`;\n\nconst getNextPlacement = (\n placement: TooltipPlacement | TooltipPlacement[],\n): [TooltipPlacement | undefined, TooltipPlacement[]] => {\n if (Array.isArray(placement)) {\n if (placement.length === 0) {\n return [undefined, placement];\n } else {\n return [placement[0], placement.slice(1)];\n }\n } else {\n return [placement, []];\n }\n};\n\nexport const useTooltipAnchoredPosition = ({\n anchorElement,\n placement,\n}: TooltipAnchoredPositionHookProps) => {\n const ref = useCallback<RefCallback<HTMLDivElement>>(\n (el) => {\n if (el && anchorElement.current) {\n const anchorRect = anchorElement.current.getBoundingClientRect();\n const tooltipRect = el.getBoundingClientRect();\n let nextPlacement: TooltipPlacement | undefined;\n let placements: TooltipPlacement | TooltipPlacement[] = placement;\n [nextPlacement = \"right\", placements] = getNextPlacement(placements);\n do {\n if (\n roomAvailableAtPlacement(nextPlacement, anchorRect, tooltipRect)\n ) {\n el.style.cssText = toCSSText(\n keepWithinTheScreen(\n tooltipRect,\n positionAtPlacement(nextPlacement, anchorRect, tooltipRect),\n ),\n );\n el.dataset.align = nextPlacement;\n return;\n }\n [nextPlacement, placements] = getNextPlacement(placements);\n } while (nextPlacement);\n }\n el?.classList.remove(\"vuuHidden\");\n },\n [anchorElement, placement],\n );\n return ref;\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useTooltipAnchoredPosition.js","sources":["../../../../packages/vuu-popups/src/tooltip/useTooltipAnchoredPosition.ts"],"sourcesContent":["// TODO merge with Popup\n\nimport { RefCallback, RefObject, useCallback } from \"react\";\n\nexport type TooltipPlacement = \"above\" | \"right\" | \"below\" | \"left\";\n\nconst pointerSize = 12;\nexport interface TooltipAnchoredPositionHookProps {\n anchorElement: RefObject<HTMLElement | null>;\n placement: TooltipPlacement | TooltipPlacement[];\n}\n\nconst roomAbove = (anchor: DOMRect, tooltip: DOMRect) =>\n tooltip.height + pointerSize < anchor.top;\nconst roomLeft = (anchor: DOMRect, tooltip: DOMRect) =>\n tooltip.width + pointerSize < anchor.left;\nconst roomRight = (anchor: DOMRect, tooltip: DOMRect) =>\n anchor.right + tooltip.width + pointerSize < document.body.clientWidth;\nconst roomBelow = (anchor: DOMRect, tooltip: DOMRect) =>\n document.body.clientHeight - anchor.bottom > tooltip.height + pointerSize;\n\nconst roomAvailableAtPlacement = (\n placement: TooltipPlacement,\n anchor: DOMRect,\n tooltip: DOMRect,\n) => {\n switch (placement) {\n case \"above\":\n return roomAbove(anchor, tooltip);\n case \"left\":\n return roomLeft(anchor, tooltip);\n case \"below\":\n return roomBelow(anchor, tooltip);\n case \"right\":\n return roomRight(anchor, tooltip);\n default:\n throw Error(\"invalid tooltip placement\");\n }\n};\n\ntype Position = { left: number; top: number };\ntype Positioner = (anchorRect: DOMRect, tooltipRect: DOMRect) => Position;\n\nconst positionAbove: Positioner = (anchor, tooltip) => ({\n left: anchor.left - (tooltip.width - anchor.width) / 2,\n top: anchor.top - (tooltip.height + pointerSize),\n});\n\nconst positionBelow: Positioner = (anchor, tooltip) => ({\n left: anchor.left - (tooltip.width - anchor.width) / 2,\n top: anchor.bottom + pointerSize,\n});\nconst positionLeft: Positioner = (anchor, tooltip) => ({\n left: anchor.left - pointerSize - tooltip.width,\n top: anchor.top - (tooltip.height - anchor.height) / 2,\n});\n\nconst positionRight: Positioner = (anchor, tooltip) => ({\n left: anchor.right + pointerSize,\n top: anchor.top - (tooltip.height - anchor.height) / 2,\n});\n\nconst positionAtPlacement = (\n placement: TooltipPlacement,\n anchor: DOMRect,\n tooltip: DOMRect,\n) => {\n switch (placement) {\n case \"above\":\n return positionAbove(anchor, tooltip);\n case \"left\":\n return positionLeft(anchor, tooltip);\n case \"below\":\n return positionBelow(anchor, tooltip);\n case \"right\":\n return positionRight(anchor, tooltip);\n default:\n throw Error(\"invalid tooltip placement\");\n }\n};\n\nconst keepWithinTheScreen = (\n { height, width }: DOMRect,\n position: Position,\n) => {\n const { clientWidth, clientHeight } = document.body;\n let { left, top } = position;\n if (left + width > clientWidth) {\n left -= left + width - clientWidth;\n }\n if (left < 0) {\n left = 0;\n }\n if (top + height > clientHeight) {\n top -= top + height - clientHeight;\n }\n if (top < 0) {\n top = 0;\n }\n\n return { left, top };\n};\n\nconst toCSSText = ({ left, top }: Position) =>\n `left:${left}px;top:${top}px;opacity:1;`;\n\nconst getNextPlacement = (\n placement: TooltipPlacement | TooltipPlacement[],\n): [TooltipPlacement | undefined, TooltipPlacement[]] => {\n if (Array.isArray(placement)) {\n if (placement.length === 0) {\n return [undefined, placement];\n } else {\n return [placement[0], placement.slice(1)];\n }\n } else {\n return [placement, []];\n }\n};\n\nexport const useTooltipAnchoredPosition = ({\n anchorElement,\n placement,\n}: TooltipAnchoredPositionHookProps) => {\n const ref = useCallback<RefCallback<HTMLDivElement>>(\n (el) => {\n if (el && anchorElement.current) {\n const anchorRect = anchorElement.current.getBoundingClientRect();\n const tooltipRect = el.getBoundingClientRect();\n let nextPlacement: TooltipPlacement | undefined;\n let placements: TooltipPlacement | TooltipPlacement[] = placement;\n [nextPlacement = \"right\", placements] = getNextPlacement(placements);\n do {\n if (\n roomAvailableAtPlacement(nextPlacement, anchorRect, tooltipRect)\n ) {\n el.style.cssText = toCSSText(\n keepWithinTheScreen(\n tooltipRect,\n positionAtPlacement(nextPlacement, anchorRect, tooltipRect),\n ),\n );\n el.dataset.align = nextPlacement;\n return;\n }\n [nextPlacement, placements] = getNextPlacement(placements);\n } while (nextPlacement);\n }\n el?.classList.remove(\"vuuHidden\");\n },\n [anchorElement, placement],\n );\n return ref;\n};\n"],"names":[],"mappings":";;AAMA,MAAM,WAAc,GAAA,EAAA;AAMpB,MAAM,YAAY,CAAC,MAAA,EAAiB,YAClC,OAAQ,CAAA,MAAA,GAAS,cAAc,MAAO,CAAA,GAAA;AACxC,MAAM,WAAW,CAAC,MAAA,EAAiB,YACjC,OAAQ,CAAA,KAAA,GAAQ,cAAc,MAAO,CAAA,IAAA;AACvC,MAAM,SAAA,GAAY,CAAC,MAAA,EAAiB,OAClC,KAAA,MAAA,CAAO,QAAQ,OAAQ,CAAA,KAAA,GAAQ,WAAc,GAAA,QAAA,CAAS,IAAK,CAAA,WAAA;AAC7D,MAAM,SAAA,GAAY,CAAC,MAAA,EAAiB,OAClC,KAAA,QAAA,CAAS,KAAK,YAAe,GAAA,MAAA,CAAO,MAAS,GAAA,OAAA,CAAQ,MAAS,GAAA,WAAA;AAEhE,MAAM,wBAA2B,GAAA,CAC/B,SACA,EAAA,MAAA,EACA,OACG,KAAA;AACH,EAAA,QAAQ,SAAW;AAAA,IACjB,KAAK,OAAA;AACH,MAAO,OAAA,SAAA,CAAU,QAAQ,OAAO,CAAA;AAAA,IAClC,KAAK,MAAA;AACH,MAAO,OAAA,QAAA,CAAS,QAAQ,OAAO,CAAA;AAAA,IACjC,KAAK,OAAA;AACH,MAAO,OAAA,SAAA,CAAU,QAAQ,OAAO,CAAA;AAAA,IAClC,KAAK,OAAA;AACH,MAAO,OAAA,SAAA,CAAU,QAAQ,OAAO,CAAA;AAAA,IAClC;AACE,MAAA,MAAM,MAAM,2BAA2B,CAAA;AAAA;AAE7C,CAAA;AAKA,MAAM,aAAA,GAA4B,CAAC,MAAA,EAAQ,OAAa,MAAA;AAAA,EACtD,MAAM,MAAO,CAAA,IAAA,GAAA,CAAQ,OAAQ,CAAA,KAAA,GAAQ,OAAO,KAAS,IAAA,CAAA;AAAA,EACrD,GAAK,EAAA,MAAA,CAAO,GAAO,IAAA,OAAA,CAAQ,MAAS,GAAA,WAAA;AACtC,CAAA,CAAA;AAEA,MAAM,aAAA,GAA4B,CAAC,MAAA,EAAQ,OAAa,MAAA;AAAA,EACtD,MAAM,MAAO,CAAA,IAAA,GAAA,CAAQ,OAAQ,CAAA,KAAA,GAAQ,OAAO,KAAS,IAAA,CAAA;AAAA,EACrD,GAAA,EAAK,OAAO,MAAS,GAAA;AACvB,CAAA,CAAA;AACA,MAAM,YAAA,GAA2B,CAAC,MAAA,EAAQ,OAAa,MAAA;AAAA,EACrD,IAAM,EAAA,MAAA,CAAO,IAAO,GAAA,WAAA,GAAc,OAAQ,CAAA,KAAA;AAAA,EAC1C,KAAK,MAAO,CAAA,GAAA,GAAA,CAAO,OAAQ,CAAA,MAAA,GAAS,OAAO,MAAU,IAAA;AACvD,CAAA,CAAA;AAEA,MAAM,aAAA,GAA4B,CAAC,MAAA,EAAQ,OAAa,MAAA;AAAA,EACtD,IAAA,EAAM,OAAO,KAAQ,GAAA,WAAA;AAAA,EACrB,KAAK,MAAO,CAAA,GAAA,GAAA,CAAO,OAAQ,CAAA,MAAA,GAAS,OAAO,MAAU,IAAA;AACvD,CAAA,CAAA;AAEA,MAAM,mBAAsB,GAAA,CAC1B,SACA,EAAA,MAAA,EACA,OACG,KAAA;AACH,EAAA,QAAQ,SAAW;AAAA,IACjB,KAAK,OAAA;AACH,MAAO,OAAA,aAAA,CAAc,QAAQ,OAAO,CAAA;AAAA,IACtC,KAAK,MAAA;AACH,MAAO,OAAA,YAAA,CAAa,QAAQ,OAAO,CAAA;AAAA,IACrC,KAAK,OAAA;AACH,MAAO,OAAA,aAAA,CAAc,QAAQ,OAAO,CAAA;AAAA,IACtC,KAAK,OAAA;AACH,MAAO,OAAA,aAAA,CAAc,QAAQ,OAAO,CAAA;AAAA,IACtC;AACE,MAAA,MAAM,MAAM,2BAA2B,CAAA;AAAA;AAE7C,CAAA;AAEA,MAAM,sBAAsB,CAC1B,EAAE,MAAQ,EAAA,KAAA,IACV,QACG,KAAA;AACH,EAAA,MAAM,EAAE,WAAA,EAAa,YAAa,EAAA,GAAI,QAAS,CAAA,IAAA;AAC/C,EAAI,IAAA,EAAE,IAAM,EAAA,GAAA,EAAQ,GAAA,QAAA;AACpB,EAAI,IAAA,IAAA,GAAO,QAAQ,WAAa,EAAA;AAC9B,IAAA,IAAA,IAAQ,OAAO,KAAQ,GAAA,WAAA;AAAA;AAEzB,EAAA,IAAI,OAAO,CAAG,EAAA;AACZ,IAAO,IAAA,GAAA,CAAA;AAAA;AAET,EAAI,IAAA,GAAA,GAAM,SAAS,YAAc,EAAA;AAC/B,IAAA,GAAA,IAAO,MAAM,MAAS,GAAA,YAAA;AAAA;AAExB,EAAA,IAAI,MAAM,CAAG,EAAA;AACX,IAAM,GAAA,GAAA,CAAA;AAAA;AAGR,EAAO,OAAA,EAAE,MAAM,GAAI,EAAA;AACrB,CAAA;AAEA,MAAM,SAAA,GAAY,CAAC,EAAE,IAAA,EAAM,KACzB,KAAA,CAAA,KAAA,EAAQ,IAAI,CAAA,OAAA,EAAU,GAAG,CAAA,aAAA,CAAA;AAE3B,MAAM,gBAAA,GAAmB,CACvB,SACuD,KAAA;AACvD,EAAI,IAAA,KAAA,CAAM,OAAQ,CAAA,SAAS,CAAG,EAAA;AAC5B,IAAI,IAAA,SAAA,CAAU,WAAW,CAAG,EAAA;AAC1B,MAAO,OAAA,CAAC,QAAW,SAAS,CAAA;AAAA,KACvB,MAAA;AACL,MAAA,OAAO,CAAC,SAAU,CAAA,CAAC,GAAG,SAAU,CAAA,KAAA,CAAM,CAAC,CAAC,CAAA;AAAA;AAC1C,GACK,MAAA;AACL,IAAO,OAAA,CAAC,SAAW,EAAA,EAAE,CAAA;AAAA;AAEzB,CAAA;AAEO,MAAM,6BAA6B,CAAC;AAAA,EACzC,aAAA;AAAA,EACA;AACF,CAAwC,KAAA;AACtC,EAAA,MAAM,GAAM,GAAA,WAAA;AAAA,IACV,CAAC,EAAO,KAAA;AACN,MAAI,IAAA,EAAA,IAAM,cAAc,OAAS,EAAA;AAC/B,QAAM,MAAA,UAAA,GAAa,aAAc,CAAA,OAAA,CAAQ,qBAAsB,EAAA;AAC/D,QAAM,MAAA,WAAA,GAAc,GAAG,qBAAsB,EAAA;AAC7C,QAAI,IAAA,aAAA;AACJ,QAAA,IAAI,UAAoD,GAAA,SAAA;AACxD,QAAA,CAAC,aAAgB,GAAA,OAAA,EAAS,UAAU,CAAA,GAAI,iBAAiB,UAAU,CAAA;AACnE,QAAG,GAAA;AACD,UAAA,IACE,wBAAyB,CAAA,aAAA,EAAe,UAAY,EAAA,WAAW,CAC/D,EAAA;AACA,YAAA,EAAA,CAAG,MAAM,OAAU,GAAA,SAAA;AAAA,cACjB,mBAAA;AAAA,gBACE,WAAA;AAAA,gBACA,mBAAA,CAAoB,aAAe,EAAA,UAAA,EAAY,WAAW;AAAA;AAC5D,aACF;AACA,YAAA,EAAA,CAAG,QAAQ,KAAQ,GAAA,aAAA;AACnB,YAAA;AAAA;AAEF,UAAA,CAAC,aAAe,EAAA,UAAU,CAAI,GAAA,gBAAA,CAAiB,UAAU,CAAA;AAAA,SAClD,QAAA,aAAA;AAAA;AAEX,MAAI,EAAA,EAAA,SAAA,CAAU,OAAO,WAAW,CAAA;AAAA,KAClC;AAAA,IACA,CAAC,eAAe,SAAS;AAAA,GAC3B;AACA,EAAO,OAAA,GAAA;AACT;;;;"}
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.13.14",
2
+ "version": "0.13.16",
3
3
  "description": "VUU popup components - Context Menu, Dialog etc",
4
4
  "author": "heswell",
5
5
  "license": "Apache-2.0",
@@ -7,11 +7,11 @@
7
7
  "@salt-ds/core": "1.43.0",
8
8
  "@salt-ds/styles": "0.2.1",
9
9
  "@salt-ds/window": "0.1.1",
10
- "@vuu-ui/vuu-context-menu": "0.13.14",
11
- "@vuu-ui/vuu-data-types": "0.13.14",
12
- "@vuu-ui/vuu-layout": "0.13.14",
13
- "@vuu-ui/vuu-utils": "0.13.14",
14
- "@vuu-ui/vuu-ui-controls": "0.13.14"
10
+ "@vuu-ui/vuu-context-menu": "0.13.16",
11
+ "@vuu-ui/vuu-data-types": "0.13.16",
12
+ "@vuu-ui/vuu-layout": "0.13.16",
13
+ "@vuu-ui/vuu-utils": "0.13.16",
14
+ "@vuu-ui/vuu-ui-controls": "0.13.16"
15
15
  },
16
16
  "peerDependencies": {
17
17
  "clsx": "^2.0.0",