@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/radio.js CHANGED
@@ -1,40 +1,18 @@
1
1
  "use client";
2
- import { RadioGroup } from '@hanzo/gui';
2
+ import { RadioGroup, Label, VisuallyHidden, Text } from '@hanzo/gui';
3
3
  import * as React from 'react';
4
- import { clsx } from 'clsx';
5
- import { twMerge } from 'tailwind-merge';
6
4
  import { jsx, jsxs } from 'react/jsx-runtime';
7
5
 
8
6
  // src/radio.tsx
9
- function cn(...inputs) {
10
- return twMerge(clsx(inputs));
11
- }
12
- var SIZE_CLASSES = {
13
- xs: {
14
- root: "gap-1.5",
15
- control: "h-3 w-3",
16
- indicator: "h-1.5 w-1.5",
17
- label: "text-xs"
18
- },
19
- sm: {
20
- root: "gap-1.5",
21
- control: "h-3.5 w-3.5",
22
- indicator: "h-1.5 w-1.5",
23
- label: "text-xs"
24
- },
25
- md: {
26
- root: "gap-2",
27
- control: "h-4 w-4",
28
- indicator: "h-2 w-2",
29
- label: "text-sm"
30
- },
31
- lg: {
32
- root: "gap-2.5",
33
- control: "h-5 w-5",
34
- indicator: "h-2.5 w-2.5",
35
- label: "text-base"
36
- }
7
+ var SIZE = {
8
+ xs: { rootGap: 6, control: 12, indicator: 6, label: 12 },
9
+ sm: { rootGap: 6, control: 14, indicator: 6, label: 12 },
10
+ md: { rootGap: 8, control: 16, indicator: 8, label: 14 },
11
+ lg: { rootGap: 10, control: 20, indicator: 10, label: 16 }
37
12
  };
13
+ var INK = "var(--color-text-primary)";
14
+ var RESTING_BORDER = "var(--color-input-border)";
15
+ var OUTLINE = "var(--color-gray-500)";
38
16
  var RadioSizeContext = React.createContext("md");
39
17
  var RadioGroupBase = React.forwardRef(
40
18
  function RadioGroup$1(props, ref) {
@@ -51,7 +29,6 @@ var RadioGroupBase = React.forwardRef(
51
29
  value,
52
30
  onValueChange,
53
31
  size = "md",
54
- className,
55
32
  ...rest
56
33
  } = props;
57
34
  const handleValueChange = React.useCallback(
@@ -73,11 +50,9 @@ var RadioGroupBase = React.forwardRef(
73
50
  defaultValue,
74
51
  value: value ?? void 0,
75
52
  onValueChange: handleValueChange,
76
- className: cn(
77
- "flex",
78
- orientation === "vertical" ? "flex-col gap-3" : "flex-row gap-6",
79
- className
80
- ),
53
+ display: "flex",
54
+ flexDirection: orientation === "vertical" ? "column" : "row",
55
+ gap: orientation === "vertical" ? 12 : 24,
81
56
  ...rest,
82
57
  children
83
58
  }
@@ -89,19 +64,20 @@ var NOOP = () => {
89
64
  };
90
65
  var RadioBase = React.forwardRef(
91
66
  function Radio(props, ref) {
92
- const { children, inputProps, rootRef, value, disabled, className, ...rest } = props;
67
+ const { children, inputProps, rootRef, value, disabled, ...rest } = props;
93
68
  const size = React.useContext(RadioSizeContext);
94
- const sizeClasses = SIZE_CLASSES[size];
69
+ const s = SIZE[size];
95
70
  return /* @__PURE__ */ jsxs(
96
- "label",
71
+ Label,
97
72
  {
98
73
  ref: rootRef,
99
- className: cn(
100
- "inline-flex items-center cursor-pointer select-none",
101
- sizeClasses.root,
102
- disabled && "opacity-50 cursor-not-allowed",
103
- className
104
- ),
74
+ unstyled: true,
75
+ flexDirection: "row",
76
+ alignItems: "center",
77
+ gap: s.rootGap,
78
+ cursor: disabled ? "not-allowed" : "pointer",
79
+ userSelect: "none",
80
+ opacity: disabled ? 0.5 : 1,
105
81
  "data-disabled": disabled || void 0,
106
82
  ...rest,
107
83
  children: [
@@ -111,32 +87,24 @@ var RadioBase = React.forwardRef(
111
87
  unstyled: true,
112
88
  value,
113
89
  disabled,
114
- className: cn(
115
- "inline-flex items-center justify-center shrink-0 rounded-full",
116
- "border-2 border-current/30",
117
- "data-[state=checked]:border-gray-800 dark:border-white",
118
- "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-500",
119
- "transition-colors duration-150",
120
- sizeClasses.control
121
- ),
122
- children: /* @__PURE__ */ jsx(
123
- RadioGroup.Indicator,
124
- {
125
- unstyled: true,
126
- className: cn(
127
- "block rounded-full bg-gray-800 dark:bg-white",
128
- sizeClasses.indicator
129
- )
130
- }
131
- )
90
+ flexShrink: 0,
91
+ alignItems: "center",
92
+ justifyContent: "center",
93
+ width: s.control,
94
+ height: s.control,
95
+ borderRadius: 9999,
96
+ borderWidth: 2,
97
+ borderColor: RESTING_BORDER,
98
+ transition: "quicker",
99
+ focusStyle: { outlineWidth: 2, outlineStyle: "solid", outlineColor: OUTLINE, outlineOffset: 2 },
100
+ children: /* @__PURE__ */ jsx(RadioGroup.Indicator, { unstyled: true, borderRadius: 9999, width: s.indicator, height: s.indicator, backgroundColor: INK })
132
101
  }
133
102
  ),
134
- /* @__PURE__ */ jsx(
103
+ /* @__PURE__ */ jsx(VisuallyHidden, { children: /* @__PURE__ */ jsx(
135
104
  "input",
136
105
  {
137
106
  ref,
138
107
  type: "radio",
139
- className: "sr-only",
140
108
  value,
141
109
  disabled,
142
110
  tabIndex: -1,
@@ -144,8 +112,8 @@ var RadioBase = React.forwardRef(
144
112
  onChange: NOOP,
145
113
  ...inputProps
146
114
  }
147
- ),
148
- children != null && /* @__PURE__ */ jsx("span", { className: sizeClasses.label, children })
115
+ ) }),
116
+ children != null && /* @__PURE__ */ jsx(Text, { fontSize: s.label, children })
149
117
  ]
150
118
  }
151
119
  );
package/dist/select.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var RadixSelect = require('@radix-ui/react-select');
4
+ var gui = require('@hanzo/gui');
5
5
  var usehooks = require('@uidotdev/usehooks');
6
6
  var React2 = require('react');
7
7
  var clsx = require('clsx');
@@ -26,7 +26,6 @@ function _interopNamespace(e) {
26
26
  return Object.freeze(n);
27
27
  }
28
28
 
29
- var RadixSelect__namespace = /*#__PURE__*/_interopNamespace(RadixSelect);
30
29
  var React2__namespace = /*#__PURE__*/_interopNamespace(React2);
31
30
 
32
31
  function cn(...inputs) {
@@ -333,16 +332,15 @@ var SelectRoot = React2__namespace.forwardRef(
333
332
  return s;
334
333
  }, [style, w, maxW, minW]);
335
334
  return /* @__PURE__ */ jsxRuntime.jsx(SelectInternalContext.Provider, { value: ctxValue, children: /* @__PURE__ */ jsxRuntime.jsx(
336
- RadixSelect__namespace.Root,
335
+ gui.Select,
337
336
  {
338
337
  value: currentValue[0] ?? "",
339
338
  defaultValue: defaultValueArr?.[0],
340
339
  onValueChange: handleRadixValueChange,
341
340
  open: isOpen,
342
341
  onOpenChange: handleOpenChange,
343
- disabled: disabled || readOnly,
342
+ disablePreventBodyScroll: true,
344
343
  name,
345
- required,
346
344
  children: /* @__PURE__ */ jsxRuntime.jsx(
347
345
  "div",
348
346
  {
@@ -367,10 +365,11 @@ var SelectControl = React2__namespace.forwardRef(
367
365
  const isDefaultValue = Array.isArray(defaultValue) ? ctx.value.every((item) => defaultValue.includes(item)) : false;
368
366
  const { asChild, px: _px, className: triggerClassName, ...radixTriggerProps } = triggerProps ?? {};
369
367
  const trigger = /* @__PURE__ */ jsxRuntime.jsx(
370
- RadixSelect__namespace.Trigger,
368
+ gui.Select.Trigger,
371
369
  {
372
370
  ref,
373
371
  asChild,
372
+ unstyled: true,
374
373
  className: cn(
375
374
  "group peer inline-flex items-center gap-2 cursor-pointer",
376
375
  "rounded-lg text-sm transition-colors outline-none",
@@ -419,41 +418,43 @@ var SelectClearTrigger = React2__namespace.forwardRef(
419
418
  }
420
419
  );
421
420
  var SelectContent = React2__namespace.forwardRef(
422
- function SelectContent2(props, ref) {
423
- const { portalled = true, portalRef, children, className, ...rest } = props;
424
- const content = /* @__PURE__ */ jsxRuntime.jsx(
425
- RadixSelect__namespace.Content,
426
- {
427
- ref,
428
- position: "popper",
429
- sideOffset: 4,
430
- className: cn(
431
- "z-50 min-w-[8rem] overflow-hidden rounded-lg",
432
- "bg-[var(--color-popover-bg)] shadow-[var(--shadow-popover)]",
433
- "border border-[var(--color-border-divider)]",
434
- "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
435
- "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
436
- className
437
- ),
438
- ...rest,
439
- children: /* @__PURE__ */ jsxRuntime.jsx(RadixSelect__namespace.Viewport, { className: "p-1", children })
440
- }
421
+ function SelectContent2(props, _ref) {
422
+ const { portalled: _portalled, portalRef: _portalRef, children, className, ...rest } = props;
423
+ let n = 0;
424
+ const counter = () => n++;
425
+ return (
426
+ // Content is the focus scope — it takes no style props at all. The
427
+ // Viewport is the box you can see, so the surface is declared there.
428
+ /* @__PURE__ */ jsxRuntime.jsx(gui.Select.Content, { ...rest, children: /* @__PURE__ */ jsxRuntime.jsx(
429
+ gui.Select.Viewport,
430
+ {
431
+ className: cn(
432
+ "min-w-[8rem] overflow-hidden rounded-lg p-1",
433
+ "bg-[var(--color-popover-bg)] shadow-[var(--shadow-popover)]",
434
+ "border border-[var(--color-border-divider)]",
435
+ className
436
+ ),
437
+ children: stampIndices(children, counter)
438
+ }
439
+ ) })
441
440
  );
442
- if (portalled) {
443
- return /* @__PURE__ */ jsxRuntime.jsx(RadixSelect__namespace.Portal, { container: portalRef?.current ?? void 0, children: content });
444
- }
445
- return content;
446
441
  }
447
442
  );
443
+ var stampIndices = (children, next) => React2__namespace.Children.map(children, (child) => {
444
+ if (!React2__namespace.isValidElement(child)) return child;
445
+ if (child.type === SelectItem) return React2__namespace.cloneElement(child, { index: next() });
446
+ const kids = child.props.children;
447
+ return kids === void 0 ? child : React2__namespace.cloneElement(child, void 0, stampIndices(kids, next));
448
+ });
448
449
  var SelectItem = React2__namespace.forwardRef(
449
450
  function SelectItem2(props, ref) {
450
- const { item, children, className, ...rest } = props;
451
+ const { item, children, className, index, ...rest } = props;
451
452
  return /* @__PURE__ */ jsxRuntime.jsxs(
452
- RadixSelect__namespace.Item,
453
+ gui.Select.Item,
453
454
  {
454
455
  ref,
456
+ index: index ?? 0,
455
457
  value: item.value,
456
- textValue: item.label,
457
458
  className: cn(
458
459
  "relative flex cursor-pointer select-none items-center gap-2",
459
460
  "rounded-md px-3 py-2 text-sm outline-none",
@@ -466,8 +467,8 @@ var SelectItem = React2__namespace.forwardRef(
466
467
  ...rest,
467
468
  children: [
468
469
  item.icon,
469
- /* @__PURE__ */ jsxRuntime.jsx(RadixSelect__namespace.ItemText, { children }),
470
- /* @__PURE__ */ jsxRuntime.jsx(RadixSelect__namespace.ItemIndicator, { className: "ml-auto shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(CheckIcon, { className: "h-5 w-5" }) })
470
+ /* @__PURE__ */ jsxRuntime.jsx(gui.Select.ItemText, { children: children ?? item.label }),
471
+ /* @__PURE__ */ jsxRuntime.jsx(gui.Select.ItemIndicator, { className: "ml-auto shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(CheckIcon, { className: "h-5 w-5" }) })
471
472
  ]
472
473
  }
473
474
  );
@@ -518,7 +519,7 @@ var SelectValueText = React2__namespace.forwardRef(
518
519
  return `${items.length} selected`;
519
520
  })();
520
521
  return /* @__PURE__ */ jsxRuntime.jsx(
521
- RadixSelect__namespace.Value,
522
+ gui.Select.Value,
522
523
  {
523
524
  ref,
524
525
  placeholder: placeholderText,
@@ -532,14 +533,14 @@ var SelectValueText = React2__namespace.forwardRef(
532
533
  var SelectItemGroup = React2__namespace.forwardRef(
533
534
  function SelectItemGroup2(props, ref) {
534
535
  const { children, label, className, ...rest } = props;
535
- return /* @__PURE__ */ jsxRuntime.jsxs(RadixSelect__namespace.Group, { ref, className: cn("py-1", className), ...rest, children: [
536
- /* @__PURE__ */ jsxRuntime.jsx(RadixSelect__namespace.Label, { className: "px-3 py-1.5 text-xs font-medium text-[var(--color-text-secondary)]", children: label }),
536
+ return /* @__PURE__ */ jsxRuntime.jsxs(gui.Select.Group, { ref, className: cn("py-1", className), ...rest, children: [
537
+ /* @__PURE__ */ jsxRuntime.jsx(gui.Select.Label, { className: "px-3 py-1.5 text-xs font-medium text-[var(--color-text-secondary)]", children: label }),
537
538
  children
538
539
  ] });
539
540
  }
540
541
  );
541
- var SelectLabel = RadixSelect__namespace.Label;
542
- var SelectItemText = RadixSelect__namespace.ItemText;
542
+ var SelectLabel = gui.Select.Label;
543
+ var SelectItemText = gui.Select.ItemText;
543
544
  var Select = React2__namespace.forwardRef((props, ref) => {
544
545
  const { collection, placeholder, portalled = true, loading, errorText, contentProps, contentHeader, itemFilter, mode, ...rest } = props;
545
546
  return /* @__PURE__ */ jsxRuntime.jsxs(
package/dist/select.d.cts CHANGED
@@ -1,4 +1,6 @@
1
- import * as RadixSelect from '@radix-ui/react-select';
1
+ import * as _hanzo_gui from '@hanzo/gui';
2
+ import { Select as Select$1 } from '@hanzo/gui';
3
+ import * as _hanzogui_web from '@hanzogui/web';
2
4
  import * as React from 'react';
3
5
 
4
6
  interface ListCollection<T> {
@@ -56,7 +58,7 @@ declare const SelectRoot: React.ForwardRefExoticComponent<SelectRootProps & Reac
56
58
  interface SelectControlProps {
57
59
  children?: React.ReactNode;
58
60
  noIndicator?: boolean;
59
- triggerProps?: React.ComponentPropsWithoutRef<typeof RadixSelect.Trigger> & {
61
+ triggerProps?: React.ComponentProps<typeof Select$1.Trigger> & {
60
62
  asChild?: boolean;
61
63
  px?: string | number;
62
64
  className?: string;
@@ -83,6 +85,15 @@ interface SelectItemProps {
83
85
  item: SelectOption;
84
86
  children?: React.ReactNode;
85
87
  className?: string;
88
+ /**
89
+ * The row's position in the list. gui's Select is positional — it keeps its
90
+ * own map of index to value to drive type-ahead, the active descendant and
91
+ * scrolling, so a row without one is a row the keyboard cannot reach. It is
92
+ * stamped by `SelectContent` rather than asked of the caller, because the
93
+ * caller writing `<SelectItem item={x}/>` has no idea what its own ordinal is
94
+ * and would have to be told twice.
95
+ */
96
+ index?: number;
86
97
  }
87
98
  declare const SelectItem: React.ForwardRefExoticComponent<SelectItemProps & React.RefAttributes<HTMLDivElement>>;
88
99
  interface SelectValueTextProps {
@@ -103,8 +114,28 @@ interface SelectItemGroupProps {
103
114
  className?: string;
104
115
  }
105
116
  declare const SelectItemGroup: React.ForwardRefExoticComponent<SelectItemGroupProps & React.RefAttributes<HTMLDivElement>>;
106
- declare const SelectLabel: React.ForwardRefExoticComponent<RadixSelect.SelectLabelProps & React.RefAttributes<HTMLDivElement>>;
107
- declare const SelectItemText: React.ForwardRefExoticComponent<RadixSelect.SelectItemTextProps & React.RefAttributes<HTMLSpanElement>>;
117
+ declare const SelectLabel: _hanzogui_web.GuiComponent<Omit<_hanzogui_web.GetFinalProps<_hanzogui_web.TextNonStyleProps, _hanzogui_web.TextStylePropsBase, {
118
+ size?: _hanzogui_web.SizeTokens | _hanzogui_web.FontSizeTokens | undefined;
119
+ unstyled?: boolean | undefined;
120
+ }>, "scope"> & {
121
+ scope?: any;
122
+ }, _hanzogui_web.GuiTextElement, _hanzogui_web.TextNonStyleProps & {
123
+ scope?: any;
124
+ }, _hanzogui_web.TextStylePropsBase, {
125
+ size?: _hanzogui_web.SizeTokens | _hanzogui_web.FontSizeTokens | undefined;
126
+ unstyled?: boolean | undefined;
127
+ }, _hanzogui_web.StaticConfigPublic>;
128
+ declare const SelectItemText: _hanzogui_web.GuiComponent<Omit<_hanzogui_web.GetFinalProps<_hanzogui_web.TextNonStyleProps, _hanzogui_web.TextStylePropsBase, {
129
+ size?: _hanzogui_web.FontSizeTokens | undefined;
130
+ unstyled?: boolean | undefined;
131
+ }>, "scope"> & {
132
+ scope?: _hanzo_gui.SelectScopes;
133
+ }, _hanzogui_web.GuiTextElement, _hanzogui_web.TextNonStyleProps & {
134
+ scope?: _hanzo_gui.SelectScopes;
135
+ }, _hanzogui_web.TextStylePropsBase, {
136
+ size?: _hanzogui_web.FontSizeTokens | undefined;
137
+ unstyled?: boolean | undefined;
138
+ }, _hanzogui_web.StaticConfigPublic>;
108
139
  interface SelectProps extends SelectRootProps {
109
140
  collection: ListCollection<SelectOption>;
110
141
  placeholder: string;
package/dist/select.d.ts CHANGED
@@ -1,4 +1,6 @@
1
- import * as RadixSelect from '@radix-ui/react-select';
1
+ import * as _hanzo_gui from '@hanzo/gui';
2
+ import { Select as Select$1 } from '@hanzo/gui';
3
+ import * as _hanzogui_web from '@hanzogui/web';
2
4
  import * as React from 'react';
3
5
 
4
6
  interface ListCollection<T> {
@@ -56,7 +58,7 @@ declare const SelectRoot: React.ForwardRefExoticComponent<SelectRootProps & Reac
56
58
  interface SelectControlProps {
57
59
  children?: React.ReactNode;
58
60
  noIndicator?: boolean;
59
- triggerProps?: React.ComponentPropsWithoutRef<typeof RadixSelect.Trigger> & {
61
+ triggerProps?: React.ComponentProps<typeof Select$1.Trigger> & {
60
62
  asChild?: boolean;
61
63
  px?: string | number;
62
64
  className?: string;
@@ -83,6 +85,15 @@ interface SelectItemProps {
83
85
  item: SelectOption;
84
86
  children?: React.ReactNode;
85
87
  className?: string;
88
+ /**
89
+ * The row's position in the list. gui's Select is positional — it keeps its
90
+ * own map of index to value to drive type-ahead, the active descendant and
91
+ * scrolling, so a row without one is a row the keyboard cannot reach. It is
92
+ * stamped by `SelectContent` rather than asked of the caller, because the
93
+ * caller writing `<SelectItem item={x}/>` has no idea what its own ordinal is
94
+ * and would have to be told twice.
95
+ */
96
+ index?: number;
86
97
  }
87
98
  declare const SelectItem: React.ForwardRefExoticComponent<SelectItemProps & React.RefAttributes<HTMLDivElement>>;
88
99
  interface SelectValueTextProps {
@@ -103,8 +114,28 @@ interface SelectItemGroupProps {
103
114
  className?: string;
104
115
  }
105
116
  declare const SelectItemGroup: React.ForwardRefExoticComponent<SelectItemGroupProps & React.RefAttributes<HTMLDivElement>>;
106
- declare const SelectLabel: React.ForwardRefExoticComponent<RadixSelect.SelectLabelProps & React.RefAttributes<HTMLDivElement>>;
107
- declare const SelectItemText: React.ForwardRefExoticComponent<RadixSelect.SelectItemTextProps & React.RefAttributes<HTMLSpanElement>>;
117
+ declare const SelectLabel: _hanzogui_web.GuiComponent<Omit<_hanzogui_web.GetFinalProps<_hanzogui_web.TextNonStyleProps, _hanzogui_web.TextStylePropsBase, {
118
+ size?: _hanzogui_web.SizeTokens | _hanzogui_web.FontSizeTokens | undefined;
119
+ unstyled?: boolean | undefined;
120
+ }>, "scope"> & {
121
+ scope?: any;
122
+ }, _hanzogui_web.GuiTextElement, _hanzogui_web.TextNonStyleProps & {
123
+ scope?: any;
124
+ }, _hanzogui_web.TextStylePropsBase, {
125
+ size?: _hanzogui_web.SizeTokens | _hanzogui_web.FontSizeTokens | undefined;
126
+ unstyled?: boolean | undefined;
127
+ }, _hanzogui_web.StaticConfigPublic>;
128
+ declare const SelectItemText: _hanzogui_web.GuiComponent<Omit<_hanzogui_web.GetFinalProps<_hanzogui_web.TextNonStyleProps, _hanzogui_web.TextStylePropsBase, {
129
+ size?: _hanzogui_web.FontSizeTokens | undefined;
130
+ unstyled?: boolean | undefined;
131
+ }>, "scope"> & {
132
+ scope?: _hanzo_gui.SelectScopes;
133
+ }, _hanzogui_web.GuiTextElement, _hanzogui_web.TextNonStyleProps & {
134
+ scope?: _hanzo_gui.SelectScopes;
135
+ }, _hanzogui_web.TextStylePropsBase, {
136
+ size?: _hanzogui_web.FontSizeTokens | undefined;
137
+ unstyled?: boolean | undefined;
138
+ }, _hanzogui_web.StaticConfigPublic>;
108
139
  interface SelectProps extends SelectRootProps {
109
140
  collection: ListCollection<SelectOption>;
110
141
  placeholder: string;
package/dist/select.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import * as RadixSelect from '@radix-ui/react-select';
2
+ import { Select as Select$1 } from '@hanzo/gui';
3
3
  import { useDebounce } from '@uidotdev/usehooks';
4
4
  import * as React2 from 'react';
5
5
  import { clsx } from 'clsx';
@@ -310,16 +310,15 @@ var SelectRoot = React2.forwardRef(
310
310
  return s;
311
311
  }, [style, w, maxW, minW]);
312
312
  return /* @__PURE__ */ jsx(SelectInternalContext.Provider, { value: ctxValue, children: /* @__PURE__ */ jsx(
313
- RadixSelect.Root,
313
+ Select$1,
314
314
  {
315
315
  value: currentValue[0] ?? "",
316
316
  defaultValue: defaultValueArr?.[0],
317
317
  onValueChange: handleRadixValueChange,
318
318
  open: isOpen,
319
319
  onOpenChange: handleOpenChange,
320
- disabled: disabled || readOnly,
320
+ disablePreventBodyScroll: true,
321
321
  name,
322
- required,
323
322
  children: /* @__PURE__ */ jsx(
324
323
  "div",
325
324
  {
@@ -344,10 +343,11 @@ var SelectControl = React2.forwardRef(
344
343
  const isDefaultValue = Array.isArray(defaultValue) ? ctx.value.every((item) => defaultValue.includes(item)) : false;
345
344
  const { asChild, px: _px, className: triggerClassName, ...radixTriggerProps } = triggerProps ?? {};
346
345
  const trigger = /* @__PURE__ */ jsx(
347
- RadixSelect.Trigger,
346
+ Select$1.Trigger,
348
347
  {
349
348
  ref,
350
349
  asChild,
350
+ unstyled: true,
351
351
  className: cn(
352
352
  "group peer inline-flex items-center gap-2 cursor-pointer",
353
353
  "rounded-lg text-sm transition-colors outline-none",
@@ -396,41 +396,43 @@ var SelectClearTrigger = React2.forwardRef(
396
396
  }
397
397
  );
398
398
  var SelectContent = React2.forwardRef(
399
- function SelectContent2(props, ref) {
400
- const { portalled = true, portalRef, children, className, ...rest } = props;
401
- const content = /* @__PURE__ */ jsx(
402
- RadixSelect.Content,
403
- {
404
- ref,
405
- position: "popper",
406
- sideOffset: 4,
407
- className: cn(
408
- "z-50 min-w-[8rem] overflow-hidden rounded-lg",
409
- "bg-[var(--color-popover-bg)] shadow-[var(--shadow-popover)]",
410
- "border border-[var(--color-border-divider)]",
411
- "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
412
- "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
413
- className
414
- ),
415
- ...rest,
416
- children: /* @__PURE__ */ jsx(RadixSelect.Viewport, { className: "p-1", children })
417
- }
399
+ function SelectContent2(props, _ref) {
400
+ const { portalled: _portalled, portalRef: _portalRef, children, className, ...rest } = props;
401
+ let n = 0;
402
+ const counter = () => n++;
403
+ return (
404
+ // Content is the focus scope — it takes no style props at all. The
405
+ // Viewport is the box you can see, so the surface is declared there.
406
+ /* @__PURE__ */ jsx(Select$1.Content, { ...rest, children: /* @__PURE__ */ jsx(
407
+ Select$1.Viewport,
408
+ {
409
+ className: cn(
410
+ "min-w-[8rem] overflow-hidden rounded-lg p-1",
411
+ "bg-[var(--color-popover-bg)] shadow-[var(--shadow-popover)]",
412
+ "border border-[var(--color-border-divider)]",
413
+ className
414
+ ),
415
+ children: stampIndices(children, counter)
416
+ }
417
+ ) })
418
418
  );
419
- if (portalled) {
420
- return /* @__PURE__ */ jsx(RadixSelect.Portal, { container: portalRef?.current ?? void 0, children: content });
421
- }
422
- return content;
423
419
  }
424
420
  );
421
+ var stampIndices = (children, next) => React2.Children.map(children, (child) => {
422
+ if (!React2.isValidElement(child)) return child;
423
+ if (child.type === SelectItem) return React2.cloneElement(child, { index: next() });
424
+ const kids = child.props.children;
425
+ return kids === void 0 ? child : React2.cloneElement(child, void 0, stampIndices(kids, next));
426
+ });
425
427
  var SelectItem = React2.forwardRef(
426
428
  function SelectItem2(props, ref) {
427
- const { item, children, className, ...rest } = props;
429
+ const { item, children, className, index, ...rest } = props;
428
430
  return /* @__PURE__ */ jsxs(
429
- RadixSelect.Item,
431
+ Select$1.Item,
430
432
  {
431
433
  ref,
434
+ index: index ?? 0,
432
435
  value: item.value,
433
- textValue: item.label,
434
436
  className: cn(
435
437
  "relative flex cursor-pointer select-none items-center gap-2",
436
438
  "rounded-md px-3 py-2 text-sm outline-none",
@@ -443,8 +445,8 @@ var SelectItem = React2.forwardRef(
443
445
  ...rest,
444
446
  children: [
445
447
  item.icon,
446
- /* @__PURE__ */ jsx(RadixSelect.ItemText, { children }),
447
- /* @__PURE__ */ jsx(RadixSelect.ItemIndicator, { className: "ml-auto shrink-0", children: /* @__PURE__ */ jsx(CheckIcon, { className: "h-5 w-5" }) })
448
+ /* @__PURE__ */ jsx(Select$1.ItemText, { children: children ?? item.label }),
449
+ /* @__PURE__ */ jsx(Select$1.ItemIndicator, { className: "ml-auto shrink-0", children: /* @__PURE__ */ jsx(CheckIcon, { className: "h-5 w-5" }) })
448
450
  ]
449
451
  }
450
452
  );
@@ -495,7 +497,7 @@ var SelectValueText = React2.forwardRef(
495
497
  return `${items.length} selected`;
496
498
  })();
497
499
  return /* @__PURE__ */ jsx(
498
- RadixSelect.Value,
500
+ Select$1.Value,
499
501
  {
500
502
  ref,
501
503
  placeholder: placeholderText,
@@ -509,14 +511,14 @@ var SelectValueText = React2.forwardRef(
509
511
  var SelectItemGroup = React2.forwardRef(
510
512
  function SelectItemGroup2(props, ref) {
511
513
  const { children, label, className, ...rest } = props;
512
- return /* @__PURE__ */ jsxs(RadixSelect.Group, { ref, className: cn("py-1", className), ...rest, children: [
513
- /* @__PURE__ */ jsx(RadixSelect.Label, { className: "px-3 py-1.5 text-xs font-medium text-[var(--color-text-secondary)]", children: label }),
514
+ return /* @__PURE__ */ jsxs(Select$1.Group, { ref, className: cn("py-1", className), ...rest, children: [
515
+ /* @__PURE__ */ jsx(Select$1.Label, { className: "px-3 py-1.5 text-xs font-medium text-[var(--color-text-secondary)]", children: label }),
514
516
  children
515
517
  ] });
516
518
  }
517
519
  );
518
- var SelectLabel = RadixSelect.Label;
519
- var SelectItemText = RadixSelect.ItemText;
520
+ var SelectLabel = Select$1.Label;
521
+ var SelectItemText = Select$1.ItemText;
520
522
  var Select = React2.forwardRef((props, ref) => {
521
523
  const { collection, placeholder, portalled = true, loading, errorText, contentProps, contentHeader, itemFilter, mode, ...rest } = props;
522
524
  return /* @__PURE__ */ jsxs(
@@ -3,8 +3,6 @@
3
3
 
4
4
  var gui = require('@hanzo/gui');
5
5
  var React = require('react');
6
- var clsx = require('clsx');
7
- var tailwindMerge = require('tailwind-merge');
8
6
  var jsxRuntime = require('react/jsx-runtime');
9
7
 
10
8
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -12,44 +10,21 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
12
10
  var React__default = /*#__PURE__*/_interopDefault(React);
13
11
 
14
12
  // src/separator.tsx
15
- function cn(...inputs) {
16
- return tailwindMerge.twMerge(clsx.clsx(inputs));
17
- }
18
- var VARIANT_CLASSES = {
19
- solid: "border-solid",
20
- dashed: "border-dashed",
21
- dotted: "border-dotted"
22
- };
23
- var HORIZONTAL_SIZE_CLASSES = {
24
- xs: "border-t-[0.5px]",
25
- sm: "border-t",
26
- md: "border-t-2",
27
- lg: "border-t-[3px]"
28
- };
29
- var VERTICAL_SIZE_CLASSES = {
30
- xs: "border-l-[0.5px]",
31
- sm: "border-l",
32
- md: "border-l-2",
33
- lg: "border-l-[3px]"
34
- };
13
+ var WEIGHT = { xs: 0.5, sm: 1, md: 2, lg: 3 };
35
14
  var Separator = React__default.default.forwardRef(
36
- function Separator2({ orientation = "horizontal", variant = "solid", size = "sm", className, ...rest }, ref) {
37
- const isVertical = orientation === "vertical";
15
+ function Separator2({ orientation = "horizontal", variant = "solid", size = "sm", ...rest }, ref) {
16
+ const vertical = orientation === "vertical";
38
17
  return /* @__PURE__ */ jsxRuntime.jsx(
39
18
  gui.Separator,
40
19
  {
41
20
  ref,
42
- vertical: isVertical,
21
+ vertical,
43
22
  role: "separator",
44
23
  "aria-orientation": orientation,
45
- className: cn(
46
- "border-[var(--color-border-divider)]",
47
- "border-0",
48
- VARIANT_CLASSES[variant],
49
- isVertical ? VERTICAL_SIZE_CLASSES[size] : HORIZONTAL_SIZE_CLASSES[size],
50
- isVertical ? "self-stretch h-auto w-0" : "w-full",
51
- className
52
- ),
24
+ borderWidth: 0,
25
+ borderStyle: variant,
26
+ borderColor: "var(--color-border-divider)",
27
+ ...vertical ? { borderLeftWidth: WEIGHT[size], alignSelf: "stretch", height: "auto", width: 0 } : { borderTopWidth: WEIGHT[size], width: "100%" },
53
28
  ...rest
54
29
  }
55
30
  );