softable-pixels-web 1.1.21 → 1.1.23
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-CES18mzR.js} +3 -2
- package/dist/BasePopover-CES18mzR.js.map +1 -0
- package/dist/{ContextMenu-B94eRUm7.js → ContextMenu-D7lPQcw1.js} +16 -8
- package/dist/ContextMenu-D7lPQcw1.js.map +1 -0
- package/dist/{Popover-BDNQO09F.js → Popover-CNon8bZo.js} +183 -80
- package/dist/Popover-CNon8bZo.js.map +1 -0
- package/dist/{Select-Bad465DY.js → Select-CGWL6BOg.js} +217 -21
- package/dist/Select-CGWL6BOg.js.map +1 -0
- package/dist/base-popover.d.ts +3 -3
- package/dist/base-popover.js +4 -4
- package/dist/button.d.ts +1 -1
- package/dist/context-menu.js +5 -5
- package/dist/{index-DEKll7zF.d.ts → index-B6t8KE4A.d.ts} +2 -3
- package/dist/{index-modFVzpZ.d.ts → index-CK68mp8m.d.ts} +3 -3
- package/dist/{index-ClqTlRGD.d.ts → index-CPoGZ0_L.d.ts} +2 -2
- package/dist/{index-CyvNJW2l.d.ts → index-CYnINkUh.d.ts} +2 -2
- package/dist/{index-DVE8mV5m.d.ts → index-DUP_xS5q.d.ts} +3 -3
- package/dist/index.d.ts +6 -6
- package/dist/index.js +6 -6
- package/dist/popover.d.ts +2 -2
- package/dist/popover.js +3 -3
- package/dist/select.d.ts +2 -2
- package/dist/select.js +5 -5
- package/dist/tab-switch.d.ts +1 -1
- package/dist/{types-CRA-1_6O.d.ts → types-Bayf6NdC.d.ts} +5 -2
- package/dist/use-dismiss.d.ts +2 -0
- package/dist/use-dismiss.js +1 -1
- package/dist/use-floating.js +1 -1
- package/dist/{useDismiss-CAEk_GV-.js → useDismiss-DwQfMU11.js} +13 -6
- package/dist/useDismiss-DwQfMU11.js.map +1 -0
- package/dist/{useFloating-DRwB71jG.js → useFloating-DCxblHIR.js} +1 -2
- package/dist/{useFloating-DRwB71jG.js.map → useFloating-DCxblHIR.js.map} +1 -1
- package/package.json +1 -1
- package/dist/BasePopover-BVeMpuWR.js.map +0 -1
- package/dist/ContextMenu-B94eRUm7.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.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-CNon8bZo.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-CES18mzR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BasePopover-CES18mzR.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,7 @@
|
|
|
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-BDNQO09F.js";
|
|
4
3
|
import { t as Typography } from "./Typography-BkFV7BhK.js";
|
|
5
|
-
import { t as BasePopover } from "./BasePopover-
|
|
4
|
+
import { t as BasePopover } from "./BasePopover-CES18mzR.js";
|
|
6
5
|
import { useEffect, useMemo, useRef, useState } from "react";
|
|
7
6
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
8
7
|
|
|
@@ -106,12 +105,13 @@ const ItemRow = (props) => {
|
|
|
106
105
|
}),
|
|
107
106
|
renderMenuType()
|
|
108
107
|
]
|
|
109
|
-
}), isGroup ? /* @__PURE__ */ jsx(
|
|
108
|
+
}), isGroup ? /* @__PURE__ */ jsx(BasePopover, {
|
|
110
109
|
anchorRef,
|
|
111
110
|
open: subOpen,
|
|
112
|
-
closeOnOutsideClick: false,
|
|
113
111
|
closeOnEscape: false,
|
|
112
|
+
closeOnOutsideClick: false,
|
|
114
113
|
floatingOptions,
|
|
114
|
+
dismissScope: props.dismissScope,
|
|
115
115
|
onMouseEnter: () => {
|
|
116
116
|
clearTimer();
|
|
117
117
|
setSubOpen(true);
|
|
@@ -119,15 +119,15 @@ const ItemRow = (props) => {
|
|
|
119
119
|
onMouseLeave: () => {
|
|
120
120
|
scheduleClose();
|
|
121
121
|
},
|
|
122
|
-
|
|
122
|
+
onOpenChange: setSubOpen,
|
|
123
|
+
children: /* @__PURE__ */ jsx(Menu, {
|
|
123
124
|
width,
|
|
124
125
|
depth: depth + 1,
|
|
125
126
|
activeId: void 0,
|
|
126
127
|
items: item.children,
|
|
127
128
|
onHover,
|
|
128
129
|
onSelect
|
|
129
|
-
})
|
|
130
|
-
onOpenChange: setSubOpen
|
|
130
|
+
})
|
|
131
131
|
}) : null] });
|
|
132
132
|
};
|
|
133
133
|
|
|
@@ -202,6 +202,7 @@ const Menu = (props) => {
|
|
|
202
202
|
depth,
|
|
203
203
|
width,
|
|
204
204
|
active: activeId === item.id,
|
|
205
|
+
dismissScope: props.dismissScope,
|
|
205
206
|
onHover,
|
|
206
207
|
onSelect
|
|
207
208
|
}, item.id);
|
|
@@ -253,6 +254,7 @@ function createContextMenuStyles(_props) {
|
|
|
253
254
|
//#region src/components/commons/toolkit/ContextMenu/index.tsx
|
|
254
255
|
const ContextMenu = (props) => {
|
|
255
256
|
const { trigger, options, offsetX = 0, offsetY = 8, columnWidth = 240, placement = "bottom-start", onSelect } = props;
|
|
257
|
+
const scopeRef = useRef(makeScopeId());
|
|
256
258
|
const items = useMemo(() => normalizeMenuOptions(options), [options]);
|
|
257
259
|
const floatingOptions = useMemo(() => ({
|
|
258
260
|
offsetX,
|
|
@@ -272,6 +274,10 @@ const ContextMenu = (props) => {
|
|
|
272
274
|
p.placement
|
|
273
275
|
]
|
|
274
276
|
});
|
|
277
|
+
function makeScopeId() {
|
|
278
|
+
if (typeof crypto !== "undefined" && crypto.randomUUID) return crypto.randomUUID();
|
|
279
|
+
return `scope_${Math.random().toString(16).slice(2)}`;
|
|
280
|
+
}
|
|
275
281
|
function handleSelect(item, close$1) {
|
|
276
282
|
if (item.type === "action") {
|
|
277
283
|
onSelect(item.id);
|
|
@@ -293,12 +299,14 @@ const ContextMenu = (props) => {
|
|
|
293
299
|
}
|
|
294
300
|
return /* @__PURE__ */ jsx(BasePopover, {
|
|
295
301
|
floatingOptions,
|
|
302
|
+
dismissScope: scopeRef.current,
|
|
296
303
|
trigger: renderTrigger,
|
|
297
304
|
children: /* @__PURE__ */ jsx(Menu, {
|
|
298
305
|
depth: 0,
|
|
299
306
|
items,
|
|
300
307
|
onHover: () => {},
|
|
301
308
|
width: columnWidth,
|
|
309
|
+
dismissScope: scopeRef.current,
|
|
302
310
|
onSelect: (item) => handleSelect(item, close)
|
|
303
311
|
})
|
|
304
312
|
});
|
|
@@ -306,4 +314,4 @@ const ContextMenu = (props) => {
|
|
|
306
314
|
|
|
307
315
|
//#endregion
|
|
308
316
|
export { types_exports as n, ContextMenu as t };
|
|
309
|
-
//# sourceMappingURL=ContextMenu-
|
|
317
|
+
//# sourceMappingURL=ContextMenu-D7lPQcw1.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContextMenu-D7lPQcw1.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 { Typography } from '@components/commons/toolkit/Typography'\nimport { BasePopover } from '@components/commons/structure/BasePopover'\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 <BasePopover\n // biome-ignore lint/suspicious/noExplicitAny: <Not needed>\n anchorRef={anchorRef as any}\n open={subOpen}\n closeOnEscape={false}\n closeOnOutsideClick={false}\n floatingOptions={floatingOptions}\n dismissScope={props.dismissScope}\n onMouseEnter={() => {\n clearTimer()\n setSubOpen(true)\n }}\n onMouseLeave={() => {\n scheduleClose()\n }}\n onOpenChange={setSubOpen}\n >\n <Menu\n width={width}\n depth={depth + 1}\n activeId={undefined}\n items={item.children}\n onHover={onHover}\n onSelect={onSelect}\n />\n </BasePopover>\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 dismissScope={props.dismissScope}\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, useRef } 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 // Refs\n const scopeRef = useRef<string>(makeScopeId())\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 makeScopeId() {\n if (typeof crypto !== 'undefined' && crypto.randomUUID)\n return crypto.randomUUID()\n return `scope_${Math.random().toString(16).slice(2)}`\n }\n\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\n floatingOptions={floatingOptions}\n dismissScope={scopeRef.current}\n trigger={renderTrigger}\n >\n <Menu\n depth={0}\n items={items}\n onHover={() => {}}\n width={columnWidth}\n dismissScope={scopeRef.current}\n onSelect={item => handleSelect(item as MenuOption<T>, close)}\n />\n </BasePopover>\n )\n}\n"],"mappings":"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"}
|
|
@@ -1,68 +1,14 @@
|
|
|
1
1
|
import { n as styled, t as useThemedStyles } from "./useThemedStyles-CrarDyWc.js";
|
|
2
|
-
import { t as useDismiss } from "./useDismiss-
|
|
3
|
-
import { t as useFloating } from "./useFloating-
|
|
2
|
+
import { t as useDismiss } from "./useDismiss-DwQfMU11.js";
|
|
3
|
+
import { t as useFloating } from "./useFloating-DCxblHIR.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,93 @@ 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/types.ts
|
|
181
|
+
var types_exports = {};
|
|
182
|
+
|
|
183
|
+
//#endregion
|
|
184
|
+
//#region src/components/commons/toolkit/Popover/index.tsx
|
|
185
|
+
const Popover = (props) => {
|
|
186
|
+
const { portalId, anchorRef, dismissScope, floatingOptions, absoluteReference, closeOnEscape = true, open: controlledOpen, closeOnOutsideClick = true, restoreFocusOnClose = true, trigger, content, onOpenChange, onMouseEnter, onMouseLeave } = props;
|
|
187
|
+
const triggerRef = useRef(null);
|
|
188
|
+
const popoverRef = useRef(null);
|
|
189
|
+
const resolvedAnchorRef = anchorRef ?? triggerRef;
|
|
190
|
+
const lastCloseReasonRef = useRef("programmatic");
|
|
191
|
+
const [uncontrolledOpen, setUncontrolledOpen] = useState(false);
|
|
192
|
+
const [widthTrigger, setWidthTrigger] = useState(0);
|
|
193
|
+
const open = controlledOpen ?? uncontrolledOpen;
|
|
194
|
+
const { portalRef, portalContainer } = usePortalContainer(portalId);
|
|
195
|
+
const { styles } = useThemedStyles(props, createPopoverStyles, {
|
|
196
|
+
applyCommonProps: true,
|
|
197
|
+
override: props.styles,
|
|
198
|
+
commonSlot: "popoverNode",
|
|
199
|
+
pick: (p) => [
|
|
200
|
+
p.open,
|
|
201
|
+
p.content,
|
|
202
|
+
p.trigger
|
|
203
|
+
]
|
|
204
|
+
});
|
|
119
205
|
const setOpen = useCallback((v) => {
|
|
120
206
|
onOpenChange?.(v);
|
|
121
207
|
if (controlledOpen === void 0) setUncontrolledOpen(v);
|
|
122
208
|
}, [controlledOpen, onOpenChange]);
|
|
123
|
-
const
|
|
209
|
+
const { floatingRef, update } = useFloating(resolvedAnchorRef, usePopoverFloatingOptions({
|
|
210
|
+
portalId,
|
|
211
|
+
portalContainer,
|
|
212
|
+
portalRef,
|
|
213
|
+
floatingOptions,
|
|
214
|
+
absoluteReference
|
|
215
|
+
}));
|
|
216
|
+
usePopoverA11yFocus({
|
|
217
|
+
open,
|
|
218
|
+
restoreFocusOnClose,
|
|
219
|
+
triggerRef,
|
|
220
|
+
lastCloseReasonRef,
|
|
221
|
+
setOpen
|
|
222
|
+
});
|
|
124
223
|
useDismiss({
|
|
125
224
|
open,
|
|
126
225
|
closeOnEscape,
|
|
127
226
|
closeOnOutsideClick,
|
|
128
|
-
|
|
129
|
-
|
|
227
|
+
dismissScope: props.dismissScope,
|
|
228
|
+
refs: [triggerRef, popoverRef],
|
|
229
|
+
onClose: () => {
|
|
230
|
+
lastCloseReasonRef.current = "outside";
|
|
231
|
+
setOpen(false);
|
|
232
|
+
}
|
|
130
233
|
});
|
|
131
234
|
useEffect(() => {
|
|
132
|
-
if (open)
|
|
235
|
+
if (!open) return;
|
|
133
236
|
setWidthTrigger(triggerRef.current?.offsetWidth ?? 0);
|
|
237
|
+
requestAnimationFrame(update);
|
|
134
238
|
}, [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
239
|
const triggerNode = trigger?.({
|
|
143
240
|
ariaExpanded: open,
|
|
144
241
|
ref: triggerRef,
|
|
@@ -151,12 +248,18 @@ const Popover = (props) => {
|
|
|
151
248
|
},
|
|
152
249
|
role: "dialog",
|
|
153
250
|
style: styles.popoverNode,
|
|
251
|
+
"data-dismiss-scope": dismissScope,
|
|
154
252
|
onMouseEnter,
|
|
155
253
|
onMouseLeave,
|
|
156
|
-
|
|
157
|
-
|
|
254
|
+
onKeyDown: (e) => {
|
|
255
|
+
if (e.key === "Escape") {
|
|
256
|
+
e.preventDefault();
|
|
257
|
+
lastCloseReasonRef.current = "escape";
|
|
258
|
+
setOpen(false);
|
|
259
|
+
}
|
|
260
|
+
},
|
|
158
261
|
children: content({
|
|
159
|
-
close,
|
|
262
|
+
close: () => setOpen(false),
|
|
160
263
|
widthTrigger
|
|
161
264
|
})
|
|
162
265
|
}) : null;
|
|
@@ -165,4 +268,4 @@ const Popover = (props) => {
|
|
|
165
268
|
|
|
166
269
|
//#endregion
|
|
167
270
|
export { types_exports as n, Popover as t };
|
|
168
|
-
//# sourceMappingURL=Popover-
|
|
271
|
+
//# sourceMappingURL=Popover-CNon8bZo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Popover-CNon8bZo.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/types.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 { MouseEventHandler, ReactNode, RefObject } from 'react'\n\n// Types\nimport type { createPopoverStyles } from './styles'\nimport type { FloatingOptions } from '@hooks/useFloating/types'\nimport type { PaddingProps } from '@hooks/useThemedStyles/types'\n\nexport type PopoverTriggerRenderProps = {\n ariaExpanded: boolean\n ref: RefObject<HTMLElement>\n onClick: () => void\n}\n\nexport type CloseReason = 'outside' | 'escape' | 'tab' | 'programmatic'\n\nexport interface PopoverProps extends PaddingProps {\n open?: boolean\n portalId?: string\n containerId?: string\n hideShadow?: boolean\n dismissScope?: string\n closeOnEscape?: boolean\n closeOnOutsideClick?: boolean\n floatingOptions?: FloatingOptions\n anchorRef?: RefObject<HTMLElement>\n absoluteReference?: FloatingOptions['absoluteReference']\n\n restoreFocusOnClose?: boolean\n\n onOpenChange?: (v: boolean) => void\n onMouseEnter?: MouseEventHandler<HTMLDivElement>\n onMouseLeave?: MouseEventHandler<HTMLDivElement>\n content: (ctx: { close: () => void; widthTrigger: number }) => ReactNode\n trigger?: (props: PopoverTriggerRenderProps) => ReactNode\n\n styles?: Partial<ReturnType<typeof createPopoverStyles>>\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 * as PopoverTypes from './types'\n\nexport const Popover: React.FC<PopoverProps> = props => {\n const {\n portalId,\n anchorRef,\n dismissScope,\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 dismissScope: props.dismissScope,\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 data-dismiss-scope={dismissScope}\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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"}
|