@salt-ds/core 1.73.0 → 1.74.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/css/salt-core.css +269 -28
  3. package/dist-cjs/drawer/Drawer.css.js +1 -1
  4. package/dist-cjs/drawer/Drawer.js +54 -6
  5. package/dist-cjs/drawer/Drawer.js.map +1 -1
  6. package/dist-cjs/drawer/DrawerContext.js +2 -0
  7. package/dist-cjs/drawer/DrawerContext.js.map +1 -1
  8. package/dist-cjs/drawer/DrawerFooter.css.js +1 -1
  9. package/dist-cjs/drawer/DrawerHeader.css.js +1 -1
  10. package/dist-cjs/drawer/DrawerHeader.js +6 -3
  11. package/dist-cjs/drawer/DrawerHeader.js.map +1 -1
  12. package/dist-cjs/drawer/internal/DrawerResizeGuide.css.js +6 -0
  13. package/dist-cjs/drawer/internal/DrawerResizeGuide.css.js.map +1 -0
  14. package/dist-cjs/drawer/internal/DrawerResizeGuide.js +44 -0
  15. package/dist-cjs/drawer/internal/DrawerResizeGuide.js.map +1 -0
  16. package/dist-cjs/drawer/internal/DrawerResizeHandle.css.js +6 -0
  17. package/dist-cjs/drawer/internal/DrawerResizeHandle.css.js.map +1 -0
  18. package/dist-cjs/drawer/internal/DrawerResizeHandle.js +43 -0
  19. package/dist-cjs/drawer/internal/DrawerResizeHandle.js.map +1 -0
  20. package/dist-cjs/drawer/internal/useDrawerResize.js +519 -0
  21. package/dist-cjs/drawer/internal/useDrawerResize.js.map +1 -0
  22. package/dist-cjs/link-button/LinkButton.css.js +1 -1
  23. package/dist-cjs/menu/MenuAlignmentContext.js +55 -0
  24. package/dist-cjs/menu/MenuAlignmentContext.js.map +1 -0
  25. package/dist-cjs/menu/MenuBase.js +9 -3
  26. package/dist-cjs/menu/MenuBase.js.map +1 -1
  27. package/dist-cjs/menu/MenuGroup.js +42 -3
  28. package/dist-cjs/menu/MenuGroup.js.map +1 -1
  29. package/dist-cjs/menu/MenuGroupContext.js +27 -0
  30. package/dist-cjs/menu/MenuGroupContext.js.map +1 -0
  31. package/dist-cjs/menu/MenuItem.css.js +1 -1
  32. package/dist-cjs/menu/MenuItem.js +176 -50
  33. package/dist-cjs/menu/MenuItem.js.map +1 -1
  34. package/dist-cjs/menu/MenuPanel.js +12 -3
  35. package/dist-cjs/menu/MenuPanel.js.map +1 -1
  36. package/dist-cjs/menu/MenuPanelContext.js +3 -1
  37. package/dist-cjs/menu/MenuPanelContext.js.map +1 -1
  38. package/dist-cjs/toggle-button/ToggleButton.css.js +1 -1
  39. package/dist-cjs/tree/TreeNodeTrigger.css.js +1 -1
  40. package/dist-cjs/tree/TreeNodeTrigger.js +0 -1
  41. package/dist-cjs/tree/TreeNodeTrigger.js.map +1 -1
  42. package/dist-es/drawer/Drawer.css.js +1 -1
  43. package/dist-es/drawer/Drawer.js +54 -6
  44. package/dist-es/drawer/Drawer.js.map +1 -1
  45. package/dist-es/drawer/DrawerContext.js +2 -0
  46. package/dist-es/drawer/DrawerContext.js.map +1 -1
  47. package/dist-es/drawer/DrawerFooter.css.js +1 -1
  48. package/dist-es/drawer/DrawerHeader.css.js +1 -1
  49. package/dist-es/drawer/DrawerHeader.js +6 -3
  50. package/dist-es/drawer/DrawerHeader.js.map +1 -1
  51. package/dist-es/drawer/internal/DrawerResizeGuide.css.js +4 -0
  52. package/dist-es/drawer/internal/DrawerResizeGuide.css.js.map +1 -0
  53. package/dist-es/drawer/internal/DrawerResizeGuide.js +42 -0
  54. package/dist-es/drawer/internal/DrawerResizeGuide.js.map +1 -0
  55. package/dist-es/drawer/internal/DrawerResizeHandle.css.js +4 -0
  56. package/dist-es/drawer/internal/DrawerResizeHandle.css.js.map +1 -0
  57. package/dist-es/drawer/internal/DrawerResizeHandle.js +41 -0
  58. package/dist-es/drawer/internal/DrawerResizeHandle.js.map +1 -0
  59. package/dist-es/drawer/internal/useDrawerResize.js +517 -0
  60. package/dist-es/drawer/internal/useDrawerResize.js.map +1 -0
  61. package/dist-es/link-button/LinkButton.css.js +1 -1
  62. package/dist-es/menu/MenuAlignmentContext.js +50 -0
  63. package/dist-es/menu/MenuAlignmentContext.js.map +1 -0
  64. package/dist-es/menu/MenuBase.js +9 -3
  65. package/dist-es/menu/MenuBase.js.map +1 -1
  66. package/dist-es/menu/MenuGroup.js +44 -5
  67. package/dist-es/menu/MenuGroup.js.map +1 -1
  68. package/dist-es/menu/MenuGroupContext.js +23 -0
  69. package/dist-es/menu/MenuGroupContext.js.map +1 -0
  70. package/dist-es/menu/MenuItem.css.js +1 -1
  71. package/dist-es/menu/MenuItem.js +177 -51
  72. package/dist-es/menu/MenuItem.js.map +1 -1
  73. package/dist-es/menu/MenuPanel.js +12 -3
  74. package/dist-es/menu/MenuPanel.js.map +1 -1
  75. package/dist-es/menu/MenuPanelContext.js +3 -1
  76. package/dist-es/menu/MenuPanelContext.js.map +1 -1
  77. package/dist-es/toggle-button/ToggleButton.css.js +1 -1
  78. package/dist-es/tree/TreeNodeTrigger.css.js +1 -1
  79. package/dist-es/tree/TreeNodeTrigger.js +0 -1
  80. package/dist-es/tree/TreeNodeTrigger.js.map +1 -1
  81. package/dist-types/drawer/Drawer.d.ts +6 -0
  82. package/dist-types/drawer/DrawerContext.d.ts +3 -0
  83. package/dist-types/drawer/DrawerHeader.d.ts +1 -1
  84. package/dist-types/drawer/internal/DrawerResizeGuide.d.ts +7 -0
  85. package/dist-types/drawer/internal/DrawerResizeHandle.d.ts +8 -0
  86. package/dist-types/drawer/internal/index.d.ts +3 -0
  87. package/dist-types/drawer/internal/useDrawerResize.d.ts +34 -0
  88. package/dist-types/menu/MenuAlignmentContext.d.ts +14 -0
  89. package/dist-types/menu/MenuGroup.d.ts +26 -4
  90. package/dist-types/menu/MenuGroupContext.d.ts +10 -0
  91. package/dist-types/menu/MenuItem.d.ts +4 -0
  92. package/dist-types/menu/MenuPanelContext.d.ts +2 -0
  93. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DrawerResizeGuide.js","sources":["../src/drawer/internal/DrawerResizeGuide.tsx"],"sourcesContent":["import { FloatingPortal } from \"@floating-ui/react\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport { type ComponentPropsWithoutRef, forwardRef } from \"react\";\nimport { SaltProvider, SaltProviderNext, useTheme } from \"../../salt-provider\";\nimport { makePrefixer } from \"../../utils\";\nimport type { DrawerProps } from \"../Drawer\";\nimport drawerResizeGuideCss from \"./DrawerResizeGuide.css\";\n\nconst withBaseName = makePrefixer(\"saltDrawerResizeGuide\");\n\nexport interface DrawerResizeGuideProps\n extends ComponentPropsWithoutRef<\"div\"> {\n position: NonNullable<DrawerProps[\"position\"]>;\n}\n\n/** Covers the viewport while placing the edge by click, so the click doesn't reach the content. */\nexport const DrawerResizeGuide = forwardRef<\n HTMLDivElement,\n DrawerResizeGuideProps\n>(function DrawerResizeGuide(props, ref) {\n const { position, className, ...rest } = props;\n\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-drawer-resize-guide\",\n css: drawerResizeGuideCss,\n window: targetWindow,\n });\n\n const { themeNext } = useTheme();\n const ChosenSaltProvider = themeNext ? SaltProviderNext : SaltProvider;\n\n const vertical = position === \"left\" || position === \"right\";\n\n return (\n <FloatingPortal>\n <ChosenSaltProvider applyClassesTo=\"scope\">\n <div\n ref={ref}\n aria-hidden\n className={clsx(\n withBaseName(),\n withBaseName(vertical ? \"vertical\" : \"horizontal\"),\n className,\n )}\n {...rest}\n />\n </ChosenSaltProvider>\n </FloatingPortal>\n );\n});\n"],"names":["DrawerResizeGuide","drawerResizeGuideCss"],"mappings":";;;;;;;;;;;;;AAUA,MAAM,YAAA,GAAe,aAAa,uBAAuB,CAAA;AAQlD,MAAM,iBAAA,GAAoB,UAAA,CAG/B,SAASA,kBAAAA,CAAkB,OAAO,GAAA,EAAK;AACvC,EAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAW,GAAG,MAAK,GAAI,KAAA;AAEzC,EAAA,MAAM,eAAe,SAAA,EAAU;AAC/B,EAAA,wBAAA,CAAyB;AAAA,IACvB,MAAA,EAAQ,0BAAA;AAAA,IACR,GAAA,EAAKC,QAAA;AAAA,IACL,MAAA,EAAQ;AAAA,GACT,CAAA;AAED,EAAA,MAAM,EAAE,SAAA,EAAU,GAAI,QAAA,EAAS;AAC/B,EAAA,MAAM,kBAAA,GAAqB,YAAY,gBAAA,GAAmB,YAAA;AAE1D,EAAA,MAAM,QAAA,GAAW,QAAA,KAAa,MAAA,IAAU,QAAA,KAAa,OAAA;AAErD,EAAA,uBACE,GAAA,CAAC,cAAA,EAAA,EACC,QAAA,kBAAA,GAAA,CAAC,kBAAA,EAAA,EAAmB,gBAAe,OAAA,EACjC,QAAA,kBAAA,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA;AAAA,MACA,aAAA,EAAW,IAAA;AAAA,MACX,SAAA,EAAW,IAAA;AAAA,QACT,YAAA,EAAa;AAAA,QACb,YAAA,CAAa,QAAA,GAAW,UAAA,GAAa,YAAY,CAAA;AAAA,QACjD;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA,KAER,CAAA,EACF,CAAA;AAEJ,CAAC;;;;"}
