@luxfi/ui 7.4.10 → 7.4.11

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 (78) hide show
  1. package/dist/accordion.cjs +107 -166
  2. package/dist/accordion.d.cts +18 -51
  3. package/dist/accordion.d.ts +18 -51
  4. package/dist/accordion.js +109 -166
  5. package/dist/chrome.cjs +193 -379
  6. package/dist/chrome.js +195 -379
  7. package/dist/collapsible.cjs +35 -26
  8. package/dist/collapsible.d.cts +2 -1
  9. package/dist/collapsible.d.ts +2 -1
  10. package/dist/collapsible.js +34 -24
  11. package/dist/dialog.d.cts +1 -1
  12. package/dist/dialog.d.ts +1 -1
  13. package/dist/drawer.cjs +92 -115
  14. package/dist/drawer.d.cts +43 -10
  15. package/dist/drawer.d.ts +43 -10
  16. package/dist/drawer.js +94 -115
  17. package/dist/field.cjs +60 -109
  18. package/dist/field.d.cts +0 -1
  19. package/dist/field.d.ts +0 -1
  20. package/dist/field.js +61 -109
  21. package/dist/heading.cjs +10 -17
  22. package/dist/heading.d.cts +0 -2
  23. package/dist/heading.d.ts +0 -2
  24. package/dist/heading.js +10 -17
  25. package/dist/icon-button.cjs +82 -82
  26. package/dist/icon-button.d.cts +16 -12
  27. package/dist/icon-button.d.ts +16 -12
  28. package/dist/icon-button.js +82 -82
  29. package/dist/index.cjs +1073 -1419
  30. package/dist/index.d.cts +1 -5
  31. package/dist/index.d.ts +1 -5
  32. package/dist/index.js +1075 -1414
  33. package/dist/input-group.cjs +11 -12
  34. package/dist/input-group.js +11 -12
  35. package/dist/input.cjs +27 -27
  36. package/dist/input.d.cts +21 -1
  37. package/dist/input.d.ts +21 -1
  38. package/dist/input.js +25 -28
  39. package/dist/menu.cjs +160 -271
  40. package/dist/menu.d.cts +41 -57
  41. package/dist/menu.d.ts +41 -57
  42. package/dist/menu.js +161 -251
  43. package/dist/popover.cjs +1 -1
  44. package/dist/popover.js +1 -1
  45. package/dist/select.cjs +40 -39
  46. package/dist/select.d.cts +35 -4
  47. package/dist/select.d.ts +35 -4
  48. package/dist/select.js +40 -38
  49. package/dist/separator.cjs +8 -33
  50. package/dist/separator.js +8 -33
  51. package/dist/tabs.cjs +108 -197
  52. package/dist/tabs.d.cts +16 -60
  53. package/dist/tabs.d.ts +16 -60
  54. package/dist/tabs.js +109 -196
  55. package/dist/textarea.cjs +56 -27
  56. package/dist/textarea.js +57 -28
  57. package/dist/toaster.cjs +97 -79
  58. package/dist/toaster.d.cts +7 -8
  59. package/dist/toaster.d.ts +7 -8
  60. package/dist/toaster.js +78 -80
  61. package/package.json +2 -16
  62. package/src/accordion.tsx +173 -227
  63. package/src/collapsible.tsx +55 -52
  64. package/src/drawer.tsx +123 -115
  65. package/src/field.tsx +68 -124
  66. package/src/heading.tsx +22 -26
  67. package/src/icon-button.tsx +134 -141
  68. package/src/ink.tsx +37 -0
  69. package/src/input-group.tsx +21 -12
  70. package/src/input.tsx +41 -32
  71. package/src/menu.tsx +224 -397
  72. package/src/popover.tsx +1 -1
  73. package/src/select.tsx +80 -59
  74. package/src/separator.tsx +13 -34
  75. package/src/tabs.tsx +166 -296
  76. package/src/textarea.tsx +19 -29
  77. package/src/toaster.tsx +118 -86
  78. package/tokens.css +61 -0
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var Collapsible = require('@radix-ui/react-collapsible');
4
+ var gui = require('@hanzo/gui');
5
5
  var React3 = require('react');
6
6
  var clsx = require('clsx');
7
7
  var tailwindMerge = require('tailwind-merge');
@@ -25,7 +25,6 @@ function _interopNamespace(e) {
25
25
  return Object.freeze(n);
26
26
  }
27
27
 
28
- var Collapsible__namespace = /*#__PURE__*/_interopNamespace(Collapsible);
29
28
  var React3__namespace = /*#__PURE__*/_interopNamespace(React3);
30
29
 
31
30
  // src/collapsible.tsx
@@ -485,66 +484,76 @@ function useUpdateEffect(effect, deps) {
485
484
  }, deps);
486
485
  }
487
486
  function scrollToElement(id) {
488
- const el = document.getElementById(id);
489
- if (el) {
490
- el.scrollIntoView({ behavior: "smooth", block: "start" });
491
- }
487
+ document.getElementById(id)?.scrollIntoView({ behavior: "smooth", block: "start" });
492
488
  }
493
489
  var CUT_ID = "CollapsibleDetails";
