@luxfi/ui 7.4.10 → 7.4.12

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 (137) 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/alert.cjs +68 -46
  6. package/dist/alert.js +69 -46
  7. package/dist/avatar.cjs +49 -46
  8. package/dist/avatar.js +52 -48
  9. package/dist/badge.cjs +82 -49
  10. package/dist/badge.js +83 -50
  11. package/dist/checkbox.cjs +42 -75
  12. package/dist/checkbox.js +43 -76
  13. package/dist/chrome.cjs +196 -386
  14. package/dist/chrome.js +198 -386
  15. package/dist/close-button.cjs +3 -7
  16. package/dist/close-button.js +3 -7
  17. package/dist/collapsible.cjs +35 -26
  18. package/dist/collapsible.d.cts +2 -1
  19. package/dist/collapsible.d.ts +2 -1
  20. package/dist/collapsible.js +34 -24
  21. package/dist/dialog.cjs +3 -7
  22. package/dist/dialog.d.cts +1 -1
  23. package/dist/dialog.d.ts +1 -1
  24. package/dist/dialog.js +3 -7
  25. package/dist/drawer.cjs +95 -122
  26. package/dist/drawer.d.cts +43 -10
  27. package/dist/drawer.d.ts +43 -10
  28. package/dist/drawer.js +97 -122
  29. package/dist/empty-state.cjs +13 -13
  30. package/dist/empty-state.js +13 -13
  31. package/dist/expiration-selector.cjs +58 -63
  32. package/dist/expiration-selector.js +58 -63
  33. package/dist/field.cjs +60 -109
  34. package/dist/field.d.cts +0 -1
  35. package/dist/field.d.ts +0 -1
  36. package/dist/field.js +61 -109
  37. package/dist/greeks-display.cjs +48 -39
  38. package/dist/greeks-display.js +48 -39
  39. package/dist/heading.cjs +10 -17
  40. package/dist/heading.d.cts +0 -2
  41. package/dist/heading.d.ts +0 -2
  42. package/dist/heading.js +10 -17
  43. package/dist/icon-button.cjs +82 -82
  44. package/dist/icon-button.d.cts +16 -12
  45. package/dist/icon-button.d.ts +16 -12
  46. package/dist/icon-button.js +82 -82
  47. package/dist/index.cjs +1812 -2105
  48. package/dist/index.d.cts +1 -5
  49. package/dist/index.d.ts +1 -5
  50. package/dist/index.js +1814 -2100
  51. package/dist/input-group.cjs +11 -12
  52. package/dist/input-group.js +11 -12
  53. package/dist/input.cjs +27 -27
  54. package/dist/input.d.cts +21 -1
  55. package/dist/input.d.ts +21 -1
  56. package/dist/input.js +25 -28
  57. package/dist/menu.cjs +160 -271
  58. package/dist/menu.d.cts +41 -57
  59. package/dist/menu.d.ts +41 -57
  60. package/dist/menu.js +161 -251
  61. package/dist/option-chain.cjs +89 -67
  62. package/dist/option-chain.js +89 -67
  63. package/dist/option-position.cjs +88 -85
  64. package/dist/option-position.js +88 -85
  65. package/dist/pnl-diagram.cjs +20 -20
  66. package/dist/pnl-diagram.js +20 -20
  67. package/dist/popover.cjs +4 -8
  68. package/dist/popover.js +4 -8
  69. package/dist/progress.cjs +15 -22
  70. package/dist/progress.d.cts +6 -6
  71. package/dist/progress.d.ts +6 -6
  72. package/dist/progress.js +15 -22
  73. package/dist/radio.cjs +35 -67
  74. package/dist/radio.d.cts +18 -18
  75. package/dist/radio.d.ts +18 -18
  76. package/dist/radio.js +36 -68
  77. package/dist/select.cjs +40 -39
  78. package/dist/select.d.cts +35 -4
  79. package/dist/select.d.ts +35 -4
  80. package/dist/select.js +40 -38
  81. package/dist/separator.cjs +8 -33
  82. package/dist/separator.js +8 -33
  83. package/dist/slider.cjs +33 -49
  84. package/dist/slider.js +34 -50
  85. package/dist/switch.cjs +48 -55
  86. package/dist/switch.js +49 -56
  87. package/dist/tabs.cjs +108 -197
  88. package/dist/tabs.d.cts +16 -60
  89. package/dist/tabs.d.ts +16 -60
  90. package/dist/tabs.js +109 -196
  91. package/dist/tag.cjs +112 -69
  92. package/dist/tag.js +113 -69
  93. package/dist/textarea.cjs +56 -27
  94. package/dist/textarea.js +57 -28
  95. package/dist/toaster.cjs +97 -79
  96. package/dist/toaster.d.cts +7 -8
  97. package/dist/toaster.d.ts +7 -8
  98. package/dist/toaster.js +78 -80
  99. package/dist/tooltip.cjs +28 -17
  100. package/dist/tooltip.js +30 -18
  101. package/package.json +2 -16
  102. package/src/accordion.tsx +173 -227
  103. package/src/alert.tsx +78 -45
  104. package/src/avatar.tsx +54 -37
  105. package/src/badge.tsx +65 -44
  106. package/src/checkbox.tsx +70 -89
  107. package/src/close-button.tsx +3 -8
  108. package/src/collapsible.tsx +55 -52
  109. package/src/drawer.tsx +123 -115
  110. package/src/empty-state.tsx +21 -17
  111. package/src/expiration-selector.tsx +84 -66
  112. package/src/field.tsx +68 -124
  113. package/src/greeks-display.tsx +59 -51
  114. package/src/heading.tsx +22 -26
  115. package/src/icon-button.tsx +134 -141
  116. package/src/ink.tsx +37 -0
  117. package/src/input-group.tsx +59 -36
  118. package/src/input.tsx +41 -32
  119. package/src/menu.tsx +224 -397
  120. package/src/option-chain.tsx +154 -104
  121. package/src/option-position.tsx +136 -114
  122. package/src/pin-input.tsx +37 -29
  123. package/src/pnl-diagram.tsx +36 -28
  124. package/src/popover.tsx +1 -1
  125. package/src/progress.tsx +17 -21
  126. package/src/radio.tsx +56 -75
  127. package/src/select.tsx +80 -59
  128. package/src/separator.tsx +13 -34
  129. package/src/slider.tsx +43 -44
  130. package/src/strategy-builder.tsx +245 -156
  131. package/src/switch.tsx +63 -64
  132. package/src/tabs.tsx +166 -296
  133. package/src/tag.tsx +89 -51
  134. package/src/textarea.tsx +19 -29
  135. package/src/toaster.tsx +118 -86
  136. package/src/tooltip.tsx +21 -13
  137. package/tokens.css +79 -0