@@ -0,0 +1,4 @@
1
+ var css_248z = "/* Styles applied to root element */\n.saltDrawerResizeHandle {\n --drawerResizeHandle-thumbSize: max(var(--salt-size-icon, 12px), 12px);\n --drawerResizeHandle-thumbImage: url(\"data:image/svg+xml,%3Csvg%20width%3D%2212%22%20height%3D%2212%22%20viewBox%3D%220%200%2012%2012%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20%3E%3Cpath%20d%3D%22M5%2011V9H7V11H5Z%22%20%2F%3E%3Cpath%20d%3D%22M5%207L5%205H7L7%207H5Z%22%20%2F%3E%3Cpath%20d%3D%22M5%201V3H7V1L5%201Z%22%20%2F%3E%3C%2Fsvg%3E\");\n --drawerResizeHandle-background: transparent;\n --drawerResizeHandle-background-hover: var(--salt-separable-background-hover);\n --drawerResizeHandle-background-active: var(--salt-separable-background-active);\n --drawerResizeHandle-dot-background: var(--salt-separable-foreground);\n --drawerResizeHandle-dot-background-hover: var(--salt-separable-foreground-hover);\n --drawerResizeHandle-dot-background-active: var(--salt-separable-foreground-active);\n /* The outset is equal on both sides, strip sits centred in the hit target. */\n --drawerResizeHandle-targetSize: calc(var(--drawer-resizeHandleSize) + 2 * var(--drawer-resizeHandleOutset));\n\n position: absolute;\n z-index: 1;\n touch-action: none;\n}\n\n/* Styles applied to the visible strip (::before) and its thumb (::after) */\n.saltDrawerResizeHandle::before,\n.saltDrawerResizeHandle::after {\n content: \"\";\n position: absolute;\n inset: var(--drawerResizeHandle-stripInset);\n}\n\n.saltDrawerResizeHandle::before {\n background: var(--drawerResizeHandle-background);\n}\n\n.saltDrawerResizeHandle::after {\n background: var(--drawerResizeHandle-dot-background);\n mask-image: var(--drawerResizeHandle-thumbImage);\n mask-position: center;\n mask-repeat: no-repeat;\n mask-size: var(--drawerResizeHandle-thumbSize);\n -webkit-mask-image: var(--drawerResizeHandle-thumbImage);\n -webkit-mask-position: center;\n -webkit-mask-repeat: no-repeat;\n -webkit-mask-size: var(--drawerResizeHandle-thumbSize);\n}\n\n.saltDrawerResizeHandle-left,\n.saltDrawerResizeHandle-right {\n --drawerResizeHandle-stripInset: 0 var(--drawer-resizeHandleOutset);\n top: 0;\n bottom: 0;\n width: var(--drawerResizeHandle-targetSize);\n}\n\n.saltDrawerResizeHandle-left {\n right: calc(-1 * var(--drawer-resizeHandleOutset));\n}\n\n.saltDrawerResizeHandle-right {\n left: calc(-1 * var(--drawer-resizeHandleOutset));\n}\n\n.saltDrawerResizeHandle-top,\n.saltDrawerResizeHandle-bottom {\n --drawerResizeHandle-thumbImage: url(\"data:image/svg+xml,%3Csvg%20width%3D%2212%22%20height%3D%2212%22%20viewBox%3D%220%200%2012%2012%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20%3E%3Cpath%20d%3D%22M1%205H3V7H1Z%22%20%2F%3E%3Cpath%20d%3D%22M5%205H7V7H5Z%22%20%2F%3E%3Cpath%20d%3D%22M9%205H11V7H9Z%22%20%2F%3E%3C%2Fsvg%3E\");\n --drawerResizeHandle-stripInset: var(--drawer-resizeHandleOutset) 0;\n left: 0;\n right: 0;\n height: var(--drawerResizeHandle-targetSize);\n}\n\n.saltDrawerResizeHandle-top {\n bottom: calc(-1 * var(--drawer-resizeHandleOutset));\n}\n\n.saltDrawerResizeHandle-bottom {\n top: calc(-1 * var(--drawer-resizeHandleOutset));\n}\n\n.saltDrawerResizeHandle-hovered {\n --drawerResizeHandle-background: var(--drawerResizeHandle-background-hover);\n --drawerResizeHandle-dot-background: var(--drawerResizeHandle-dot-background-hover);\n}\n\n.saltDrawerResizeHandle.saltDrawerResizeHandle-resizing {\n --drawerResizeHandle-background: var(--drawerResizeHandle-background-active);\n --drawerResizeHandle-dot-background: var(--drawerResizeHandle-dot-background-active);\n}\n\n.saltDrawerResizeHandle:focus-visible {\n outline: none;\n}\n\n.saltDrawerResizeHandle:focus-visible::before {\n outline-style: var(--salt-focused-outlineStyle);\n outline-width: var(--salt-focused-outlineWidth);\n outline-color: var(--salt-focused-outlineColor);\n}\n";
2
+
3
+ export { css_248z as default };
4
+ //# sourceMappingURL=DrawerResizeHandle.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DrawerResizeHandle.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -0,0 +1,41 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { useComponentCssInjection } from '@salt-ds/styles';
3
+ import { useWindow } from '@salt-ds/window';
4
+ import { clsx } from 'clsx';
5
+ import { forwardRef } from 'react';
6
+ import { makePrefixer } from '../../utils/makePrefixer.js';
7
+ import '../../utils/useFloatingUI/useFloatingUI.js';
8
+ import '../../utils/useId.js';
9
+ import '../../salt-provider/SaltProvider.js';
10
+ import '../../viewport/ViewportProvider.js';
11
+ import css_248z from './DrawerResizeHandle.css.js';
12
+
13
+ const withBaseName = makePrefixer("saltDrawerResizeHandle");
14
+ const DrawerResizeHandle = forwardRef(function DrawerResizeHandle2(props, ref) {
15
+ const { position, resizing, hovered, className, ...rest } = props;
16
+ const targetWindow = useWindow();
17
+ useComponentCssInjection({
18
+ testId: "salt-drawer-resize-handle",
19
+ css: css_248z,
20
+ window: targetWindow
21
+ });
22
+ return /* @__PURE__ */ jsx(
23
+ "div",
24
+ {
25
+ ref,
26
+ className: clsx(
27
+ withBaseName(),
28
+ withBaseName(position),
29
+ {
30
+ [withBaseName("resizing")]: resizing,
31
+ [withBaseName("hovered")]: hovered
32
+ },
33
+ className
34
+ ),
35
+ ...rest
36
+ }
37
+ );
38
+ });
39
+
40
+ export { DrawerResizeHandle };
41
+ //# sourceMappingURL=DrawerResizeHandle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DrawerResizeHandle.js","sources":["../src/drawer/internal/DrawerResizeHandle.tsx"],"sourcesContent":["import { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport { type ComponentPropsWithoutRef, forwardRef } from \"react\";\nimport { makePrefixer } from \"../../utils\";\nimport type { DrawerProps } from \"../Drawer\";\nimport drawerResizeHandleCss from \"./DrawerResizeHandle.css\";\n\nconst withBaseName = makePrefixer(\"saltDrawerResizeHandle\");\n\nexport interface DrawerResizeHandleProps\n extends ComponentPropsWithoutRef<\"div\"> {\n position: NonNullable<DrawerProps[\"position\"]>;\n resizing?: boolean;\n hovered?: boolean;\n}\n\nexport const DrawerResizeHandle = forwardRef<\n HTMLDivElement,\n DrawerResizeHandleProps\n>(function DrawerResizeHandle(props, ref) {\n const { position, resizing, hovered, className, ...rest } = props;\n\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-drawer-resize-handle\",\n css: drawerResizeHandleCss,\n window: targetWindow,\n });\n\n return (\n <div\n ref={ref}\n className={clsx(\n withBaseName(),\n withBaseName(position),\n {\n [withBaseName(\"resizing\")]: resizing,\n [withBaseName(\"hovered\")]: hovered,\n },\n className,\n )}\n {...rest}\n />\n );\n});\n"],"names":["DrawerResizeHandle","drawerResizeHandleCss"],"mappings":";;;;;;;;;;;;AAQA,MAAM,YAAA,GAAe,aAAa,wBAAwB,CAAA;AASnD,MAAM,kBAAA,GAAqB,UAAA,CAGhC,SAASA,mBAAAA,CAAmB,OAAO,GAAA,EAAK;AACxC,EAAA,MAAM,EAAE,QAAA,EAAU,QAAA,EAAU,SAAS,SAAA,EAAW,GAAG,MAAK,GAAI,KAAA;AAE5D,EAAA,MAAM,eAAe,SAAA,EAAU;AAC/B,EAAA,wBAAA,CAAyB;AAAA,IACvB,MAAA,EAAQ,2BAAA;AAAA,IACR,GAAA,EAAKC,QAAA;AAAA,IACL,MAAA,EAAQ;AAAA,GACT,CAAA;AAED,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA;AAAA,MACA,SAAA,EAAW,IAAA;AAAA,QACT,YAAA,EAAa;AAAA,QACb,aAAa,QAAQ,CAAA;AAAA,QACrB;AAAA,UACE,CAAC,YAAA,CAAa,UAAU,CAAC,GAAG,QAAA;AAAA,UAC5B,CAAC,YAAA,CAAa,SAAS,CAAC,GAAG;AAAA,SAC7B;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ,CAAC;;;;"}
@@ -0,0 +1,517 @@
1
+ import { useWindow } from '@salt-ds/window';
2
+ import { useState, useRef, useCallback, useEffect } from 'react';
3
+ import 'clsx';
4
+ import 'react/jsx-runtime';
5
+ import { useEventCallback } from '../../utils/useEventCallback.js';
6
+ import '../../utils/useFloatingUI/useFloatingUI.js';
7
+ import '../../utils/useId.js';
8
+ import { useIsomorphicLayoutEffect } from '../../utils/useIsomorphicLayoutEffect.js';
9
+ import '../../salt-provider/SaltProvider.js';
10
+ import '../../viewport/ViewportProvider.js';
11
+
12
+ const KEYBOARD_STEP = 8;
13
+ const PROBE_SIZE = 1e6;
14
+ const CLICK_THRESHOLD = 4;
15
+ const isElement = (target) => target !== null && target.nodeType === 1;
16
+ const focusWithoutRing = (element) => element == null ? void 0 : element.focus({
17
+ preventScroll: true,
18
+ focusVisible: false
19
+ });
20
+ const setDocumentCursor = (ownerDocument, cursor) => {
21
+ const view = ownerDocument.defaultView;
22
+ if (!view || !ownerDocument.adoptedStyleSheets) return void 0;
23
+ const sheet = new view.CSSStyleSheet();
24
+ sheet.replaceSync(`*, *:hover { cursor: ${cursor} !important; }`);
25
+ ownerDocument.adoptedStyleSheets = [
26
+ ...ownerDocument.adoptedStyleSheets,
27
+ sheet
28
+ ];
29
+ return () => {
30
+ ownerDocument.adoptedStyleSheets = ownerDocument.adoptedStyleSheets.filter(
31
+ (adopted) => adopted !== sheet
32
+ );
33
+ };
34
+ };
35
+ const isHorizontal = (position) => position === "left" || position === "right";
36
+ const growsWithCoordinate = (position) => position === "left" || position === "top";
37
+ const measure = (element, horizontal) => {
38
+ const { width, height } = element.getBoundingClientRect();
39
+ return horizontal ? width : height;
40
+ };
41
+ const restoreStyle = (style, property, value, priority) => {
42
+ if (value) {
43
+ style.setProperty(property, value, priority);
44
+ } else {
45
+ style.removeProperty(property);
46
+ }
47
+ };
48
+ const probeBounds = (element, horizontal) => {
49
+ const property = horizontal ? "width" : "height";
50
+ const { style } = element;
51
+ const previousValue = style.getPropertyValue(property);
52
+ const previousPriority = style.getPropertyPriority(property);
53
+ const previousTransition = style.getPropertyValue("transition-property");
54
+ const previousTransitionPriority = style.getPropertyPriority(
55
+ "transition-property"
56
+ );
57
+ style.setProperty("transition-property", "none", "important");
58
+ style.setProperty(property, "0px", "important");
59
+ const min = measure(element, horizontal);
60
+ style.setProperty(property, `${PROBE_SIZE}px`, "important");
61
+ const max = measure(element, horizontal);
62
+ restoreStyle(style, property, previousValue, previousPriority);
63
+ measure(element, horizontal);
64
+ restoreStyle(
65
+ style,
66
+ "transition-property",
67
+ previousTransition,
68
+ previousTransitionPriority
69
+ );
70
+ return { min, max: Math.max(min, max) };
71
+ };
72
+ const clamp = (value, { min, max }) => Math.min(Math.max(value, min), max);
73
+ const sizeFromPoint = (rect, position, { clientX: x, clientY: y }) => {
74
+ switch (position) {
75
+ case "left":
76
+ return x - rect.left;
77
+ case "right":
78
+ return rect.right - x;
79
+ case "top":
80
+ return y - rect.top;
81
+ case "bottom":
82
+ return rect.bottom - y;
83
+ }
84
+ };
85
+ const edgeFromSize = (rect, position, size) => {
86
+ switch (position) {
87
+ case "left":
88
+ return rect.left + size;
89
+ case "right":
90
+ return rect.right - size;
91
+ case "top":
92
+ return rect.top + size;
93
+ case "bottom":
94
+ return rect.bottom - size;
95
+ }
96
+ };
97
+ function useDrawerResize({
98
+ enabled,
99
+ position,
100
+ element
101
+ }) {
102
+ const horizontal = isHorizontal(position);
103
+ const targetWindow = useWindow();
104
+ const [sizeState, setSizeState] = useState(void 0);
105
+ const [sizeAxisHorizontal, setSizeAxisHorizontal] = useState(horizontal);
106
+ const size = enabled && sizeAxisHorizontal === horizontal ? sizeState : void 0;
107
+ const [interaction, setInteraction] = useState("inactive");
108
+ const [metrics, setMetrics] = useState(
109
+ null
110
+ );
111
+ const dragRef = useRef(null);
112
+ const placingRef = useRef(null);
113
+ const handleRef = useRef(null);
114
+ const guideRef = useRef(null);
115
+ const cancelResizeEventRef = useRef(null);
116
+ const restoreSizeRef = useRef(null);
117
+ const initialSizeRef = useRef(null);
118
+ const axisRef = useRef(horizontal);
119
+ const boundsRef = useRef(null);
120
+ const readMetrics = useEventCallback((reuseBounds = false) => {
121
+ if (!element) return null;
122
+ const bounds = reuseBounds && boundsRef.current ? boundsRef.current : probeBounds(element, horizontal);
123
+ boundsRef.current = bounds;
124
+ const current = clamp(measure(element, horizontal), bounds);
125
+ const next = { ...bounds, current };
126
+ setMetrics(next);
127
+ return next;
128
+ });
129
+ const applySize = (nextSize) => {
130
+ setSizeState(nextSize);
131
+ setSizeAxisHorizontal(horizontal);
132
+ };
133
+ const isOverHandle = ({
134
+ clientX: x,
135
+ clientY: y
136
+ }) => {
137
+ var _a;
138
+ const rect = (_a = handleRef.current) == null ? void 0 : _a.getBoundingClientRect();
139
+ return rect !== void 0 && x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom;
140
+ };
141
+ const isHandle = useEventCallback(
142
+ (target) => {
143
+ var _a;
144
+ return enabled && isElement(target) && ((_a = handleRef.current) == null ? void 0 : _a.contains(target)) === true;
145
+ }
146
+ );
147
+ const startDrag = useEventCallback((event) => {
148
+ const current = readMetrics();
149
+ if (!current) return;
150
+ event.preventDefault();
151
+ dragRef.current = {
152
+ pointerId: event.pointerId,
153
+ startX: event.clientX,
154
+ startY: event.clientY,
155
+ originSize: current.current,
156
+ previousSize: current.current,
157
+ cancelSize: size,
158
+ min: current.min,
159
+ max: current.max,
160
+ moved: false
161
+ };
162
+ focusWithoutRing(handleRef.current);
163
+ setInteraction("active");
164
+ });
165
+ const moveDrag = useEventCallback((event, drag) => {
166
+ var _a;
167
+ if (!drag.moved) {
168
+ if (Math.hypot(event.clientX - drag.startX, event.clientY - drag.startY) < CLICK_THRESHOLD) {
169
+ return;
170
+ }
171
+ drag.moved = true;
172
+ try {
173
+ (_a = handleRef.current) == null ? void 0 : _a.setPointerCapture(event.pointerId);
174
+ } catch {
175
+ }
176
+ }
177
+ const coordinate = horizontal ? event.clientX : event.clientY;
178
+ const origin = horizontal ? drag.startX : drag.startY;
179
+ const direction = growsWithCoordinate(position) ? 1 : -1;
180
+ const nextSize = clamp(
181
+ drag.originSize + (coordinate - origin) * direction,
182
+ drag
183
+ );
184
+ if (nextSize !== drag.previousSize) {
185
+ drag.previousSize = nextSize;
186
+ applySize(nextSize);
187
+ }
188
+ });
189
+ const moveGuide = (offset) => {
190
+ var _a;
191
+ const placing = placingRef.current;
192
+ if (!placing) return;
193
+ placing.guideOffset = offset;
194
+ (_a = guideRef.current) == null ? void 0 : _a.style.setProperty(
195
+ "--drawerResizeGuide-offset",
196
+ `${offset}px`
197
+ );
198
+ };
199
+ const setGuide = useCallback((node) => {
200
+ guideRef.current = node;
201
+ const placing = placingRef.current;
202
+ if (node && placing) {
203
+ node.style.setProperty(
204
+ "--drawerResizeGuide-offset",
205
+ `${placing.guideOffset}px`
206
+ );
207
+ }
208
+ }, []);
209
+ const startPlacing = useEventCallback((drag) => {
210
+ if (!element) return;
211
+ placingRef.current = {
212
+ min: drag.min,
213
+ max: drag.max,
214
+ guideOffset: edgeFromSize(
215
+ element.getBoundingClientRect(),
216
+ position,
217
+ drag.originSize
218
+ ),
219
+ pressed: false
220
+ };
221
+ setInteraction("placing");
222
+ });
223
+ const stopPlacing = useEventCallback(() => {
224
+ if (!placingRef.current) return;
225
+ placingRef.current = null;
226
+ setInteraction("inactive");
227
+ });
228
+ const endDrag = useEventCallback((event) => {
229
+ var _a;
230
+ const drag = dragRef.current;
231
+ if (!drag) return;
232
+ dragRef.current = null;
233
+ const pointer = event;
234
+ const stillHovered = "pointerType" in event && pointer.pointerType !== "touch" && isHandle(
235
+ ((_a = handleRef.current) == null ? void 0 : _a.ownerDocument.elementFromPoint(
236
+ pointer.clientX,
237
+ pointer.clientY
238
+ )) ?? null
239
+ );
240
+ setInteraction(stillHovered ? "hover" : "inactive");
241
+ });
242
+ const cancelDrag = useEventCallback((event) => {
243
+ const drag = dragRef.current;
244
+ if (!drag) return;
245
+ const handle = handleRef.current;
246
+ if (handle == null ? void 0 : handle.hasPointerCapture(drag.pointerId)) {
247
+ handle.releasePointerCapture(drag.pointerId);
248
+ }
249
+ setSizeState(drag.cancelSize);
250
+ endDrag(event);
251
+ });
252
+ const sizeToPlace = (target, rect, point, bounds) => clamp(
253
+ isOverHandle(point) ? measure(target, horizontal) : sizeFromPoint(rect, position, point),
254
+ bounds
255
+ );
256
+ const moveGuideToPointer = (event) => {
257
+ const placing = placingRef.current;
258
+ if (!placing || !element) return;
259
+ const rect = element.getBoundingClientRect();
260
+ moveGuide(
261
+ edgeFromSize(rect, position, sizeToPlace(element, rect, event, placing))
262
+ );
263
+ };
264
+ const onGuidePointerDown = useEventCallback(
265
+ (event) => {
266
+ const placing = placingRef.current;
267
+ if (!placing) return;
268
+ if (event.pointerType === "mouse" && event.button > 0) {
269
+ stopPlacing();
270
+ return;
271
+ }
272
+ event.preventDefault();
273
+ event.stopPropagation();
274
+ placing.pressed = true;
275
+ moveGuideToPointer(event);
276
+ }
277
+ );
278
+ const onGuidePointerMove = useEventCallback(
279
+ (event) => {
280
+ moveGuideToPointer(event);
281
+ }
282
+ );
283
+ const onGuideClick = useEventCallback(
284
+ (event) => {
285
+ const placing = placingRef.current;
286
+ if (!(placing == null ? void 0 : placing.pressed) || !element) return;
287
+ event.stopPropagation();
288
+ stopPlacing();
289
+ const rect = element.getBoundingClientRect();
290
+ const nextSize = sizeToPlace(element, rect, event, placing);
291
+ const current = clamp(measure(element, horizontal), placing);
292
+ if (nextSize !== current) {
293
+ applySize(nextSize);
294
+ }
295
+ focusWithoutRing(handleRef.current);
296
+ }
297
+ );
298
+ useEffect(() => {
299
+ if (!enabled || !element || !targetWindow) return;
300
+ const ownerDocument = targetWindow.document;
301
+ const onPointerDown = (event) => {
302
+ if (event.defaultPrevented || !event.isPrimary) return;
303
+ if (event.pointerType === "mouse" && event.button > 0) return;
304
+ if (placingRef.current || dragRef.current || !isHandle(event.target)) {
305
+ return;
306
+ }
307
+ startDrag(event);
308
+ };
309
+ const onPointerMove = (event) => {
310
+ if (event.defaultPrevented) return;
311
+ if (placingRef.current) return;
312
+ const drag = dragRef.current;
313
+ if (!drag) {
314
+ if (event.pointerType !== "touch") {
315
+ setInteraction(isHandle(event.target) ? "hover" : "inactive");
316
+ }
317
+ return;
318
+ }
319
+ if (event.pointerId !== drag.pointerId) return;
320
+ if (event.buttons === 0) {
321
+ endDrag(event);
322
+ return;
323
+ }
324
+ moveDrag(event, drag);
325
+ };
326
+ const onPointerUp = (event) => {
327
+ if (event.defaultPrevented) return;
328
+ if (event.pointerType === "mouse" && event.button > 0) return;
329
+ const drag = dragRef.current;
330
+ if ((drag == null ? void 0 : drag.pointerId) !== event.pointerId) return;
331
+ event.preventDefault();
332
+ if (!drag.moved) {
333
+ dragRef.current = null;
334
+ startPlacing(drag);
335
+ return;
336
+ }
337
+ endDrag(event);
338
+ };
339
+ const onPointerCancel = (event) => {
340
+ var _a;
341
+ if (((_a = dragRef.current) == null ? void 0 : _a.pointerId) === event.pointerId) endDrag(event);
342
+ };
343
+ const onContextMenu = (event) => {
344
+ if (!event.defaultPrevented) endDrag(event);
345
+ };
346
+ const onKeyDown2 = (event) => {
347
+ if (event.key !== "Escape" || !dragRef.current) return;
348
+ event.preventDefault();
349
+ cancelResizeEventRef.current = event;
350
+ cancelDrag(event);
351
+ };
352
+ const onBlur = (event) => {
353
+ endDrag(event);
354
+ stopPlacing();
355
+ };
356
+ const onPointerOut = (event) => {
357
+ if (!dragRef.current && isElement(event.relatedTarget) && event.relatedTarget.tagName === "IFRAME") {
358
+ setInteraction("inactive");
359
+ }
360
+ };
361
+ ownerDocument.addEventListener("pointerdown", onPointerDown, true);
362
+ ownerDocument.addEventListener("pointermove", onPointerMove);
363
+ ownerDocument.addEventListener("pointerup", onPointerUp, true);
364
+ ownerDocument.addEventListener("pointercancel", onPointerCancel);
365
+ ownerDocument.addEventListener("contextmenu", onContextMenu, true);
366
+ ownerDocument.addEventListener("keydown", onKeyDown2, true);
367
+ ownerDocument.addEventListener("pointerout", onPointerOut);
368
+ targetWindow.addEventListener("blur", onBlur);
369
+ return () => {
370
+ ownerDocument.removeEventListener("pointerdown", onPointerDown, true);
371
+ ownerDocument.removeEventListener("pointermove", onPointerMove);
372
+ ownerDocument.removeEventListener("pointerup", onPointerUp, true);
373
+ ownerDocument.removeEventListener("pointercancel", onPointerCancel);
374
+ ownerDocument.removeEventListener("contextmenu", onContextMenu, true);
375
+ ownerDocument.removeEventListener("keydown", onKeyDown2, true);
376
+ ownerDocument.removeEventListener("pointerout", onPointerOut);
377
+ targetWindow.removeEventListener("blur", onBlur);
378
+ dragRef.current = null;
379
+ placingRef.current = null;
380
+ setInteraction("inactive");
381
+ };
382
+ }, [
383
+ enabled,
384
+ element,
385
+ targetWindow,
386
+ isHandle,
387
+ startDrag,
388
+ moveDrag,
389
+ endDrag,
390
+ cancelDrag,
391
+ startPlacing,
392
+ stopPlacing
393
+ ]);
394
+ const showResizeCursor = interaction !== "inactive";
395
+ useEffect(() => {
396
+ if (!showResizeCursor || !targetWindow) return;
397
+ return setDocumentCursor(
398
+ targetWindow.document,
399
+ horizontal ? "var(--salt-cursor-drag-ew, ew-resize)" : "var(--salt-cursor-drag-ns, ns-resize)"
400
+ );
401
+ }, [showResizeCursor, targetWindow, horizontal]);
402
+ const onKeyDown = useEventCallback(
403
+ (event) => {
404
+ const { key } = event;
405
+ if (placingRef.current) {
406
+ stopPlacing();
407
+ if (key === "Escape") {
408
+ event.preventDefault();
409
+ cancelResizeEventRef.current = event.nativeEvent;
410
+ return;
411
+ }
412
+ }
413
+ const resizeKeys = horizontal ? ["ArrowLeft", "ArrowRight"] : ["ArrowUp", "ArrowDown"];
414
+ if (!resizeKeys.includes(key) && key !== "Home" && key !== "End" && key !== "Enter") {
415
+ return;
416
+ }
417
+ const current = readMetrics(true);
418
+ if (!current) return;
419
+ event.preventDefault();
420
+ const collapsed = current.current <= current.min + 1;
421
+ let nextSize;
422
+ if (key === "Home") {
423
+ if (!collapsed) {
424
+ restoreSizeRef.current = current.current;
425
+ }
426
+ nextSize = current.min;
427
+ } else if (key === "End") {
428
+ nextSize = current.max;
429
+ } else if (key === "Enter") {
430
+ if (collapsed) {
431
+ nextSize = restoreSizeRef.current ?? initialSizeRef.current ?? current.max;
432
+ } else {
433
+ restoreSizeRef.current = current.current;
434
+ nextSize = current.min;
435
+ }
436
+ } else {
437
+ const towardsHigherCoordinate = key === "ArrowRight" || key === "ArrowDown";
438
+ const direction = towardsHigherCoordinate === growsWithCoordinate(position) ? 1 : -1;
439
+ nextSize = current.current + KEYBOARD_STEP * direction;
440
+ }
441
+ nextSize = clamp(nextSize, current);
442
+ if (nextSize === current.current) return;
443
+ applySize(nextSize);
444
+ }
445
+ );
446
+ const isCancelResizeEvent = useCallback(
447
+ (event) => event !== void 0 && event === cancelResizeEventRef.current,
448
+ []
449
+ );
450
+ const onFocus = useCallback(() => {
451
+ if (!dragRef.current) readMetrics();
452
+ }, [readMetrics]);
453
+ const setHandle = useCallback((node) => {
454
+ handleRef.current = node;
455
+ }, []);
456
+ useEffect(() => {
457
+ if (!enabled) {
458
+ setSizeState(void 0);
459
+ setMetrics(null);
460
+ restoreSizeRef.current = null;
461
+ initialSizeRef.current = null;
462
+ }
463
+ }, [enabled]);
464
+ useIsomorphicLayoutEffect(() => {
465
+ if (!enabled || !element) return;
466
+ if (axisRef.current !== horizontal) {
467
+ axisRef.current = horizontal;
468
+ restoreSizeRef.current = null;
469
+ initialSizeRef.current = null;
470
+ }
471
+ const next = readMetrics();
472
+ if (next && initialSizeRef.current === null) {
473
+ initialSizeRef.current = next.current;
474
+ }
475
+ }, [enabled, element, horizontal, readMetrics]);
476
+ useIsomorphicLayoutEffect(() => {
477
+ if (!enabled || !element) return;
478
+ readMetrics(true);
479
+ }, [enabled, element, size, readMetrics]);
480
+ useEffect(() => {
481
+ if (!enabled || !element || !targetWindow) return;
482
+ const onResize = () => {
483
+ stopPlacing();
484
+ readMetrics();
485
+ };
486
+ targetWindow.addEventListener("resize", onResize);
487
+ return () => targetWindow.removeEventListener("resize", onResize);
488
+ }, [enabled, element, targetWindow, readMetrics, stopPlacing]);
489
+ return {
490
+ sizeStyle: size !== void 0 ? { [horizontal ? "width" : "height"]: size } : void 0,
491
+ isResizing: interaction === "active" || interaction === "placing",
492
+ isHovered: interaction === "hover",
493
+ isPlacing: interaction === "placing",
494
+ isCancelResizeEvent,
495
+ separatorProps: {
496
+ role: "separator",
497
+ tabIndex: 0,
498
+ ref: setHandle,
499
+ "aria-orientation": horizontal ? "vertical" : "horizontal",
500
+ "aria-valuenow": metrics ? Math.round(metrics.current) : void 0,
501
+ "aria-valuemin": metrics ? Math.round(metrics.min) : void 0,
502
+ "aria-valuemax": metrics ? Math.round(metrics.max) : void 0,
503
+ onKeyDown,
504
+ onFocus
505
+ },
506
+ guideProps: {
507
+ ref: setGuide,
508
+ onPointerDown: onGuidePointerDown,
509
+ onPointerMove: onGuidePointerMove,
510
+ onClick: onGuideClick,
511
+ onContextMenu: stopPlacing
512
+ }
513
+ };
514
+ }
515
+
516
+ export { useDrawerResize };
517
+ //# sourceMappingURL=useDrawerResize.js.map