494
490
  var CollapsibleDetails = (props) => {
495
- const { children, id = CUT_ID, onClick, isExpanded: isExpandedProp = false, text: textProp, loading, noScroll, ...rest } = props;
491
+ const {
492
+ children,
493
+ id = CUT_ID,
494
+ onClick,
495
+ isExpanded: isExpandedProp = false,
496
+ text: textProp,
497
+ loading,
498
+ noScroll,
499
+ ...rest
500
+ } = props;
496
501
  const [isExpanded, setIsExpanded] = React3__namespace.default.useState(isExpandedProp);
497
502
  const handleClick = React3__namespace.default.useCallback((event) => {
498
503
  setIsExpanded((flag) => !flag);
499
- if (!noScroll) {
500
- scrollToElement(id);
501
- }
504
+ if (!noScroll) scrollToElement(id);
502
505
  onClick?.(event);
503
506
  }, [id, noScroll, onClick]);
504
507
  useUpdateEffect(() => {
505
508
  setIsExpanded(isExpandedProp);
506
- if (isExpandedProp && !noScroll) {
507
- scrollToElement(id);
508
- }
509
+ if (isExpandedProp && !noScroll) scrollToElement(id);
509
510
  }, [isExpandedProp, id, noScroll]);
510
511
  const text = isExpanded ? textProp?.[1] ?? "Hide details" : textProp?.[0] ?? "View details";
511
- return /* @__PURE__ */ jsxRuntime.jsxs(Collapsible__namespace.Root, { open: isExpanded, children: [
512
- /* @__PURE__ */ jsxRuntime.jsx(Collapsible__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
512
+ return /* @__PURE__ */ jsxRuntime.jsxs(gui.Collapsible, { open: isExpanded, onOpenChange: setIsExpanded, children: [
513
+ /* @__PURE__ */ jsxRuntime.jsx(
513
514
  Link,
514
515
  {
515
516
  className: "text-sm underline decoration-dashed w-fit",
517
+ "aria-expanded": isExpanded,
516
518
  onClick: handleClick,
517
519
  loading,
518
520
  ...rest,
519
521
  children: /* @__PURE__ */ jsxRuntime.jsx("span", { id, children: text })
520
522
  }
521
- ) }),
522
- /* @__PURE__ */ jsxRuntime.jsx(Collapsible__namespace.Content, { children })
523
+ ),
524
+ /* @__PURE__ */ jsxRuntime.jsx(gui.Collapsible.Content, { children })
523
525
  ] });
524
526
  };
527
+ var CUT_LENGTH = 3;
525
528
  var CollapsibleList = (props) => {
526
- const CUT_LENGTH = 3;
527
- const { items, renderItem, triggerProps, cutLength = CUT_LENGTH, text: textProp, defaultExpanded = false, className, ...rest } = props;
529
+ const {
530
+ items,
531
+ renderItem,
532
+ triggerProps,
533
+ cutLength = CUT_LENGTH,
534
+ text: textProp,
535
+ defaultExpanded = false,
536
+ ...rest
537
+ } = props;
528
538
  const [isExpanded, setIsExpanded] = React3__namespace.default.useState(defaultExpanded);
529
539
  React3__namespace.default.useEffect(() => {
530
540
  setIsExpanded(defaultExpanded);
531
541
  }, [defaultExpanded]);
532
- const handleToggle = React3__namespace.default.useCallback(() => {
533
- setIsExpanded((flag) => !flag);
534
- }, []);
542
+ const handleToggle = React3__namespace.default.useCallback(() => setIsExpanded((flag) => !flag), []);
535
543
  const text = isExpanded ? textProp?.[1] ?? "Hide" : textProp?.[0] ?? "Show all";
536
- return /* @__PURE__ */ jsxRuntime.jsx(Collapsible__namespace.Root, { open: isExpanded, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col w-full", className), ...rest, children: [
544
+ return /* @__PURE__ */ jsxRuntime.jsxs(gui.YStack, { width: "100%", ...rest, children: [
537
545
  items.slice(0, isExpanded ? void 0 : cutLength).map(renderItem),
538
- items.length > cutLength && /* @__PURE__ */ jsxRuntime.jsx(Collapsible__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
546
+ items.length > cutLength && /* @__PURE__ */ jsxRuntime.jsx(
539
547
  Link,
540
548
  {
541
549
  className: "text-sm underline decoration-dashed w-fit min-w-0",
550
+ "aria-expanded": isExpanded,
542
551
  onClick: handleToggle,
543
552
  ...triggerProps,
544
553
  children: text
545
554
  }
546
- ) })
547
- ] }) });
555
+ )
556
+ ] });
548
557
  };
549
558
 
550
559
  exports.CollapsibleDetails = CollapsibleDetails;
@@ -1,4 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { YStack } from '@hanzo/gui';
2
3
  import React__default from 'react';
3
4
  import { LinkProps } from './link.cjs';
4
5
 
@@ -10,7 +11,7 @@ interface CollapsibleDetailsProps extends LinkProps {
10
11
  noScroll?: boolean;
11
12
  }
12
13
  declare const CollapsibleDetails: (props: CollapsibleDetailsProps) => react_jsx_runtime.JSX.Element;