package/dist/drawer.js CHANGED
@@ -1,28 +1,10 @@
1
1
  "use client";
2
- import { styled, View, Sheet } from '@hanzo/gui';
3
- import * as RadixDialog from '@radix-ui/react-dialog';
2
+ import { styled, View, Sheet, Dialog, YStack, Text, XStack } from '@hanzo/gui';
4
3
  import * as React3 from 'react';
5
- import { clsx } from 'clsx';
6
- import { twMerge } from 'tailwind-merge';
4
+ import { Children, createElement } from 'react';
7
5
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
8
6
 
9
7
  // src/drawer.tsx
10
- var NARROW_PX = 640;
11
- function useBelow(px) {
12
- const [below, setBelow] = React3.useState(false);
13
- React3.useEffect(() => {
14
- const mql = window.matchMedia(`(max-width: ${px - 1}px)`);
15
- const apply = () => setBelow(mql.matches);
16
- apply();
17
- mql.addEventListener("change", apply);
18
- return () => mql.removeEventListener("change", apply);
19
- }, [px]);
20
- return below;
21
- }
22
- var useIsNarrow = () => useBelow(NARROW_PX);
23
- function cn(...inputs) {
24
- return twMerge(clsx(inputs));
25
- }
26
8
  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";
27
9
  var CloseButtonFrame = styled(View, {
28
10
  name: "LuxCloseButton",
@@ -53,23 +35,19 @@ var CloseButtonFrame = styled(View, {
53
35
  }
54
36
  }
55
37
  });
