softable-pixels-web 1.1.21 → 1.1.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{BasePopover-BVeMpuWR.js → BasePopover-PZwz1wdH.js} +3 -2
- package/dist/BasePopover-PZwz1wdH.js.map +1 -0
- package/dist/{ContextMenu-B94eRUm7.js → ContextMenu-ByeABVhU.js} +3 -3
- package/dist/{ContextMenu-B94eRUm7.js.map → ContextMenu-ByeABVhU.js.map} +1 -1
- package/dist/{Popover-BDNQO09F.js → Popover-DpD3G9_i.js} +177 -80
- package/dist/Popover-DpD3G9_i.js.map +1 -0
- package/dist/{Select-Bad465DY.js → Select-BIj1BrzP.js} +217 -21
- package/dist/Select-BIj1BrzP.js.map +1 -0
- package/dist/base-popover.d.ts +3 -3
- package/dist/base-popover.js +3 -3
- package/dist/context-menu.js +4 -4
- package/dist/{index-CyvNJW2l.d.ts → index-B_PqEEta.d.ts} +2 -3
- package/dist/{index-modFVzpZ.d.ts → index-CK68mp8m.d.ts} +3 -3
- package/dist/{index-DEKll7zF.d.ts → index-DX2iqN-v.d.ts} +2 -3
- package/dist/{index-ClqTlRGD.d.ts → index-VwpQusI_.d.ts} +2 -2
- package/dist/index.d.ts +6 -6
- package/dist/index.js +6 -6
- package/dist/popover.d.ts +3 -3
- package/dist/popover.js +3 -3
- package/dist/select.d.ts +2 -2
- package/dist/select.js +4 -4
- package/dist/tab-switch.d.ts +1 -1
- package/dist/{types-CRA-1_6O.d.ts → types-Dm-fEm6s.d.ts} +5 -5
- package/dist/use-dismiss.js +1 -1
- package/dist/useDismiss-CgVHqmqk.js +46 -0
- package/dist/useDismiss-CgVHqmqk.js.map +1 -0
- package/package.json +1 -1
- package/dist/BasePopover-BVeMpuWR.js.map +0 -1
- package/dist/Popover-BDNQO09F.js.map +0 -1
- package/dist/Select-Bad465DY.js.map +0 -1
- package/dist/useDismiss-CAEk_GV-.js +0 -35
- package/dist/useDismiss-CAEk_GV-.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as styled, t as useThemedStyles } from "./useThemedStyles-CrarDyWc.js";
|
|
2
|
-
import { t as Popover } from "./Popover-
|
|
2
|
+
import { t as Popover } from "./Popover-DpD3G9_i.js";
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
4
|
|
|
5
5
|
//#region src/components/commons/structure/BasePopover/styles.ts
|
|
@@ -13,6 +13,7 @@ function createBasePopoverStyles({ maxWidth = "unset", minWidth = "fit-content",
|
|
|
13
13
|
flexDirection: "column",
|
|
14
14
|
zIndex: 10,
|
|
15
15
|
overflowY: "auto",
|
|
16
|
+
overflowX: "hidden",
|
|
16
17
|
overscrollBehavior: "contain",
|
|
17
18
|
borderWidth: 1,
|
|
18
19
|
rowGap: "0.25rem",
|
|
@@ -48,4 +49,4 @@ const BasePopover = (props) => {
|
|
|
48
49
|
|
|
49
50
|
//#endregion
|
|
50
51
|
export { BasePopover as t };
|
|
51
|
-
//# sourceMappingURL=BasePopover-
|
|
52
|
+
//# sourceMappingURL=BasePopover-PZwz1wdH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BasePopover-PZwz1wdH.js","names":["BasePopover: React.FC<BasePopoverProps>"],"sources":["../src/components/commons/structure/BasePopover/styles.ts","../src/components/commons/structure/BasePopover/index.tsx"],"sourcesContent":["// Types\nimport type { BasePopoverProps } from './types'\nimport { styled } from '@hooks/useThemedStyles/types'\n\nexport function createBasePopoverStyles({\n maxWidth = 'unset',\n minWidth = 'fit-content',\n minHeight = 'fit-content',\n maxHeight = '15rem',\n panel\n}: BasePopoverProps) {\n return styled({\n content: {\n minWidth,\n maxWidth,\n minHeight,\n maxHeight,\n\n display: 'flex',\n flexDirection: 'column',\n\n zIndex: 10,\n\n overflowY: 'auto',\n overflowX: 'hidden',\n overscrollBehavior: 'contain',\n\n borderWidth: 1,\n rowGap: '0.25rem',\n padding: panel?.padding ? panel.padding : '0.5rem',\n borderRadius: '0.75rem',\n\n backgroundColor: 'var(--px-bg)',\n boxShadow: 'var(--px-shadow-default)',\n borderColor: 'var(--px-border-primary)'\n }\n })\n}\n","// External Libraries\nimport type React from 'react'\n\n// Hooks\nimport { useThemedStyles } from '@hooks/useThemedStyles'\n\n// Components\nimport { Popover } from '@components/commons/toolkit/Popover'\n\n// Types\nimport type { BasePopoverProps } from './types'\n\n// Styles\nimport { createBasePopoverStyles } from './styles'\n\nexport const BasePopover: React.FC<BasePopoverProps> = props => {\n const { children, ...rest } = props\n\n const { styles } = useThemedStyles(props, createBasePopoverStyles, {\n applyCommonProps: false,\n pick: p => [p.open, p.trigger]\n })\n\n return (\n <Popover\n p={0}\n hideShadow\n {...rest}\n content={({ widthTrigger }) => (\n <div style={{ ...styles.content, width: widthTrigger }}>{children}</div>\n )}\n />\n )\n}\n"],"mappings":";;;;;AAIA,SAAgB,wBAAwB,EACtC,WAAW,SACX,WAAW,eACX,YAAY,eACZ,YAAY,SACZ,SACmB;AACnB,QAAO,OAAO,EACZ,SAAS;EACP;EACA;EACA;EACA;EAEA,SAAS;EACT,eAAe;EAEf,QAAQ;EAER,WAAW;EACX,WAAW;EACX,oBAAoB;EAEpB,aAAa;EACb,QAAQ;EACR,SAAS,OAAO,UAAU,MAAM,UAAU;EAC1C,cAAc;EAEd,iBAAiB;EACjB,WAAW;EACX,aAAa;EACd,EACF,CAAC;;;;;ACrBJ,MAAaA,eAA0C,UAAS;CAC9D,MAAM,EAAE,UAAU,GAAG,SAAS;CAE9B,MAAM,EAAE,WAAW,gBAAgB,OAAO,yBAAyB;EACjE,kBAAkB;EAClB,OAAM,MAAK,CAAC,EAAE,MAAM,EAAE,QAAQ;EAC/B,CAAC;AAEF,QACE,oBAAC;EACC,GAAG;EACH;EACA,GAAI;EACJ,UAAU,EAAE,mBACV,oBAAC;GAAI,OAAO;IAAE,GAAG,OAAO;IAAS,OAAO;IAAc;GAAG;IAAe;GAE1E"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { n as styled, t as useThemedStyles } from "./useThemedStyles-CrarDyWc.js";
|
|
2
2
|
import { t as Switch } from "./Switch-DJNZbvzy.js";
|
|
3
|
-
import { t as Popover } from "./Popover-
|
|
3
|
+
import { t as Popover } from "./Popover-DpD3G9_i.js";
|
|
4
4
|
import { t as Typography } from "./Typography-BkFV7BhK.js";
|
|
5
|
-
import { t as BasePopover } from "./BasePopover-
|
|
5
|
+
import { t as BasePopover } from "./BasePopover-PZwz1wdH.js";
|
|
6
6
|
import { useEffect, useMemo, useRef, useState } from "react";
|
|
7
7
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
|
|
@@ -306,4 +306,4 @@ const ContextMenu = (props) => {
|
|
|
306
306
|
|
|
307
307
|
//#endregion
|
|
308
308
|
export { types_exports as n, ContextMenu as t };
|
|
309
|
-
//# sourceMappingURL=ContextMenu-
|
|
309
|
+
//# sourceMappingURL=ContextMenu-ByeABVhU.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContextMenu-B94eRUm7.js","names":["floatingOptions: FloatingOptions","DividerRow: React.FC"],"sources":["../src/components/commons/toolkit/ContextMenu/components/Menu/components/ItemRow/styles.ts","../src/components/commons/toolkit/ContextMenu/components/Menu/components/ItemRow/index.tsx","../src/components/commons/toolkit/ContextMenu/components/Menu/components/CustomRow/styles.ts","../src/components/commons/toolkit/ContextMenu/components/Menu/components/CustomRow/index.tsx","../src/components/commons/toolkit/ContextMenu/components/Menu/components/DividerRow/styles.ts","../src/components/commons/toolkit/ContextMenu/components/Menu/components/DividerRow/index.tsx","../src/components/commons/toolkit/ContextMenu/components/Menu/styles.ts","../src/components/commons/toolkit/ContextMenu/components/Menu/index.tsx","../src/components/commons/toolkit/ContextMenu/utils/normalizeMenuOptions.ts","../src/components/commons/toolkit/ContextMenu/types.ts","../src/components/commons/toolkit/ContextMenu/styles.ts","../src/components/commons/toolkit/ContextMenu/index.tsx"],"sourcesContent":["// Types\nimport type { ItemRowProps } from './types'\nimport { styled } from '@hooks/useThemedStyles/types'\n\nexport function createItemRowStyles<T>({ item, active }: ItemRowProps<T>) {\n return styled({\n button: {\n width: '100%',\n textAlign: 'left',\n\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '0.5rem',\n\n borderRadius: '0.5rem',\n\n paddingInline: '0.5rem',\n paddingBlock: '0.25rem',\n\n userSelect: 'none',\n\n backgroundColor:\n item.disabled || active\n ? 'var(--px-background-card-hover)'\n : 'transparent',\n\n __rules: {\n '&:hover': {\n transition: 'all 200ms',\n backgroundColor: 'var(--px-background-card-hover) !important'\n }\n }\n },\n containerIcon: {\n width: '1rem',\n flexShrink: 0,\n display: 'flex',\n alignItems: 'center'\n }\n })\n}\n","// External Libraries\nimport { useEffect, useRef, useState } from 'react'\n\n// Components\nimport { Menu } from '../..'\nimport { Switch } from '@components/commons/toolkit/Switch'\nimport { Popover } from '@components/commons/toolkit/Popover'\nimport { Typography } from '@components/commons/toolkit/Typography'\n\n// Hooks\nimport { useThemedStyles } from '@hooks/useThemedStyles'\n\n// Types\nimport type { ItemRowProps } from './types'\nimport type { FloatingOptions } from '@hooks/useFloating/types'\n\n// Styles\nimport { createItemRowStyles } from './styles'\n\nexport const ItemRow = <T extends string>(props: ItemRowProps<T>) => {\n const { item, depth, width, onHover, onSelect } = props\n const isGroup = item.type === 'group'\n\n const [subOpen, setSubOpen] = useState(false)\n const closeTimer = useRef<number | null>(null)\n const anchorRef = useRef<HTMLButtonElement | null>(null)\n const floatingOptions: FloatingOptions = {\n offsetX: 10,\n offsetY: -4,\n strategy: 'fixed',\n keepInViewport: true,\n placement: 'right-start'\n }\n\n // Hooks\n const { styles, classes } = useThemedStyles(props, createItemRowStyles, {\n applyCommonProps: true,\n override: props.styles,\n pick: p => [p.active]\n })\n\n // Functions\n function handleMouseEnter() {\n onHover(item.id, isGroup)\n\n if (!isGroup) return\n clearTimer()\n setSubOpen(true)\n }\n\n function handleMouseLeave() {\n if (!isGroup) return\n scheduleClose()\n }\n\n function handleClick() {\n if (isGroup) return\n onSelect(item)\n }\n\n function clearTimer() {\n if (closeTimer.current) window.clearTimeout(closeTimer.current)\n closeTimer.current = null\n }\n\n function scheduleClose() {\n clearTimer()\n closeTimer.current = window.setTimeout(() => setSubOpen(false), 150)\n }\n\n function renderMenuType() {\n if (item.type === 'switch') return <Switch checked={item.checked} />\n else {\n return (\n <>\n {item.shortcut ? <span>{item.shortcut}</span> : null}\n\n {isGroup ? <span>›</span> : null}\n </>\n )\n }\n }\n\n // UseEffects\n // biome-ignore lint/correctness/useExhaustiveDependencies: <Not needed>\n useEffect(() => {\n return () => clearTimer()\n }, [])\n\n return (\n <>\n <button\n ref={anchorRef}\n type=\"button\"\n role=\"menuitem\"\n style={styles.button}\n className={classes.button}\n disabled={!!item.disabled}\n aria-disabled={item.disabled || undefined}\n onClick={handleClick}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n >\n {item.icon ? (\n <span style={styles.containerIcon}>{item.icon ?? null}</span>\n ) : null}\n\n <Typography variant=\"b2\">{item.label}</Typography>\n\n {renderMenuType()}\n </button>\n\n {isGroup ? (\n <Popover\n // biome-ignore lint/suspicious/noExplicitAny: <Not needed>\n anchorRef={anchorRef as any}\n open={subOpen}\n closeOnOutsideClick={false}\n closeOnEscape={false}\n floatingOptions={floatingOptions}\n onMouseEnter={() => {\n clearTimer()\n setSubOpen(true)\n }}\n onMouseLeave={() => {\n scheduleClose()\n }}\n content={() => (\n <Menu\n width={width}\n depth={depth + 1}\n activeId={undefined}\n items={item.children}\n onHover={onHover}\n onSelect={onSelect}\n />\n )}\n onOpenChange={setSubOpen}\n />\n ) : null}\n </>\n )\n}\n","// Types\nimport { styled } from '@hooks/useThemedStyles/types'\n\nexport function createCustomRowStyles() {\n return styled({\n container: {\n padding: '0.25rem'\n }\n })\n}\n","// Hooks\nimport { useThemedStyles } from '@hooks/useThemedStyles'\n\n// Types\nimport type { CustomRowProps } from './types'\n\n// Styles\nimport { createCustomRowStyles } from './styles'\n\nexport const CustomRow = <T extends string>(props: CustomRowProps<T>) => {\n const { item, close } = props\n\n // Hooks\n const { styles } = useThemedStyles(props, createCustomRowStyles)\n\n return <div style={styles.container}>{item.render({ close })}</div>\n}\n","// Types\nimport { styled } from '@hooks/useThemedStyles/types'\n\nexport function createDividerRowStyles() {\n return styled({\n container: {\n border: 0,\n display: 'flex',\n marginBlock: '0.1rem',\n borderTop: '1px solid var(--px-border-primary)'\n }\n })\n}\n","// External Libraries\nimport type React from 'react'\n\n// Hooks\nimport { useThemedStyles } from '@hooks/useThemedStyles'\n\n// Styles\nimport { createDividerRowStyles } from './styles'\n\nexport const DividerRow: React.FC = props => {\n // Hooks\n const { styles } = useThemedStyles(props, createDividerRowStyles)\n\n return <hr style={styles.container} />\n}\n","// Types\nimport type { MenuProps } from './types'\nimport { styled } from '@hooks/useThemedStyles/types'\n\nexport function createMenuStyles<T>({ width }: MenuProps<T>) {\n return styled({\n container: {\n width,\n flexShrink: 0\n }\n })\n}\n","// Components\nimport { ItemRow } from './components/ItemRow'\nimport { CustomRow } from './components/CustomRow'\nimport { DividerRow } from './components/DividerRow'\n\n// Hooks\nimport { useThemedStyles } from '@hooks/useThemedStyles'\n\n// Types\nimport type { MenuProps } from './types'\n\n// Styles\nimport { createMenuStyles } from './styles'\n\nexport const Menu = <T extends string>(props: MenuProps<T>) => {\n const { items, depth, activeId, width = 240, onHover, onSelect } = props\n\n const { styles } = useThemedStyles(props, createMenuStyles, {\n applyCommonProps: true,\n override: props.styles,\n pick: p => [p.items, p.width, p.activeId, p.onSelect, p.onHover]\n })\n\n // Functions\n function renderItems() {\n return items.map(item => {\n if (item.type === 'divider') return <DividerRow key={item.id} />\n if (item.type === 'custom')\n return <CustomRow key={item.id} item={item} close={close} />\n\n return (\n <ItemRow\n key={item.id}\n item={item}\n depth={depth}\n width={width}\n active={activeId === item.id}\n onHover={onHover}\n onSelect={onSelect}\n />\n )\n })\n }\n\n return (\n <div style={styles.container} role={depth === 0 ? 'menu' : undefined}>\n {renderItems()}\n </div>\n )\n}\n","// Types\nimport type { MenuOption, MenuOptionInput } from '../types'\n\nexport function normalizeMenuOptions<T>(\n options: MenuOptionInput<T>[]\n): MenuOption<T>[] {\n return options.map(opt => {\n if ('children' in opt) {\n return {\n id: opt.id,\n label: opt.label,\n icon: opt.icon,\n shortcut: opt.shortcut,\n disabled: opt.disabled,\n className: opt.className,\n type: 'group' as const,\n children: normalizeMenuOptions(opt.children)\n }\n }\n return opt as MenuOption<T>\n })\n}\n","// External Libraries\nimport type { ReactNode } from 'react'\n\n// Hooks\nimport type { Placement } from '@hooks/useFloating/types'\n\n// Styles\nimport type { createContextMenuStyles } from './styles'\n\ninterface BaseOption<T> {\n id: T\n icon?: ReactNode\n label?: ReactNode\n disabled?: boolean\n className?: string\n shortcut?: ReactNode\n closeOnSelect?: boolean\n}\n\nexport type MenuActionOption<T> = BaseOption<T> & {\n type: 'action'\n closeOnSelect?: boolean\n}\n\nexport type MenuSwitchOption<T> = BaseOption<T> & {\n type: 'switch'\n checked: boolean\n closeOnSelect?: boolean\n onCheckedChange: (next: boolean) => void\n}\n\nexport interface MenuDividerOption<T> {\n id: T\n type: 'divider'\n}\n\nexport interface MenuCustomOption<T> extends BaseOption<T> {\n type: 'custom'\n render: (ctx: { close: () => void }) => ReactNode\n}\n\nexport interface MenuGroupInput<T> extends BaseOption<T> {\n type?: 'group'\n children: MenuOptionInput<T>[]\n}\n\nexport type MenuOptionInput<T> =\n | MenuGroupInput<T>\n | MenuActionOption<T>\n | MenuSwitchOption<T>\n | MenuCustomOption<T>\n | MenuDividerOption<T>\n\nexport interface MenuGroup<T> extends BaseOption<T> {\n type: 'group'\n children: MenuOption<T>[]\n}\n\nexport type MenuOption<T> =\n | MenuGroup<T>\n | MenuActionOption<T>\n | MenuSwitchOption<T>\n | MenuCustomOption<T>\n | MenuDividerOption<T>\n\nexport interface ContextMenuProps<T> {\n trigger: ReactNode\n options: MenuOptionInput<T>[]\n\n offsetX?: number\n offsetY?: number\n columnWidth?: number\n placement?: Placement\n\n onSelect: (actionId: T) => void\n\n styles?: Partial<ReturnType<typeof createContextMenuStyles>>\n}\n","// Types\nimport type { ContextMenuProps } from './types'\nimport { styled } from '@hooks/useThemedStyles/types'\n\nexport function createContextMenuStyles<T>(_props: ContextMenuProps<T>) {\n return styled({\n trigger: {\n width: 'fit-content',\n height: 'fit-content',\n\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer'\n }\n })\n}\n","// External Libraries\nimport { useMemo } from 'react'\n\n// Components\nimport { Menu } from './components/Menu'\nimport { BasePopover } from '@components/commons/structure/BasePopover'\n\n// Hooks\nimport { useThemedStyles } from '@hooks/useThemedStyles'\n\n// Utils\nimport { normalizeMenuOptions } from './utils'\n\n// Types\nimport type { ContextMenuProps, MenuOption } from './types'\nimport type { PopoverTriggerRenderProps } from '../Popover/types'\n\nexport * as ContextMenuTypes from './types'\n\n// Styles\nimport { createContextMenuStyles } from './styles'\n\nexport const ContextMenu = <T extends string>(props: ContextMenuProps<T>) => {\n const {\n trigger,\n options,\n offsetX = 0,\n offsetY = 8,\n columnWidth = 240,\n placement = 'bottom-start',\n onSelect\n } = props\n\n const items = useMemo(() => normalizeMenuOptions(options), [options])\n const floatingOptions = useMemo(\n () => ({\n offsetX,\n offsetY,\n placement\n }),\n [offsetX, offsetY, placement]\n )\n\n // Hooks\n const { styles } = useThemedStyles(props, createContextMenuStyles, {\n applyCommonProps: true,\n override: props.styles,\n pick: p => [p.options, p.columnWidth, p.placement]\n })\n\n // Functions\n function handleSelect(item: MenuOption<T>, close: () => void) {\n if (item.type === 'action') {\n onSelect(item.id)\n if (item.closeOnSelect ?? true) close()\n }\n\n if (item.type === 'switch') {\n item.onCheckedChange(!item.checked)\n if (item.closeOnSelect ?? false) close()\n }\n }\n\n function renderTrigger({\n ref,\n ariaExpanded,\n onClick\n }: PopoverTriggerRenderProps) {\n return (\n // biome-ignore lint/a11y/noStaticElementInteractions: <Not needed>\n // biome-ignore lint/a11y/useKeyWithClickEvents: <Not needed>\n <span\n ref={ref as any}\n style={styles.trigger}\n aria-expanded={ariaExpanded}\n onClick={onClick}\n >\n {trigger}\n </span>\n )\n }\n\n return (\n <BasePopover floatingOptions={floatingOptions} trigger={renderTrigger}>\n <Menu\n depth={0}\n items={items}\n onHover={() => {}}\n width={columnWidth}\n onSelect={item => handleSelect(item as MenuOption<T>, close)}\n />\n </BasePopover>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ContextMenu-ByeABVhU.js","names":["floatingOptions: FloatingOptions","DividerRow: React.FC"],"sources":["../src/components/commons/toolkit/ContextMenu/components/Menu/components/ItemRow/styles.ts","../src/components/commons/toolkit/ContextMenu/components/Menu/components/ItemRow/index.tsx","../src/components/commons/toolkit/ContextMenu/components/Menu/components/CustomRow/styles.ts","../src/components/commons/toolkit/ContextMenu/components/Menu/components/CustomRow/index.tsx","../src/components/commons/toolkit/ContextMenu/components/Menu/components/DividerRow/styles.ts","../src/components/commons/toolkit/ContextMenu/components/Menu/components/DividerRow/index.tsx","../src/components/commons/toolkit/ContextMenu/components/Menu/styles.ts","../src/components/commons/toolkit/ContextMenu/components/Menu/index.tsx","../src/components/commons/toolkit/ContextMenu/utils/normalizeMenuOptions.ts","../src/components/commons/toolkit/ContextMenu/types.ts","../src/components/commons/toolkit/ContextMenu/styles.ts","../src/components/commons/toolkit/ContextMenu/index.tsx"],"sourcesContent":["// Types\nimport type { ItemRowProps } from './types'\nimport { styled } from '@hooks/useThemedStyles/types'\n\nexport function createItemRowStyles<T>({ item, active }: ItemRowProps<T>) {\n return styled({\n button: {\n width: '100%',\n textAlign: 'left',\n\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '0.5rem',\n\n borderRadius: '0.5rem',\n\n paddingInline: '0.5rem',\n paddingBlock: '0.25rem',\n\n userSelect: 'none',\n\n backgroundColor:\n item.disabled || active\n ? 'var(--px-background-card-hover)'\n : 'transparent',\n\n __rules: {\n '&:hover': {\n transition: 'all 200ms',\n backgroundColor: 'var(--px-background-card-hover) !important'\n }\n }\n },\n containerIcon: {\n width: '1rem',\n flexShrink: 0,\n display: 'flex',\n alignItems: 'center'\n }\n })\n}\n","// External Libraries\nimport { useEffect, useRef, useState } from 'react'\n\n// Components\nimport { Menu } from '../..'\nimport { Switch } from '@components/commons/toolkit/Switch'\nimport { Popover } from '@components/commons/toolkit/Popover'\nimport { Typography } from '@components/commons/toolkit/Typography'\n\n// Hooks\nimport { useThemedStyles } from '@hooks/useThemedStyles'\n\n// Types\nimport type { ItemRowProps } from './types'\nimport type { FloatingOptions } from '@hooks/useFloating/types'\n\n// Styles\nimport { createItemRowStyles } from './styles'\n\nexport const ItemRow = <T extends string>(props: ItemRowProps<T>) => {\n const { item, depth, width, onHover, onSelect } = props\n const isGroup = item.type === 'group'\n\n const [subOpen, setSubOpen] = useState(false)\n const closeTimer = useRef<number | null>(null)\n const anchorRef = useRef<HTMLButtonElement | null>(null)\n const floatingOptions: FloatingOptions = {\n offsetX: 10,\n offsetY: -4,\n strategy: 'fixed',\n keepInViewport: true,\n placement: 'right-start'\n }\n\n // Hooks\n const { styles, classes } = useThemedStyles(props, createItemRowStyles, {\n applyCommonProps: true,\n override: props.styles,\n pick: p => [p.active]\n })\n\n // Functions\n function handleMouseEnter() {\n onHover(item.id, isGroup)\n\n if (!isGroup) return\n clearTimer()\n setSubOpen(true)\n }\n\n function handleMouseLeave() {\n if (!isGroup) return\n scheduleClose()\n }\n\n function handleClick() {\n if (isGroup) return\n onSelect(item)\n }\n\n function clearTimer() {\n if (closeTimer.current) window.clearTimeout(closeTimer.current)\n closeTimer.current = null\n }\n\n function scheduleClose() {\n clearTimer()\n closeTimer.current = window.setTimeout(() => setSubOpen(false), 150)\n }\n\n function renderMenuType() {\n if (item.type === 'switch') return <Switch checked={item.checked} />\n else {\n return (\n <>\n {item.shortcut ? <span>{item.shortcut}</span> : null}\n\n {isGroup ? <span>›</span> : null}\n </>\n )\n }\n }\n\n // UseEffects\n // biome-ignore lint/correctness/useExhaustiveDependencies: <Not needed>\n useEffect(() => {\n return () => clearTimer()\n }, [])\n\n return (\n <>\n <button\n ref={anchorRef}\n type=\"button\"\n role=\"menuitem\"\n style={styles.button}\n className={classes.button}\n disabled={!!item.disabled}\n aria-disabled={item.disabled || undefined}\n onClick={handleClick}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n >\n {item.icon ? (\n <span style={styles.containerIcon}>{item.icon ?? null}</span>\n ) : null}\n\n <Typography variant=\"b2\">{item.label}</Typography>\n\n {renderMenuType()}\n </button>\n\n {isGroup ? (\n <Popover\n // biome-ignore lint/suspicious/noExplicitAny: <Not needed>\n anchorRef={anchorRef as any}\n open={subOpen}\n closeOnOutsideClick={false}\n closeOnEscape={false}\n floatingOptions={floatingOptions}\n onMouseEnter={() => {\n clearTimer()\n setSubOpen(true)\n }}\n onMouseLeave={() => {\n scheduleClose()\n }}\n content={() => (\n <Menu\n width={width}\n depth={depth + 1}\n activeId={undefined}\n items={item.children}\n onHover={onHover}\n onSelect={onSelect}\n />\n )}\n onOpenChange={setSubOpen}\n />\n ) : null}\n </>\n )\n}\n","// Types\nimport { styled } from '@hooks/useThemedStyles/types'\n\nexport function createCustomRowStyles() {\n return styled({\n container: {\n padding: '0.25rem'\n }\n })\n}\n","// Hooks\nimport { useThemedStyles } from '@hooks/useThemedStyles'\n\n// Types\nimport type { CustomRowProps } from './types'\n\n// Styles\nimport { createCustomRowStyles } from './styles'\n\nexport const CustomRow = <T extends string>(props: CustomRowProps<T>) => {\n const { item, close } = props\n\n // Hooks\n const { styles } = useThemedStyles(props, createCustomRowStyles)\n\n return <div style={styles.container}>{item.render({ close })}</div>\n}\n","// Types\nimport { styled } from '@hooks/useThemedStyles/types'\n\nexport function createDividerRowStyles() {\n return styled({\n container: {\n border: 0,\n display: 'flex',\n marginBlock: '0.1rem',\n borderTop: '1px solid var(--px-border-primary)'\n }\n })\n}\n","// External Libraries\nimport type React from 'react'\n\n// Hooks\nimport { useThemedStyles } from '@hooks/useThemedStyles'\n\n// Styles\nimport { createDividerRowStyles } from './styles'\n\nexport const DividerRow: React.FC = props => {\n // Hooks\n const { styles } = useThemedStyles(props, createDividerRowStyles)\n\n return <hr style={styles.container} />\n}\n","// Types\nimport type { MenuProps } from './types'\nimport { styled } from '@hooks/useThemedStyles/types'\n\nexport function createMenuStyles<T>({ width }: MenuProps<T>) {\n return styled({\n container: {\n width,\n flexShrink: 0\n }\n })\n}\n","// Components\nimport { ItemRow } from './components/ItemRow'\nimport { CustomRow } from './components/CustomRow'\nimport { DividerRow } from './components/DividerRow'\n\n// Hooks\nimport { useThemedStyles } from '@hooks/useThemedStyles'\n\n// Types\nimport type { MenuProps } from './types'\n\n// Styles\nimport { createMenuStyles } from './styles'\n\nexport const Menu = <T extends string>(props: MenuProps<T>) => {\n const { items, depth, activeId, width = 240, onHover, onSelect } = props\n\n const { styles } = useThemedStyles(props, createMenuStyles, {\n applyCommonProps: true,\n override: props.styles,\n pick: p => [p.items, p.width, p.activeId, p.onSelect, p.onHover]\n })\n\n // Functions\n function renderItems() {\n return items.map(item => {\n if (item.type === 'divider') return <DividerRow key={item.id} />\n if (item.type === 'custom')\n return <CustomRow key={item.id} item={item} close={close} />\n\n return (\n <ItemRow\n key={item.id}\n item={item}\n depth={depth}\n width={width}\n active={activeId === item.id}\n onHover={onHover}\n onSelect={onSelect}\n />\n )\n })\n }\n\n return (\n <div style={styles.container} role={depth === 0 ? 'menu' : undefined}>\n {renderItems()}\n </div>\n )\n}\n","// Types\nimport type { MenuOption, MenuOptionInput } from '../types'\n\nexport function normalizeMenuOptions<T>(\n options: MenuOptionInput<T>[]\n): MenuOption<T>[] {\n return options.map(opt => {\n if ('children' in opt) {\n return {\n id: opt.id,\n label: opt.label,\n icon: opt.icon,\n shortcut: opt.shortcut,\n disabled: opt.disabled,\n className: opt.className,\n type: 'group' as const,\n children: normalizeMenuOptions(opt.children)\n }\n }\n return opt as MenuOption<T>\n })\n}\n","// External Libraries\nimport type { ReactNode } from 'react'\n\n// Hooks\nimport type { Placement } from '@hooks/useFloating/types'\n\n// Styles\nimport type { createContextMenuStyles } from './styles'\n\ninterface BaseOption<T> {\n id: T\n icon?: ReactNode\n label?: ReactNode\n disabled?: boolean\n className?: string\n shortcut?: ReactNode\n closeOnSelect?: boolean\n}\n\nexport type MenuActionOption<T> = BaseOption<T> & {\n type: 'action'\n closeOnSelect?: boolean\n}\n\nexport type MenuSwitchOption<T> = BaseOption<T> & {\n type: 'switch'\n checked: boolean\n closeOnSelect?: boolean\n onCheckedChange: (next: boolean) => void\n}\n\nexport interface MenuDividerOption<T> {\n id: T\n type: 'divider'\n}\n\nexport interface MenuCustomOption<T> extends BaseOption<T> {\n type: 'custom'\n render: (ctx: { close: () => void }) => ReactNode\n}\n\nexport interface MenuGroupInput<T> extends BaseOption<T> {\n type?: 'group'\n children: MenuOptionInput<T>[]\n}\n\nexport type MenuOptionInput<T> =\n | MenuGroupInput<T>\n | MenuActionOption<T>\n | MenuSwitchOption<T>\n | MenuCustomOption<T>\n | MenuDividerOption<T>\n\nexport interface MenuGroup<T> extends BaseOption<T> {\n type: 'group'\n children: MenuOption<T>[]\n}\n\nexport type MenuOption<T> =\n | MenuGroup<T>\n | MenuActionOption<T>\n | MenuSwitchOption<T>\n | MenuCustomOption<T>\n | MenuDividerOption<T>\n\nexport interface ContextMenuProps<T> {\n trigger: ReactNode\n options: MenuOptionInput<T>[]\n\n offsetX?: number\n offsetY?: number\n columnWidth?: number\n placement?: Placement\n\n onSelect: (actionId: T) => void\n\n styles?: Partial<ReturnType<typeof createContextMenuStyles>>\n}\n","// Types\nimport type { ContextMenuProps } from './types'\nimport { styled } from '@hooks/useThemedStyles/types'\n\nexport function createContextMenuStyles<T>(_props: ContextMenuProps<T>) {\n return styled({\n trigger: {\n width: 'fit-content',\n height: 'fit-content',\n\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer'\n }\n })\n}\n","// External Libraries\nimport { useMemo } from 'react'\n\n// Components\nimport { Menu } from './components/Menu'\nimport { BasePopover } from '@components/commons/structure/BasePopover'\n\n// Hooks\nimport { useThemedStyles } from '@hooks/useThemedStyles'\n\n// Utils\nimport { normalizeMenuOptions } from './utils'\n\n// Types\nimport type { ContextMenuProps, MenuOption } from './types'\nimport type { PopoverTriggerRenderProps } from '../Popover/types'\n\nexport * as ContextMenuTypes from './types'\n\n// Styles\nimport { createContextMenuStyles } from './styles'\n\nexport const ContextMenu = <T extends string>(props: ContextMenuProps<T>) => {\n const {\n trigger,\n options,\n offsetX = 0,\n offsetY = 8,\n columnWidth = 240,\n placement = 'bottom-start',\n onSelect\n } = props\n\n const items = useMemo(() => normalizeMenuOptions(options), [options])\n const floatingOptions = useMemo(\n () => ({\n offsetX,\n offsetY,\n placement\n }),\n [offsetX, offsetY, placement]\n )\n\n // Hooks\n const { styles } = useThemedStyles(props, createContextMenuStyles, {\n applyCommonProps: true,\n override: props.styles,\n pick: p => [p.options, p.columnWidth, p.placement]\n })\n\n // Functions\n function handleSelect(item: MenuOption<T>, close: () => void) {\n if (item.type === 'action') {\n onSelect(item.id)\n if (item.closeOnSelect ?? true) close()\n }\n\n if (item.type === 'switch') {\n item.onCheckedChange(!item.checked)\n if (item.closeOnSelect ?? false) close()\n }\n }\n\n function renderTrigger({\n ref,\n ariaExpanded,\n onClick\n }: PopoverTriggerRenderProps) {\n return (\n // biome-ignore lint/a11y/noStaticElementInteractions: <Not needed>\n // biome-ignore lint/a11y/useKeyWithClickEvents: <Not needed>\n <span\n ref={ref as any}\n style={styles.trigger}\n aria-expanded={ariaExpanded}\n onClick={onClick}\n >\n {trigger}\n </span>\n )\n }\n\n return (\n <BasePopover floatingOptions={floatingOptions} trigger={renderTrigger}>\n <Menu\n depth={0}\n items={items}\n onHover={() => {}}\n width={columnWidth}\n onSelect={item => handleSelect(item as MenuOption<T>, close)}\n />\n </BasePopover>\n )\n}\n"],"mappings":";;;;;;;;;AAIA,SAAgB,oBAAuB,EAAE,MAAM,UAA2B;AACxE,QAAO,OAAO;EACZ,QAAQ;GACN,OAAO;GACP,WAAW;GAEX,SAAS;GACT,YAAY;GACZ,gBAAgB;GAChB,KAAK;GAEL,cAAc;GAEd,eAAe;GACf,cAAc;GAEd,YAAY;GAEZ,iBACE,KAAK,YAAY,SACb,oCACA;GAEN,SAAS,EACP,WAAW;IACT,YAAY;IACZ,iBAAiB;IAClB,EACF;GACF;EACD,eAAe;GACb,OAAO;GACP,YAAY;GACZ,SAAS;GACT,YAAY;GACb;EACF,CAAC;;;;;ACrBJ,MAAa,WAA6B,UAA2B;CACnE,MAAM,EAAE,MAAM,OAAO,OAAO,SAAS,aAAa;CAClD,MAAM,UAAU,KAAK,SAAS;CAE9B,MAAM,CAAC,SAAS,cAAc,SAAS,MAAM;CAC7C,MAAM,aAAa,OAAsB,KAAK;CAC9C,MAAM,YAAY,OAAiC,KAAK;CACxD,MAAMA,kBAAmC;EACvC,SAAS;EACT,SAAS;EACT,UAAU;EACV,gBAAgB;EAChB,WAAW;EACZ;CAGD,MAAM,EAAE,QAAQ,YAAY,gBAAgB,OAAO,qBAAqB;EACtE,kBAAkB;EAClB,UAAU,MAAM;EAChB,OAAM,MAAK,CAAC,EAAE,OAAO;EACtB,CAAC;CAGF,SAAS,mBAAmB;AAC1B,UAAQ,KAAK,IAAI,QAAQ;AAEzB,MAAI,CAAC,QAAS;AACd,cAAY;AACZ,aAAW,KAAK;;CAGlB,SAAS,mBAAmB;AAC1B,MAAI,CAAC,QAAS;AACd,iBAAe;;CAGjB,SAAS,cAAc;AACrB,MAAI,QAAS;AACb,WAAS,KAAK;;CAGhB,SAAS,aAAa;AACpB,MAAI,WAAW,QAAS,QAAO,aAAa,WAAW,QAAQ;AAC/D,aAAW,UAAU;;CAGvB,SAAS,gBAAgB;AACvB,cAAY;AACZ,aAAW,UAAU,OAAO,iBAAiB,WAAW,MAAM,EAAE,IAAI;;CAGtE,SAAS,iBAAiB;AACxB,MAAI,KAAK,SAAS,SAAU,QAAO,oBAAC,UAAO,SAAS,KAAK,UAAW;MAElE,QACE,4CACG,KAAK,WAAW,oBAAC,oBAAM,KAAK,WAAgB,GAAG,MAE/C,UAAU,oBAAC,oBAAK,MAAQ,GAAG,QAC3B;;AAOT,iBAAgB;AACd,eAAa,YAAY;IACxB,EAAE,CAAC;AAEN,QACE,4CACE,qBAAC;EACC,KAAK;EACL,MAAK;EACL,MAAK;EACL,OAAO,OAAO;EACd,WAAW,QAAQ;EACnB,UAAU,CAAC,CAAC,KAAK;EACjB,iBAAe,KAAK,YAAY;EAChC,SAAS;EACT,cAAc;EACd,cAAc;;GAEb,KAAK,OACJ,oBAAC;IAAK,OAAO,OAAO;cAAgB,KAAK,QAAQ;KAAY,GAC3D;GAEJ,oBAAC;IAAW,SAAQ;cAAM,KAAK;KAAmB;GAEjD,gBAAgB;;GACV,EAER,UACC,oBAAC;EAEY;EACX,MAAM;EACN,qBAAqB;EACrB,eAAe;EACE;EACjB,oBAAoB;AAClB,eAAY;AACZ,cAAW,KAAK;;EAElB,oBAAoB;AAClB,kBAAe;;EAEjB,eACE,oBAAC;GACQ;GACP,OAAO,QAAQ;GACf,UAAU;GACV,OAAO,KAAK;GACH;GACC;IACV;EAEJ,cAAc;GACd,GACA,QACH;;;;;ACzIP,SAAgB,wBAAwB;AACtC,QAAO,OAAO,EACZ,WAAW,EACT,SAAS,WACV,EACF,CAAC;;;;;ACCJ,MAAa,aAA+B,UAA6B;CACvE,MAAM,EAAE,MAAM,mBAAU;CAGxB,MAAM,EAAE,WAAW,gBAAgB,OAAO,sBAAsB;AAEhE,QAAO,oBAAC;EAAI,OAAO,OAAO;YAAY,KAAK,OAAO,EAAE,gBAAO,CAAC;GAAO;;;;;ACZrE,SAAgB,yBAAyB;AACvC,QAAO,OAAO,EACZ,WAAW;EACT,QAAQ;EACR,SAAS;EACT,aAAa;EACb,WAAW;EACZ,EACF,CAAC;;;;;ACFJ,MAAaC,cAAuB,UAAS;CAE3C,MAAM,EAAE,WAAW,gBAAgB,OAAO,uBAAuB;AAEjE,QAAO,oBAAC,QAAG,OAAO,OAAO,YAAa;;;;;ACTxC,SAAgB,iBAAoB,EAAE,SAAuB;AAC3D,QAAO,OAAO,EACZ,WAAW;EACT;EACA,YAAY;EACb,EACF,CAAC;;;;;ACIJ,MAAa,QAA0B,UAAwB;CAC7D,MAAM,EAAE,OAAO,OAAO,UAAU,QAAQ,KAAK,SAAS,aAAa;CAEnE,MAAM,EAAE,WAAW,gBAAgB,OAAO,kBAAkB;EAC1D,kBAAkB;EAClB,UAAU,MAAM;EAChB,OAAM,MAAK;GAAC,EAAE;GAAO,EAAE;GAAO,EAAE;GAAU,EAAE;GAAU,EAAE;GAAQ;EACjE,CAAC;CAGF,SAAS,cAAc;AACrB,SAAO,MAAM,KAAI,SAAQ;AACvB,OAAI,KAAK,SAAS,UAAW,QAAO,oBAAC,gBAAgB,KAAK,GAAM;AAChE,OAAI,KAAK,SAAS,SAChB,QAAO,oBAAC;IAA8B;IAAa;MAA5B,KAAK,GAAgC;AAE9D,UACE,oBAAC;IAEO;IACC;IACA;IACP,QAAQ,aAAa,KAAK;IACjB;IACC;MANL,KAAK,GAOV;IAEJ;;AAGJ,QACE,oBAAC;EAAI,OAAO,OAAO;EAAW,MAAM,UAAU,IAAI,SAAS;YACxD,aAAa;GACV;;;;;AC5CV,SAAgB,qBACd,SACiB;AACjB,QAAO,QAAQ,KAAI,QAAO;AACxB,MAAI,cAAc,IAChB,QAAO;GACL,IAAI,IAAI;GACR,OAAO,IAAI;GACX,MAAM,IAAI;GACV,UAAU,IAAI;GACd,UAAU,IAAI;GACd,WAAW,IAAI;GACf,MAAM;GACN,UAAU,qBAAqB,IAAI,SAAS;GAC7C;AAEH,SAAO;GACP;;;;;;;;;AEhBJ,SAAgB,wBAA2B,QAA6B;AACtE,QAAO,OAAO,EACZ,SAAS;EACP,OAAO;EACP,QAAQ;EAER,SAAS;EACT,YAAY;EACZ,gBAAgB;EAChB,QAAQ;EACT,EACF,CAAC;;;;;ACOJ,MAAa,eAAiC,UAA+B;CAC3E,MAAM,EACJ,SACA,SACA,UAAU,GACV,UAAU,GACV,cAAc,KACd,YAAY,gBACZ,aACE;CAEJ,MAAM,QAAQ,cAAc,qBAAqB,QAAQ,EAAE,CAAC,QAAQ,CAAC;CACrE,MAAM,kBAAkB,eACf;EACL;EACA;EACA;EACD,GACD;EAAC;EAAS;EAAS;EAAU,CAC9B;CAGD,MAAM,EAAE,WAAW,gBAAgB,OAAO,yBAAyB;EACjE,kBAAkB;EAClB,UAAU,MAAM;EAChB,OAAM,MAAK;GAAC,EAAE;GAAS,EAAE;GAAa,EAAE;GAAU;EACnD,CAAC;CAGF,SAAS,aAAa,MAAqB,SAAmB;AAC5D,MAAI,KAAK,SAAS,UAAU;AAC1B,YAAS,KAAK,GAAG;AACjB,OAAI,KAAK,iBAAiB,KAAM,UAAO;;AAGzC,MAAI,KAAK,SAAS,UAAU;AAC1B,QAAK,gBAAgB,CAAC,KAAK,QAAQ;AACnC,OAAI,KAAK,iBAAiB,MAAO,UAAO;;;CAI5C,SAAS,cAAc,EACrB,KACA,cACA,WAC4B;AAC5B,SAGE,oBAAC;GACM;GACL,OAAO,OAAO;GACd,iBAAe;GACN;aAER;IACI;;AAIX,QACE,oBAAC;EAA6B;EAAiB,SAAS;YACtD,oBAAC;GACC,OAAO;GACA;GACP,eAAe;GACf,OAAO;GACP,WAAU,SAAQ,aAAa,MAAuB,MAAM;IAC5D;GACU"}
|
|
@@ -1,68 +1,14 @@
|
|
|
1
1
|
import { n as styled, t as useThemedStyles } from "./useThemedStyles-CrarDyWc.js";
|
|
2
|
-
import { t as useDismiss } from "./useDismiss-
|
|
2
|
+
import { t as useDismiss } from "./useDismiss-CgVHqmqk.js";
|
|
3
3
|
import { t as useFloating } from "./useFloating-DRwB71jG.js";
|
|
4
4
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
5
5
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
import { createPortal } from "react-dom";
|
|
7
7
|
|
|
8
|
-
//#region src/components/commons/toolkit/Popover/
|
|
9
|
-
function
|
|
10
|
-
return styled({
|
|
11
|
-
popoverNode: {
|
|
12
|
-
position: "fixed",
|
|
13
|
-
left: 0,
|
|
14
|
-
top: 0,
|
|
15
|
-
zIndex: 10,
|
|
16
|
-
padding: "0.25rem",
|
|
17
|
-
backgroundColor: "var(--px-bg)",
|
|
18
|
-
boxShadow: hideShadow ? "none" : "var(--px-ring-1)",
|
|
19
|
-
borderRadius: "var(--px-radius-xl)"
|
|
20
|
-
},
|
|
21
|
-
trigger: {
|
|
22
|
-
width: "fit-content",
|
|
23
|
-
height: "fit-content"
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
//#endregion
|
|
29
|
-
//#region src/components/commons/toolkit/Popover/utils/portal.ts
|
|
30
|
-
function createsFixedContainingBlock(el) {
|
|
31
|
-
let node = el;
|
|
32
|
-
while (node) {
|
|
33
|
-
const s = getComputedStyle(node);
|
|
34
|
-
if (s.transform !== "none" || s.translate !== "none" || s.perspective !== "none" || s.filter !== "none" || s.backdropFilter !== "none" || s.contain.includes("paint")) return true;
|
|
35
|
-
node = node.parentElement;
|
|
36
|
-
}
|
|
37
|
-
return false;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
//#endregion
|
|
41
|
-
//#region src/components/commons/toolkit/Popover/types.ts
|
|
42
|
-
var types_exports = {};
|
|
43
|
-
|
|
44
|
-
//#endregion
|
|
45
|
-
//#region src/components/commons/toolkit/Popover/index.tsx
|
|
46
|
-
const Popover = (props) => {
|
|
47
|
-
const { portalId, anchorRef, floatingOptions, absoluteReference, closeOnEscape = true, open: controlledOpen, closeOnOutsideClick = true, trigger, content, onOpenChange, onMouseEnter, onMouseLeave } = props;
|
|
48
|
-
const triggerRef = useRef(null);
|
|
49
|
-
const popoverRef = useRef(null);
|
|
8
|
+
//#region src/components/commons/toolkit/Popover/hooks/usePortalContainer/index.ts
|
|
9
|
+
function usePortalContainer(portalId) {
|
|
50
10
|
const portalRef = useRef(null);
|
|
51
|
-
const resolvedAnchorRef = anchorRef ?? triggerRef;
|
|
52
|
-
const [uncontrolledOpen, setUncontrolledOpen] = useState(false);
|
|
53
|
-
const [widthTrigger, setWidthTrigger] = useState(triggerRef.current?.offsetWidth ?? 0);
|
|
54
11
|
const [portalEl, setPortalEl] = useState(null);
|
|
55
|
-
const open = controlledOpen ?? uncontrolledOpen;
|
|
56
|
-
const { styles } = useThemedStyles(props, createPopoverStyles, {
|
|
57
|
-
applyCommonProps: true,
|
|
58
|
-
override: props.styles,
|
|
59
|
-
commonSlot: "popoverNode",
|
|
60
|
-
pick: (p) => [
|
|
61
|
-
p.open,
|
|
62
|
-
p.content,
|
|
63
|
-
p.trigger
|
|
64
|
-
]
|
|
65
|
-
});
|
|
66
12
|
useEffect(() => {
|
|
67
13
|
if (typeof document === "undefined") return;
|
|
68
14
|
if (!portalId) {
|
|
@@ -88,11 +34,100 @@ const Popover = (props) => {
|
|
|
88
34
|
useEffect(() => {
|
|
89
35
|
portalRef.current = portalEl;
|
|
90
36
|
}, [portalEl]);
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
37
|
+
return {
|
|
38
|
+
portalRef,
|
|
39
|
+
portalEl,
|
|
40
|
+
portalContainer: useMemo(() => {
|
|
41
|
+
if (typeof document === "undefined") return null;
|
|
42
|
+
return portalEl ?? document.body;
|
|
43
|
+
}, [portalEl])
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
//#endregion
|
|
48
|
+
//#region src/components/commons/toolkit/Popover/utils/focusNextFrom.ts
|
|
49
|
+
const SELECTOR = [
|
|
50
|
+
"a[href]",
|
|
51
|
+
"button:not([disabled])",
|
|
52
|
+
"input:not([disabled]):not([type=\"hidden\"])",
|
|
53
|
+
"select:not([disabled])",
|
|
54
|
+
"textarea:not([disabled])",
|
|
55
|
+
"[tabindex]:not([tabindex=\"-1\"])",
|
|
56
|
+
"[contenteditable=\"true\"]"
|
|
57
|
+
].join(",");
|
|
58
|
+
function isVisible(el) {
|
|
59
|
+
const style = window.getComputedStyle(el);
|
|
60
|
+
if (style.display === "none" || style.visibility === "hidden") return false;
|
|
61
|
+
const r = el.getBoundingClientRect();
|
|
62
|
+
return r.width > 0 && r.height > 0;
|
|
63
|
+
}
|
|
64
|
+
function focusNextFrom(from, root = document) {
|
|
65
|
+
const list = Array.from(root.querySelectorAll(SELECTOR)).filter(isVisible);
|
|
66
|
+
const i = list.indexOf(from);
|
|
67
|
+
const next = i >= 0 ? list[i + 1] : list[0];
|
|
68
|
+
next?.focus?.();
|
|
69
|
+
return next ?? null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
//#endregion
|
|
73
|
+
//#region src/components/commons/toolkit/Popover/utils/portal.ts
|
|
74
|
+
function createsFixedContainingBlock(el) {
|
|
75
|
+
let node = el;
|
|
76
|
+
while (node) {
|
|
77
|
+
const s = getComputedStyle(node);
|
|
78
|
+
if (s.transform !== "none" || s.translate !== "none" || s.perspective !== "none" || s.filter !== "none" || s.backdropFilter !== "none" || s.contain.includes("paint")) return true;
|
|
79
|
+
node = node.parentElement;
|
|
80
|
+
}
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
//#endregion
|
|
85
|
+
//#region src/components/commons/toolkit/Popover/hooks/usePopoverA11yFocus/index.ts
|
|
86
|
+
function usePopoverA11yFocus({ open, restoreFocusOnClose, triggerRef, lastCloseReasonRef, setOpen }) {
|
|
87
|
+
const tabFocusFromRef = useRef(null);
|
|
88
|
+
useEffect(() => {
|
|
89
|
+
if (!open) return;
|
|
90
|
+
if (typeof document === "undefined") return;
|
|
91
|
+
const onKeyDownCapture = (e) => {
|
|
92
|
+
if (e.key !== "Tab") return;
|
|
93
|
+
lastCloseReasonRef.current = "tab";
|
|
94
|
+
tabFocusFromRef.current = triggerRef.current;
|
|
95
|
+
setOpen(false);
|
|
96
|
+
};
|
|
97
|
+
document.addEventListener("keydown", onKeyDownCapture, true);
|
|
98
|
+
return () => document.removeEventListener("keydown", onKeyDownCapture, true);
|
|
99
|
+
}, [
|
|
100
|
+
open,
|
|
101
|
+
setOpen,
|
|
102
|
+
triggerRef,
|
|
103
|
+
lastCloseReasonRef
|
|
104
|
+
]);
|
|
105
|
+
useEffect(() => {
|
|
106
|
+
if (open) return;
|
|
107
|
+
if (!restoreFocusOnClose) return;
|
|
108
|
+
if (lastCloseReasonRef.current === "tab") {
|
|
109
|
+
const from = tabFocusFromRef.current;
|
|
110
|
+
tabFocusFromRef.current = null;
|
|
111
|
+
lastCloseReasonRef.current = "programmatic";
|
|
112
|
+
if (from) requestAnimationFrame(() => {
|
|
113
|
+
focusNextFrom(from, document);
|
|
114
|
+
});
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
requestAnimationFrame(() => triggerRef.current?.focus?.());
|
|
118
|
+
lastCloseReasonRef.current = "programmatic";
|
|
119
|
+
}, [
|
|
120
|
+
open,
|
|
121
|
+
restoreFocusOnClose,
|
|
122
|
+
triggerRef,
|
|
123
|
+
lastCloseReasonRef
|
|
124
|
+
]);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
//#endregion
|
|
128
|
+
//#region src/components/commons/toolkit/Popover/hooks/usePopoverFloatingOptions/index.ts
|
|
129
|
+
function usePopoverFloatingOptions({ portalId, portalContainer, portalRef, floatingOptions, absoluteReference }) {
|
|
130
|
+
return useMemo(() => {
|
|
96
131
|
const base = {
|
|
97
132
|
offsetY: 6,
|
|
98
133
|
keepInViewport: true,
|
|
@@ -114,31 +149,88 @@ const Popover = (props) => {
|
|
|
114
149
|
}, [
|
|
115
150
|
portalId,
|
|
116
151
|
portalContainer,
|
|
117
|
-
|
|
118
|
-
|
|
152
|
+
portalRef,
|
|
153
|
+
floatingOptions,
|
|
154
|
+
absoluteReference
|
|
155
|
+
]);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
//#endregion
|
|
159
|
+
//#region src/components/commons/toolkit/Popover/styles.ts
|
|
160
|
+
function createPopoverStyles({ hideShadow = false }) {
|
|
161
|
+
return styled({
|
|
162
|
+
popoverNode: {
|
|
163
|
+
position: "fixed",
|
|
164
|
+
left: 0,
|
|
165
|
+
top: 0,
|
|
166
|
+
zIndex: 10,
|
|
167
|
+
padding: "0.25rem",
|
|
168
|
+
backgroundColor: "var(--px-bg)",
|
|
169
|
+
boxShadow: hideShadow ? "none" : "var(--px-ring-1)",
|
|
170
|
+
borderRadius: "var(--px-radius-xl)"
|
|
171
|
+
},
|
|
172
|
+
trigger: {
|
|
173
|
+
width: "fit-content",
|
|
174
|
+
height: "fit-content"
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
//#endregion
|
|
180
|
+
//#region src/components/commons/toolkit/Popover/index.tsx
|
|
181
|
+
const Popover = (props) => {
|
|
182
|
+
const { portalId, anchorRef, floatingOptions, absoluteReference, closeOnEscape = true, open: controlledOpen, closeOnOutsideClick = true, restoreFocusOnClose = true, trigger, content, onOpenChange, onMouseEnter, onMouseLeave } = props;
|
|
183
|
+
const triggerRef = useRef(null);
|
|
184
|
+
const popoverRef = useRef(null);
|
|
185
|
+
const resolvedAnchorRef = anchorRef ?? triggerRef;
|
|
186
|
+
const lastCloseReasonRef = useRef("programmatic");
|
|
187
|
+
const [uncontrolledOpen, setUncontrolledOpen] = useState(false);
|
|
188
|
+
const [widthTrigger, setWidthTrigger] = useState(0);
|
|
189
|
+
const open = controlledOpen ?? uncontrolledOpen;
|
|
190
|
+
const { portalRef, portalContainer } = usePortalContainer(portalId);
|
|
191
|
+
const { styles } = useThemedStyles(props, createPopoverStyles, {
|
|
192
|
+
applyCommonProps: true,
|
|
193
|
+
override: props.styles,
|
|
194
|
+
commonSlot: "popoverNode",
|
|
195
|
+
pick: (p) => [
|
|
196
|
+
p.open,
|
|
197
|
+
p.content,
|
|
198
|
+
p.trigger
|
|
199
|
+
]
|
|
200
|
+
});
|
|
119
201
|
const setOpen = useCallback((v) => {
|
|
120
202
|
onOpenChange?.(v);
|
|
121
203
|
if (controlledOpen === void 0) setUncontrolledOpen(v);
|
|
122
204
|
}, [controlledOpen, onOpenChange]);
|
|
123
|
-
const
|
|
205
|
+
const { floatingRef, update } = useFloating(resolvedAnchorRef, usePopoverFloatingOptions({
|
|
206
|
+
portalId,
|
|
207
|
+
portalContainer,
|
|
208
|
+
portalRef,
|
|
209
|
+
floatingOptions,
|
|
210
|
+
absoluteReference
|
|
211
|
+
}));
|
|
212
|
+
usePopoverA11yFocus({
|
|
213
|
+
open,
|
|
214
|
+
restoreFocusOnClose,
|
|
215
|
+
triggerRef,
|
|
216
|
+
lastCloseReasonRef,
|
|
217
|
+
setOpen
|
|
218
|
+
});
|
|
124
219
|
useDismiss({
|
|
125
220
|
open,
|
|
126
221
|
closeOnEscape,
|
|
127
222
|
closeOnOutsideClick,
|
|
128
|
-
refs: [
|
|
129
|
-
onClose:
|
|
223
|
+
refs: [triggerRef, popoverRef],
|
|
224
|
+
onClose: () => {
|
|
225
|
+
lastCloseReasonRef.current = "outside";
|
|
226
|
+
setOpen(false);
|
|
227
|
+
}
|
|
130
228
|
});
|
|
131
229
|
useEffect(() => {
|
|
132
|
-
if (open)
|
|
230
|
+
if (!open) return;
|
|
133
231
|
setWidthTrigger(triggerRef.current?.offsetWidth ?? 0);
|
|
232
|
+
requestAnimationFrame(update);
|
|
134
233
|
}, [open, update]);
|
|
135
|
-
useEffect(() => {
|
|
136
|
-
const handleResize = () => {
|
|
137
|
-
setWidthTrigger(triggerRef.current?.offsetWidth ?? 0);
|
|
138
|
-
};
|
|
139
|
-
window.addEventListener("resize", handleResize);
|
|
140
|
-
return () => window.removeEventListener("resize", handleResize);
|
|
141
|
-
}, []);
|
|
142
234
|
const triggerNode = trigger?.({
|
|
143
235
|
ariaExpanded: open,
|
|
144
236
|
ref: triggerRef,
|
|
@@ -153,10 +245,15 @@ const Popover = (props) => {
|
|
|
153
245
|
style: styles.popoverNode,
|
|
154
246
|
onMouseEnter,
|
|
155
247
|
onMouseLeave,
|
|
156
|
-
|
|
157
|
-
|
|
248
|
+
onKeyDown: (e) => {
|
|
249
|
+
if (e.key === "Escape") {
|
|
250
|
+
e.preventDefault();
|
|
251
|
+
lastCloseReasonRef.current = "escape";
|
|
252
|
+
setOpen(false);
|
|
253
|
+
}
|
|
254
|
+
},
|
|
158
255
|
children: content({
|
|
159
|
-
close,
|
|
256
|
+
close: () => setOpen(false),
|
|
160
257
|
widthTrigger
|
|
161
258
|
})
|
|
162
259
|
}) : null;
|
|
@@ -164,5 +261,5 @@ const Popover = (props) => {
|
|
|
164
261
|
};
|
|
165
262
|
|
|
166
263
|
//#endregion
|
|
167
|
-
export {
|
|
168
|
-
//# sourceMappingURL=Popover-
|
|
264
|
+
export { Popover as t };
|
|
265
|
+
//# sourceMappingURL=Popover-DpD3G9_i.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Popover-DpD3G9_i.js","names":["node: HTMLElement | null","Popover: React.FC<PopoverProps>"],"sources":["../src/components/commons/toolkit/Popover/hooks/usePortalContainer/index.ts","../src/components/commons/toolkit/Popover/utils/focusNextFrom.ts","../src/components/commons/toolkit/Popover/utils/portal.ts","../src/components/commons/toolkit/Popover/hooks/usePopoverA11yFocus/index.ts","../src/components/commons/toolkit/Popover/hooks/usePopoverFloatingOptions/index.ts","../src/components/commons/toolkit/Popover/styles.ts","../src/components/commons/toolkit/Popover/index.tsx"],"sourcesContent":["// External Libraries\nimport { useEffect, useMemo, useRef, useState } from 'react'\n\nexport function usePortalContainer(portalId?: string) {\n const portalRef = useRef<HTMLElement | null>(null)\n const [portalEl, setPortalEl] = useState<HTMLElement | null>(null)\n\n useEffect(() => {\n if (typeof document === 'undefined') return\n\n if (!portalId) {\n setPortalEl(null)\n return\n }\n\n const found = document.getElementById(portalId) as HTMLElement | null\n setPortalEl(found)\n if (found) return\n\n const obs = new MutationObserver(() => {\n const el = document.getElementById(portalId) as HTMLElement | null\n if (el) {\n setPortalEl(el)\n obs.disconnect()\n }\n })\n\n obs.observe(document.documentElement, { childList: true, subtree: true })\n return () => obs.disconnect()\n }, [portalId])\n\n useEffect(() => {\n portalRef.current = portalEl\n }, [portalEl])\n\n const portalContainer = useMemo(() => {\n if (typeof document === 'undefined') return null\n return portalEl ?? document.body\n }, [portalEl])\n\n return { portalRef, portalEl, portalContainer }\n}\n","const SELECTOR = [\n 'a[href]',\n 'button:not([disabled])',\n 'input:not([disabled]):not([type=\"hidden\"])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n '[contenteditable=\"true\"]'\n].join(',')\n\nfunction isVisible(el: HTMLElement) {\n const style = window.getComputedStyle(el)\n if (style.display === 'none' || style.visibility === 'hidden') return false\n const r = el.getBoundingClientRect()\n return r.width > 0 && r.height > 0\n}\n\nexport function focusNextFrom(from: HTMLElement, root: ParentNode = document) {\n const list = Array.from(root.querySelectorAll<HTMLElement>(SELECTOR)).filter(\n isVisible\n )\n\n const i = list.indexOf(from)\n const next = i >= 0 ? list[i + 1] : list[0]\n next?.focus?.()\n return next ?? null\n}\n","export function resolvePortalContainer(portalId?: string): HTMLElement | null {\n if (typeof document === 'undefined') return null\n if (!portalId) return document.body\n return document.getElementById(portalId) ?? document.body\n}\n\nexport function createsFixedContainingBlock(el: HTMLElement): boolean {\n let node: HTMLElement | null = el\n while (node) {\n const s = getComputedStyle(node)\n if (\n s.transform !== 'none' ||\n s.translate !== 'none' ||\n s.perspective !== 'none' ||\n s.filter !== 'none' ||\n s.backdropFilter !== 'none' ||\n s.contain.includes('paint')\n ) {\n return true\n }\n node = node.parentElement\n }\n return false\n}\n","// External Libraries\nimport { useEffect, useRef } from 'react'\n\n// Utils\nimport { focusNextFrom } from '../../utils'\n\n// Types\nimport type { CloseReason } from '../../types'\n\ntype Params = {\n open: boolean\n restoreFocusOnClose: boolean\n triggerRef: React.RefObject<HTMLElement | null>\n lastCloseReasonRef: React.MutableRefObject<CloseReason>\n setOpen: (v: boolean) => void\n}\n\nexport function usePopoverA11yFocus({\n open,\n restoreFocusOnClose,\n triggerRef,\n lastCloseReasonRef,\n setOpen\n}: Params) {\n const tabFocusFromRef = useRef<HTMLElement | null>(null)\n\n useEffect(() => {\n if (!open) return\n if (typeof document === 'undefined') return\n\n const onKeyDownCapture = (e: KeyboardEvent) => {\n if (e.key !== 'Tab') return\n lastCloseReasonRef.current = 'tab'\n tabFocusFromRef.current = triggerRef.current\n setOpen(false)\n }\n\n document.addEventListener('keydown', onKeyDownCapture, true)\n return () => document.removeEventListener('keydown', onKeyDownCapture, true)\n }, [open, setOpen, triggerRef, lastCloseReasonRef])\n\n useEffect(() => {\n if (open) return\n if (!restoreFocusOnClose) return\n\n const reason = lastCloseReasonRef.current\n\n if (reason === 'tab') {\n const from = tabFocusFromRef.current\n tabFocusFromRef.current = null\n lastCloseReasonRef.current = 'programmatic'\n\n if (from) {\n requestAnimationFrame(() => {\n focusNextFrom(from, document)\n })\n }\n return\n }\n\n requestAnimationFrame(() => triggerRef.current?.focus?.())\n lastCloseReasonRef.current = 'programmatic'\n }, [open, restoreFocusOnClose, triggerRef, lastCloseReasonRef])\n}\n","// External Libraries\nimport { useMemo } from 'react'\nimport type { RefObject } from 'react'\n\n// Hooks\nimport type { FloatingOptions } from '@hooks/useFloating/types'\n\n// Utils\nimport { createsFixedContainingBlock } from '../../utils'\n\ntype Params = {\n portalId?: string\n portalContainer: HTMLElement | null\n portalRef: RefObject<HTMLElement | null>\n floatingOptions?: FloatingOptions\n absoluteReference?: FloatingOptions['absoluteReference']\n}\n\nexport function usePopoverFloatingOptions({\n portalId,\n portalContainer,\n portalRef,\n floatingOptions,\n absoluteReference\n}: Params) {\n return useMemo(() => {\n const base = {\n offsetY: 6,\n keepInViewport: true,\n placement: 'bottom-start',\n portalRef\n } as const\n\n const userStrategy = floatingOptions?.strategy ?? 'fixed'\n\n const shouldFixFixedInPortal =\n !!portalId &&\n portalContainer &&\n userStrategy === 'fixed' &&\n portalContainer !== document.body &&\n createsFixedContainingBlock(portalContainer)\n\n if (shouldFixFixedInPortal) {\n return {\n ...base,\n ...floatingOptions,\n strategy: 'absolute',\n absoluteReference: 'offsetParent'\n } as any\n }\n\n return {\n ...base,\n ...floatingOptions,\n absoluteReference\n } as any\n }, [portalId, portalContainer, portalRef, floatingOptions, absoluteReference])\n}\n","// Types\nimport type { PopoverProps } from './types'\nimport { styled } from '@hooks/useThemedStyles/types'\n\nexport function createPopoverStyles({ hideShadow = false }: PopoverProps) {\n return styled({\n popoverNode: {\n position: 'fixed',\n left: 0,\n top: 0,\n\n zIndex: 10,\n\n padding: '0.25rem',\n\n backgroundColor: 'var(--px-bg)',\n boxShadow: hideShadow ? 'none' : 'var(--px-ring-1)',\n\n borderRadius: 'var(--px-radius-xl)'\n },\n\n trigger: {\n width: 'fit-content',\n height: 'fit-content'\n }\n })\n}\n","// External Libraries\nimport type React from 'react'\nimport { createPortal } from 'react-dom'\nimport { useCallback, useEffect, useRef, useState } from 'react'\n\n// Hooks\nimport { useDismiss } from '@hooks/useDismiss'\nimport { useFloating } from '@hooks/useFloating'\nimport { useThemedStyles } from '@hooks/useThemedStyles'\nimport { usePortalContainer } from './hooks/usePortalContainer'\nimport { usePopoverA11yFocus } from './hooks/usePopoverA11yFocus'\nimport { usePopoverFloatingOptions } from './hooks/usePopoverFloatingOptions'\n\n// Types\nimport type { CloseReason, PopoverProps } from './types'\n\n// Styles\nimport { createPopoverStyles } from './styles'\n\nexport const Popover: React.FC<PopoverProps> = props => {\n const {\n portalId,\n anchorRef,\n floatingOptions,\n absoluteReference,\n closeOnEscape = true,\n open: controlledOpen,\n closeOnOutsideClick = true,\n restoreFocusOnClose = true,\n trigger,\n content,\n onOpenChange,\n onMouseEnter,\n onMouseLeave\n } = props\n\n const triggerRef = useRef<HTMLElement | null>(null)\n const popoverRef = useRef<HTMLDivElement | null>(null)\n const resolvedAnchorRef = (anchorRef ?? triggerRef) as any\n\n const lastCloseReasonRef = useRef<CloseReason>('programmatic')\n\n const [uncontrolledOpen, setUncontrolledOpen] = useState(false)\n const [widthTrigger, setWidthTrigger] = useState(0)\n const open = controlledOpen ?? uncontrolledOpen\n\n const { portalRef, portalContainer } = usePortalContainer(portalId)\n\n const { styles } = useThemedStyles(props, createPopoverStyles, {\n applyCommonProps: true,\n override: props.styles,\n commonSlot: 'popoverNode',\n pick: p => [p.open, p.content, p.trigger]\n })\n\n const setOpen = useCallback(\n (v: boolean) => {\n onOpenChange?.(v)\n if (controlledOpen === undefined) setUncontrolledOpen(v)\n },\n [controlledOpen, onOpenChange]\n )\n\n const effectiveFloating = usePopoverFloatingOptions({\n portalId,\n portalContainer: portalContainer as any,\n portalRef,\n floatingOptions,\n absoluteReference\n })\n\n const { floatingRef, update } = useFloating(\n resolvedAnchorRef,\n effectiveFloating\n )\n\n usePopoverA11yFocus({\n open,\n restoreFocusOnClose,\n triggerRef,\n lastCloseReasonRef,\n setOpen\n })\n\n useDismiss({\n open,\n closeOnEscape,\n closeOnOutsideClick,\n refs: [triggerRef, popoverRef],\n onClose: () => {\n lastCloseReasonRef.current = 'outside'\n setOpen(false)\n }\n })\n\n useEffect(() => {\n if (!open) return\n setWidthTrigger(triggerRef.current?.offsetWidth ?? 0)\n requestAnimationFrame(update)\n }, [open, update])\n\n const triggerNode =\n trigger?.({\n ariaExpanded: open,\n ref: triggerRef as any,\n onClick: () => setOpen(!open)\n }) ?? null\n\n const popoverNode = open ? (\n <div\n ref={el => {\n popoverRef.current = el\n floatingRef(el as any)\n }}\n role=\"dialog\"\n style={styles.popoverNode}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n onKeyDown={e => {\n if (e.key === 'Escape') {\n e.preventDefault()\n lastCloseReasonRef.current = 'escape'\n setOpen(false)\n }\n }}\n >\n {content({ close: () => setOpen(false), widthTrigger })}\n </div>\n ) : null\n\n return (\n <>\n {triggerNode}\n {typeof document !== 'undefined'\n ? createPortal(popoverNode, portalContainer ?? document.body)\n : null}\n </>\n )\n}\n"],"mappings":"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"}
|