@luxfi/ui 6.1.2 → 7.0.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 (240) hide show
  1. package/dist/accordion.cjs +213 -0
  2. package/dist/accordion.d.cts +74 -0
  3. package/dist/accordion.d.ts +74 -0
  4. package/dist/accordion.js +186 -0
  5. package/dist/alert.cjs +553 -0
  6. package/dist/alert.d.cts +30 -0
  7. package/dist/alert.d.ts +30 -0
  8. package/dist/alert.js +531 -0
  9. package/dist/avatar.cjs +149 -0
  10. package/dist/avatar.d.cts +25 -0
  11. package/dist/avatar.d.ts +25 -0
  12. package/dist/avatar.js +125 -0
  13. package/dist/badge.cjs +611 -0
  14. package/dist/badge.d.cts +23 -0
  15. package/dist/badge.d.ts +23 -0
  16. package/dist/badge.js +589 -0
  17. package/dist/bank.cjs +272 -0
  18. package/dist/bank.d.cts +76 -0
  19. package/dist/bank.d.ts +76 -0
  20. package/dist/bank.js +258 -0
  21. package/dist/button.cjs +689 -0
  22. package/dist/button.d.cts +52 -0
  23. package/dist/button.d.ts +52 -0
  24. package/dist/button.js +664 -0
  25. package/dist/checkbox.cjs +265 -0
  26. package/dist/checkbox.d.cts +31 -0
  27. package/dist/checkbox.d.ts +31 -0
  28. package/dist/checkbox.js +241 -0
  29. package/dist/close-button.cjs +73 -0
  30. package/dist/close-button.d.cts +9 -0
  31. package/dist/close-button.d.ts +9 -0
  32. package/dist/close-button.js +51 -0
  33. package/dist/collapsible.cjs +702 -0
  34. package/dist/collapsible.d.cts +23 -0
  35. package/dist/collapsible.d.ts +23 -0
  36. package/dist/collapsible.js +679 -0
  37. package/dist/color-mode.cjs +96 -0
  38. package/dist/color-mode.d.cts +25 -0
  39. package/dist/color-mode.d.ts +25 -0
  40. package/dist/color-mode.js +72 -0
  41. package/dist/dialog.cjs +279 -0
  42. package/dist/dialog.d.cts +66 -0
  43. package/dist/dialog.d.ts +66 -0
  44. package/dist/dialog.js +246 -0
  45. package/dist/drawer.cjs +207 -0
  46. package/dist/drawer.d.cts +36 -0
  47. package/dist/drawer.d.ts +36 -0
  48. package/dist/drawer.js +175 -0
  49. package/dist/empty-state.cjs +93 -0
  50. package/dist/empty-state.d.cts +13 -0
  51. package/dist/empty-state.d.ts +13 -0
  52. package/dist/empty-state.js +71 -0
  53. package/dist/expiration-selector.cjs +138 -0
  54. package/dist/expiration-selector.d.cts +16 -0
  55. package/dist/expiration-selector.d.ts +16 -0
  56. package/dist/expiration-selector.js +116 -0
  57. package/dist/field.cjs +183 -0
  58. package/dist/field.d.cts +24 -0
  59. package/dist/field.d.ts +24 -0
  60. package/dist/field.js +160 -0
  61. package/dist/greeks-display.cjs +114 -0
  62. package/dist/greeks-display.d.cts +14 -0
  63. package/dist/greeks-display.d.ts +14 -0
  64. package/dist/greeks-display.js +92 -0
  65. package/dist/heading.cjs +46 -0
  66. package/dist/heading.d.cts +10 -0
  67. package/dist/heading.d.ts +10 -0
  68. package/dist/heading.js +40 -0
  69. package/dist/icon-button.cjs +491 -0
  70. package/dist/icon-button.d.cts +33 -0
  71. package/dist/icon-button.d.ts +33 -0
  72. package/dist/icon-button.js +470 -0
  73. package/dist/image.cjs +572 -0
  74. package/dist/image.d.cts +57 -0
  75. package/dist/image.d.ts +57 -0
  76. package/dist/image.js +551 -0
  77. package/dist/index.cjs +7316 -0
  78. package/dist/index.d.cts +58 -0
  79. package/dist/index.d.ts +58 -0
  80. package/dist/index.js +7137 -0
  81. package/dist/input-group.cjs +155 -0
  82. package/dist/input-group.d.cts +17 -0
  83. package/dist/input-group.d.ts +17 -0
  84. package/dist/input-group.js +133 -0
  85. package/dist/input.cjs +65 -0
  86. package/dist/input.d.cts +11 -0
  87. package/dist/input.d.ts +11 -0
  88. package/dist/input.js +59 -0
  89. package/dist/link.cjs +630 -0
  90. package/dist/link.d.cts +37 -0
  91. package/dist/link.d.ts +37 -0
  92. package/dist/link.js +606 -0
  93. package/dist/menu.cjs +305 -0
  94. package/dist/menu.d.cts +84 -0
  95. package/dist/menu.d.ts +84 -0
  96. package/dist/menu.js +269 -0
  97. package/dist/option-chain.cjs +221 -0
  98. package/dist/option-chain.d.cts +37 -0
  99. package/dist/option-chain.d.ts +37 -0
  100. package/dist/option-chain.js +199 -0
  101. package/dist/option-position.cjs +164 -0
  102. package/dist/option-position.d.cts +29 -0
  103. package/dist/option-position.d.ts +29 -0
  104. package/dist/option-position.js +142 -0
  105. package/dist/pin-input.cjs +182 -0
  106. package/dist/pin-input.d.cts +25 -0
  107. package/dist/pin-input.d.ts +25 -0
  108. package/dist/pin-input.js +160 -0
  109. package/dist/pnl-diagram.cjs +453 -0
  110. package/dist/pnl-diagram.d.cts +11 -0
  111. package/dist/pnl-diagram.d.ts +11 -0
  112. package/dist/pnl-diagram.js +431 -0
  113. package/dist/popover.cjs +327 -0
  114. package/dist/popover.d.cts +73 -0
  115. package/dist/popover.d.ts +73 -0
  116. package/dist/popover.js +294 -0
  117. package/dist/progress-circle.cjs +152 -0
  118. package/dist/progress-circle.d.cts +47 -0
  119. package/dist/progress-circle.d.ts +47 -0
  120. package/dist/progress-circle.js +128 -0
  121. package/dist/progress.cjs +117 -0
  122. package/dist/progress.d.cts +28 -0
  123. package/dist/progress.d.ts +28 -0
  124. package/dist/progress.js +94 -0
  125. package/dist/provider.cjs +62 -0
  126. package/dist/provider.d.cts +7 -0
  127. package/dist/provider.d.ts +7 -0
  128. package/dist/provider.js +40 -0
  129. package/dist/radio.cjs +177 -0
  130. package/dist/radio.d.cts +53 -0
  131. package/dist/radio.d.ts +53 -0
  132. package/dist/radio.js +153 -0
  133. package/dist/rating.cjs +80 -0
  134. package/dist/rating.d.cts +14 -0
  135. package/dist/rating.d.ts +14 -0
  136. package/dist/rating.js +58 -0
  137. package/dist/select.cjs +791 -0
  138. package/dist/select.d.cts +130 -0
  139. package/dist/select.d.ts +130 -0
  140. package/dist/select.js +757 -0
  141. package/dist/separator.cjs +57 -0
  142. package/dist/separator.d.cts +13 -0
  143. package/dist/separator.d.ts +13 -0
  144. package/dist/separator.js +51 -0
  145. package/dist/skeleton.cjs +370 -0
  146. package/dist/skeleton.d.cts +60 -0
  147. package/dist/skeleton.d.ts +60 -0
  148. package/dist/skeleton.js +346 -0
  149. package/dist/slider.cjs +138 -0
  150. package/dist/slider.d.cts +24 -0
  151. package/dist/slider.d.ts +24 -0
  152. package/dist/slider.js +115 -0
  153. package/dist/strategy-builder.cjs +373 -0
  154. package/dist/strategy-builder.d.cts +26 -0
  155. package/dist/strategy-builder.d.ts +26 -0
  156. package/dist/strategy-builder.js +351 -0
  157. package/dist/switch.cjs +163 -0
  158. package/dist/switch.d.cts +27 -0
  159. package/dist/switch.d.ts +27 -0
  160. package/dist/switch.js +140 -0
  161. package/dist/table.cjs +1044 -0
  162. package/dist/table.d.cts +107 -0
  163. package/dist/table.d.ts +107 -0
  164. package/dist/table.js +1013 -0
  165. package/dist/tabs.cjs +240 -0
  166. package/dist/tabs.d.cts +78 -0
  167. package/dist/tabs.d.ts +78 -0
  168. package/dist/tabs.js +213 -0
  169. package/dist/tag.cjs +651 -0
  170. package/dist/tag.d.cts +21 -0
  171. package/dist/tag.d.ts +21 -0
  172. package/dist/tag.js +628 -0
  173. package/dist/textarea.cjs +65 -0
  174. package/dist/textarea.d.cts +11 -0
  175. package/dist/textarea.d.ts +11 -0
  176. package/dist/textarea.js +59 -0
  177. package/dist/toaster.cjs +99 -0
  178. package/dist/toaster.d.cts +29 -0
  179. package/dist/toaster.d.ts +29 -0
  180. package/dist/toaster.js +96 -0
  181. package/dist/tooltip.cjs +171 -0
  182. package/dist/tooltip.d.cts +39 -0
  183. package/dist/tooltip.d.ts +39 -0
  184. package/dist/tooltip.js +148 -0
  185. package/dist/utils.cjs +11 -0
  186. package/dist/utils.d.cts +5 -0
  187. package/dist/utils.d.ts +5 -0
  188. package/dist/utils.js +9 -0
  189. package/package.json +284 -85
  190. package/src/accordion.tsx +285 -0
  191. package/src/alert.tsx +221 -0
  192. package/src/avatar.tsx +174 -0
  193. package/src/badge.tsx +158 -0
  194. package/src/bank.tsx +325 -0
  195. package/src/button.tsx +411 -0
  196. package/src/checkbox.tsx +307 -0
  197. package/src/close-button.tsx +51 -0
  198. package/src/collapsible.tsx +126 -0
  199. package/src/color-mode.tsx +125 -0
  200. package/src/dialog.tsx +356 -0
  201. package/src/drawer.tsx +186 -0
  202. package/src/empty-state.tsx +97 -0
  203. package/src/expiration-selector.tsx +163 -0
  204. package/src/field.tsx +202 -0
  205. package/src/greeks-display.tsx +138 -0
  206. package/src/heading.tsx +55 -0
  207. package/src/icon-button.tsx +192 -0
  208. package/src/image.tsx +280 -0
  209. package/src/index.ts +268 -0
  210. package/src/input-group.tsx +159 -0
  211. package/src/input.tsx +60 -0
  212. package/src/link.tsx +326 -0
  213. package/src/menu.tsx +471 -0
  214. package/src/option-chain.tsx +261 -0
  215. package/src/option-position.tsx +200 -0
  216. package/src/pin-input.tsx +187 -0
  217. package/src/pnl-diagram.tsx +458 -0
  218. package/src/popover.tsx +400 -0
  219. package/src/progress-circle.tsx +180 -0
  220. package/src/progress.tsx +109 -0
  221. package/src/provider.tsx +12 -0
  222. package/src/radio.tsx +175 -0
  223. package/src/rating.tsx +79 -0
  224. package/src/select.tsx +696 -0
  225. package/src/separator.tsx +59 -0
  226. package/src/skeleton.tsx +302 -0
  227. package/src/slider.tsx +152 -0
  228. package/src/strategy-builder.tsx +466 -0
  229. package/src/switch.tsx +158 -0
  230. package/src/table.tsx +621 -0
  231. package/src/tabs.tsx +354 -0
  232. package/src/tag.tsx +159 -0
  233. package/src/textarea.tsx +60 -0
  234. package/src/toaster.tsx +117 -0
  235. package/src/tokens.css +438 -0
  236. package/src/tooltip.tsx +184 -0
  237. package/src/utils/cn.ts +7 -0
  238. package/src/utils.ts +6 -0
  239. package/tokens.css +438 -0
  240. package/README.md +0 -109
