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.
Files changed (38) hide show
  1. package/dist/{BasePopover-BVeMpuWR.js → BasePopover-CES18mzR.js} +3 -2
  2. package/dist/BasePopover-CES18mzR.js.map +1 -0
  3. package/dist/{ContextMenu-B94eRUm7.js → ContextMenu-D7lPQcw1.js} +16 -8
  4. package/dist/ContextMenu-D7lPQcw1.js.map +1 -0
  5. package/dist/{Popover-BDNQO09F.js → Popover-CNon8bZo.js} +183 -80
  6. package/dist/Popover-CNon8bZo.js.map +1 -0
  7. package/dist/{Select-Bad465DY.js → Select-CGWL6BOg.js} +217 -21
  8. package/dist/Select-CGWL6BOg.js.map +1 -0
  9. package/dist/base-popover.d.ts +3 -3
  10. package/dist/base-popover.js +4 -4
  11. package/dist/button.d.ts +1 -1
  12. package/dist/context-menu.js +5 -5
  13. package/dist/{index-DEKll7zF.d.ts → index-B6t8KE4A.d.ts} +2 -3
  14. package/dist/{index-modFVzpZ.d.ts → index-CK68mp8m.d.ts} +3 -3
  15. package/dist/{index-ClqTlRGD.d.ts → index-CPoGZ0_L.d.ts} +2 -2
  16. package/dist/{index-CyvNJW2l.d.ts → index-CYnINkUh.d.ts} +2 -2
  17. package/dist/{index-DVE8mV5m.d.ts → index-DUP_xS5q.d.ts} +3 -3
  18. package/dist/index.d.ts +6 -6
  19. package/dist/index.js +6 -6
  20. package/dist/popover.d.ts +2 -2
  21. package/dist/popover.js +3 -3
  22. package/dist/select.d.ts +2 -2
  23. package/dist/select.js +5 -5
  24. package/dist/tab-switch.d.ts +1 -1
  25. package/dist/{types-CRA-1_6O.d.ts → types-Bayf6NdC.d.ts} +5 -2
  26. package/dist/use-dismiss.d.ts +2 -0
  27. package/dist/use-dismiss.js +1 -1
  28. package/dist/use-floating.js +1 -1
  29. package/dist/{useDismiss-CAEk_GV-.js → useDismiss-DwQfMU11.js} +13 -6
  30. package/dist/useDismiss-DwQfMU11.js.map +1 -0
  31. package/dist/{useFloating-DRwB71jG.js → useFloating-DCxblHIR.js} +1 -2
  32. package/dist/{useFloating-DRwB71jG.js.map → useFloating-DCxblHIR.js.map} +1 -1
  33. package/package.json +1 -1
  34. package/dist/BasePopover-BVeMpuWR.js.map +0 -1
  35. package/dist/ContextMenu-B94eRUm7.js.map +0 -1
  36. package/dist/Popover-BDNQO09F.js.map +0 -1
  37. package/dist/Select-Bad465DY.js.map +0 -1
  38. 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-BDNQO09F.js";
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-BVeMpuWR.js.map
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-BVeMpuWR.js";
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(Popover, {
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
- content: () => /* @__PURE__ */ jsx(Menu, {
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-B94eRUm7.js.map
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-CAEk_GV-.js";
3
- import { t as useFloating } from "./useFloating-DRwB71jG.js";
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/styles.ts
9
- function createPopoverStyles({ hideShadow = false }) {
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
- const portalContainer = useMemo(() => {
92
- if (typeof document === "undefined") return null;
93
- return portalEl ?? document.body;
94
- }, [portalEl]);
95
- const { floatingRef, update } = useFloating(resolvedAnchorRef, useMemo(() => {
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
- floatingOptions
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 close = useCallback(() => setOpen(false), [setOpen]);
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
- refs: [resolvedAnchorRef, popoverRef],
129
- onClose: close
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) requestAnimationFrame(update);
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
- onPointerDownCapture: (e) => e.stopPropagation(),
157
- onMouseDownCapture: (e) => e.stopPropagation(),
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-BDNQO09F.js.map
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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"}