@luxfi/ui 7.0.0 → 7.1.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 (60) hide show
  1. package/dist/alert.cjs +162 -285
  2. package/dist/alert.js +162 -285
  3. package/dist/badge.cjs +162 -321
  4. package/dist/badge.d.cts +3 -7
  5. package/dist/badge.d.ts +3 -7
  6. package/dist/badge.js +162 -320
  7. package/dist/button.cjs +373 -484
  8. package/dist/button.d.cts +10 -7
  9. package/dist/button.d.ts +10 -7
  10. package/dist/button.js +373 -484
  11. package/dist/close-button.cjs +37 -18
  12. package/dist/close-button.d.cts +1 -1
  13. package/dist/close-button.d.ts +1 -1
  14. package/dist/close-button.js +37 -18
  15. package/dist/collapsible.cjs +125 -272
  16. package/dist/collapsible.js +125 -272
  17. package/dist/dialog.cjs +60 -44
  18. package/dist/dialog.d.cts +7 -8
  19. package/dist/dialog.d.ts +7 -8
  20. package/dist/dialog.js +60 -43
  21. package/dist/drawer.cjs +37 -13
  22. package/dist/drawer.js +37 -13
  23. package/dist/heading.cjs +3 -8
  24. package/dist/heading.js +3 -8
  25. package/dist/icon-button.cjs +213 -337
  26. package/dist/icon-button.d.cts +4 -4
  27. package/dist/icon-button.d.ts +4 -4
  28. package/dist/icon-button.js +213 -338
  29. package/dist/image.cjs +125 -272
  30. package/dist/image.js +125 -272
  31. package/dist/index.cjs +604 -700
  32. package/dist/index.d.cts +0 -3
  33. package/dist/index.d.ts +0 -3
  34. package/dist/index.js +604 -698
  35. package/dist/link.cjs +125 -272
  36. package/dist/link.js +125 -272
  37. package/dist/popover.cjs +55 -40
  38. package/dist/popover.js +55 -39
  39. package/dist/select.cjs +125 -272
  40. package/dist/select.js +125 -272
  41. package/dist/skeleton.cjs +125 -272
  42. package/dist/skeleton.js +125 -272
  43. package/dist/table.cjs +127 -274
  44. package/dist/table.js +127 -274
  45. package/dist/tag.cjs +184 -306
  46. package/dist/tag.js +184 -305
  47. package/dist/tooltip.cjs +22 -21
  48. package/dist/tooltip.d.cts +2 -3
  49. package/dist/tooltip.d.ts +2 -3
  50. package/dist/tooltip.js +22 -20
  51. package/package.json +9 -7
  52. package/src/badge.tsx +20 -31
  53. package/src/button.tsx +304 -238
  54. package/src/close-button.tsx +48 -22
  55. package/src/dialog.tsx +37 -47
  56. package/src/heading.tsx +8 -19
  57. package/src/icon-button.tsx +129 -104
  58. package/src/popover.tsx +30 -44
  59. package/src/skeleton.tsx +96 -144
  60. package/src/tooltip.tsx +54 -47
package/dist/button.cjs CHANGED
@@ -1,8 +1,7 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var reactSlot = require('@radix-ui/react-slot');
5
- var classVarianceAuthority = require('class-variance-authority');
4
+ var core = require('@hanzogui/core');
6
5
  var React2 = require('react');
7
6
  var clsx = require('clsx');
8
7
  var tailwindMerge = require('tailwind-merge');
@@ -32,272 +31,137 @@ var React2__namespace = /*#__PURE__*/_interopNamespace(React2);
32
31
  function cn(...inputs) {
33
32
  return tailwindMerge.twMerge(clsx.clsx(inputs));
34
33
  }