13
- interface CollapsibleListProps<T> extends React__default.ComponentPropsWithoutRef<'div'> {
14
+ interface CollapsibleListProps<T> extends Omit<React__default.ComponentProps<typeof YStack>, 'children' | 'text' | 'items'> {
14
15
  items: Array<T>;
15
16
  renderItem: (item: T, index: number) => React__default.ReactNode;
16
17
  triggerProps?: LinkProps;
@@ -1,4 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { YStack } from '@hanzo/gui';
2
3
  import React__default from 'react';
3
4
  import { LinkProps } from './link.js';
4
5
 
@@ -10,7 +11,7 @@ interface CollapsibleDetailsProps extends LinkProps {
10
11
  noScroll?: boolean;
11
12
  }
12
13
  declare const CollapsibleDetails: (props: CollapsibleDetailsProps) => react_jsx_runtime.JSX.Element;
13
- interface CollapsibleListProps<T> extends React__default.ComponentPropsWithoutRef<'div'> {
14
+ interface CollapsibleListProps<T> extends Omit<React__default.ComponentProps<typeof YStack>, 'children' | 'text' | 'items'> {
14
15
  items: Array<T>;
15
16
  renderItem: (item: T, index: number) => React__default.ReactNode;
16
17
  triggerProps?: LinkProps;
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import * as Collapsible from '@radix-ui/react-collapsible';
2
+ import { Collapsible, YStack } from '@hanzo/gui';
3
3
  import * as React3 from 'react';
4
4
  import React3__default from 'react';
5
5
  import { clsx } from 'clsx';
@@ -463,66 +463,76 @@ function useUpdateEffect(effect, deps) {
463
463
  }, deps);
464
464
  }
465
465
  function scrollToElement(id) {
466
- const el = document.getElementById(id);
467
- if (el) {
468
- el.scrollIntoView({ behavior: "smooth", block: "start" });
469
- }
466
+ document.getElementById(id)?.scrollIntoView({ behavior: "smooth", block: "start" });
470
467
  }
471
468
  var CUT_ID = "CollapsibleDetails";
472
469
  var CollapsibleDetails = (props) => {
473
- const { children, id = CUT_ID, onClick, isExpanded: isExpandedProp = false, text: textProp, loading, noScroll, ...rest } = props;
470
+ const {
471
+ children,
472
+ id = CUT_ID,
473
+ onClick,
474
+ isExpanded: isExpandedProp = false,
475
+ text: textProp,
476
+ loading,
477
+ noScroll,
478
+ ...rest
479
+ } = props;
474
480
  const [isExpanded, setIsExpanded] = React3__default.useState(isExpandedProp);
475
481
  const handleClick = React3__default.useCallback((event) => {
476
482
  setIsExpanded((flag) => !flag);
477
- if (!noScroll) {
478
- scrollToElement(id);
479
- }
483
+ if (!noScroll) scrollToElement(id);
480
484
  onClick?.(event);
481
485
  }, [id, noScroll, onClick]);
482
486
  useUpdateEffect(() => {
483
487
  setIsExpanded(isExpandedProp);
484
- if (isExpandedProp && !noScroll) {
485
- scrollToElement(id);
486
- }
488
+ if (isExpandedProp && !noScroll) scrollToElement(id);
487
489
  }, [isExpandedProp, id, noScroll]);
488
490
  const text = isExpanded ? textProp?.[1] ?? "Hide details" : textProp?.[0] ?? "View details";
489
- return /* @__PURE__ */ jsxs(Collapsible.Root, { open: isExpanded, children: [
490
- /* @__PURE__ */ jsx(Collapsible.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(
491
+ return /* @__PURE__ */ jsxs(Collapsible, { open: isExpanded, onOpenChange: setIsExpanded, children: [
492
+ /* @__PURE__ */ jsx(
491
493
  Link,
492
494
  {
493
495
  className: "text-sm underline decoration-dashed w-fit",
496
+ "aria-expanded": isExpanded,
494
497
  onClick: handleClick,
495
498
  loading,
496
499
  ...rest,
497
500
  children: /* @__PURE__ */ jsx("span", { id, children: text })
498
501
  }
499
- ) }),
502
+ ),
500
503
  /* @__PURE__ */ jsx(Collapsible.Content, { children })
501
504
  ] });
502
505
  };
506
+ var CUT_LENGTH = 3;
503
507
  var CollapsibleList = (props) => {
504
- const CUT_LENGTH = 3;
505
- const { items, renderItem, triggerProps, cutLength = CUT_LENGTH, text: textProp, defaultExpanded = false, className, ...rest } = props;
508
+ const {
509
+ items,
510
+ renderItem,
511
+ triggerProps,
512
+ cutLength = CUT_LENGTH,
513
+ text: textProp,
514
+ defaultExpanded = false,
515
+ ...rest
516
+ } = props;
506
517
  const [isExpanded, setIsExpanded] = React3__default.useState(defaultExpanded);
507
518
  React3__default.useEffect(() => {
508
519
  setIsExpanded(defaultExpanded);
509
520
  }, [defaultExpanded]);
510
- const handleToggle = React3__default.useCallback(() => {
511
- setIsExpanded((flag) => !flag);
512
- }, []);
521
+ const handleToggle = React3__default.useCallback(() => setIsExpanded((flag) => !flag), []);
513
522
  const text = isExpanded ? textProp?.[1] ?? "Hide" : textProp?.[0] ?? "Show all";
514
- return /* @__PURE__ */ jsx(Collapsible.Root, { open: isExpanded, children: /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col w-full", className), ...rest, children: [
523
+ return /* @__PURE__ */ jsxs(YStack, { width: "100%", ...rest, children: [
515
524
  items.slice(0, isExpanded ? void 0 : cutLength).map(renderItem),
516
- items.length > cutLength && /* @__PURE__ */ jsx(Collapsible.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(
525
+ items.length > cutLength && /* @__PURE__ */ jsx(
517
526
  Link,
518
527
  {
519
528
  className: "text-sm underline decoration-dashed w-fit min-w-0",
529
+ "aria-expanded": isExpanded,
520
530
  onClick: handleToggle,
521
531
  ...triggerProps,
522
532
  children: text
523
533
  }
524
- ) })
525
- ] }) });
534
+ )
535
+ ] });
526
536
  };
