@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/separator.js CHANGED
@@ -1,49 +1,24 @@
1
1
  "use client";
2
2
  import { Separator as Separator$1 } from '@hanzo/gui';
3
3
  import React from 'react';
4
- import { clsx } from 'clsx';
5
- import { twMerge } from 'tailwind-merge';
6
4
  import { jsx } from 'react/jsx-runtime';
7
5
 
8
6
  // src/separator.tsx
9
- function cn(...inputs) {
10
- return twMerge(clsx(inputs));
11
- }
12
- var VARIANT_CLASSES = {
13
- solid: "border-solid",
14
- dashed: "border-dashed",
15
- dotted: "border-dotted"
16
- };
17
- var HORIZONTAL_SIZE_CLASSES = {
18
- xs: "border-t-[0.5px]",
19
- sm: "border-t",
20
- md: "border-t-2",
21
- lg: "border-t-[3px]"
22
- };
23
- var VERTICAL_SIZE_CLASSES = {
24
- xs: "border-l-[0.5px]",
25
- sm: "border-l",
26
- md: "border-l-2",
27
- lg: "border-l-[3px]"
28
- };
7
+ var WEIGHT = { xs: 0.5, sm: 1, md: 2, lg: 3 };
29
8
  var Separator = React.forwardRef(
30
- function Separator2({ orientation = "horizontal", variant = "solid", size = "sm", className, ...rest }, ref) {
31
- const isVertical = orientation === "vertical";
9
+ function Separator2({ orientation = "horizontal", variant = "solid", size = "sm", ...rest }, ref) {
10
+ const vertical = orientation === "vertical";
32
11
  return /* @__PURE__ */ jsx(
33
12
  Separator$1,
34
13
  {
35
14
  ref,
36
- vertical: isVertical,
15
+ vertical,
37
16
  role: "separator",
38
17
  "aria-orientation": orientation,
39
- className: cn(
40
- "border-[var(--color-border-divider)]",
41
- "border-0",
42
- VARIANT_CLASSES[variant],
43
- isVertical ? VERTICAL_SIZE_CLASSES[size] : HORIZONTAL_SIZE_CLASSES[size],
44
- isVertical ? "self-stretch h-auto w-0" : "w-full",
45
- className
46
- ),
18
+ borderWidth: 0,
19
+ borderStyle: variant,
20
+ borderColor: "var(--color-border-divider)",
21
+ ...vertical ? { borderLeftWidth: WEIGHT[size], alignSelf: "stretch", height: "auto", width: 0 } : { borderTopWidth: WEIGHT[size], width: "100%" },
47
22
  ...rest
48
23
  }
49
24
  );
package/dist/slider.cjs CHANGED
@@ -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 _interopNamespace(e) {
@@ -28,9 +26,11 @@ function _interopNamespace(e) {
28
26
  var React__namespace = /*#__PURE__*/_interopNamespace(React);
29
27
 
30
28
  // src/slider.tsx
31
- function cn(...inputs) {
32
- return tailwindMerge.twMerge(clsx.clsx(inputs));
33
- }
29
+ var MUTED = "var(--color-text-secondary)";
30
+ var TRACK = "var(--color-border-divider)";
31
+ var ACTIVE = "var(--color-link-primary)";
32
+ var ACTIVE_HOVER = "var(--color-link-primary-hover)";
33
+ var WHITE = "var(--color-white)";
34
34
  var Slider = React__namespace.forwardRef(
35
35
  function Slider2(props, ref) {
36
36
  const {
@@ -63,21 +63,23 @@ var Slider = React__namespace.forwardRef(
63
63
  const handleSlideEnd = React__namespace.useCallback(() => {
64
64
  onValueCommit?.(latest.current);
65
65
  }, [onValueCommit]);
66
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-1", className), children: [
67
- label && !showValue && /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium text-text-secondary", children: label }),
68
- label && showValue && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
69
- /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium text-text-secondary", children: label }),
70
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-text-secondary", children: (value ?? defaultValue ?? [])?.join(", ") })
66
+ return /* @__PURE__ */ jsxRuntime.jsxs(gui.YStack, { className, gap: 4, children: [
67
+ label && !showValue && /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: 14, fontWeight: "500", color: MUTED, children: label }),
68
+ label && showValue && /* @__PURE__ */ jsxRuntime.jsxs(gui.XStack, { alignItems: "center", justifyContent: "space-between", children: [
69
+ /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: 14, fontWeight: "500", color: MUTED, children: label }),
70
+ /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: 14, color: MUTED, children: (value ?? defaultValue ?? [])?.join(", ") })
71
71
  ] }),
72
72
  /* @__PURE__ */ jsxRuntime.jsxs(
73
73
  gui.Slider,
74
74
  {
75
75
  ref,
76
76
  unstyled: true,
77
- className: cn(
78
- "relative flex w-full touch-none select-none items-center",
79
- hasMarkLabel && "mb-6"
80
- ),
77
+ position: "relative",
78
+ flexDirection: "row",
79
+ width: "100%",
80
+ userSelect: "none",
81
+ alignItems: "center",
82
+ marginBottom: hasMarkLabel ? 24 : 0,
81
83
  value,
82
84
  defaultValue,
83
85
  min,
@@ -89,33 +91,23 @@ var Slider = React__namespace.forwardRef(
89
91
  onValueChange: handleValueChange,
90
92
  onSlideEnd: handleSlideEnd,
91
93
  children: [
92
- /* @__PURE__ */ jsxRuntime.jsx(
93
- gui.Slider.Track,
94
- {
95
- unstyled: true,
96
- className: "relative grow h-1.5 rounded-full bg-border-divider",
97
- children: /* @__PURE__ */ jsxRuntime.jsx(
98
- gui.Slider.TrackActive,
99
- {
100
- unstyled: true,
101
- className: "absolute h-full rounded-full bg-link-primary"
102
- }
103
- )
104
- }
105
- ),
94
+ /* @__PURE__ */ jsxRuntime.jsx(gui.Slider.Track, { unstyled: true, position: "relative", flexGrow: 1, height: 6, borderRadius: 9999, backgroundColor: TRACK, children: /* @__PURE__ */ jsxRuntime.jsx(gui.Slider.TrackActive, { unstyled: true, position: "absolute", height: "100%", borderRadius: 9999, backgroundColor: ACTIVE }) }),
106
95
  resolvedValue?.map((_, index) => /* @__PURE__ */ jsxRuntime.jsx(
107
96
  gui.Slider.Thumb,
108
97
  {
109
98
  index,
110
99
  unstyled: true,
111
- className: cn(
112
- "block h-5 w-5",
113
- "rounded-full border-2 border-link-primary bg-white",
114
- "shadow-sm transition-colors",
115
- "hover:border-link-primary-hover",
116
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-link-primary focus-visible:ring-offset-2",
117
- "disabled:pointer-events-none disabled:opacity-50"
118
- )
100
+ width: 20,
101
+ height: 20,
102
+ borderRadius: 9999,
103
+ borderWidth: 2,
104
+ borderColor: ACTIVE,
105
+ backgroundColor: WHITE,
106
+ boxShadow: "0 1px 2px 0 rgba(0,0,0,0.05)",
107
+ transition: "quick",
108
+ hoverStyle: { borderColor: ACTIVE_HOVER },
109
+ focusStyle: { outlineWidth: 2, outlineStyle: "solid", outlineColor: ACTIVE, outlineOffset: 2 },
110
+ disabledStyle: { pointerEvents: "none", opacity: 0.5 }
119
111
  },
120
112
  index
121
113
  ))
@@ -130,20 +122,12 @@ function SliderMarks(props) {
130
122
  const { marks, min, max } = props;
131
123
  if (!marks?.length) return null;
132
124
  const range = max - min;
133
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative w-full h-4", children: marks.map((mark, index) => {
125
+ return /* @__PURE__ */ jsxRuntime.jsx(gui.View, { position: "relative", width: "100%", height: 16, children: marks.map((mark, index) => {
134
126
  const percent = (mark.value - min) / range * 100;
135
- return /* @__PURE__ */ jsxRuntime.jsxs(
136
- "div",
137
- {
138
- className: "absolute flex flex-col items-center -translate-x-1/2",
139
- style: { left: `${percent}%` },
140
- children: [
141
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-1.5 w-0.5 bg-border-divider" }),
142
- mark.label != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mt-0.5 text-xs text-text-secondary whitespace-nowrap", children: mark.label })
143
- ]
144
- },
145
- index
146
- );
127
+ return /* @__PURE__ */ jsxRuntime.jsxs(gui.View, { position: "absolute", left: `${percent}%`, alignItems: "center", children: [
128
+ /* @__PURE__ */ jsxRuntime.jsx(gui.View, { width: 2, height: 6, backgroundColor: TRACK }),
129
+ mark.label != null && /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { marginTop: 2, fontSize: 12, color: MUTED, children: mark.label })
130
+ ] }, index);
147
131
  }) });
148
132
  }
149
133
 
package/dist/slider.js CHANGED
@@ -1,14 +1,14 @@
1
1
  "use client";
2
- import { Slider as Slider$1 } from '@hanzo/gui';
2
+ import { YStack, Text, XStack, Slider as Slider$1, View } from '@hanzo/gui';
3
3
  import * as React from 'react';
4
- import { clsx } from 'clsx';
5
- import { twMerge } from 'tailwind-merge';
6
4
  import { jsxs, jsx } from 'react/jsx-runtime';
7
5
 
8
6
  // src/slider.tsx
9
- function cn(...inputs) {
10
- return twMerge(clsx(inputs));
11
- }
7
+ var MUTED = "var(--color-text-secondary)";
8
+ var TRACK = "var(--color-border-divider)";
9
+ var ACTIVE = "var(--color-link-primary)";
10
+ var ACTIVE_HOVER = "var(--color-link-primary-hover)";
11
+ var WHITE = "var(--color-white)";
12
12
  var Slider = React.forwardRef(
13
13
  function Slider2(props, ref) {
14
14
  const {
@@ -41,21 +41,23 @@ var Slider = React.forwardRef(
41
41
  const handleSlideEnd = React.useCallback(() => {
42
42
  onValueCommit?.(latest.current);
43
43
  }, [onValueCommit]);
44
- return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-1", className), children: [
45
- label && !showValue && /* @__PURE__ */ jsx("label", { className: "text-sm font-medium text-text-secondary", children: label }),
46
- label && showValue && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
47
- /* @__PURE__ */ jsx("label", { className: "text-sm font-medium text-text-secondary", children: label }),
48
- /* @__PURE__ */ jsx("span", { className: "text-sm text-text-secondary", children: (value ?? defaultValue ?? [])?.join(", ") })
44
+ return /* @__PURE__ */ jsxs(YStack, { className, gap: 4, children: [
45
+ label && !showValue && /* @__PURE__ */ jsx(Text, { fontSize: 14, fontWeight: "500", color: MUTED, children: label }),
46
+ label && showValue && /* @__PURE__ */ jsxs(XStack, { alignItems: "center", justifyContent: "space-between", children: [
47
+ /* @__PURE__ */ jsx(Text, { fontSize: 14, fontWeight: "500", color: MUTED, children: label }),
48
+ /* @__PURE__ */ jsx(Text, { fontSize: 14, color: MUTED, children: (value ?? defaultValue ?? [])?.join(", ") })
49
49
  ] }),
50
50
  /* @__PURE__ */ jsxs(
51
51
  Slider$1,
52
52
  {
53
53
  ref,
54
54
  unstyled: true,
55
- className: cn(
56
- "relative flex w-full touch-none select-none items-center",
57
- hasMarkLabel && "mb-6"
58
- ),
55
+ position: "relative",
56
+ flexDirection: "row",
57
+ width: "100%",
58
+ userSelect: "none",
59
+ alignItems: "center",
60
+ marginBottom: hasMarkLabel ? 24 : 0,
59
61
  value,
60
62
  defaultValue,
61
63
  min,
@@ -67,33 +69,23 @@ var Slider = React.forwardRef(
67
69
  onValueChange: handleValueChange,
68
70
  onSlideEnd: handleSlideEnd,
69
71
  children: [
70
- /* @__PURE__ */ jsx(
71
- Slider$1.Track,
72
- {
73
- unstyled: true,
74
- className: "relative grow h-1.5 rounded-full bg-border-divider",
75
- children: /* @__PURE__ */ jsx(
76
- Slider$1.TrackActive,
77
- {
78
- unstyled: true,
79
- className: "absolute h-full rounded-full bg-link-primary"
80
- }
81
- )
82
- }
83
- ),
72
+ /* @__PURE__ */ jsx(Slider$1.Track, { unstyled: true, position: "relative", flexGrow: 1, height: 6, borderRadius: 9999, backgroundColor: TRACK, children: /* @__PURE__ */ jsx(Slider$1.TrackActive, { unstyled: true, position: "absolute", height: "100%", borderRadius: 9999, backgroundColor: ACTIVE }) }),
84
73
  resolvedValue?.map((_, index) => /* @__PURE__ */ jsx(
85
74
  Slider$1.Thumb,
86
75
  {
87
76
  index,
88
77
  unstyled: true,
89
- className: cn(
90
- "block h-5 w-5",
91
- "rounded-full border-2 border-link-primary bg-white",
92
- "shadow-sm transition-colors",
93
- "hover:border-link-primary-hover",
94
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-link-primary focus-visible:ring-offset-2",
95
- "disabled:pointer-events-none disabled:opacity-50"
96
- )
78
+ width: 20,
79
+ height: 20,
80
+ borderRadius: 9999,
81
+ borderWidth: 2,
82
+ borderColor: ACTIVE,
83
+ backgroundColor: WHITE,
84
+ boxShadow: "0 1px 2px 0 rgba(0,0,0,0.05)",
85
+ transition: "quick",
86
+ hoverStyle: { borderColor: ACTIVE_HOVER },
87
+ focusStyle: { outlineWidth: 2, outlineStyle: "solid", outlineColor: ACTIVE, outlineOffset: 2 },
88
+ disabledStyle: { pointerEvents: "none", opacity: 0.5 }
97
89
  },
98
90
  index
99
91
  ))
@@ -108,20 +100,12 @@ function SliderMarks(props) {
108
100
  const { marks, min, max } = props;
109
101
  if (!marks?.length) return null;
110
102
  const range = max - min;
111
- return /* @__PURE__ */ jsx("div", { className: "relative w-full h-4", children: marks.map((mark, index) => {
103
+ return /* @__PURE__ */ jsx(View, { position: "relative", width: "100%", height: 16, children: marks.map((mark, index) => {
112
104
  const percent = (mark.value - min) / range * 100;
113
- return /* @__PURE__ */ jsxs(
114
- "div",
115
- {
116
- className: "absolute flex flex-col items-center -translate-x-1/2",
117
- style: { left: `${percent}%` },
118
- children: [
119
- /* @__PURE__ */ jsx("div", { className: "h-1.5 w-0.5 bg-border-divider" }),
120
- mark.label != null && /* @__PURE__ */ jsx("span", { className: "mt-0.5 text-xs text-text-secondary whitespace-nowrap", children: mark.label })
121
- ]
122
- },
123
- index
124
- );
105
+ return /* @__PURE__ */ jsxs(View, { position: "absolute", left: `${percent}%`, alignItems: "center", children: [
106
+ /* @__PURE__ */ jsx(View, { width: 2, height: 6, backgroundColor: TRACK }),
107
+ mark.label != null && /* @__PURE__ */ jsx(Text, { marginTop: 2, fontSize: 12, color: MUTED, children: mark.label })
108
+ ] }, index);
125
109
  }) });
126
110
  }
127
111
 
package/dist/switch.cjs CHANGED
@@ -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 _interopNamespace(e) {
@@ -28,28 +26,17 @@ function _interopNamespace(e) {
28
26
  var React__namespace = /*#__PURE__*/_interopNamespace(React);
29
27
 
30
28
  // src/switch.tsx
31
- function cn(...inputs) {
32
- return tailwindMerge.twMerge(clsx.clsx(inputs));
33
- }
34
29
  var NOOP = () => {
35
30
  };
36
- var SIZE_CLASSES = {
37
- sm: {
38
- root: "h-4 w-7",
39
- thumb: "h-3 w-3",
40
- label: "text-xs"
41
- },
42
- md: {
43
- root: "h-5 w-9",
44
- thumb: "h-4 w-4",
45
- label: "text-sm"
46
- },
47
- lg: {
48
- root: "h-6 w-11",
49
- thumb: "h-5 w-5",
50
- label: "text-base"
51
- }
31
+ var SIZE = {
32
+ sm: { width: 28, height: 16, thumb: 12, label: 12 },
33
+ md: { width: 36, height: 20, thumb: 16, label: 14 },
34
+ lg: { width: 44, height: 24, thumb: 20, label: 16 }
52
35
  };
36
+ var TRACK_ON = "var(--color-text-primary)";
37
+ var TRACK_OFF = "var(--color-switch-bg)";
38
+ var OUTLINE = "var(--color-gray-500)";
39
+ var WHITE = "var(--color-white)";
53
40
  var SwitchBase = React__namespace.forwardRef(
54
41
  function Switch(props, ref) {
55
42
  const {
@@ -66,7 +53,6 @@ var SwitchBase = React__namespace.forwardRef(
66
53
  disabled = false,
67
54
  size = "md",
68
55
  direction,
69
- className,
70
56
  ...rest
71
57
  } = props;
72
58
  const [internalChecked, setInternalChecked] = React__namespace.useState(defaultChecked ?? false);
@@ -81,18 +67,19 @@ var SwitchBase = React__namespace.forwardRef(
81
67
  },
82
68
  [isControlled, onCheckedChange]
83
69
  );
84
- const sizeClasses = SIZE_CLASSES[size];
70
+ const s = SIZE[size];
85
71
  const isRtl = direction === "rtl";
86
72
  return /* @__PURE__ */ jsxRuntime.jsxs(
87
- "label",
73
+ gui.Label,
88
74
  {
89
75
  ref: rootRef,
90
- className: cn(
91
- "inline-flex items-center cursor-pointer select-none gap-2",
92
- isRtl && "flex-row-reverse",
93
- disabled && "opacity-50 cursor-not-allowed",
94
- className
95
- ),
76
+ unstyled: true,
77
+ flexDirection: isRtl ? "row-reverse" : "row",
78
+ alignItems: "center",
79
+ gap: 8,
80
+ cursor: disabled ? "not-allowed" : "pointer",
81
+ userSelect: "none",
82
+ opacity: disabled ? 0.5 : 1,
96
83
  onChange,
97
84
  "data-disabled": disabled || void 0,
98
85
  ...rest,
@@ -104,38 +91,51 @@ var SwitchBase = React__namespace.forwardRef(
104
91
  checked: checkedState,
105
92
  onCheckedChange: handleCheckedChange,
106
93
  disabled,
107
- className: cn(
108
- "relative inline-flex shrink-0 items-center rounded-full",
109
- "bg-gray-300 dark:bg-gray-600",
110
- "data-[state=checked]:bg-gray-800 dark:bg-white",
111
- "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-500",
112
- "transition-colors duration-200",
113
- sizeClasses.root
114
- ),
94
+ position: "relative",
95
+ flexShrink: 0,
96
+ alignItems: "center",
97
+ width: s.width,
98
+ height: s.height,
99
+ borderRadius: 9999,
100
+ backgroundColor: checkedState ? TRACK_ON : TRACK_OFF,
101
+ transition: "quick",
102
+ focusStyle: { outlineWidth: 2, outlineStyle: "solid", outlineColor: OUTLINE, outlineOffset: 2 },
115
103
  children: [
116
- trackLabel && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute inset-0 flex items-center justify-center text-[8px] font-bold text-white pointer-events-none", children: checkedState ? trackLabel.on : trackLabel.off }),
104
+ trackLabel && /* @__PURE__ */ jsxRuntime.jsx(
105
+ gui.Text,
106
+ {
107
+ position: "absolute",
108
+ width: "100%",
109
+ textAlign: "center",
110
+ fontSize: 8,
111
+ fontWeight: "700",
112
+ color: WHITE,
113
+ pointerEvents: "none",
114
+ children: checkedState ? trackLabel.on : trackLabel.off
115
+ }
116
+ ),
117
117
  /* @__PURE__ */ jsxRuntime.jsx(
118
118
  gui.Switch.Thumb,
119
119
  {
120
120
  unstyled: true,
121
121
  "data-thumb": true,
122
122
  transition: "quicker",
123
- className: cn(
124
- "block rounded-full bg-white shadow-sm",
125
- sizeClasses.thumb
126
- ),
127
- children: thumbLabel && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex items-center justify-center h-full w-full text-[8px]", children: checkedState ? thumbLabel.on : thumbLabel.off })
123
+ width: s.thumb,
124
+ height: s.thumb,
125
+ borderRadius: 9999,
126
+ backgroundColor: WHITE,
127
+ boxShadow: "0 1px 2px 0 rgba(0,0,0,0.05)",
128
+ children: thumbLabel && /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { width: "100%", height: "100%", textAlign: "center", fontSize: 8, children: checkedState ? thumbLabel.on : thumbLabel.off })
128
129
  }
129
130
  )
130
131
  ]
131
132
  }
132
133
  ),
133
- /* @__PURE__ */ jsxRuntime.jsx(
134
+ /* @__PURE__ */ jsxRuntime.jsx(gui.VisuallyHidden, { children: /* @__PURE__ */ jsxRuntime.jsx(
134
135
  "input",
135
136
  {
136
137
  ref,
137
138
  type: "checkbox",
138
- className: "sr-only",
139
139
  checked: checkedState,
140
140
  disabled,
141
141
  tabIndex: -1,
@@ -143,15 +143,8 @@ var SwitchBase = React__namespace.forwardRef(
143
143
  onChange: NOOP,
144
144
  ...inputProps
145
145
  }
146
- ),
147
- children != null && /* @__PURE__ */ jsxRuntime.jsx(
148
- "span",
149
- {
150
- ...labelProps,
151
- className: cn(sizeClasses.label, labelProps?.className),
152
- children
153
- }
154
- )
146
+ ) }),
147
+ children != null && /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { ...labelProps, fontSize: s.label, children })
155
148
  ]
156
149
  }
157
150
  );
package/dist/switch.js CHANGED
@@ -1,33 +1,20 @@
1
1
  "use client";
2
- import { Switch } from '@hanzo/gui';
2
+ import { Label, Switch, Text, VisuallyHidden } from '@hanzo/gui';
3
3
  import * as React from 'react';
4
- import { clsx } from 'clsx';
5
- import { twMerge } from 'tailwind-merge';
6
4
  import { jsxs, jsx } from 'react/jsx-runtime';
7
5
 
8
6
  // src/switch.tsx
9
- function cn(...inputs) {
10
- return twMerge(clsx(inputs));
11
- }
12
7
  var NOOP = () => {
13
8
  };
14
- var SIZE_CLASSES = {
15
- sm: {
16
- root: "h-4 w-7",
17
- thumb: "h-3 w-3",
18
- label: "text-xs"
19
- },
20
- md: {
21
- root: "h-5 w-9",
22
- thumb: "h-4 w-4",
23
- label: "text-sm"
24
- },
25
- lg: {
26
- root: "h-6 w-11",
27
- thumb: "h-5 w-5",
28
- label: "text-base"
29
- }
9
+ var SIZE = {
10
+ sm: { width: 28, height: 16, thumb: 12, label: 12 },
11
+ md: { width: 36, height: 20, thumb: 16, label: 14 },
12
+ lg: { width: 44, height: 24, thumb: 20, label: 16 }
30
13
  };
14
+ var TRACK_ON = "var(--color-text-primary)";
15
+ var TRACK_OFF = "var(--color-switch-bg)";
16
+ var OUTLINE = "var(--color-gray-500)";
17
+ var WHITE = "var(--color-white)";
31
18
  var SwitchBase = React.forwardRef(
32
19
  function Switch$1(props, ref) {
33
20
  const {
@@ -44,7 +31,6 @@ var SwitchBase = React.forwardRef(
44
31
  disabled = false,
45
32
  size = "md",
46
33
  direction,
47
- className,
48
34
  ...rest
49
35
  } = props;
50
36
  const [internalChecked, setInternalChecked] = React.useState(defaultChecked ?? false);
@@ -59,18 +45,19 @@ var SwitchBase = React.forwardRef(
59
45
  },
60
46
  [isControlled, onCheckedChange]
61
47
  );
62
- const sizeClasses = SIZE_CLASSES[size];
48
+ const s = SIZE[size];
63
49
  const isRtl = direction === "rtl";
64
50
  return /* @__PURE__ */ jsxs(
65
- "label",
51
+ Label,
66
52
  {
67
53
  ref: rootRef,
68
- className: cn(
69
- "inline-flex items-center cursor-pointer select-none gap-2",
70
- isRtl && "flex-row-reverse",
71
- disabled && "opacity-50 cursor-not-allowed",
72
- className
73
- ),
54
+ unstyled: true,
55
+ flexDirection: isRtl ? "row-reverse" : "row",
56
+ alignItems: "center",
57
+ gap: 8,
58
+ cursor: disabled ? "not-allowed" : "pointer",
59
+ userSelect: "none",
60
+ opacity: disabled ? 0.5 : 1,
74
61
  onChange,
75
62
  "data-disabled": disabled || void 0,
76
63
  ...rest,
@@ -82,38 +69,51 @@ var SwitchBase = React.forwardRef(
82
69
  checked: checkedState,
83
70
  onCheckedChange: handleCheckedChange,
84
71
  disabled,
85
- className: cn(
86
- "relative inline-flex shrink-0 items-center rounded-full",
87
- "bg-gray-300 dark:bg-gray-600",
88
- "data-[state=checked]:bg-gray-800 dark:bg-white",
89
- "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-500",
90
- "transition-colors duration-200",
91
- sizeClasses.root
92
- ),
72
+ position: "relative",
73
+ flexShrink: 0,
74
+ alignItems: "center",
75
+ width: s.width,
76
+ height: s.height,
77
+ borderRadius: 9999,
78
+ backgroundColor: checkedState ? TRACK_ON : TRACK_OFF,
79
+ transition: "quick",
80
+ focusStyle: { outlineWidth: 2, outlineStyle: "solid", outlineColor: OUTLINE, outlineOffset: 2 },
93
81
  children: [
94
- trackLabel && /* @__PURE__ */ jsx("span", { className: "absolute inset-0 flex items-center justify-center text-[8px] font-bold text-white pointer-events-none", children: checkedState ? trackLabel.on : trackLabel.off }),
82
+ trackLabel && /* @__PURE__ */ jsx(
83
+ Text,
84
+ {
85
+ position: "absolute",
86
+ width: "100%",
87
+ textAlign: "center",
88
+ fontSize: 8,
89
+ fontWeight: "700",
90
+ color: WHITE,
91
+ pointerEvents: "none",
92
+ children: checkedState ? trackLabel.on : trackLabel.off
93
+ }
94
+ ),
95
95
  /* @__PURE__ */ jsx(
96
96
  Switch.Thumb,
97
97
  {
98
98
  unstyled: true,
99
99
  "data-thumb": true,
100
100
  transition: "quicker",
101
- className: cn(
102
- "block rounded-full bg-white shadow-sm",
103
- sizeClasses.thumb
104
- ),
105
- children: thumbLabel && /* @__PURE__ */ jsx("span", { className: "flex items-center justify-center h-full w-full text-[8px]", children: checkedState ? thumbLabel.on : thumbLabel.off })
101
+ width: s.thumb,
102
+ height: s.thumb,
103
+ borderRadius: 9999,
104
+ backgroundColor: WHITE,
105
+ boxShadow: "0 1px 2px 0 rgba(0,0,0,0.05)",
106
+ children: thumbLabel && /* @__PURE__ */ jsx(Text, { width: "100%", height: "100%", textAlign: "center", fontSize: 8, children: checkedState ? thumbLabel.on : thumbLabel.off })
106
107
  }
107
108
  )
108
109
  ]
109
110
  }
110
111
  ),
111
- /* @__PURE__ */ jsx(
112
+ /* @__PURE__ */ jsx(VisuallyHidden, { children: /* @__PURE__ */ jsx(
112
113
  "input",
113
114
  {
114
115
  ref,
115
116
  type: "checkbox",
116
- className: "sr-only",
117
117
  checked: checkedState,
118
118
  disabled,
119
119
  tabIndex: -1,
@@ -121,15 +121,8 @@ var SwitchBase = React.forwardRef(
121
121
  onChange: NOOP,
122
122
  ...inputProps
123
123
  }
124
- ),
125
- children != null && /* @__PURE__ */ jsx(
126
- "span",
127
- {
128
- ...labelProps,
129
- className: cn(sizeClasses.label, labelProps?.className),
130
- children
131
- }
132
- )
124
+ ) }),
125
+ children != null && /* @__PURE__ */ jsx(Text, { ...labelProps, fontSize: s.label, children })
133
126
  ]
134
127
  }
135
128
  );