35
- var SPACING_SCALE = 4;
36
- function toStylePx(value) {
37
- if (value === void 0) return void 0;
38
- if (typeof value === "string") return value;
39
- return `${value * SPACING_SCALE}px`;
34
+ var SHIM_PROPS = [
35
+ "w",
36
+ "h",
37
+ "minW",
38
+ "maxW",
39
+ "display",
40
+ "flexGrow",
41
+ "flexShrink",
42
+ "flexBasis",
43
+ "fontWeight",
44
+ "textStyle",
45
+ "borderRadius",
46
+ "alignSelf",
47
+ "alignItems",
48
+ "justifyContent",
49
+ "color",
50
+ "mt",
51
+ "mb",
52
+ "ml",
53
+ "mr",
54
+ "height",
55
+ "overflow",
56
+ "whiteSpace",
57
+ "textOverflow",
58
+ "textTransform",
59
+ "gap",
60
+ "gridTemplateColumns",
61
+ "minWidth",
62
+ "boxSize",
63
+ "py",
64
+ "px",
65
+ "p",
66
+ "hideBelow",
67
+ "fontSize",
68
+ "flexWrap",
69
+ "wordBreak",
70
+ "lineHeight",
71
+ "marginRight",
72
+ "position",
73
+ "background"
74
+ ];
75
+ var S = 4;
76
+ function dim(v) {
77
+ if (v == null) return void 0;
78
+ if (typeof v === "number") return `${v * S}px`;
79
+ if (typeof v === "string") return v;
80
+ if (typeof v === "object") {
81
+ const o = v;
82
+ return o.base ?? o.lg ?? o.xl ?? Object.values(o)[0];
83
+ }
84
+ return void 0;
40
85
  }
41
- function extractSkeletonStyleProps(props) {
42
- const style = {};
43
- const rest = {};
44
- function resolveDimension(value) {
45
- if (value === void 0 || value === null) return void 0;
46
- if (typeof value === "number") return `${value * SPACING_SCALE}px`;
47
- if (typeof value === "string") return value;
48
- if (typeof value === "object") {
49
- const obj = value;
50
- return obj.base ?? obj.lg ?? obj.xl ?? Object.values(obj)[0];
51
- }
52
- return void 0;
86
+ function sp(v) {
87
+ if (v === void 0) return void 0;
88
+ return typeof v === "number" ? `${v * S}px` : v;
89
+ }
90
+ function shimToStyle(props) {
91
+ const s = {};
92
+ if (props.w !== void 0) s.width = dim(props.w);
93
+ if (props.h !== void 0) s.height = dim(props.h);
94
+ if (props.minW !== void 0) s.minWidth = dim(props.minW);
95
+ if (props.maxW !== void 0) s.maxWidth = dim(props.maxW);
96
+ if (props.display !== void 0) s.display = props.display;
97
+ if (props.flexGrow !== void 0) s.flexGrow = props.flexGrow;
98
+ if (props.flexShrink !== void 0) s.flexShrink = props.flexShrink;
99
+ if (props.flexBasis !== void 0) s.flexBasis = props.flexBasis;
100
+ if (props.fontWeight !== void 0) s.fontWeight = props.fontWeight;
101
+ if (props.borderRadius !== void 0) s.borderRadius = props.borderRadius;
102
+ if (props.alignSelf !== void 0) s.alignSelf = props.alignSelf;
103
+ if (props.alignItems !== void 0) s.alignItems = props.alignItems;
104
+ if (props.justifyContent !== void 0) s.justifyContent = props.justifyContent;
105
+ if (props.color !== void 0) s.color = props.color;
106
+ if (props.mt !== void 0) s.marginTop = sp(props.mt);
107
+ if (props.mb !== void 0) s.marginBottom = sp(props.mb);
108
+ if (props.ml !== void 0) s.marginLeft = sp(props.ml);
109
+ if (props.mr !== void 0) s.marginRight = sp(props.mr);
110
+ if (props.height !== void 0) s.height = props.height;
111
+ if (props.overflow !== void 0) s.overflow = props.overflow;
112
+ if (props.whiteSpace !== void 0) s.whiteSpace = props.whiteSpace;
113
+ if (props.textOverflow !== void 0) s.textOverflow = props.textOverflow;
114
+ if (props.textTransform !== void 0) s.textTransform = props.textTransform;
115
+ if (props.gap !== void 0) s.gap = sp(props.gap);
116
+ if (props.gridTemplateColumns !== void 0) s.gridTemplateColumns = props.gridTemplateColumns;
117
+ if (props.minWidth !== void 0) s.minWidth = props.minWidth;
118
+ if (props.boxSize !== void 0) {
119
+ const v = typeof props.boxSize === "number" ? `${props.boxSize * S}px` : props.boxSize;
120
+ s.width = v;
121
+ s.height = v;
53
122
  }
54
- for (const [key, value] of Object.entries(props)) {
55
- if (value === void 0) continue;
56
- switch (key) {
57
- case "w": {
58
- const v = resolveDimension(value);
59
- if (v) style.width = v;
60
- break;
61
- }
62
- case "h": {
63
- const v = resolveDimension(value);
64
- if (v) style.height = v;
65
- break;
66
- }
67
- case "minW": {
68
- const v = resolveDimension(value);
69
- if (v) style.minWidth = v;
70
- break;
71
- }
72
- case "maxW": {
73
- const v = resolveDimension(value);
74
- if (v) style.maxWidth = v;
75
- break;
76
- }
77
- case "height":
78
- style.height = value;
79
- break;
80
- case "display":
81
- style.display = value;
82
- break;
83
- case "flexGrow":
84
- style.flexGrow = value;
85
- break;
86
- case "flexShrink":
87
- style.flexShrink = value;
88
- break;
89
- case "flexBasis":
90
- style.flexBasis = value;
91
- break;
92
- case "fontWeight":
93
- style.fontWeight = value;
94
- break;
95
- case "borderRadius":
96
- style.borderRadius = value;
97
- break;
98
- case "alignSelf":
99
- style.alignSelf = value;
100
- break;
101
- case "alignItems":
102
- style.alignItems = value;
103
- break;
104
- case "justifyContent":
105
- style.justifyContent = value;
106
- break;
107
- case "color":
108
- style.color = value;
109
- break;
110
- case "mt":
111
- style.marginTop = toStylePx(value);
112
- break;
113
- case "mb":
114
- style.marginBottom = toStylePx(value);
115
- break;
116
- case "ml":
117
- style.marginLeft = toStylePx(value);
118
- break;
119
- case "mr":
120
- style.marginRight = toStylePx(value);
121
- break;
122
- case "overflow":
123
- style.overflow = value;
124
- break;
125
- case "whiteSpace":
126
- style.whiteSpace = value;
127
- break;
128
- case "textOverflow":
129
- style.textOverflow = value;
130
- break;
131
- case "textTransform":
132
- style.textTransform = value;
133
- break;
134
- case "gap":
135
- style.gap = typeof value === "number" ? `${value * SPACING_SCALE}px` : value;
136
- break;
137
- case "gridTemplateColumns":
138
- style.gridTemplateColumns = value;
139
- break;
140
- case "minWidth":
141
- style.minWidth = value;
142
- break;
143
- case "boxSize": {
144
- const s = typeof value === "number" ? `${value * SPACING_SCALE}px` : value;
145
- style.width = s;
146
- style.height = s;
147
- break;
148
- }
149
- case "py": {
150
- const v = toStylePx(value);
151
- style.paddingTop = v;
152
- style.paddingBottom = v;
153
- break;
154
- }
155
- case "px": {
156
- const v = toStylePx(value);
157
- style.paddingLeft = v;
158
- style.paddingRight = v;
159
- break;
160
- }
161
- case "p": {
162
- const v = toStylePx(value);
163
- style.padding = v;
164
- break;
165
- }
166
- case "hideBelow":
167
- break;
168
- // handled via className
169
- case "textStyle":
170
- break;
171
- // drop textStyle, not directly applicable
172
- case "fontSize":
173
- style.fontSize = value;
174
- break;
175
- case "flexWrap":
176
- style.flexWrap = value;
177
- break;
178
- case "wordBreak":
179
- style.wordBreak = value;
180
- break;
181
- case "lineHeight":
182
- style.lineHeight = value;
183
- break;
184
- case "marginRight":
185
- style.marginRight = value;
186
- break;
187
- case "position":
188
- style.position = value;
189
- break;
190
- case "background":
191
- style.background = value;
192
- break;
193
- default:
194
- rest[key] = value;
195
- break;
196
- }
123
+ if (props.py !== void 0) {
124
+ const v = sp(props.py);
125
+ s.paddingTop = v;
126
+ s.paddingBottom = v;
197
127
  }
198
- return { style, rest };
128
+ if (props.px !== void 0) {
129
+ const v = sp(props.px);
130
+ s.paddingLeft = v;
131
+ s.paddingRight = v;
132
+ }
133
+ if (props.p !== void 0) s.padding = sp(props.p);
134
+ if (props.fontSize !== void 0) s.fontSize = props.fontSize;
135
+ if (props.flexWrap !== void 0) s.flexWrap = props.flexWrap;
136
+ if (props.wordBreak !== void 0) s.wordBreak = props.wordBreak;
137
+ if (props.lineHeight !== void 0) s.lineHeight = props.lineHeight;
138
+ if (props.marginRight !== void 0) s.marginRight = props.marginRight;
139
+ if (props.position !== void 0) s.position = props.position;
140
+ if (props.background !== void 0) s.background = props.background;
141
+ return s;
142
+ }
143
+ function stripShims(props) {
144
+ const out = { ...props };
145
+ for (const k of SHIM_PROPS) delete out[k];
146
+ return out;
199
147
  }
148
+ var SKELETON_CLASSES = [
149
+ "animate-skeleton-shimmer rounded-sm",
150
+ "bg-[linear-gradient(90deg,var(--color-skeleton-start)_0%,var(--color-skeleton-end)_50%,var(--color-skeleton-start)_100%)]",
151
+ "bg-[length:200%_100%]"
152
+ ].join(" ");
153
+ var HIDE_BELOW_MAP = { lg: "lg:hidden", md: "md:hidden", sm: "sm:hidden" };
200
154
  var Skeleton = React2__namespace.forwardRef(
201
155
  function Skeleton2(props, ref) {
202
- const {
203
- loading = false,
204
- asChild,
205
- className,
206
- children,
207
- style: styleProp,
208
- // Destructure style-prop shims so they don't leak into DOM
209
- w: _w,
210
- h: _h,
211
- minW: _minW,
212
- maxW: _maxW,
213
- display: _display,
214
- flexGrow: _flexGrow,
215
- flexShrink: _flexShrink,
216
- flexBasis: _flexBasis,
217
- fontWeight: _fontWeight,
218
- textStyle: _textStyle,
219
- borderRadius: _borderRadius,
220
- alignSelf: _alignSelf,
221
- alignItems: _alignItems,
222
- justifyContent: _justifyContent,
223
- color: _color,
224
- mt: _mt,
225
- mb: _mb,
226
- ml: _ml,
227
- mr: _mr,
228
- height: _height,
229
- overflow: _overflow,
230
- whiteSpace: _whiteSpace,
231
- textOverflow: _textOverflow,
232
- textTransform: _textTransform,
233
- gap: _gap,
234
- gridTemplateColumns: _gridTemplateColumns,
235
- minWidth: _minWidth,
236
- boxSize: _boxSize,
237
- py: _py,
238
- px: _px,
239
- p: _p,
240
- hideBelow: _hideBelow,
241
- fontSize: _fontSize,
242
- flexWrap: _flexWrap,
243
- wordBreak: _wordBreak,
244
- lineHeight: _lineHeight,
245
- marginRight: _marginRight,
246
- position: _position,
247
- background: _background,
248
- as: Component = "div",
249
- ...htmlRest
250
- } = props;
251
- const { style: shimStyle } = extractSkeletonStyleProps({
252
- w: _w,
253
- h: _h,
254
- minW: _minW,
255
- maxW: _maxW,
256
- display: _display,
257
- flexGrow: _flexGrow,
258
- flexShrink: _flexShrink,
259
- flexBasis: _flexBasis,
260
- fontWeight: _fontWeight,
261
- textStyle: _textStyle,
262
- borderRadius: _borderRadius,
263
- alignSelf: _alignSelf,
264
- alignItems: _alignItems,
265
- justifyContent: _justifyContent,
266
- color: _color,
267
- mt: _mt,
268
- mb: _mb,
269
- ml: _ml,
270
- mr: _mr,
271
- height: _height,
272
- overflow: _overflow,
273
- whiteSpace: _whiteSpace,
274
- textOverflow: _textOverflow,
275
- textTransform: _textTransform,
276
- gap: _gap,
277
- gridTemplateColumns: _gridTemplateColumns,
278
- minWidth: _minWidth,
279
- boxSize: _boxSize,
280
- py: _py,
281
- px: _px,
282
- p: _p,
283
- hideBelow: _hideBelow,
284
- fontSize: _fontSize,
285
- flexWrap: _flexWrap,
286
- wordBreak: _wordBreak,
287
- lineHeight: _lineHeight,
288
- marginRight: _marginRight,
289
- position: _position,
290
- background: _background
291
- });
156
+ const { loading = false, asChild, className, children, style: styleProp, as: Component = "div", ...allRest } = props;
157
+ const shimStyle = shimToStyle(props);
292
158
  const mergedStyle = Object.keys(shimStyle).length > 0 || styleProp ? { ...shimStyle, ...styleProp } : void 0;
293
- const HIDE_BELOW_MAP = { lg: "lg:hidden", md: "md:hidden", sm: "sm:hidden" };
294
- const hideBelowClass = _hideBelow ? HIDE_BELOW_MAP[_hideBelow] : void 0;
295
- const finalClassName = hideBelowClass ? cn(className, hideBelowClass) : className;
159
+ const hideBelowClass = props.hideBelow ? HIDE_BELOW_MAP[props.hideBelow] : void 0;
160
+ const cls = hideBelowClass ? cn(className, hideBelowClass) : className;
161
+ const htmlRest = stripShims(allRest);
296
162
  if (!loading) {
297
- if (asChild && React2__namespace.isValidElement(children)) {
298
- return children;
299
- }
300
- return /* @__PURE__ */ jsxRuntime.jsx(Component, { ref, className: finalClassName, style: mergedStyle, ...htmlRest, children });
163
+ if (asChild && React2__namespace.isValidElement(children)) return children;
164
+ return /* @__PURE__ */ jsxRuntime.jsx(Component, { ref, className: cls, style: mergedStyle, ...htmlRest, children });
301
165
  }
302
166
  if (asChild && React2__namespace.isValidElement(children)) {
303
167
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -305,13 +169,7 @@ var Skeleton = React2__namespace.forwardRef(
305
169
  {
306
170
  ref,
307
171
  "data-loading": true,
308
- className: cn(
309
- "animate-skeleton-shimmer rounded-sm",
310
- "bg-[linear-gradient(90deg,var(--color-skeleton-start)_0%,var(--color-skeleton-end)_50%,var(--color-skeleton-start)_100%)]",
311
- "bg-[length:200%_100%]",
312
- "text-transparent [&_*]:invisible",
313
- finalClassName
314
- ),
172
+ className: cn(SKELETON_CLASSES, "text-transparent [&_*]:invisible", cls),
315
173
  style: mergedStyle,
316
174
  ...htmlRest,
317
175
  children
@@ -323,13 +181,7 @@ var Skeleton = React2__namespace.forwardRef(
323
181
  {
324
182
  ref,
325
183
  "data-loading": true,
326
- className: cn(
327
- "animate-skeleton-shimmer rounded-sm",
328
- "bg-[linear-gradient(90deg,var(--color-skeleton-start)_0%,var(--color-skeleton-end)_50%,var(--color-skeleton-start)_100%)]",
329
- "bg-[length:200%_100%]",
330
- children ? "text-transparent [&_*]:invisible" : "min-h-5",
331
- finalClassName
332
- ),
184
+ className: cn(SKELETON_CLASSES, children ? "text-transparent [&_*]:invisible" : "min-h-5", cls),
333
185
  style: mergedStyle,
334
186
  ...htmlRest,
335
187
  children
@@ -366,171 +218,202 @@ React2__namespace.forwardRef(
366
218
  )) });
367
219
  }
368
220
  );
369
- var buttonVariants = classVarianceAuthority.cva(
370
- // base styles (shared across all variants)
371
- [
372
- "inline-flex items-center justify-center",
373
- "gap-0 font-semibold overflow-hidden rounded-md",
374
- "cursor-pointer select-none whitespace-nowrap",
375
- "transition-colors duration-150",
376
- "disabled:opacity-[0.2] disabled:cursor-not-allowed"
377
- ],
378
- {
379
- variants: {
380
- variant: {
381
- // --- Solid ---
382
- solid: [
383
- "bg-[var(--color-button-solid-bg)] text-[var(--color-button-solid-text)]",
384
- "hover:bg-[var(--color-hover)]",
385
- "data-[expanded]:bg-[var(--color-hover)]"
386
- ],
387
- // --- Solid Danger ---
388
- solid_danger: [
389
- "bg-red-600 text-[var(--color-button-solid-text)]",
390
- "hover:bg-red-500",
391
- "data-[expanded]:bg-red-500"
392
- ],
393
- // --- Outline ---
394
- outline: [
395
- "border-2 border-solid bg-transparent",
396
- "text-[var(--color-button-outline-fg)] border-[var(--color-button-outline-fg)]",
397
- "hover:bg-transparent hover:text-[var(--color-hover)] hover:border-[var(--color-hover)]"
398
- ],
399
- // --- Outline Danger ---
400
- outline_danger: [
401
- "border-2 border-solid bg-transparent",
402
- "text-red-600 border-red-600",
403
- "hover:bg-transparent hover:text-red-500 hover:border-red-500"
404
- ],
405
- // --- Dropdown ---
406
- dropdown: [
407
- "border-2 border-solid bg-transparent",
408
- "text-[var(--color-button-dropdown-fg)] border-[var(--color-button-dropdown-border)]",
409
- "hover:bg-transparent hover:text-[var(--color-hover)] hover:border-[var(--color-hover)]",
410
- "data-[expanded]:bg-transparent data-[expanded]:text-[var(--color-hover)] data-[expanded]:border-[var(--color-hover)]",
411
- "data-[selected]:bg-[var(--color-selected-control-bg)] data-[selected]:text-[var(--color-selected-control-text)] data-[selected]:border-transparent",
412
- "data-[selected]:hover:bg-[var(--color-selected-control-bg)]",
413
- "data-[selected]:hover:text-[var(--color-hover)] data-[selected]:hover:border-transparent",
414
- "data-[selected]:data-[expanded]:text-[var(--color-hover)]"
415
- ],
416
- // --- Header ---
417
- header: [
418
- "bg-transparent border-2 border-solid",
419
- "text-[var(--color-button-header-fg)] border-[var(--color-button-header-border)]",
420
- "hover:bg-transparent hover:text-[var(--color-hover)] hover:border-[var(--color-hover)]",
421
- // selected
422
- "data-[selected]:bg-[var(--color-button-header-bg-selected)]",
423
- "data-[selected]:text-[var(--color-button-header-fg-selected)] data-[selected]:border-transparent data-[selected]:border-0",
424
- "data-[selected]:hover:bg-[var(--color-button-header-bg-selected)] data-[selected]:hover:text-[var(--color-hover)]",
425
- "data-[selected]:data-[expanded]:text-[var(--color-hover)]",
426
- // selected + highlighted
427
- "data-[selected]:data-[highlighted]:bg-[var(--color-button-header-bg-highlighted)]",
428
- "data-[selected]:data-[highlighted]:text-[var(--color-button-header-fg-highlighted)]",
429
- "data-[selected]:data-[highlighted]:border-transparent data-[selected]:data-[highlighted]:border-0",
430
- "data-[selected]:data-[highlighted]:hover:bg-[var(--color-button-header-bg-highlighted)]",
431
- "data-[selected]:data-[highlighted]:hover:text-[var(--color-hover)]",
432
- "data-[selected]:data-[highlighted]:data-[expanded]:text-[var(--color-hover)]"
433
- ],
434
- // --- Hero ---
435
- hero: [
436
- "bg-[var(--color-button-hero-bg)] text-[var(--color-button-hero-fg)]",
437
- "hover:bg-[var(--color-button-hero-bg-hover)] hover:text-[var(--color-button-hero-fg-hover)]",
438
- "data-[selected]:bg-[var(--color-button-hero-bg-selected)] data-[selected]:text-[var(--color-button-hero-fg-selected)]",
439
- "data-[selected]:hover:bg-[var(--color-button-hero-bg-selected)] data-[selected]:hover:text-[var(--color-hover)]",
440
- "data-[selected]:data-[expanded]:text-[var(--color-hover)]"
441
- ],
442
- // --- Segmented ---
443
- segmented: [
444
- "bg-transparent border-2 border-solid rounded-none",
445
- "text-[var(--color-button-segmented-fg)] border-[var(--color-selected-control-bg)]",
446
- "hover:text-[var(--color-hover)]",
447
- // selected
448
- "data-[selected]:bg-[var(--color-selected-control-bg)] data-[selected]:text-[var(--color-selected-control-text)]",
449
- "data-[selected]:hover:bg-[var(--color-selected-control-bg)] data-[selected]:hover:text-[var(--color-selected-control-text)]",
450
- // border collapse: hide right border except when selected; first/last get rounded
451
- "[&:not(:last-child)]:border-r-0 data-[selected]:[&:not(:last-child)]:border-r-2",
452
- "data-[selected]+*:border-l-0",
453
- "first:rounded-l-md last:rounded-r-md"
454
- ],
455
- // --- Plain ---
456
- plain: [
457
- "bg-transparent text-inherit border-none",
458
- "hover:bg-transparent"
459
- ],
460
- // --- Subtle ---
461
- subtle: [
462
- "bg-[var(--color-button-subtle-bg)] text-[var(--color-button-subtle-fg)]",
463
- "hover:bg-[var(--color-button-subtle-bg)] hover:text-[var(--color-hover)]",
464
- "disabled:bg-[var(--color-button-subtle-bg)] disabled:text-[var(--color-button-subtle-fg)]"
465
- ],
466
- // --- Link ---
467
- link: [
468
- "bg-transparent text-[var(--color-link-primary)] border-none font-normal",
469
- "px-0 h-auto",
470
- "hover:bg-transparent hover:text-[var(--color-link-primary-hover)]",
471
- "disabled:text-[var(--color-text-secondary)]"
472
- ],
473
- // --- Icon Secondary ---
474
- icon_secondary: [
475
- "bg-transparent text-[var(--color-icon-secondary)] border-none",
476
- "hover:text-[var(--color-hover)]",
477
- "data-[selected]:bg-[var(--color-selected-control-bg)] data-[selected]:text-[var(--color-selected-control-text)]",
478
- "data-[selected]:hover:bg-[var(--color-selected-control-bg)] data-[selected]:hover:text-[var(--color-hover)]",
479
- "data-[selected]:data-[expanded]:text-[var(--color-hover)]",
480
- "data-[expanded]:text-[var(--color-hover)]"
481
- ],
482
- // --- Icon Background ---
483
- icon_background: [
484
- "bg-[var(--color-button-icon-background-bg)] text-[var(--color-icon-secondary)] border-none",
485
- "hover:text-[var(--color-hover)]",
486
- "data-[selected]:bg-[var(--color-selected-control-bg)] data-[selected]:text-[var(--color-selected-control-text)]",
487
- "data-[selected]:hover:bg-[var(--color-selected-control-bg)] data-[selected]:hover:text-[var(--color-hover)]",
488
- "data-[selected]:data-[expanded]:text-[var(--color-hover)]",
489
- "data-[expanded]:text-[var(--color-hover)]"
490
- ],
491
- // --- Pagination ---
492
- pagination: [
493
- "border-2 border-solid bg-transparent",
494
- "text-[var(--color-button-pagination-fg)] border-[var(--color-button-pagination-border)]",
495
- "hover:bg-transparent hover:text-[var(--color-hover)] hover:border-[var(--color-hover)]",
496
- "data-[selected]:bg-[var(--color-selected-control-bg)] data-[selected]:text-[var(--color-selected-control-text)] data-[selected]:border-transparent",
497
- "data-[selected]:hover:bg-[var(--color-selected-control-bg)]",
498
- "data-[selected]:hover:text-[var(--color-selected-control-text)] data-[selected]:hover:border-transparent"
499
- ]
500
- },
501
- size: {
502
- "2xs": "px-2 h-5 min-w-5 text-xs rounded-sm gap-1",
503
- xs: "px-2 h-6 min-w-6 text-sm rounded-sm gap-1",
504
- sm: "px-3 h-8 min-w-8 text-sm rounded-md gap-1",
505
- md: "px-3 h-10 min-w-10 text-base rounded-md gap-2"
506
- }
507
- },
508
- defaultVariants: {
509
- variant: "solid",
510
- size: "md"
511
- }
512
- }
513
- );
221
+ var SpinnerFrame = core.styled(core.View, {
222
+ name: "ButtonSpinner",
223
+ render: /* @__PURE__ */ jsxRuntime.jsx("span", {}),
224
+ width: 16,
225
+ height: 16,
226
+ borderRadius: 1e3,
227
+ borderWidth: 2,
228
+ borderColor: "currentColor",
229
+ borderBottomColor: "transparent",
230
+ borderLeftColor: "transparent"
231
+ });
514
232
  function Spinner({ className }) {
515
233
  return /* @__PURE__ */ jsxRuntime.jsx(
516
- "span",
234
+ SpinnerFrame,
517
235
  {
518
- className: cn(
519
- "inline-block h-4 w-4 animate-spin rounded-full",
520
- "border-2 border-current border-b-transparent border-l-transparent",
521
- className
522
- ),
523
236
  role: "status",
524
- "aria-label": "Loading"
237
+ "aria-label": "Loading",
238
+ className: [
239
+ "animate-spin",
240
+ className
241
+ ].filter(Boolean).join(" ")
525
242
  }
526
243
  );
527
244
  }
245
+ var ButtonFrame = core.styled(core.View, {
246
+ name: "LuxButton",
247
+ render: /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button" }),
248
+ role: "button",
249
+ tabIndex: 0,
250
+ cursor: "pointer",
251
+ userSelect: "none",
252
+ display: "inline-flex",
253
+ alignItems: "center",
254
+ justifyContent: "center",
255
+ gap: 0,
256
+ overflow: "hidden",
257
+ borderRadius: 6,
258
+ // Whitespace nowrap via className since hanzogui doesn't have a direct token
259
+ // Transition via className
260
+ variants: {
261
+ size: {
262
+ "2xs": { paddingHorizontal: 8, height: 20, minWidth: 20, fontSize: 12, borderRadius: 4, gap: 4 },
263
+ xs: { paddingHorizontal: 8, height: 24, minWidth: 24, fontSize: 14, borderRadius: 4, gap: 4 },
264
+ sm: { paddingHorizontal: 12, height: 32, minWidth: 32, fontSize: 14, borderRadius: 6, gap: 4 },
265
+ md: { paddingHorizontal: 12, height: 40, minWidth: 40, fontSize: 16, borderRadius: 6, gap: 8 }
266
+ },
267
+ disabled: {
268
+ true: {
269
+ opacity: 0.2,
270
+ cursor: "not-allowed",
271
+ pointerEvents: "none"
272
+ }
273
+ }
274
+ },
275
+ defaultVariants: {
276
+ size: "md"
277
+ }
278
+ });
279
+ var VARIANT_CLASSES = {
280
+ solid: [
281
+ "bg-[var(--color-button-solid-bg)] text-[var(--color-button-solid-text)]",
282
+ "hover:bg-[var(--color-hover)]",
283
+ "data-[expanded]:bg-[var(--color-hover)]"
284
+ ].join(" "),
285
+ solid_danger: [
286
+ "bg-red-600 text-[var(--color-button-solid-text)]",
287
+ "hover:bg-red-500",
288
+ "data-[expanded]:bg-red-500"
289
+ ].join(" "),
290
+ outline: [
291
+ "border-2 border-solid bg-transparent",
292
+ "text-[var(--color-button-outline-fg)] border-[var(--color-button-outline-fg)]",
293
+ "hover:bg-transparent hover:text-[var(--color-hover)] hover:border-[var(--color-hover)]"
294
+ ].join(" "),
295
+ outline_danger: [
296
+ "border-2 border-solid bg-transparent",
297
+ "text-red-600 border-red-600",
298
+ "hover:bg-transparent hover:text-red-500 hover:border-red-500"
299
+ ].join(" "),
300
+ dropdown: [
301
+ "border-2 border-solid bg-transparent",
302
+ "text-[var(--color-button-dropdown-fg)] border-[var(--color-button-dropdown-border)]",
303
+ "hover:bg-transparent hover:text-[var(--color-hover)] hover:border-[var(--color-hover)]",
304
+ "data-[expanded]:bg-transparent data-[expanded]:text-[var(--color-hover)] data-[expanded]:border-[var(--color-hover)]",
305
+ "data-[selected]:bg-[var(--color-selected-control-bg)] data-[selected]:text-[var(--color-selected-control-text)] data-[selected]:border-transparent",
306
+ "data-[selected]:hover:bg-[var(--color-selected-control-bg)]",
307
+ "data-[selected]:hover:text-[var(--color-hover)] data-[selected]:hover:border-transparent",
308
+ "data-[selected]:data-[expanded]:text-[var(--color-hover)]"
309
+ ].join(" "),
310
+ header: [
311
+ "bg-transparent border-2 border-solid",
312
+ "text-[var(--color-button-header-fg)] border-[var(--color-button-header-border)]",
313
+ "hover:bg-transparent hover:text-[var(--color-hover)] hover:border-[var(--color-hover)]",
314
+ "data-[selected]:bg-[var(--color-button-header-bg-selected)]",
315
+ "data-[selected]:text-[var(--color-button-header-fg-selected)] data-[selected]:border-transparent data-[selected]:border-0",
316
+ "data-[selected]:hover:bg-[var(--color-button-header-bg-selected)] data-[selected]:hover:text-[var(--color-hover)]",
317
+ "data-[selected]:data-[expanded]:text-[var(--color-hover)]",
318
+ "data-[selected]:data-[highlighted]:bg-[var(--color-button-header-bg-highlighted)]",
319
+ "data-[selected]:data-[highlighted]:text-[var(--color-button-header-fg-highlighted)]",
320
+ "data-[selected]:data-[highlighted]:border-transparent data-[selected]:data-[highlighted]:border-0",
321
+ "data-[selected]:data-[highlighted]:hover:bg-[var(--color-button-header-bg-highlighted)]",
322
+ "data-[selected]:data-[highlighted]:hover:text-[var(--color-hover)]",
323
+ "data-[selected]:data-[highlighted]:data-[expanded]:text-[var(--color-hover)]"
324
+ ].join(" "),
325
+ hero: [
326
+ "bg-[var(--color-button-hero-bg)] text-[var(--color-button-hero-fg)]",
327
+ "hover:bg-[var(--color-button-hero-bg-hover)] hover:text-[var(--color-button-hero-fg-hover)]",
328
+ "data-[selected]:bg-[var(--color-button-hero-bg-selected)] data-[selected]:text-[var(--color-button-hero-fg-selected)]",
329
+ "data-[selected]:hover:bg-[var(--color-button-hero-bg-selected)] data-[selected]:hover:text-[var(--color-hover)]",
330
+ "data-[selected]:data-[expanded]:text-[var(--color-hover)]"
331
+ ].join(" "),
332
+ segmented: [
333
+ "bg-transparent border-2 border-solid rounded-none",
334
+ "text-[var(--color-button-segmented-fg)] border-[var(--color-selected-control-bg)]",
335
+ "hover:text-[var(--color-hover)]",
336
+ "data-[selected]:bg-[var(--color-selected-control-bg)] data-[selected]:text-[var(--color-selected-control-text)]",
337
+ "data-[selected]:hover:bg-[var(--color-selected-control-bg)] data-[selected]:hover:text-[var(--color-selected-control-text)]",
338
+ "[&:not(:last-child)]:border-r-0 data-[selected]:[&:not(:last-child)]:border-r-2",
339
+ "data-[selected]+*:border-l-0",
340
+ "first:rounded-l-md last:rounded-r-md"
341
+ ].join(" "),
342
+ plain: "bg-transparent text-inherit border-none hover:bg-transparent",
343
+ subtle: [
344
+ "bg-[var(--color-button-subtle-bg)] text-[var(--color-button-subtle-fg)]",
345
+ "hover:bg-[var(--color-button-subtle-bg)] hover:text-[var(--color-hover)]",
346
+ "disabled:bg-[var(--color-button-subtle-bg)] disabled:text-[var(--color-button-subtle-fg)]"
347
+ ].join(" "),
348
+ link: [
349
+ "bg-transparent text-[var(--color-link-primary)] border-none font-normal",
350
+ "px-0 h-auto",
351
+ "hover:bg-transparent hover:text-[var(--color-link-primary-hover)]",
352
+ "disabled:text-[var(--color-text-secondary)]"
353
+ ].join(" "),
354
+ icon_secondary: [
355
+ "bg-transparent text-[var(--color-icon-secondary)] border-none",
356
+ "hover:text-[var(--color-hover)]",
357
+ "data-[selected]:bg-[var(--color-selected-control-bg)] data-[selected]:text-[var(--color-selected-control-text)]",
358
+ "data-[selected]:hover:bg-[var(--color-selected-control-bg)] data-[selected]:hover:text-[var(--color-hover)]",
359
+ "data-[selected]:data-[expanded]:text-[var(--color-hover)]",
360
+ "data-[expanded]:text-[var(--color-hover)]"
361
+ ].join(" "),
362
+ icon_background: [
363
+ "bg-[var(--color-button-icon-background-bg)] text-[var(--color-icon-secondary)] border-none",
364
+ "hover:text-[var(--color-hover)]",
365
+ "data-[selected]:bg-[var(--color-selected-control-bg)] data-[selected]:text-[var(--color-selected-control-text)]",
366
+ "data-[selected]:hover:bg-[var(--color-selected-control-bg)] data-[selected]:hover:text-[var(--color-hover)]",
367
+ "data-[selected]:data-[expanded]:text-[var(--color-hover)]",
368
+ "data-[expanded]:text-[var(--color-hover)]"
369
+ ].join(" "),
370
+ pagination: [
371
+ "border-2 border-solid bg-transparent",
372
+ "text-[var(--color-button-pagination-fg)] border-[var(--color-button-pagination-border)]",
373
+ "hover:bg-transparent hover:text-[var(--color-hover)] hover:border-[var(--color-hover)]",
374
+ "data-[selected]:bg-[var(--color-selected-control-bg)] data-[selected]:text-[var(--color-selected-control-text)] data-[selected]:border-transparent",
375
+ "data-[selected]:hover:bg-[var(--color-selected-control-bg)]",
376
+ "data-[selected]:hover:text-[var(--color-selected-control-text)] data-[selected]:hover:border-transparent"
377
+ ].join(" ")
378
+ };
379
+ var BASE_CLASSES = "font-semibold whitespace-nowrap transition-colors duration-150";
380
+ var SP = 4;
381
+ function buildShimStyle(props) {
382
+ const s = { ...props.style };
383
+ if (props.mt !== void 0) s.marginTop = typeof props.mt === "number" ? `${props.mt * SP}px` : props.mt;
384
+ if (props.ml !== void 0) s.marginLeft = typeof props.ml === "number" ? `${props.ml * SP}px` : props.ml;
385
+ if (props.mr !== void 0) s.marginRight = typeof props.mr === "number" ? `${props.mr * SP}px` : props.mr;
386
+ if (props.px !== void 0) {
387
+ const v = typeof props.px === "number" ? `${props.px * SP}px` : props.px;
388
+ s.paddingLeft = v;
389
+ s.paddingRight = v;
390
+ }
391
+ if (props.py !== void 0) {
392
+ const v = typeof props.py === "number" ? `${props.py * SP}px` : props.py;
393
+ s.paddingTop = v;
394
+ s.paddingBottom = v;
395
+ }
396
+ if (props.fontWeight !== void 0) s.fontWeight = props.fontWeight;
397
+ if (props.gap !== void 0) s.gap = typeof props.gap === "number" ? `${props.gap * SP}px` : props.gap;
398
+ if (props.flexShrink !== void 0) s.flexShrink = props.flexShrink;
399
+ if (props.columnGap !== void 0) s.columnGap = typeof props.columnGap === "number" ? `${props.columnGap * SP}px` : props.columnGap;
400
+ if (props.gridColumn !== void 0) s.gridColumn = typeof props.gridColumn === "number" ? String(props.gridColumn) : props.gridColumn;
401
+ if (props.gridRow) s.gridRow = props.gridRow;
402
+ if (props.justifySelf) s.justifySelf = props.justifySelf;
403
+ if (props.alignSelf) s.alignSelf = props.alignSelf;
404
+ if (props.h) s.height = props.h;
405
+ if (props.w) s.width = props.w;
406
+ if (props.display) s.display = props.display;
407
+ if (props.borderBottomRightRadius !== void 0) s.borderBottomRightRadius = typeof props.borderBottomRightRadius === "number" ? `${props.borderBottomRightRadius}px` : props.borderBottomRightRadius;
408
+ if (props.borderTopRightRadius !== void 0) s.borderTopRightRadius = typeof props.borderTopRightRadius === "number" ? `${props.borderTopRightRadius}px` : props.borderTopRightRadius;
409
+ return Object.keys(s).length > 0 ? s : void 0;
410
+ }
528
411
  var Button = React2__namespace.forwardRef(
529
412
  function Button2(props, ref) {
530
413
  const {
531
414
  className,
532
- variant,
533
- size,
415
+ variant = "solid",
416
+ size = "md",
534
417
  asChild = false,
535
418
  loading = false,
536
419
  loadingText,
@@ -542,57 +425,48 @@ var Button = React2__namespace.forwardRef(
542
425
  children,
543
426
  style: styleProp,
544
427
  // Strip Chakra style props
545
- mt: _mt,
546
- ml: _ml,
547
- mr: _mr,
548
- px: _px,
549
- py: _py,
550
- fontWeight: _fontWeight,
551
- gap: _gap,
552
- flexShrink: _flexShrink,
553
- columnGap: _columnGap,
554
- gridColumn: _gridColumn,
555
- gridRow: _gridRow,
556
- justifySelf: _justifySelf,
557
- alignSelf: _alignSelf,
428
+ mt,
429
+ ml,
430
+ mr,
431
+ px,
432
+ py,
433
+ fontWeight,
434
+ gap,
435
+ flexShrink,
436
+ columnGap,
437
+ gridColumn,
438
+ gridRow,
439
+ justifySelf,
440
+ alignSelf,
558
441
  textStyle: _textStyle,
559
- h: _h,
560
- w: _w,
561
- display: _display,
562
- borderBottomRightRadius: _bbrr,
563
- borderTopRightRadius: _btrr,
442
+ h,
443
+ w,
444
+ display,
445
+ borderBottomRightRadius,
446
+ borderTopRightRadius,
564
447
  ...rest
565
448
  } = props;
566
- const SP = 4;
567
- const shimStyle = { ...styleProp };
568
- if (_mt !== void 0) shimStyle.marginTop = typeof _mt === "number" ? `${_mt * SP}px` : _mt;
569
- if (_ml !== void 0) shimStyle.marginLeft = typeof _ml === "number" ? `${_ml * SP}px` : _ml;
570
- if (_mr !== void 0) shimStyle.marginRight = typeof _mr === "number" ? `${_mr * SP}px` : _mr;
571
- if (_px !== void 0) {
572
- const v = typeof _px === "number" ? `${_px * SP}px` : _px;
573
- shimStyle.paddingLeft = v;
574
- shimStyle.paddingRight = v;
575
- }
576
- if (_py !== void 0) {
577
- const v = typeof _py === "number" ? `${_py * SP}px` : _py;
578
- shimStyle.paddingTop = v;
579
- shimStyle.paddingBottom = v;
580
- }
581
- if (_fontWeight !== void 0) shimStyle.fontWeight = _fontWeight;
582
- if (_gap !== void 0) shimStyle.gap = typeof _gap === "number" ? `${_gap * SP}px` : _gap;
583
- if (_flexShrink !== void 0) shimStyle.flexShrink = _flexShrink;
584
- if (_columnGap !== void 0) shimStyle.columnGap = typeof _columnGap === "number" ? `${_columnGap * SP}px` : _columnGap;
585
- if (_gridColumn !== void 0) shimStyle.gridColumn = typeof _gridColumn === "number" ? String(_gridColumn) : _gridColumn;
586
- if (_gridRow) shimStyle.gridRow = _gridRow;
587
- if (_justifySelf) shimStyle.justifySelf = _justifySelf;
588
- if (_alignSelf) shimStyle.alignSelf = _alignSelf;
589
- if (_h) shimStyle.height = _h;
590
- if (_w) shimStyle.width = _w;
591
- if (_display) shimStyle.display = _display;
592
- if (_bbrr !== void 0) shimStyle.borderBottomRightRadius = typeof _bbrr === "number" ? `${_bbrr}px` : _bbrr;
593
- if (_btrr !== void 0) shimStyle.borderTopRightRadius = typeof _btrr === "number" ? `${_btrr}px` : _btrr;
594
- const mergedStyle = Object.keys(shimStyle).length > 0 ? shimStyle : void 0;
595
- const Comp = asChild ? reactSlot.Slot : "button";
449
+ const mergedStyle = buildShimStyle({
450
+ style: styleProp,
451
+ mt,
452
+ ml,
453
+ mr,
454
+ px,
455
+ py,
456
+ fontWeight,
457
+ gap,
458
+ flexShrink,
459
+ columnGap,
460
+ gridColumn,
461
+ gridRow,
462
+ justifySelf,
463
+ alignSelf,
464
+ h,
465
+ w,
466
+ display,
467
+ borderBottomRightRadius,
468
+ borderTopRightRadius
469
+ });
596
470
  const dataAttrs = {};
597
471
  if (expanded) dataAttrs["data-expanded"] = true;
598
472
  if (selected) dataAttrs["data-selected"] = true;
@@ -601,15 +475,19 @@ var Button = React2__namespace.forwardRef(
601
475
  const isDisabled = !loadingSkeleton && (loading || disabled);
602
476
  const inner = loading ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
603
477
  /* @__PURE__ */ jsxRuntime.jsx(Spinner, {}),
604
- loadingText != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-2", children: loadingText })
478
+ loadingText != null && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { marginLeft: 8 }, children: loadingText })
605
479
  ] }) : children;
480
+ const variantClass = VARIANT_CLASSES[variant] ?? VARIANT_CLASSES.solid;
481
+ const combinedClassName = [BASE_CLASSES, variantClass, className].filter(Boolean).join(" ");
606
482
  const button = /* @__PURE__ */ jsxRuntime.jsx(
607
- Comp,
483
+ ButtonFrame,
608
484
  {
609
485
  ref,
610
- className: cn(buttonVariants({ variant, size }), className),
611
- style: mergedStyle,
486
+ size,
612
487
  disabled: isDisabled || void 0,
488
+ asChild: asChild || void 0,
489
+ className: combinedClassName,
490
+ style: mergedStyle,
613
491
  ...dataAttrs,
614
492
  ...rest,
615
493
  children: inner
@@ -621,6 +499,17 @@ var Button = React2__namespace.forwardRef(
621
499
  return button;
622
500
  }
623
501
  );
502
+ var SIZE_CLASSES = {
503
+ "2xs": "px-2 h-5 min-w-5 text-xs rounded-sm gap-1",
504
+ xs: "px-2 h-6 min-w-6 text-sm rounded-sm gap-1",
505
+ sm: "px-3 h-8 min-w-8 text-sm rounded-md gap-1",
506
+ md: "px-3 h-10 min-w-10 text-base rounded-md gap-2"
507
+ };
508
+ function buttonVariants(opts) {
509
+ const v = opts?.variant ?? "solid";
510
+ const s = opts?.size ?? "md";
511
+ return [BASE_CLASSES, VARIANT_CLASSES[v] ?? "", SIZE_CLASSES[s] ?? ""].filter(Boolean).join(" ");
512
+ }
624
513
  var ButtonGroup = React2__namespace.forwardRef(
625
514
  function ButtonGroup2(props, ref) {
626
515
  const { className, ...rest } = props;
@@ -628,7 +517,7 @@ var ButtonGroup = React2__namespace.forwardRef(
628
517
  "div",
629
518
  {
630
519
  ref,
631
- className: cn("inline-flex", className),
520
+ className: ["inline-flex", className].filter(Boolean).join(" "),
632
521
  role: "group",
633
522
  ...rest
634
523
  }
@@ -669,11 +558,11 @@ var ButtonGroupRadio = React2__namespace.forwardRef(
669
558
  "div",
670
559
  {
671
560
  ref,
672
- className: cn(
561
+ className: [
673
562
  "inline-flex gap-0",
674
- equalWidth && "grid",
563
+ equalWidth ? "grid" : "",
675
564
  className
676
- ),
565
+ ].filter(Boolean).join(" "),
677
566
  style: equalWidth ? { gridTemplateColumns: `repeat(${childrenLength}, 1fr)` } : void 0,
678
567
  role: "group",
679
568
  ...rest,