527
537
 
528
538
  export { CollapsibleDetails, CollapsibleList };
package/dist/dialog.d.cts CHANGED
@@ -57,7 +57,7 @@ declare const DialogBackdrop: _hanzogui_web.GuiComponent<Omit<_hanzogui_web.GetF
57
57
  unstyled?: boolean | undefined;
58
58
  elevation?: number | _hanzogui_web.SizeTokens | undefined;
59
59
  fullscreen?: boolean | undefined;
60
- }>, "forceMount" | "scope"> & {
60
+ }>, "scope" | "forceMount"> & {
61
61
  forceMount?: boolean;
62
62
  } & {
63
63
  scope?: _hanzo_gui.DialogScopes;
package/dist/dialog.d.ts CHANGED
@@ -57,7 +57,7 @@ declare const DialogBackdrop: _hanzogui_web.GuiComponent<Omit<_hanzogui_web.GetF
57
57
  unstyled?: boolean | undefined;
58
58
  elevation?: number | _hanzogui_web.SizeTokens | undefined;
59
59
  fullscreen?: boolean | undefined;
60
- }>, "forceMount" | "scope"> & {
60
+ }>, "scope" | "forceMount"> & {
61
61
  forceMount?: boolean;
62
62
  } & {
63
63
  scope?: _hanzo_gui.DialogScopes;
package/dist/drawer.cjs CHANGED
@@ -2,10 +2,7 @@
2
2
  'use strict';
3
3
 
4
4
  var gui = require('@hanzo/gui');
5
- var RadixDialog = require('@radix-ui/react-dialog');
6
5
  var React3 = require('react');
7
- var clsx = require('clsx');
8
- var tailwindMerge = require('tailwind-merge');
9
6
  var jsxRuntime = require('react/jsx-runtime');
10
7
 
11
8
  function _interopNamespace(e) {
@@ -26,26 +23,9 @@ function _interopNamespace(e) {
26
23
  return Object.freeze(n);
27
24
  }
28
25
 
29
- var RadixDialog__namespace = /*#__PURE__*/_interopNamespace(RadixDialog);
30
26
  var React3__namespace = /*#__PURE__*/_interopNamespace(React3);
31
27
 
32
28
  // src/drawer.tsx
33
- var NARROW_PX = 640;
34
- function useBelow(px) {
35
- const [below, setBelow] = React3__namespace.useState(false);
36
- React3__namespace.useEffect(() => {
37
- const mql = window.matchMedia(`(max-width: ${px - 1}px)`);
38
- const apply = () => setBelow(mql.matches);
39
- apply();
40
- mql.addEventListener("change", apply);
41
- return () => mql.removeEventListener("change", apply);
42
- }, [px]);
43
- return below;
44
- }
45
- var useIsNarrow = () => useBelow(NARROW_PX);
46
- function cn(...inputs) {
47
- return tailwindMerge.twMerge(clsx.clsx(inputs));
48
- }
49
29
  var CLOSE_ICON_PATH = "M9.44 8.035a.791.791 0 0 0 1.12 0l3.802-3.803a.791.791 0 0 1 1.119 0l.287.287a.79.79 0 0 1 0 1.119L11.965 9.44a.79.79 0 0 0 0 1.118l3.803 3.803a.791.791 0 0 1 0 1.119l-.287.287a.791.791 0 0 1-1.119 0l-3.803-3.803a.79.79 0 0 0-1.118 0l-3.803 3.803a.79.79 0 0 1-1.119 0l-.287-.287a.791.791 0 0 1 0-1.119l3.803-3.803a.791.791 0 0 0 0-1.118L4.232 5.638a.791.791 0 0 1 0-1.119l.287-.287a.791.791 0 0 1 1.119 0L9.44 8.035Z";
50
30
  var CloseButtonFrame = gui.styled(gui.View, {
51
31
  name: "LuxCloseButton",
@@ -108,13 +88,35 @@ var CloseButton = React3__namespace.forwardRef(function CloseButton2(props, ref)
108
88
  }
109
89
  );
110
90
  });
91
+ var ink = (children, Wrap = gui.Text, props = {}) => {
92
+ let hasText = false;
93
+ React3.Children.forEach(children, (child) => {
94
+ if (typeof child === "string" || typeof child === "number") hasText = true;
95
+ });
96
+ if (!hasText) return children;
97
+ return React3.Children.map(children, (child) => typeof child === "string" || typeof child === "number" ? React3.createElement(Wrap, props, child) : child);
98
+ };
99
+ var NARROW_PX = 640;
100
+ function useBelow(px) {
101
+ const [below, setBelow] = React3__namespace.useState(false);
102
+ React3__namespace.useEffect(() => {
103
+ const mql = window.matchMedia(`(max-width: ${px - 1}px)`);
104
+ const apply = () => setBelow(mql.matches);
105
+ apply();
106
+ mql.addEventListener("change", apply);
107
+ return () => mql.removeEventListener("change", apply);
108
+ }, [px]);
109
+ return below;
110
+ }
111
+ var useIsNarrow = () => useBelow(NARROW_PX);
111
112
  var DrawerPlacementContext = React3__namespace.createContext("right");
112
113
  var DrawerSizeContext = React3__namespace.createContext("md");
113
114
  var DrawerStateContext = React3__namespace.createContext({
114
115
  open: false,
115
116
  setOpen: () => {
116
117
  },
117
- modal: true
118
+ modal: true,
119
+ narrow: false
118
120
  });
119
121
  var DrawerRoot = (props) => {
120
122
  const {
@@ -129,60 +131,40 @@ var DrawerRoot = (props) => {
129
131
  const [uncontrolled, setUncontrolled] = React3__namespace.useState(defaultOpen ?? false);
130
132
  const isControlled = open !== void 0;
131
133
  const isOpen = isControlled ? open : uncontrolled;
134
+ const narrow = useIsNarrow();
132
135
  const setOpen = React3__namespace.useCallback((nextOpen) => {
133
136
  if (!isControlled) setUncontrolled(nextOpen);
134
137
  onOpenChange?.({ open: nextOpen });
135
138
  }, [isControlled, onOpenChange]);
136
139
  const state = React3__namespace.useMemo(
137
- () => ({ open: isOpen, setOpen, modal }),
138
- [isOpen, setOpen, modal]
140
+ () => ({ open: isOpen, setOpen, modal, narrow }),
141
+ [isOpen, setOpen, modal, narrow]
139
142
  );
140
- return /* @__PURE__ */ jsxRuntime.jsx(DrawerPlacementContext.Provider, { value: placement, children: /* @__PURE__ */ jsxRuntime.jsx(DrawerSizeContext.Provider, { value: size, children: /* @__PURE__ */ jsxRuntime.jsx(DrawerStateContext.Provider, { value: state, children: /* @__PURE__ */ jsxRuntime.jsx(
141
- RadixDialog__namespace.Root,
142
- {
143
- open: isOpen,
144
- onOpenChange: setOpen,
145
- modal,
146
- children
147
- }
148
- ) }) }) });
143
+ return /* @__PURE__ */ jsxRuntime.jsx(DrawerPlacementContext.Provider, { value: placement, children: /* @__PURE__ */ jsxRuntime.jsx(DrawerSizeContext.Provider, { value: size, children: /* @__PURE__ */ jsxRuntime.jsx(DrawerStateContext.Provider, { value: state, children: narrow ? children : /* @__PURE__ */ jsxRuntime.jsx(gui.Dialog, { open: isOpen, onOpenChange: setOpen, modal, children }) }) }) });
149
144
  };
150
- var PLACEMENT_CLASSES = {
151
- right: [
152
- "inset-y-0 right-0",
153
- "data-[state=open]:animate-in data-[state=open]:slide-in-from-right",
154
- "data-[state=closed]:animate-out data-[state=closed]:slide-out-to-right"
155
- ].join(" "),
156
- left: [
157
- "inset-y-0 left-0",
158
- "data-[state=open]:animate-in data-[state=open]:slide-in-from-left",
159
- "data-[state=closed]:animate-out data-[state=closed]:slide-out-to-left"
160
- ].join(" "),
161
- top: [
162
- "inset-x-0 top-0",
163
- "data-[state=open]:animate-in data-[state=open]:slide-in-from-top",
164
- "data-[state=closed]:animate-out data-[state=closed]:slide-out-to-top"
165
- ].join(" "),
166
- bottom: [
167
- "inset-x-0 bottom-0",
168
- "data-[state=open]:animate-in data-[state=open]:slide-in-from-bottom",
169
- "data-[state=closed]:animate-out data-[state=closed]:slide-out-to-bottom"
170
- ].join(" ")
145
+ var ANCHOR = {
146
+ right: { top: 0, bottom: 0, right: 0, enterStyle: { x: 24, opacity: 0 }, exitStyle: { x: 24, opacity: 0 } },
147
+ left: { top: 0, bottom: 0, left: 0, enterStyle: { x: -24, opacity: 0 }, exitStyle: { x: -24, opacity: 0 } },
148
+ top: { left: 0, right: 0, top: 0, enterStyle: { y: -24, opacity: 0 }, exitStyle: { y: -24, opacity: 0 } },
149
+ bottom: { left: 0, right: 0, bottom: 0, enterStyle: { y: 24, opacity: 0 }, exitStyle: { y: 24, opacity: 0 } }
171
150
  };
172
- var SIZE_CLASSES = {
173
- right: { xs: "w-60", sm: "w-80", md: "w-96", lg: "w-[480px]", xl: "w-[640px]", full: "w-screen" },
174
- left: { xs: "w-60", sm: "w-80", md: "w-96", lg: "w-[480px]", xl: "w-[640px]", full: "w-screen" },
175
- top: { xs: "h-40", sm: "h-60", md: "h-80", lg: "h-96", xl: "h-[480px]", full: "h-screen" },
176
- bottom: { xs: "h-40", sm: "h-60", md: "h-80", lg: "h-96", xl: "h-[480px]", full: "h-screen" }
151
+ var ACROSS = {
152
+ xs: 240,
153
+ sm: 320,
154
+ md: 384,
155
+ lg: 480,
156
+ xl: 640,
157
+ full: "100%"
177
158
  };
159
+ var extent = (placement, size) => placement === "left" || placement === "right" ? { width: ACROSS[size], maxWidth: "100%" } : { height: ACROSS[size], maxHeight: "100%" };
160
+ var SCRIM = "rgba(0,0,0,0.5)";
178
161
  var DrawerContent = React3__namespace.forwardRef(
179
162
  function DrawerContent2(props, ref) {
180
- const { children, portalled = true, portalRef, offset: _offset, backdrop = true, className, ...rest } = props;
163
+ const { children, portalled = true, portalRef: _portalRef, offset: _offset, backdrop = true, ...rest } = props;
181
164
  const placement = React3__namespace.useContext(DrawerPlacementContext);
182
165
  const size = React3__namespace.useContext(DrawerSizeContext);
183
- const { open, setOpen, modal } = React3__namespace.useContext(DrawerStateContext);
184
- const isNarrow = useIsNarrow();
185
- if (isNarrow) {
166
+ const { open, setOpen, modal, narrow } = React3__namespace.useContext(DrawerStateContext);
167
+ if (narrow) {
186
168
  return /* @__PURE__ */ jsxRuntime.jsxs(
187
169
  gui.Sheet,
188
170
  {
@@ -200,7 +182,7 @@ var DrawerContent = React3__namespace.forwardRef(
200
182
  transition: "lazy",
201
183
  enterStyle: { opacity: 0 },
202
184
  exitStyle: { opacity: 0 },
203
- className: "bg-black/50"
185
+ backgroundColor: SCRIM
204
186
  }
205
187
  ),
206
188
  /* @__PURE__ */ jsxRuntime.jsx(gui.Sheet.Handle, {}),
@@ -208,10 +190,11 @@ var DrawerContent = React3__namespace.forwardRef(
208
190
  gui.Sheet.Frame,
209
191
  {
210
192
  unstyled: true,
211
- className: cn(
212
- "flex flex-col rounded-t-2xl bg-[var(--color-drawer-bg)] shadow-[var(--shadow-drawer)]",
213
- className
214
- ),
193
+ flexDirection: "column",
194
+ borderTopLeftRadius: 16,
195
+ borderTopRightRadius: 16,
196
+ backgroundColor: "var(--color-drawer-bg)",
197
+ shadowColor: "var(--shadow-drawer)",
215
198
  ...rest,
216
199
  children
217
200
  }
@@ -222,68 +205,62 @@ var DrawerContent = React3__namespace.forwardRef(
222
205
  }
223
206
  const content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
224
207
  backdrop && /* @__PURE__ */ jsxRuntime.jsx(
225
- RadixDialog__namespace.Overlay,
208
+ gui.Dialog.Overlay,
226
209
  {
227
- className: cn(
228
- "fixed inset-0 z-50 bg-black/50",
229
- "data-[state=open]:animate-in data-[state=open]:fade-in-0",
230
- "data-[state=closed]:animate-out data-[state=closed]:fade-out-0"
231
- )
232
- }
210
+ position: "fixed",
211
+ top: 0,
212
+ right: 0,
213
+ bottom: 0,
214
+ left: 0,
215
+ zIndex: 50,
216
+ backgroundColor: SCRIM,
217
+ transition: "lazy",
218
+ enterStyle: { opacity: 0 },
219
+ exitStyle: { opacity: 0 }
220
+ },
221
+ "overlay"
233
222
  ),
234
223
  /* @__PURE__ */ jsxRuntime.jsx(
235
- RadixDialog__namespace.Content,
224
+ gui.Dialog.Content,
236
225
  {
237
226
  ref,
238
- className: cn(
239
- "fixed z-50 flex flex-col bg-[var(--color-drawer-bg)] shadow-[var(--shadow-drawer)] duration-300",
240
- PLACEMENT_CLASSES[placement] ?? PLACEMENT_CLASSES.right,
241
- SIZE_CLASSES[placement]?.[size] ?? SIZE_CLASSES.right?.md,
242
- className
243
- ),
227
+ unstyled: true,
228
+ position: "fixed",
229
+ zIndex: 50,
230
+ flexDirection: "column",
231
+ backgroundColor: "var(--color-drawer-bg)",
232
+ transition: "medium",
233
+ ...ANCHOR[placement],
234
+ ...extent(placement, size),
244
235
  ...rest,
245
236
  children
246
- }
237
+ },
238
+ "content"
247
239
  )
248
240
  ] });
249
- if (portalled) {
250
- return /* @__PURE__ */ jsxRuntime.jsx(RadixDialog__namespace.Portal, { container: portalRef?.current ?? void 0, children: content });
251
- }
252
- return content;
241
+ return portalled ? /* @__PURE__ */ jsxRuntime.jsx(gui.Dialog.Portal, { children: content }) : content;
253
242
  }
254
243
  );
255
244
  var DrawerCloseTrigger = React3__namespace.forwardRef(function DrawerCloseTrigger2(props, ref) {
256
- return /* @__PURE__ */ jsxRuntime.jsx(RadixDialog__namespace.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
257
- CloseButton,
258
- {
259
- ref,
260
- className: cn("absolute top-7 right-5", props.className),
261
- ...props
262
- }
263
- ) });
245
+ return (
246
+ // Placement belongs to the surrounding box, not to the button: CloseButton
247
+ // is a fixed 20px control and has no opinion about where it sits.
248
+ /* @__PURE__ */ jsxRuntime.jsx(gui.View, { position: "absolute", top: 28, right: 20, zIndex: 1, children: /* @__PURE__ */ jsxRuntime.jsx(gui.Dialog.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(CloseButton, { ref, ...props }) }) })
249
+ );
264
250
  });
265
- var DrawerTrigger = (props) => {
266
- const { asChild = true, ...rest } = props;
267
- return /* @__PURE__ */ jsxRuntime.jsx(RadixDialog__namespace.Trigger, { asChild, ...rest });
268
- };
269
- var DrawerHeader = React3__namespace.forwardRef(
270
- function DrawerHeader2({ className, ...props }, ref) {
271
- return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("flex flex-col gap-1.5 p-6 pb-0", className), ...props });
251
+ var DrawerTrigger = ({ asChild = true, children, ...rest }) => {
252
+ const { setOpen, narrow } = React3__namespace.useContext(DrawerStateContext);
253
+ if (narrow) {
254
+ return React3__namespace.isValidElement(children) ? React3__namespace.cloneElement(children, { onClick: () => setOpen(true) }) : /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
272
255
  }
273
- );
274
- var DrawerBody = React3__namespace.forwardRef(
275
- function DrawerBody2({ className, ...props }, ref) {
276
- return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("flex-1 overflow-auto p-6", className), ...props });
277
- }
278
- );
279
- var DrawerFooter = React3__namespace.forwardRef(
280
- function DrawerFooter2({ className, ...props }, ref) {
281
- return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("flex items-center justify-end gap-2 p-6 pt-0", className), ...props });
282
- }
283
- );
284
- var DrawerTitle = RadixDialog__namespace.Title;
285
- var DrawerDescription = RadixDialog__namespace.Description;
286
- var DrawerActionTrigger = RadixDialog__namespace.Close;
256
+ return /* @__PURE__ */ jsxRuntime.jsx(gui.Dialog.Trigger, { asChild, ...rest, children });
257
+ };
258
+ var DrawerHeader = ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(gui.YStack, { gap: 6, padding: 24, paddingBottom: 0, ...props, children: ink(children) });
259
+ var DrawerBody = ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(gui.YStack, { flex: 1, overflow: "scroll", padding: 24, ...props, children: ink(children) });
260
+ var DrawerFooter = ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(gui.XStack, { alignItems: "center", justifyContent: "flex-end", gap: 8, padding: 24, paddingTop: 0, ...props, children: ink(children) });
261
+ var DrawerTitle = gui.Dialog.Title;
262
+ var DrawerDescription = gui.Dialog.Description;
263
+ var DrawerActionTrigger = gui.Dialog.Close;
287
264
 