56
- var CLOSE_BUTTON_CLASSES = [
57
- "text-[var(--closeButton-fg,currentColor)]",
58
- "hover:text-[var(--hover-color,currentColor)]",
59
- "disabled:opacity-40"
60
- ].join(" ");
61
38
  var CloseButton = React3.forwardRef(function CloseButton2(props, ref) {
62
39
  const { variant: _variant, size: _size, className, children, ...rest } = props;
63
40
  return /* @__PURE__ */ jsx(
64
41
  CloseButtonFrame,
65
42
  {
66
43
  ref,
67
- className: [CLOSE_BUTTON_CLASSES, className].filter(Boolean).join(" "),
44
+ className,
68
45
  ...rest,
69
46
  children: children ?? /* @__PURE__ */ jsx(
70
47
  "svg",
71
48
  {
72
- className: "size-5",
49
+ width: 20,
50
+ height: 20,
73
51
  viewBox: "0 0 20 20",
74
52
  fill: "none",
75
53
  "aria-hidden": "true",
@@ -85,13 +63,35 @@ var CloseButton = React3.forwardRef(function CloseButton2(props, ref) {
85
63
  }
86
64
  );
87
65
  });
66
+ var ink = (children, Wrap = Text, props = {}) => {
67
+ let hasText = false;
68
+ Children.forEach(children, (child) => {
69
+ if (typeof child === "string" || typeof child === "number") hasText = true;
70
+ });
71
+ if (!hasText) return children;
72
+ return Children.map(children, (child) => typeof child === "string" || typeof child === "number" ? createElement(Wrap, props, child) : child);
73
+ };
74
+ var NARROW_PX = 640;
75
+ function useBelow(px) {
76
+ const [below, setBelow] = React3.useState(false);
77
+ React3.useEffect(() => {
78
+ const mql = window.matchMedia(`(max-width: ${px - 1}px)`);
79
+ const apply = () => setBelow(mql.matches);
80
+ apply();
81
+ mql.addEventListener("change", apply);
82
+ return () => mql.removeEventListener("change", apply);
83
+ }, [px]);
84
+ return below;
85
+ }
86
+ var useIsNarrow = () => useBelow(NARROW_PX);
88
87
  var DrawerPlacementContext = React3.createContext("right");
89
88
  var DrawerSizeContext = React3.createContext("md");
90
89
  var DrawerStateContext = React3.createContext({
91
90
  open: false,
92
91
  setOpen: () => {
93
92
  },
94
- modal: true
93
+ modal: true,
94
+ narrow: false
95
95
  });
96
96
  var DrawerRoot = (props) => {
97
97
  const {
@@ -106,60 +106,40 @@ var DrawerRoot = (props) => {
106
106
  const [uncontrolled, setUncontrolled] = React3.useState(defaultOpen ?? false);
107
107
  const isControlled = open !== void 0;
108
108
  const isOpen = isControlled ? open : uncontrolled;
109
+ const narrow = useIsNarrow();
109
110
  const setOpen = React3.useCallback((nextOpen) => {
110
111
  if (!isControlled) setUncontrolled(nextOpen);
111
112
  onOpenChange?.({ open: nextOpen });
112
113
  }, [isControlled, onOpenChange]);
113
114
  const state = React3.useMemo(
114
- () => ({ open: isOpen, setOpen, modal }),
115
- [isOpen, setOpen, modal]
115
+ () => ({ open: isOpen, setOpen, modal, narrow }),
116
+ [isOpen, setOpen, modal, narrow]
116
117
  );
117
- return /* @__PURE__ */ jsx(DrawerPlacementContext.Provider, { value: placement, children: /* @__PURE__ */ jsx(DrawerSizeContext.Provider, { value: size, children: /* @__PURE__ */ jsx(DrawerStateContext.Provider, { value: state, children: /* @__PURE__ */ jsx(
118
- RadixDialog.Root,
119
- {
120
- open: isOpen,
121
- onOpenChange: setOpen,
122
- modal,
123
- children
124
- }
125
- ) }) }) });
118
+ return /* @__PURE__ */ jsx(DrawerPlacementContext.Provider, { value: placement, children: /* @__PURE__ */ jsx(DrawerSizeContext.Provider, { value: size, children: /* @__PURE__ */ jsx(DrawerStateContext.Provider, { value: state, children: narrow ? children : /* @__PURE__ */ jsx(Dialog, { open: isOpen, onOpenChange: setOpen, modal, children }) }) }) });
126
119
  };
127
- var PLACEMENT_CLASSES = {
128
- right: [
129
- "inset-y-0 right-0",
130
- "data-[state=open]:animate-in data-[state=open]:slide-in-from-right",
131
- "data-[state=closed]:animate-out data-[state=closed]:slide-out-to-right"
132
- ].join(" "),
133
- left: [
134
- "inset-y-0 left-0",
135
- "data-[state=open]:animate-in data-[state=open]:slide-in-from-left",
136
- "data-[state=closed]:animate-out data-[state=closed]:slide-out-to-left"
137
- ].join(" "),
138
- top: [
139
- "inset-x-0 top-0",
140
- "data-[state=open]:animate-in data-[state=open]:slide-in-from-top",
141
- "data-[state=closed]:animate-out data-[state=closed]:slide-out-to-top"
142
- ].join(" "),
143
- bottom: [
144
- "inset-x-0 bottom-0",
145
- "data-[state=open]:animate-in data-[state=open]:slide-in-from-bottom",
146
- "data-[state=closed]:animate-out data-[state=closed]:slide-out-to-bottom"
147
- ].join(" ")
120
+ var ANCHOR = {
121
+ right: { top: 0, bottom: 0, right: 0, enterStyle: { x: 24, opacity: 0 }, exitStyle: { x: 24, opacity: 0 } },
122
+ left: { top: 0, bottom: 0, left: 0, enterStyle: { x: -24, opacity: 0 }, exitStyle: { x: -24, opacity: 0 } },
123
+ top: { left: 0, right: 0, top: 0, enterStyle: { y: -24, opacity: 0 }, exitStyle: { y: -24, opacity: 0 } },
124
+ bottom: { left: 0, right: 0, bottom: 0, enterStyle: { y: 24, opacity: 0 }, exitStyle: { y: 24, opacity: 0 } }
148
125
  };
149
- var SIZE_CLASSES = {
150
- right: { xs: "w-60", sm: "w-80", md: "w-96", lg: "w-[480px]", xl: "w-[640px]", full: "w-screen" },
151
- left: { xs: "w-60", sm: "w-80", md: "w-96", lg: "w-[480px]", xl: "w-[640px]", full: "w-screen" },
152
- top: { xs: "h-40", sm: "h-60", md: "h-80", lg: "h-96", xl: "h-[480px]", full: "h-screen" },
153
- bottom: { xs: "h-40", sm: "h-60", md: "h-80", lg: "h-96", xl: "h-[480px]", full: "h-screen" }
126
+ var ACROSS = {
127
+ xs: 240,
128
+ sm: 320,
129
+ md: 384,
130
+ lg: 480,
131
+ xl: 640,
132
+ full: "100%"
154
133
  };
134
+ var extent = (placement, size) => placement === "left" || placement === "right" ? { width: ACROSS[size], maxWidth: "100%" } : { height: ACROSS[size], maxHeight: "100%" };
135
+ var SCRIM = "rgba(0,0,0,0.5)";
155
136
  var DrawerContent = React3.forwardRef(
156
137
  function DrawerContent2(props, ref) {
157
- const { children, portalled = true, portalRef, offset: _offset, backdrop = true, className, ...rest } = props;
138
+ const { children, portalled = true, portalRef: _portalRef, offset: _offset, backdrop = true, ...rest } = props;
158
139
  const placement = React3.useContext(DrawerPlacementContext);
159
140
  const size = React3.useContext(DrawerSizeContext);
160
- const { open, setOpen, modal } = React3.useContext(DrawerStateContext);
161
- const isNarrow = useIsNarrow();
162
- if (isNarrow) {
141
+ const { open, setOpen, modal, narrow } = React3.useContext(DrawerStateContext);
142
+ if (narrow) {
163
143
  return /* @__PURE__ */ jsxs(
164
144
  Sheet,
165
145
  {
@@ -177,7 +157,7 @@ var DrawerContent = React3.forwardRef(
177
157
  transition: "lazy",
178
158
  enterStyle: { opacity: 0 },
179
159
  exitStyle: { opacity: 0 },
180
- className: "bg-black/50"
160
+ backgroundColor: SCRIM
181
161
  }
182
162
  ),
183
163
  /* @__PURE__ */ jsx(Sheet.Handle, {}),
@@ -185,10 +165,11 @@ var DrawerContent = React3.forwardRef(
185
165
  Sheet.Frame,
186
166
  {
187
167
  unstyled: true,
188
- className: cn(
189
- "flex flex-col rounded-t-2xl bg-[var(--color-drawer-bg)] shadow-[var(--shadow-drawer)]",
190
- className
191
- ),
168
+ flexDirection: "column",
169
+ borderTopLeftRadius: 16,
170
+ borderTopRightRadius: 16,
171
+ backgroundColor: "var(--color-drawer-bg)",
172
+ shadowColor: "var(--shadow-drawer)",
192
173
  ...rest,
193
174
  children
194
175
  }
@@ -199,67 +180,61 @@ var DrawerContent = React3.forwardRef(
199
180
  }
200
181
  const content = /* @__PURE__ */ jsxs(Fragment, { children: [
201
182
  backdrop && /* @__PURE__ */ jsx(
202
- RadixDialog.Overlay,
183
+ Dialog.Overlay,
203
184
  {
204
- className: cn(
205
- "fixed inset-0 z-50 bg-black/50",
206
- "data-[state=open]:animate-in data-[state=open]:fade-in-0",
207
- "data-[state=closed]:animate-out data-[state=closed]:fade-out-0"
208
- )
209
- }
185
+ position: "fixed",
186
+ top: 0,
187
+ right: 0,
188
+ bottom: 0,
189
+ left: 0,
190
+ zIndex: 50,
191
+ backgroundColor: SCRIM,
192
+ transition: "lazy",
193
+ enterStyle: { opacity: 0 },
194
+ exitStyle: { opacity: 0 }
195
+ },
196
+ "overlay"
210
197
  ),
211
198
  /* @__PURE__ */ jsx(
212
- RadixDialog.Content,
199
+ Dialog.Content,
213
200
  {
214
201
  ref,
215
- className: cn(
216
- "fixed z-50 flex flex-col bg-[var(--color-drawer-bg)] shadow-[var(--shadow-drawer)] duration-300",
217
- PLACEMENT_CLASSES[placement] ?? PLACEMENT_CLASSES.right,
218
- SIZE_CLASSES[placement]?.[size] ?? SIZE_CLASSES.right?.md,
219
- className
220
- ),
202
+ unstyled: true,
203
+ position: "fixed",
204
+ zIndex: 50,
205
+ flexDirection: "column",
206
+ backgroundColor: "var(--color-drawer-bg)",
207
+ transition: "medium",
208
+ ...ANCHOR[placement],
209
+ ...extent(placement, size),
221
210
  ...rest,
222
211
  children
223
- }
212
+ },
213
+ "content"
224
214
  )
225
215
  ] });
226
- if (portalled) {
227
- return /* @__PURE__ */ jsx(RadixDialog.Portal, { container: portalRef?.current ?? void 0, children: content });
228
- }
229
- return content;
216
+ return portalled ? /* @__PURE__ */ jsx(Dialog.Portal, { children: content }) : content;
230
217
  }
231
218
  );
232
219
  var DrawerCloseTrigger = React3.forwardRef(function DrawerCloseTrigger2(props, ref) {
233
- return /* @__PURE__ */ jsx(RadixDialog.Close, { asChild: true, children: /* @__PURE__ */ jsx(
234
- CloseButton,
235
- {
236
- ref,
237
- className: cn("absolute top-7 right-5", props.className),
238
- ...props
239
- }
240
- ) });
220
+ return (
221
+ // Placement belongs to the surrounding box, not to the button: CloseButton
222
+ // is a fixed 20px control and has no opinion about where it sits.
223
+ /* @__PURE__ */ jsx(View, { position: "absolute", top: 28, right: 20, zIndex: 1, children: /* @__PURE__ */ jsx(Dialog.Close, { asChild: true, children: /* @__PURE__ */ jsx(CloseButton, { ref, ...props }) }) })
224
+ );
241
225
  });
242
- var DrawerTrigger = (props) => {
243
- const { asChild = true, ...rest } = props;
244
- return /* @__PURE__ */ jsx(RadixDialog.Trigger, { asChild, ...rest });
245
- };
246
- var DrawerHeader = React3.forwardRef(
247
- function DrawerHeader2({ className, ...props }, ref) {
248
- return /* @__PURE__ */ jsx("div", { ref, className: cn("flex flex-col gap-1.5 p-6 pb-0", className), ...props });
226
+ var DrawerTrigger = ({ asChild = true, children, ...rest }) => {
227
+ const { setOpen, narrow } = React3.useContext(DrawerStateContext);
228
+ if (narrow) {
229
+ return React3.isValidElement(children) ? React3.cloneElement(children, { onClick: () => setOpen(true) }) : /* @__PURE__ */ jsx(Fragment, { children });
249
230
  }
250
- );
251
- var DrawerBody = React3.forwardRef(
252
- function DrawerBody2({ className, ...props }, ref) {
253
- return /* @__PURE__ */ jsx("div", { ref, className: cn("flex-1 overflow-auto p-6", className), ...props });
254
- }
255
- );
256
- var DrawerFooter = React3.forwardRef(
257
- function DrawerFooter2({ className, ...props }, ref) {
258
- return /* @__PURE__ */ jsx("div", { ref, className: cn("flex items-center justify-end gap-2 p-6 pt-0", className), ...props });
259
- }
260
- );
261
- var DrawerTitle = RadixDialog.Title;
262
- var DrawerDescription = RadixDialog.Description;
263
- var DrawerActionTrigger = RadixDialog.Close;
231
+ return /* @__PURE__ */ jsx(Dialog.Trigger, { asChild, ...rest, children });
232
+ };
233
+ var DrawerHeader = ({ children, ...props }) => /* @__PURE__ */ jsx(YStack, { gap: 6, padding: 24, paddingBottom: 0, ...props, children: ink(children) });
234
+ var DrawerBody = ({ children, ...props }) => /* @__PURE__ */ jsx(YStack, { flex: 1, overflow: "scroll", padding: 24, ...props, children: ink(children) });
235
+ var DrawerFooter = ({ children, ...props }) => /* @__PURE__ */ jsx(XStack, { alignItems: "center", justifyContent: "flex-end", gap: 8, padding: 24, paddingTop: 0, ...props, children: ink(children) });
236
+ var DrawerTitle = Dialog.Title;
237
+ var DrawerDescription = Dialog.Description;
238
+ var DrawerActionTrigger = Dialog.Close;
264
239
 
265
240
  export { DrawerActionTrigger, DrawerBody, DrawerCloseTrigger, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerRoot, DrawerTitle, DrawerTrigger };
@@ -1,9 +1,8 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
+ var gui = require('@hanzo/gui');
4
5
  var React = require('react');
5
- var clsx = require('clsx');
6
- var tailwindMerge = require('tailwind-merge');
7
6
  var jsxRuntime = require('react/jsx-runtime');
8
7
 
9
8
  function _interopNamespace(e) {
@@ -27,14 +26,12 @@ function _interopNamespace(e) {
27
26
  var React__namespace = /*#__PURE__*/_interopNamespace(React);
28
27
 
29
28
  // src/empty-state.tsx
30
- function cn(...inputs) {
31
- return tailwindMerge.twMerge(clsx.clsx(inputs));
32
- }
33
29
  var apos = "\u2019";
34
30
  function upperFirst(str) {
35
31
  return str.charAt(0).toUpperCase() + str.slice(1);
36
32
  }
37
33
  var ICONS = {};
34
+ var MUTED = "var(--color-text-secondary)";
38
35
  var EmptyState = React__namespace.forwardRef(
39
36
  function EmptyState2(props, ref) {
40
37
  const { title, description, term, type = "query", icon, children, className, ...rest } = props;
@@ -72,17 +69,20 @@ var EmptyState = React__namespace.forwardRef(
72
69
  return icon;
73
70
  })();
74
71
  return /* @__PURE__ */ jsxRuntime.jsx(
75
- "div",
72
+ gui.XStack,
76
73
  {
77
74
  ref,
78
- className: cn("flex items-center justify-center py-10", className),
75
+ alignItems: "center",
76
+ justifyContent: "center",
77
+ paddingVertical: 40,
78
+ className,
79
79
  ...rest,
80
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-5", children: [
81
- iconContent && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center", children: iconContent }),
82
- descriptionContent ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-2 text-center", children: [
83
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-lg font-semibold text-text-secondary", children: titleContent }),
84
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-text-secondary", children: descriptionContent })
85
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-lg font-semibold text-text-secondary", children: titleContent }),
80
+ children: /* @__PURE__ */ jsxRuntime.jsxs(gui.YStack, { alignItems: "center", gap: 20, children: [
81
+ iconContent && /* @__PURE__ */ jsxRuntime.jsx(gui.XStack, { alignItems: "center", justifyContent: "center", children: iconContent }),
82
+ descriptionContent ? /* @__PURE__ */ jsxRuntime.jsxs(gui.YStack, { alignItems: "center", gap: 8, children: [
83
+ /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: 18, fontWeight: "600", textAlign: "center", color: MUTED, children: titleContent }),
84
+ /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: 14, textAlign: "center", color: MUTED, children: descriptionContent })
85
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: 18, fontWeight: "600", textAlign: "center", color: MUTED, children: titleContent }),
86
86
  children
87
87
  ] })
88
88
  }
@@ -1,18 +1,15 @@
1
1
  "use client";
2
+ import { XStack, YStack, Text } from '@hanzo/gui';
2
3
  import * as React from 'react';
3
- import { clsx } from 'clsx';
4
- import { twMerge } from 'tailwind-merge';
5
4
  import { jsx, jsxs } from 'react/jsx-runtime';
6
5
 
7
6
  // src/empty-state.tsx
8
- function cn(...inputs) {
9
- return twMerge(clsx(inputs));
10
- }
11
7
  var apos = "\u2019";
12
8
  function upperFirst(str) {
13
9
  return str.charAt(0).toUpperCase() + str.slice(1);
14
10
  }
15
11
  var ICONS = {};
12
+ var MUTED = "var(--color-text-secondary)";
16
13
  var EmptyState = React.forwardRef(
17
14
  function EmptyState2(props, ref) {
18
15
  const { title, description, term, type = "query", icon, children, className, ...rest } = props;
@@ -50,17 +47,20 @@ var EmptyState = React.forwardRef(
50
47
  return icon;
51
48
  })();
52
49
  return /* @__PURE__ */ jsx(
53
- "div",
50
+ XStack,
54
51
  {
55
52
  ref,
56
- className: cn("flex items-center justify-center py-10", className),
53
+ alignItems: "center",
54
+ justifyContent: "center",
55
+ paddingVertical: 40,
56
+ className,
57
57
  ...rest,
58
- children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-5", children: [
59
- iconContent && /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center", children: iconContent }),
60
- descriptionContent ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2 text-center", children: [
61
- /* @__PURE__ */ jsx("span", { className: "text-lg font-semibold text-text-secondary", children: titleContent }),
62
- /* @__PURE__ */ jsx("span", { className: "text-sm text-text-secondary", children: descriptionContent })
63
- ] }) : /* @__PURE__ */ jsx("span", { className: "text-lg font-semibold text-text-secondary", children: titleContent }),
58
+ children: /* @__PURE__ */ jsxs(YStack, { alignItems: "center", gap: 20, children: [
59
+ iconContent && /* @__PURE__ */ jsx(XStack, { alignItems: "center", justifyContent: "center", children: iconContent }),
60
+ descriptionContent ? /* @__PURE__ */ jsxs(YStack, { alignItems: "center", gap: 8, children: [
61
+ /* @__PURE__ */ jsx(Text, { fontSize: 18, fontWeight: "600", textAlign: "center", color: MUTED, children: titleContent }),
62
+ /* @__PURE__ */ jsx(Text, { fontSize: 14, textAlign: "center", color: MUTED, children: descriptionContent })
63
+ ] }) : /* @__PURE__ */ jsx(Text, { fontSize: 18, fontWeight: "600", textAlign: "center", color: MUTED, children: titleContent }),
64
64
  children
65
65
  ] })
66
66
  }
@@ -1,9 +1,8 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
+ var gui = require('@hanzo/gui');
4
5
  var React = require('react');
5
- var clsx = require('clsx');
6
- var tailwindMerge = require('tailwind-merge');
7
6
  var jsxRuntime = require('react/jsx-runtime');
8
7
 
9
8
  function _interopNamespace(e) {
@@ -26,9 +25,6 @@ function _interopNamespace(e) {
26
25
 
27
26
  var React__namespace = /*#__PURE__*/_interopNamespace(React);
28
27
 
29
- function cn(...inputs) {
30
- return tailwindMerge.twMerge(clsx.clsx(inputs));
31
- }
32
28
  function formatExpDate(date) {
33
29
  const d = new Date(date);
34
30
  return d.toLocaleDateString("en-US", { month: "short", day: "numeric" });
@@ -39,28 +35,53 @@ var GROUP_LABELS = {
39
35
  monthly: "Monthly",
40
36
  quarterly: "Quarterly"
41
37
  };
38
+ var SHAPE = {
39
+ selected: {
40
+ borderColor: "transparent",
41
+ backgroundColor: "var(--color-selected-control-bg)",
42
+ color: "var(--color-selected-control-text)"
43
+ },
44
+ resting: {
45
+ borderColor: "var(--color-border-divider)",
46
+ backgroundColor: "var(--card)",
47
+ color: "var(--color-text-secondary)",
48
+ hoverStyle: { borderColor: "var(--color-hover)", color: "var(--color-hover)" }
49
+ }
50
+ };
42
51
  function ExpirationPill({ exp, isSelected, onClick }) {
52
+ const shape = isSelected ? SHAPE.selected : SHAPE.resting;
53
+ const dteColor = exp.dte <= 7 && !isSelected ? "var(--color-status-warn)" : isSelected ? "var(--color-selected-control-text)" : "var(--muted-foreground)";
43
54
  return /* @__PURE__ */ jsxRuntime.jsxs(
44
- "button",
55
+ gui.YStack,
45
56
  {
46
- type: "button",
57
+ unstyled: true,
58
+ render: /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button" }),
47
59
  onClick,
48
- className: cn(
49
- "flex flex-col items-center gap-0.5 rounded-md px-3 py-1.5 transition-colors shrink-0",
50
- "border text-xs",
51
- isSelected ? "border-blue-500/60 bg-blue-900/30 text-blue-300" : "border-zinc-800 bg-zinc-900/50 text-zinc-400 hover:border-zinc-600 hover:text-zinc-200"
52
- ),
60
+ alignItems: "center",
61
+ gap: 2,
62
+ borderRadius: 6,
63
+ paddingHorizontal: 12,
64
+ paddingVertical: 6,
65
+ flexShrink: 0,
66
+ borderWidth: 1,
67
+ borderStyle: "solid",
68
+ cursor: "pointer",
69
+ ...shape,
53
70
  children: [
54
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium whitespace-nowrap", children: formatExpDate(exp.date) }),
55
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn(
56
- "font-mono tabular-nums text-[10px]",
57
- isSelected ? "text-[var(--foreground)]" : "text-[var(--muted-foreground)]",
58
- // Near expiry is a notice, and a notice in Lux is the loudest neutral.
59
- exp.dte <= 7 && !isSelected && "text-[var(--color-status-warn)]"
60
- ), children: [
61
- exp.dte,
62
- "d"
63
- ] })
71
+ /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { unstyled: true, fontSize: 12, fontWeight: "500", style: { whiteSpace: "nowrap" }, children: formatExpDate(exp.date) }),
72
+ /* @__PURE__ */ jsxRuntime.jsxs(
73
+ gui.Text,
74
+ {
75
+ fontVariant: ["tabular-nums"],
76
+ style: { fontFamily: "monospace" },
77
+ fontSize: 10,
78
+ color: dteColor,
79
+ children: [
80
+ exp.dte,
81
+ "d"
82
+ ]
83
+ }
84
+ )
64
85
  ]
65
86
  }
66
87
  );
@@ -90,49 +111,23 @@ var ExpirationSelector = React__namespace.forwardRef(
90
111
  label: GROUP_LABELS[type],
91
112
  items: expirations.filter((e) => e.type === type)
92
113
  })).filter((g) => g.items.length > 0);
93
- return /* @__PURE__ */ jsxRuntime.jsx(
94
- "div",
95
- {
96
- ref,
97
- className: cn("flex flex-col gap-2", className),
98
- ...rest,
99
- children: grouped.map((group) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
100
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-semibold uppercase tracking-wider text-zinc-600 px-1", children: group.label }),
101
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-1.5 overflow-x-auto no-scrollbar", children: group.items.map((exp) => /* @__PURE__ */ jsxRuntime.jsx("div", { "data-selected": exp.date === selected || void 0, children: /* @__PURE__ */ jsxRuntime.jsx(
102
- ExpirationPill,
103
- {
104
- exp,
105
- isSelected: exp.date === selected,
106
- onClick: () => onSelect(exp.date)
107
- }
108
- ) }, exp.date)) })
109
- ] }, group.type))
110
- }
111
- );
112
- }
113
- return /* @__PURE__ */ jsxRuntime.jsx(
114
- "div",
115
- {
116
- ref,
117
- className: cn("flex items-center gap-1", className),
118
- ...rest,
119
- children: /* @__PURE__ */ jsxRuntime.jsx(
120
- "div",
114
+ return /* @__PURE__ */ jsxRuntime.jsx(gui.YStack, { ref, gap: 8, className, ...rest, children: grouped.map((group) => /* @__PURE__ */ jsxRuntime.jsxs(gui.YStack, { gap: 4, children: [
115
+ /* @__PURE__ */ jsxRuntime.jsx(
116
+ gui.Text,
121
117
  {
122
- ref: scrollRef,
123
- className: "flex gap-1.5 overflow-x-auto no-scrollbar",
124
- children: expirations.map((exp) => /* @__PURE__ */ jsxRuntime.jsx("div", { "data-selected": exp.date === selected || void 0, children: /* @__PURE__ */ jsxRuntime.jsx(
125
- ExpirationPill,
126
- {
127
- exp,
128
- isSelected: exp.date === selected,
129
- onClick: () => onSelect(exp.date)
130
- }
131
- ) }, exp.date))
118
+ fontSize: 10,
119
+ fontWeight: "600",
120
+ textTransform: "uppercase",
121
+ letterSpacing: 0.5,
122
+ paddingHorizontal: 4,
123
+ color: "var(--color-text-secondary)",
124
+ children: group.label
132
125
  }
133
- )
134
- }
135
- );
126
+ ),
127
+ /* @__PURE__ */ jsxRuntime.jsx(gui.XStack, { gap: 6, overflowX: "auto", overflowY: "hidden", className: "lux-no-scrollbar", children: group.items.map((exp) => /* @__PURE__ */ jsxRuntime.jsx("div", { "data-selected": exp.date === selected || void 0, children: /* @__PURE__ */ jsxRuntime.jsx(ExpirationPill, { exp, isSelected: exp.date === selected, onClick: () => onSelect(exp.date) }) }, exp.date)) })
128
+ ] }, group.type)) });
129
+ }
130
+ return /* @__PURE__ */ jsxRuntime.jsx(gui.XStack, { ref, alignItems: "center", gap: 4, className, ...rest, children: /* @__PURE__ */ jsxRuntime.jsx(gui.XStack, { ref: scrollRef, gap: 6, overflowX: "auto", overflowY: "hidden", className: "lux-no-scrollbar", children: expirations.map((exp) => /* @__PURE__ */ jsxRuntime.jsx("div", { "data-selected": exp.date === selected || void 0, children: /* @__PURE__ */ jsxRuntime.jsx(ExpirationPill, { exp, isSelected: exp.date === selected, onClick: () => onSelect(exp.date) }) }, exp.date)) }) });
136
131
  }
137
132
  );
138
133