package/dist/menu.js ADDED
@@ -0,0 +1,269 @@
1
+ "use client";
2
+ import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
3
+ import * as React from 'react';
4
+ import { LuCheck, LuChevronRight } from 'react-icons/lu';
5
+ import { clsx } from 'clsx';
6
+ import { twMerge } from 'tailwind-merge';
7
+ import { jsx, jsxs } from 'react/jsx-runtime';
8
+
9
+ function cn(...inputs) {
10
+ return twMerge(clsx(inputs));
11
+ }
12
+ function parsePlacement(placement) {
13
+ if (!placement) {
14
+ return { side: "bottom", align: "start" };
15
+ }
16
+ const parts = placement.split("-");
17
+ const side = parts[0] ?? "bottom";
18
+ const alignPart = parts[1];
19
+ let align = "center";
20
+ if (alignPart === "start") {
21
+ align = "start";
22
+ } else if (alignPart === "end") {
23
+ align = "end";
24
+ }
25
+ return { side, align };
26
+ }
27
+ var PositioningContext = React.createContext({
28
+ side: "bottom",
29
+ align: "start",
30
+ sideOffset: 4,
31
+ alignOffset: 0
32
+ });
33
+ var MenuRoot = (props) => {
34
+ const {
35
+ children,
36
+ open,
37
+ defaultOpen,
38
+ onOpenChange,
39
+ positioning,
40
+ modal = true,
41
+ // lazyMount / unmountOnExit have no direct Radix equivalent; Radix handles
42
+ // mount/unmount automatically.
43
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
44
+ lazyMount: _lazyMount,
45
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
46
+ unmountOnExit: _unmountOnExit
47
+ } = props;
48
+ const mergedPositioning = {
49
+ placement: "bottom-start",
50
+ ...positioning,
51
+ offset: {
52
+ mainAxis: 4,
53
+ ...positioning?.offset
54
+ }
55
+ };
56
+ const { side, align } = parsePlacement(mergedPositioning.placement);
57
+ const positioningValue = React.useMemo(() => ({
58
+ side,
59
+ align,
60
+ sideOffset: mergedPositioning.offset?.mainAxis ?? 4,
61
+ alignOffset: mergedPositioning.offset?.crossAxis ?? 0
62
+ }), [side, align, mergedPositioning.offset?.mainAxis, mergedPositioning.offset?.crossAxis]);
63
+ const handleOpenChange = React.useCallback((isOpen) => {
64
+ onOpenChange?.({ open: isOpen });
65
+ }, [onOpenChange]);
66
+ return /* @__PURE__ */ jsx(PositioningContext.Provider, { value: positioningValue, children: /* @__PURE__ */ jsx(
67
+ DropdownMenu.Root,
68
+ {
69
+ open,
70
+ defaultOpen,
71
+ onOpenChange: handleOpenChange,
72
+ modal,
73
+ children
74
+ }
75
+ ) });
76
+ };
77
+ var MenuTrigger = React.forwardRef(function MenuTrigger2(props, ref) {
78
+ const { asChild = false, ...rest } = props;
79
+ return /* @__PURE__ */ jsx(DropdownMenu.Trigger, { asChild, ref, ...rest });
80
+ });
81
+ var MenuContent = React.forwardRef(function MenuContent2(props, ref) {
82
+ const { portalled = true, portalRef, className, zIndex, minW, style, ...rest } = props;
83
+ const positioning = React.useContext(PositioningContext);
84
+ const mergedStyle = {
85
+ ...style,
86
+ ...zIndex !== void 0 ? { zIndex: typeof zIndex === "string" ? `var(--z-index-${zIndex}, ${zIndex})` : zIndex } : {},
87
+ ...minW !== void 0 ? { minWidth: minW } : {}
88
+ };
89
+ const content = /* @__PURE__ */ jsx(
90
+ DropdownMenu.Content,
91
+ {
92
+ ref,
93
+ side: positioning.side,
94
+ align: positioning.align,
95
+ sideOffset: positioning.sideOffset,
96
+ alignOffset: positioning.alignOffset,
97
+ className: cn(
98
+ "z-50 min-w-[8rem] overflow-hidden rounded-lg p-1",
99
+ "border border-[var(--color-popover-border,var(--color-border-divider))]",
100
+ "bg-[var(--color-popover-bg,var(--color-dialog-bg))]",
101
+ "shadow-[0_4px_12px_var(--color-popover-shadow)]",
102
+ "outline-none",
103
+ "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
104
+ "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
105
+ "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2",
106
+ "data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
107
+ className
108
+ ),
109
+ style: Object.keys(mergedStyle).length > 0 ? mergedStyle : void 0,
110
+ ...rest
111
+ }
112
+ );
113
+ if (!portalled) {
114
+ return content;
115
+ }
116
+ return /* @__PURE__ */ jsx(DropdownMenu.Portal, { container: portalRef?.current ?? void 0, children: content });
117
+ });
118
+ var MenuItem = React.forwardRef(function MenuItem2(props, ref) {
119
+ const { className, value: _value, asChild, closeOnSelect: _closeOnSelect, disabled, children, onClick, ...rest } = props;
120
+ return /* @__PURE__ */ jsx(
121
+ DropdownMenu.Item,
122
+ {
123
+ ref,
124
+ asChild,
125
+ disabled,
126
+ onClick,
127
+ className: cn(
128
+ "relative flex cursor-pointer select-none items-center gap-2 rounded-md px-2 py-1.5 text-sm",
129
+ "outline-none transition-colors",
130
+ "text-[var(--color-text-primary,inherit)]",
131
+ "data-[highlighted]:bg-[var(--color-popover-item-hover,rgba(0,0,0,0.04))]",
132
+ "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
133
+ className
134
+ ),
135
+ ...rest,
136
+ children
137
+ }
138
+ );
139
+ });
140
+ var MenuItemText = React.forwardRef(function MenuItemText2(props, ref) {
141
+ const { className, ...rest } = props;
142
+ return /* @__PURE__ */ jsx("span", { ref, className: cn("flex-1", className), ...rest });
143
+ });
144
+ var MenuItemCommand = React.forwardRef(function MenuItemCommand2(props, ref) {
145
+ const { className, ...rest } = props;
146
+ return /* @__PURE__ */ jsx(
147
+ "span",
148
+ {
149
+ ref,
150
+ className: cn("ml-auto text-xs tracking-widest opacity-60", className),
151
+ ...rest
152
+ }
153
+ );
154
+ });
155
+ var MenuSeparator = React.forwardRef(function MenuSeparator2(props, ref) {
156
+ const { className, ...rest } = props;
157
+ return /* @__PURE__ */ jsx(
158
+ DropdownMenu.Separator,
159
+ {
160
+ ref,
161
+ className: cn("-mx-1 my-1 h-px bg-[var(--color-border-divider)]", className),
162
+ ...rest
163
+ }
164
+ );
165
+ });
166
+ var MenuItemGroup = React.forwardRef(function MenuItemGroup2(props, ref) {
167
+ const { title, children, className, ...rest } = props;
168
+ return /* @__PURE__ */ jsxs(DropdownMenu.Group, { ref, className, ...rest, children: [
169
+ title && /* @__PURE__ */ jsx(DropdownMenu.Label, { className: "px-2 py-1.5 text-xs font-semibold select-none opacity-60", children: title }),
170
+ children
171
+ ] });
172
+ });
173
+ var MenuArrow = React.forwardRef(function MenuArrow2(props, ref) {
174
+ const { className, ...rest } = props;
175
+ return /* @__PURE__ */ jsx(
176
+ DropdownMenu.Arrow,
177
+ {
178
+ ref,
179
+ className: cn("fill-[var(--color-popover-bg,var(--color-dialog-bg))]", className),
180
+ ...rest
181
+ }
182
+ );
183
+ });
184
+ var MenuCheckboxItem = React.forwardRef(function MenuCheckboxItem2(props, ref) {
185
+ const { className, children, checked, onCheckedChange, onClick, ...rest } = props;
186
+ return /* @__PURE__ */ jsxs(
187
+ DropdownMenu.CheckboxItem,
188
+ {
189
+ ref,
190
+ checked,
191
+ onCheckedChange,
192
+ onClick,
193
+ className: cn(
194
+ "relative flex cursor-pointer select-none items-center rounded-md py-1.5 pr-2 pl-8 text-sm",
195
+ "outline-none transition-colors",
196
+ "data-[highlighted]:bg-[var(--color-popover-item-hover,rgba(0,0,0,0.04))]",
197
+ "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
198
+ className
199
+ ),
200
+ ...rest,
201
+ children: [
202
+ /* @__PURE__ */ jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(DropdownMenu.ItemIndicator, { children: /* @__PURE__ */ jsx(LuCheck, { className: "h-4 w-4" }) }) }),
203
+ children
204
+ ]
205
+ }
206
+ );
207
+ });
208
+ var MenuRadioItemGroup = React.forwardRef(function MenuRadioItemGroup2(props, ref) {
209
+ const { value, onValueChange, ...rest } = props;
210
+ return /* @__PURE__ */ jsx(
211
+ DropdownMenu.RadioGroup,
212
+ {
213
+ ref,
214
+ value,
215
+ onValueChange,
216
+ ...rest
217
+ }
218
+ );
219
+ });
220
+ var MenuRadioItem = React.forwardRef(function MenuRadioItem2(props, ref) {
221
+ const { className, children, value, onClick, ...rest } = props;
222
+ const { value: _v, ...radixRest } = rest;
223
+ return /* @__PURE__ */ jsxs(
224
+ DropdownMenu.RadioItem,
225
+ {
226
+ ref,
227
+ value,
228
+ onClick,
229
+ className: cn(
230
+ "relative flex cursor-pointer select-none items-center rounded-md py-1.5 pr-2 pl-8 text-sm",
231
+ "outline-none transition-colors",
232
+ "data-[highlighted]:bg-[var(--color-popover-item-hover,rgba(0,0,0,0.04))]",
233
+ "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
234
+ className
235
+ ),
236
+ children: [
237
+ /* @__PURE__ */ jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(DropdownMenu.ItemIndicator, { children: /* @__PURE__ */ jsx(LuCheck, { className: "h-4 w-4" }) }) }),
238
+ /* @__PURE__ */ jsx("span", { children })
239
+ ]
240
+ }
241
+ );
242
+ });
243
+ var MenuContextTrigger = React.forwardRef(function MenuContextTrigger2(props, ref) {
244
+ const { asChild: _asChild, ...rest } = props;
245
+ return /* @__PURE__ */ jsx("span", { ref, ...rest });
246
+ });
247
+ var MenuTriggerItem = React.forwardRef(function MenuTriggerItem2(props, ref) {
248
+ const { startIcon, children, className, ...rest } = props;
249
+ return /* @__PURE__ */ jsx(DropdownMenu.Sub, { children: /* @__PURE__ */ jsxs(
250
+ DropdownMenu.SubTrigger,
251
+ {
252
+ ref,
253
+ className: cn(
254
+ "relative flex cursor-pointer select-none items-center gap-2 rounded-md px-2 py-1.5 text-sm",
255
+ "outline-none transition-colors",
256
+ "data-[highlighted]:bg-[var(--color-popover-item-hover,rgba(0,0,0,0.04))]",
257
+ className
258
+ ),
259
+ ...rest,
260
+ children: [
261
+ startIcon,
262
+ /* @__PURE__ */ jsx("span", { className: "flex-1", children }),
263
+ /* @__PURE__ */ jsx(LuChevronRight, { className: "h-4 w-4" })
264
+ ]
265
+ }
266
+ ) });
267
+ });
268
+
269
+ export { MenuArrow, MenuCheckboxItem, MenuContent, MenuContextTrigger, MenuItem, MenuItemCommand, MenuItemGroup, MenuItemText, MenuRadioItem, MenuRadioItemGroup, MenuRoot, MenuSeparator, MenuTrigger, MenuTriggerItem };
@@ -0,0 +1,221 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var React = require('react');
5
+ var clsx = require('clsx');
6
+ var tailwindMerge = require('tailwind-merge');
7
+ var jsxRuntime = require('react/jsx-runtime');
8
+
9
+ function _interopNamespace(e) {
10
+ if (e && e.__esModule) return e;
11
+ var n = Object.create(null);
12
+ if (e) {
13
+ Object.keys(e).forEach(function (k) {
14
+ if (k !== 'default') {
15
+ var d = Object.getOwnPropertyDescriptor(e, k);
16
+ Object.defineProperty(n, k, d.get ? d : {
17
+ enumerable: true,
18
+ get: function () { return e[k]; }
19
+ });
20
+ }
21
+ });
22
+ }
23
+ n.default = e;
24
+ return Object.freeze(n);
25
+ }
26
+
27
+ var React__namespace = /*#__PURE__*/_interopNamespace(React);
28
+
29
+ function cn(...inputs) {
30
+ return tailwindMerge.twMerge(clsx.clsx(inputs));
31
+ }
32
+ function fmt(n, decimals = 2) {
33
+ if (n === void 0 || n === null) return "-";
34
+ return n.toFixed(decimals);
35
+ }
36
+ function fmtInt(n) {
37
+ if (n === void 0 || n === null) return "-";
38
+ if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
39
+ if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K`;
40
+ return n.toLocaleString();
41
+ }
42
+ function fmtPct(n) {
43
+ if (n === void 0 || n === null) return "-";
44
+ return `${(n * 100).toFixed(1)}%`;
45
+ }
46
+ function QuoteCell({ value, highlight, align = "right", onClick, className }) {
47
+ return /* @__PURE__ */ jsxRuntime.jsx(
48
+ "td",
49
+ {
50
+ className: cn(
51
+ "px-1.5 py-1 font-mono tabular-nums text-xs whitespace-nowrap",
52
+ align === "right" ? "text-right" : "text-left",
53
+ highlight && "text-zinc-100",
54
+ !highlight && "text-zinc-400",
55
+ onClick && "cursor-pointer hover:bg-zinc-700/50 transition-colors",
56
+ className
57
+ ),
58
+ onClick,
59
+ children: value
60
+ }
61
+ );
62
+ }
63
+ var CALL_HEADERS = ["Bid", "Ask", "Last", "Vol", "OI", "IV", "Delta"];
64
+ var PUT_HEADERS = ["Delta", "IV", "OI", "Vol", "Last", "Ask", "Bid"];
65
+ var OptionChain = React__namespace.forwardRef(
66
+ function OptionChain2(props, ref) {
67
+ const {
68
+ symbol: _symbol,
69
+ expiration: _expiration,
70
+ strikes,
71
+ spotPrice,
72
+ onSelectContract,
73
+ className,
74
+ ...rest
75
+ } = props;
76
+ const handleClick = React__namespace.useCallback(
77
+ (quote, type, strike) => {
78
+ if (!quote || !onSelectContract) return;
79
+ onSelectContract({
80
+ symbol: quote.symbol,
81
+ type,
82
+ strike,
83
+ bid: quote.bid,
84
+ ask: quote.ask
85
+ });
86
+ },
87
+ [onSelectContract]
88
+ );
89
+ return /* @__PURE__ */ jsxRuntime.jsx(
90
+ "div",
91
+ {
92
+ ref,
93
+ className: cn("w-full overflow-x-auto", className),
94
+ ...rest,
95
+ children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full border-collapse text-xs", children: [
96
+ /* @__PURE__ */ jsxRuntime.jsxs("thead", { children: [
97
+ /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "border-b border-zinc-800", children: [
98
+ /* @__PURE__ */ jsxRuntime.jsx(
99
+ "th",
100
+ {
101
+ colSpan: CALL_HEADERS.length,
102
+ className: "px-2 py-1.5 text-center text-[10px] font-semibold uppercase tracking-wider text-emerald-400",
103
+ children: "Calls"
104
+ }
105
+ ),
106
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-2 py-1.5 text-center text-[10px] font-semibold uppercase tracking-wider text-zinc-500", children: "Strike" }),
107
+ /* @__PURE__ */ jsxRuntime.jsx(
108
+ "th",
109
+ {
110
+ colSpan: PUT_HEADERS.length,
111
+ className: "px-2 py-1.5 text-center text-[10px] font-semibold uppercase tracking-wider text-red-400",
112
+ children: "Puts"
113
+ }
114
+ )
115
+ ] }),
116
+ /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "border-b border-zinc-800/60", children: [
117
+ CALL_HEADERS.map((h) => /* @__PURE__ */ jsxRuntime.jsx(
118
+ "th",
119
+ {
120
+ className: "px-1.5 py-1 text-right text-[10px] font-medium uppercase tracking-wider text-zinc-500",
121
+ children: h
122
+ },
123
+ `call-${h}`
124
+ )),
125
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-2 py-1 text-center text-[10px] font-medium uppercase tracking-wider text-zinc-500" }),
126
+ PUT_HEADERS.map((h) => /* @__PURE__ */ jsxRuntime.jsx(
127
+ "th",
128
+ {
129
+ className: cn(
130
+ "px-1.5 py-1 text-[10px] font-medium uppercase tracking-wider text-zinc-500",
131
+ h === "Bid" || h === "Ask" || h === "Last" ? "text-left" : "text-right"
132
+ ),
133
+ children: h
134
+ },
135
+ `put-${h}`
136
+ ))
137
+ ] })
138
+ ] }),
139
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: strikes.map((row) => {
140
+ const isATM = Math.abs(row.strike - spotPrice) <= (strikes.length > 1 ? Math.abs((strikes[1]?.strike ?? 0) - (strikes[0]?.strike ?? 0)) / 2 : 0.5);
141
+ const callITM = row.strike < spotPrice;
142
+ const putITM = row.strike > spotPrice;
143
+ const c = row.call;
144
+ const p = row.put;
145
+ return /* @__PURE__ */ jsxRuntime.jsxs(
146
+ "tr",
147
+ {
148
+ className: cn(
149
+ "border-b border-zinc-800/30 transition-colors",
150
+ isATM && "bg-zinc-800/60",
151
+ !isATM && callITM && "bg-emerald-950/20",
152
+ !isATM && putITM && "bg-red-950/20",
153
+ !isATM && !callITM && !putITM && "hover:bg-zinc-800/30"
154
+ ),
155
+ children: [
156
+ /* @__PURE__ */ jsxRuntime.jsx(
157
+ QuoteCell,
158
+ {
159
+ value: fmt(c?.bid),
160
+ highlight: !!c,
161
+ onClick: () => handleClick(c, "call", row.strike)
162
+ }
163
+ ),
164
+ /* @__PURE__ */ jsxRuntime.jsx(
165
+ QuoteCell,
166
+ {
167
+ value: fmt(c?.ask),
168
+ highlight: !!c,
169
+ onClick: () => handleClick(c, "call", row.strike)
170
+ }
171
+ ),
172
+ /* @__PURE__ */ jsxRuntime.jsx(QuoteCell, { value: fmt(c?.last), highlight: !!c }),
173
+ /* @__PURE__ */ jsxRuntime.jsx(QuoteCell, { value: fmtInt(c?.volume) }),
174
+ /* @__PURE__ */ jsxRuntime.jsx(QuoteCell, { value: fmtInt(c?.openInterest) }),
175
+ /* @__PURE__ */ jsxRuntime.jsx(QuoteCell, { value: fmtPct(c?.iv) }),
176
+ /* @__PURE__ */ jsxRuntime.jsx(QuoteCell, { value: fmt(c?.delta, 3) }),
177
+ /* @__PURE__ */ jsxRuntime.jsx(
178
+ "td",
179
+ {
180
+ className: cn(
181
+ "px-2 py-1 text-center font-mono tabular-nums text-xs font-semibold",
182
+ isATM ? "text-amber-400 bg-zinc-800/80" : "text-zinc-300"
183
+ ),
184
+ children: fmt(row.strike)
185
+ }
186
+ ),
187
+ /* @__PURE__ */ jsxRuntime.jsx(QuoteCell, { value: fmt(p?.delta, 3), align: "right" }),
188
+ /* @__PURE__ */ jsxRuntime.jsx(QuoteCell, { value: fmtPct(p?.iv), align: "right" }),
189
+ /* @__PURE__ */ jsxRuntime.jsx(QuoteCell, { value: fmtInt(p?.openInterest), align: "right" }),
190
+ /* @__PURE__ */ jsxRuntime.jsx(QuoteCell, { value: fmtInt(p?.volume), align: "right" }),
191
+ /* @__PURE__ */ jsxRuntime.jsx(QuoteCell, { value: fmt(p?.last), align: "left", highlight: !!p }),
192
+ /* @__PURE__ */ jsxRuntime.jsx(
193
+ QuoteCell,
194
+ {
195
+ value: fmt(p?.ask),
196
+ align: "left",
197
+ highlight: !!p,
198
+ onClick: () => handleClick(p, "put", row.strike)
199
+ }
200
+ ),
201
+ /* @__PURE__ */ jsxRuntime.jsx(
202
+ QuoteCell,
203
+ {
204
+ value: fmt(p?.bid),
205
+ align: "left",
206
+ highlight: !!p,
207
+ onClick: () => handleClick(p, "put", row.strike)
208
+ }
209
+ )
210
+ ]
211
+ },
212
+ row.strike
213
+ );
214
+ }) })
215
+ ] })
216
+ }
217
+ );
218
+ }
219
+ );
220
+
221
+ exports.OptionChain = OptionChain;
@@ -0,0 +1,37 @@
1
+ import * as React from 'react';
2
+
3
+ interface OptionQuote {
4
+ symbol: string;
5
+ bid: number;
6
+ ask: number;
7
+ last: number;
8
+ volume: number;
9
+ openInterest: number;
10
+ iv: number;
11
+ delta: number;
12
+ gamma: number;
13
+ theta: number;
14
+ vega: number;
15
+ }
16
+ interface OptionContract {
17
+ symbol: string;
18
+ type: 'call' | 'put';
19
+ strike: number;
20
+ bid: number;
21
+ ask: number;
22
+ }
23
+ interface Strike {
24
+ strike: number;
25
+ call: OptionQuote | null;
26
+ put: OptionQuote | null;
27
+ }
28
+ interface OptionChainProps extends React.HTMLAttributes<HTMLDivElement> {
29
+ readonly symbol: string;
30
+ readonly expiration: string;
31
+ readonly strikes: Strike[];
32
+ readonly spotPrice: number;
33
+ readonly onSelectContract?: (contract: OptionContract) => void;
34
+ }
35
+ declare const OptionChain: React.ForwardRefExoticComponent<OptionChainProps & React.RefAttributes<HTMLDivElement>>;
36
+
37
+ export { OptionChain, type OptionChainProps, type OptionContract, type OptionQuote, type Strike };
@@ -0,0 +1,37 @@
1
+ import * as React from 'react';
2
+
3
+ interface OptionQuote {
4
+ symbol: string;
5
+ bid: number;
6
+ ask: number;
7
+ last: number;
8
+ volume: number;
9
+ openInterest: number;
10
+ iv: number;
11
+ delta: number;
12
+ gamma: number;
13
+ theta: number;
14
+ vega: number;
15
+ }
16
+ interface OptionContract {
17
+ symbol: string;
18
+ type: 'call' | 'put';
19
+ strike: number;
20
+ bid: number;
21
+ ask: number;
22
+ }
23
+ interface Strike {
24
+ strike: number;
25
+ call: OptionQuote | null;
26
+ put: OptionQuote | null;
27
+ }
28
+ interface OptionChainProps extends React.HTMLAttributes<HTMLDivElement> {
29
+ readonly symbol: string;
30
+ readonly expiration: string;
31
+ readonly strikes: Strike[];
32
+ readonly spotPrice: number;
33
+ readonly onSelectContract?: (contract: OptionContract) => void;
34
+ }
35
+ declare const OptionChain: React.ForwardRefExoticComponent<OptionChainProps & React.RefAttributes<HTMLDivElement>>;
36
+
37
+ export { OptionChain, type OptionChainProps, type OptionContract, type OptionQuote, type Strike };