288
265
  exports.DrawerActionTrigger = DrawerActionTrigger;
289
266
  exports.DrawerBody = DrawerBody;
package/dist/drawer.d.cts CHANGED
@@ -1,5 +1,8 @@
1
+ import * as _hanzogui_core from '@hanzogui/core';
2
+ import * as _hanzo_gui from '@hanzo/gui';
3
+ import { Dialog, YStack, XStack } from '@hanzo/gui';
4
+ import * as _hanzogui_web from '@hanzogui/web';
1
5
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import * as RadixDialog from '@radix-ui/react-dialog';
3
6
  import * as React from 'react';
4
7
 
5
8
  interface DrawerRootProps {
@@ -9,13 +12,15 @@ interface DrawerRootProps {
9
12
  onOpenChange?: (details: {
10
13
  open: boolean;
11
14
  }) => void;
12
- placement?: 'left' | 'right' | 'top' | 'bottom';
15
+ placement?: Placement;
13
16
  initialFocusEl?: (() => HTMLElement | null) | React.RefObject<HTMLElement>;
14
17
  lazyMount?: boolean;
15
18
  unmountOnExit?: boolean;
16
19
  modal?: boolean;
17
- size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'full';
20
+ size?: Size;
18
21
  }
22
+ type Placement = 'left' | 'right' | 'top' | 'bottom';
23
+ type Size = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'full';
19
24
  declare const DrawerRoot: (props: DrawerRootProps) => react_jsx_runtime.JSX.Element;
20
25
  interface DrawerContentProps extends React.ComponentPropsWithoutRef<'div'> {
21
26
  portalled?: boolean;
@@ -25,12 +30,40 @@ interface DrawerContentProps extends React.ComponentPropsWithoutRef<'div'> {
25
30
  }
26
31
  declare const DrawerContent: React.ForwardRefExoticComponent<DrawerContentProps & React.RefAttributes<HTMLDivElement>>;
27
32
  declare const DrawerCloseTrigger: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
28
- declare const DrawerTrigger: (props: React.ComponentPropsWithoutRef<typeof RadixDialog.Trigger>) => react_jsx_runtime.JSX.Element;
29
- declare const DrawerHeader: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
30
- declare const DrawerBody: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
31
- declare const DrawerFooter: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
32
- declare const DrawerTitle: React.ForwardRefExoticComponent<RadixDialog.DialogTitleProps & React.RefAttributes<HTMLHeadingElement>>;
33
- declare const DrawerDescription: React.ForwardRefExoticComponent<RadixDialog.DialogDescriptionProps & React.RefAttributes<HTMLParagraphElement>>;
34
- declare const DrawerActionTrigger: React.ForwardRefExoticComponent<RadixDialog.DialogCloseProps & React.RefAttributes<HTMLButtonElement>>;
33
+ declare const DrawerTrigger: ({ asChild, children, ...rest }: React.ComponentProps<typeof Dialog.Trigger>) => react_jsx_runtime.JSX.Element;
34
+ declare const DrawerHeader: ({ children, ...props }: React.ComponentProps<typeof YStack>) => react_jsx_runtime.JSX.Element;
35
+ declare const DrawerBody: ({ children, ...props }: React.ComponentProps<typeof YStack>) => react_jsx_runtime.JSX.Element;
36
+ declare const DrawerFooter: ({ children, ...props }: React.ComponentProps<typeof XStack>) => react_jsx_runtime.JSX.Element;
37
+ declare const DrawerTitle: _hanzogui_web.GuiComponent<Omit<_hanzogui_web.GetFinalProps<_hanzogui_web.TextNonStyleProps, _hanzogui_web.TextStylePropsBase, {
38
+ unstyled?: boolean | undefined;
39
+ size?: _hanzogui_web.FontSizeTokens | undefined;
40
+ }>, "scope"> & {
41
+ scope?: _hanzo_gui.DialogScopes;
42
+ }, _hanzogui_web.GuiTextElement, _hanzogui_web.TextNonStyleProps & {
43
+ scope?: _hanzo_gui.DialogScopes;
44
+ }, _hanzogui_web.TextStylePropsBase, {
45
+ unstyled?: boolean | undefined;
46
+ size?: _hanzogui_web.FontSizeTokens | undefined;
47
+ }, _hanzogui_web.StaticConfigPublic>;
48
+ declare const DrawerDescription: _hanzogui_web.GuiComponent<Omit<_hanzogui_web.GetFinalProps<_hanzogui_web.TextNonStyleProps, _hanzogui_web.TextStylePropsBase, {
49
+ unstyled?: boolean | undefined;
50
+ size?: _hanzogui_web.FontSizeTokens | undefined;
51
+ }>, "scope"> & {
52
+ scope?: _hanzo_gui.DialogScopes;
53
+ }, _hanzogui_web.GuiTextElement, _hanzogui_web.TextNonStyleProps & {
54
+ scope?: _hanzo_gui.DialogScopes;
55
+ }, _hanzogui_web.TextStylePropsBase, {
56
+ unstyled?: boolean | undefined;
57
+ size?: _hanzogui_web.FontSizeTokens | undefined;
58
+ }, _hanzogui_web.StaticConfigPublic>;
59
+ declare const DrawerActionTrigger: _hanzogui_web.GuiComponent<Omit<_hanzogui_web.GetFinalProps<_hanzogui_core.RNViewNonStyleProps, _hanzogui_web.StackStyleBase, {}>, "scope" | "displayWhenAdapted"> & {
60
+ displayWhenAdapted?: boolean;
61
+ } & {
62
+ scope?: _hanzo_gui.DialogScopes;
63
+ }, _hanzogui_web.GuiElement, _hanzogui_core.RNViewNonStyleProps & {
64
+ displayWhenAdapted?: boolean;
65
+ } & {
66
+ scope?: _hanzo_gui.DialogScopes;
67
+ }, _hanzogui_web.StackStyleBase, {}, _hanzogui_web.StaticConfigPublic>;
35
68
 
36
69
  export { DrawerActionTrigger, DrawerBody, DrawerCloseTrigger, DrawerContent, type DrawerContentProps, DrawerDescription, DrawerFooter, DrawerHeader, DrawerRoot, type DrawerRootProps, DrawerTitle, DrawerTrigger };