@xemahq/ui-kernel 0.11.1 → 0.11.2

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 (234) hide show
  1. package/package.json +1 -2
  2. package/src/index.ts +0 -17
  3. package/src/lib/biome-host/agent-validation.ts +0 -239
  4. package/src/lib/biome-host/biome-builders.ts +0 -112
  5. package/src/lib/biome-host/biome-mode.ts +0 -6
  6. package/src/lib/biome-host/biome-navigation.ts +0 -37
  7. package/src/lib/biome-host/biome-registry.ts +0 -299
  8. package/src/lib/biome-host/biome-scope-hooks.ts +0 -41
  9. package/src/lib/biome-host/biome-scope.tsx +0 -52
  10. package/src/lib/biome-host/biome-scoped-query.ts +0 -134
  11. package/src/lib/biome-host/create-biome-orval-config.ts +0 -82
  12. package/src/lib/biome-host/define-web-biome.spec.ts +0 -221
  13. package/src/lib/biome-host/define-web-biome.ts +0 -222
  14. package/src/lib/biome-host/errors.ts +0 -220
  15. package/src/lib/biome-host/frontend-biome.ts +0 -256
  16. package/src/lib/biome-host/host-bridge.ts +0 -281
  17. package/src/lib/biome-host/host-sources.ts +0 -54
  18. package/src/lib/biome-host/i18n-hooks.ts +0 -51
  19. package/src/lib/biome-host/i18n-port.test.ts +0 -50
  20. package/src/lib/biome-host/i18n-port.ts +0 -96
  21. package/src/lib/biome-host/index.ts +0 -35
  22. package/src/lib/biome-host/realtime-hooks.ts +0 -75
  23. package/src/lib/biome-host/realtime-port.ts +0 -115
  24. package/src/lib/biome-host/session-contributions.ts +0 -296
  25. package/src/lib/biome-host/use-mutation-with-error-toast.ts +0 -90
  26. package/src/lib/biome-host/use-page-state.ts +0 -248
  27. package/src/lib/capabilities/capability-context.ts +0 -25
  28. package/src/lib/capabilities/capability-provider.tsx +0 -73
  29. package/src/lib/capabilities/index.ts +0 -17
  30. package/src/lib/capabilities/types.ts +0 -69
  31. package/src/lib/capabilities/use-capability.ts +0 -79
  32. package/src/lib/contribution-registry/contribution-registry.spec.ts +0 -141
  33. package/src/lib/contribution-registry/contribution-registry.ts +0 -204
  34. package/src/lib/contribution-registry/index.ts +0 -9
  35. package/src/lib/contribution-registry/renderable-registry.ts +0 -142
  36. package/src/lib/system-bus/capability-invoke.ts +0 -92
  37. package/src/lib/system-bus/deeplink.ts +0 -210
  38. package/src/lib/system-bus/enums.ts +0 -86
  39. package/src/lib/system-bus/host-ports.ts +0 -93
  40. package/src/lib/system-bus/index.ts +0 -16
  41. package/src/lib/system-bus/intent-registry.ts +0 -109
  42. package/src/lib/system-bus/intents.ts +0 -113
  43. package/src/lib/system-bus/palette.ts +0 -78
  44. package/src/lib/system-bus/system-bus-builder.ts +0 -159
  45. package/src/lib/system-bus/system-bus.ts +0 -37
  46. package/src/lib/system-bus/windows.ts +0 -51
  47. package/src/offline/id.ts +0 -16
  48. package/src/offline/index.ts +0 -54
  49. package/src/offline/mutation.ts +0 -75
  50. package/src/offline/offline-status-badge.tsx +0 -51
  51. package/src/offline/online-controller.ts +0 -105
  52. package/src/offline/outbox.test.ts +0 -172
  53. package/src/offline/outbox.ts +0 -348
  54. package/src/offline/react-hooks.ts +0 -40
  55. package/src/offline/react.tsx +0 -32
  56. package/src/offline/storage.ts +0 -112
  57. package/src/offline/types.ts +0 -77
  58. package/src/org-db/components/DbResultTable.tsx +0 -176
  59. package/src/org-db/index.ts +0 -1
  60. package/src/pdf/index.ts +0 -11
  61. package/src/registry/index.ts +0 -9
  62. package/src/registry/lib/agent-validation-host.ts +0 -36
  63. package/src/registry/lib/biome-slot.tsx +0 -50
  64. package/src/registry/lib/biomes-enabled-context.ts +0 -20
  65. package/src/registry/lib/extension-points.ts +0 -134
  66. package/src/registry/lib/primitives/SessionEventCard.tsx +0 -164
  67. package/src/registry/lib/primitives/SessionEventTimeline.tsx +0 -95
  68. package/src/registry/lib/primitives/SessionMutationBar.tsx +0 -76
  69. package/src/registry/lib/primitives/SessionTabbedDrawer.tsx +0 -165
  70. package/src/registry/lib/primitives/index.ts +0 -18
  71. package/src/registry/lib/session-context-builder.ts +0 -84
  72. package/src/registry/lib/session-context-provider.tsx +0 -33
  73. package/src/registry/lib/session-context.ts +0 -21
  74. package/src/registry/lib/session-selectors.ts +0 -272
  75. package/src/session/comments/CommentRail.tsx +0 -164
  76. package/src/session/index.ts +0 -3
  77. package/src/session/lib/cn.ts +0 -11
  78. package/src/session/shell/SessionWorkspaceShell.tsx +0 -147
  79. package/src/session-kit/approvals/ApprovalButton.tsx +0 -89
  80. package/src/session-kit/approvals/ApprovalCard.tsx +0 -341
  81. package/src/session-kit/approvals/ApprovalsCenter.tsx +0 -336
  82. package/src/session-kit/approvals/CapabilityApprovalStickyBar.tsx +0 -118
  83. package/src/session-kit/approvals/Obligation.tsx +0 -111
  84. package/src/session-kit/approvals/ScopedBody.tsx +0 -392
  85. package/src/session-kit/approvals/approval-icons.ts +0 -31
  86. package/src/session-kit/approvals/approval-model.ts +0 -204
  87. package/src/session-kit/approvals/index.ts +0 -22
  88. package/src/session-kit/approvals/obligation-display.ts +0 -100
  89. package/src/session-kit/approvals/risk-accent.ts +0 -47
  90. package/src/session-kit/approvals/scope-icons.ts +0 -19
  91. package/src/session-kit/combobox/Combobox.tsx +0 -358
  92. package/src/session-kit/combobox/use-click-outside.ts +0 -21
  93. package/src/session-kit/display/ContextHeader.tsx +0 -148
  94. package/src/session-kit/display/FileDiffCard.tsx +0 -140
  95. package/src/session-kit/display/MD.tsx +0 -162
  96. package/src/session-kit/display/MessageTurn.tsx +0 -157
  97. package/src/session-kit/display/ThinkingPanel.tsx +0 -81
  98. package/src/session-kit/display/TodoChecklist.tsx +0 -120
  99. package/src/session-kit/display/TokenMeter.tsx +0 -89
  100. package/src/session-kit/display/ToolStrip.tsx +0 -278
  101. package/src/session-kit/display/TypingDots.tsx +0 -24
  102. package/src/session-kit/index.ts +0 -44
  103. package/src/session-kit/lib/enums.ts +0 -66
  104. package/src/session-kit/lib/portal-accent.ts +0 -30
  105. package/src/session-kit/lib/status-dot.ts +0 -68
  106. package/src/session-kit/primitives/Avatar.tsx +0 -44
  107. package/src/session-kit/primitives/PortalGlyph.tsx +0 -51
  108. package/src/session-kit/primitives/RiskPill.tsx +0 -95
  109. package/src/session-kit/primitives/ScopeDot.tsx +0 -47
  110. package/src/session-kit/primitives/Segmented.tsx +0 -71
  111. package/src/ui/branding/app-branding-context.ts +0 -20
  112. package/src/ui/branding/app-branding-provider.tsx +0 -123
  113. package/src/ui/branding/sanitize.ts +0 -89
  114. package/src/ui/breakpoints.ts +0 -14
  115. package/src/ui/capture/document-preview.tsx +0 -166
  116. package/src/ui/capture/field-spec-to-zod.test.ts +0 -81
  117. package/src/ui/capture/field-spec-to-zod.ts +0 -174
  118. package/src/ui/capture/field-spec-validate.ts +0 -236
  119. package/src/ui/capture/field-spec.test.ts +0 -49
  120. package/src/ui/capture/field-spec.ts +0 -274
  121. package/src/ui/capture/index.ts +0 -51
  122. package/src/ui/capture/schema-field-input.tsx +0 -620
  123. package/src/ui/capture/schema-form.tsx +0 -149
  124. package/src/ui/capture/submit-values.test.ts +0 -70
  125. package/src/ui/capture/submit-values.ts +0 -63
  126. package/src/ui/capture/use-prefill.ts +0 -186
  127. package/src/ui/capture/use-schema-validation.ts +0 -145
  128. package/src/ui/capture/use-wizard.ts +0 -180
  129. package/src/ui/capture/value-format.ts +0 -32
  130. package/src/ui/capture/wizard.tsx +0 -105
  131. package/src/ui/charts/bar-chart.tsx +0 -139
  132. package/src/ui/charts/chart-frame.tsx +0 -125
  133. package/src/ui/charts/chart-types.ts +0 -52
  134. package/src/ui/charts/chart-utils.ts +0 -190
  135. package/src/ui/charts/charts.test.tsx +0 -204
  136. package/src/ui/charts/donut-chart.tsx +0 -129
  137. package/src/ui/charts/index.ts +0 -27
  138. package/src/ui/charts/line-chart.tsx +0 -202
  139. package/src/ui/charts/sparkline.tsx +0 -109
  140. package/src/ui/chrome/AsyncBoundary.tsx +0 -74
  141. package/src/ui/chrome/EmptyState.tsx +0 -257
  142. package/src/ui/chrome/ErrorCard.tsx +0 -63
  143. package/src/ui/chrome/LoadingState.tsx +0 -61
  144. package/src/ui/chrome/PageHeader.tsx +0 -137
  145. package/src/ui/chrome/RecordCardList.tsx +0 -98
  146. package/src/ui/chrome/StateCard.tsx +0 -150
  147. package/src/ui/chrome/confirm-delete-dialog.tsx +0 -59
  148. package/src/ui/chrome/page-shell.spec.tsx +0 -117
  149. package/src/ui/chrome/page-shell.tsx +0 -221
  150. package/src/ui/chrome/scope-badge.tsx +0 -40
  151. package/src/ui/chrome/status-badge.tsx +0 -79
  152. package/src/ui/cn.ts +0 -32
  153. package/src/ui/design-tokens.ts +0 -372
  154. package/src/ui/hooks/use-debounced-value.ts +0 -16
  155. package/src/ui/hooks/use-is-mobile.ts +0 -28
  156. package/src/ui/index.ts +0 -110
  157. package/src/ui/pdf/pdf-preview.tsx +0 -122
  158. package/src/ui/primitives/alert-dialog.tsx +0 -104
  159. package/src/ui/primitives/async-combobox.tsx +0 -182
  160. package/src/ui/primitives/badge-variants.ts +0 -21
  161. package/src/ui/primitives/badge.tsx +0 -25
  162. package/src/ui/primitives/button-variants.ts +0 -31
  163. package/src/ui/primitives/button.tsx +0 -29
  164. package/src/ui/primitives/card.tsx +0 -43
  165. package/src/ui/primitives/checkbox.tsx +0 -26
  166. package/src/ui/primitives/collapsible.tsx +0 -9
  167. package/src/ui/primitives/dialog.tsx +0 -103
  168. package/src/ui/primitives/dropdown-menu.tsx +0 -179
  169. package/src/ui/primitives/form-stepper.tsx +0 -94
  170. package/src/ui/primitives/form-stepper.types.ts +0 -15
  171. package/src/ui/primitives/input.tsx +0 -22
  172. package/src/ui/primitives/label.tsx +0 -17
  173. package/src/ui/primitives/overflow-tabs.tsx +0 -331
  174. package/src/ui/primitives/popover.tsx +0 -33
  175. package/src/ui/primitives/preview-device-frame.tsx +0 -213
  176. package/src/ui/primitives/radio-group.tsx +0 -36
  177. package/src/ui/primitives/resizable.tsx +0 -67
  178. package/src/ui/primitives/scroll-area.tsx +0 -38
  179. package/src/ui/primitives/select.tsx +0 -143
  180. package/src/ui/primitives/separator.tsx +0 -20
  181. package/src/ui/primitives/sheet.tsx +0 -107
  182. package/src/ui/primitives/skeleton.tsx +0 -99
  183. package/src/ui/primitives/switch.tsx +0 -27
  184. package/src/ui/primitives/table.tsx +0 -72
  185. package/src/ui/primitives/tabs.tsx +0 -53
  186. package/src/ui/primitives/tag-multi-select.tsx +0 -261
  187. package/src/ui/primitives/textarea.tsx +0 -21
  188. package/src/ui/primitives/tooltip.tsx +0 -30
  189. package/src/ui/primitives/url-preview-chrome.tsx +0 -103
  190. package/src/vista/GenericCatalogueSurface.tsx +0 -179
  191. package/src/vista/SurfaceFallbackCard.tsx +0 -109
  192. package/src/vista/VistaPanel.tsx +0 -163
  193. package/src/vista/form-payload.spec.ts +0 -139
  194. package/src/vista/html/CustomUiFrame.spec.tsx +0 -127
  195. package/src/vista/html/CustomUiFrame.tsx +0 -206
  196. package/src/vista/html/custom-ui-frame-bridge.spec.ts +0 -191
  197. package/src/vista/html/custom-ui-frame-bridge.ts +0 -98
  198. package/src/vista/html/custom-ui-frame-contract.ts +0 -88
  199. package/src/vista/html/custom-ui-intents.spec.ts +0 -135
  200. package/src/vista/html/custom-ui-intents.ts +0 -155
  201. package/src/vista/html/custom-ui-srcdoc.spec.ts +0 -151
  202. package/src/vista/html/custom-ui-srcdoc.ts +0 -193
  203. package/src/vista/html/index.ts +0 -13
  204. package/src/vista/index.ts +0 -52
  205. package/src/vista/surface-catalogue.spec.ts +0 -140
  206. package/src/vista/surface-catalogue.ts +0 -90
  207. package/src/vista/surface-icons.ts +0 -57
  208. package/src/vista/surface-registry.ts +0 -56
  209. package/src/vista/surfaces/ChartSurface.tsx +0 -34
  210. package/src/vista/surfaces/FilesSurface.tsx +0 -202
  211. package/src/vista/surfaces/FormSurface.tsx +0 -380
  212. package/src/vista/surfaces/HtmlSurface.tsx +0 -43
  213. package/src/vista/surfaces/TableSurface.tsx +0 -100
  214. package/src/vista/surfaces/UrlSurface.tsx +0 -40
  215. package/src/vista/surfaces/blob-surfaces.tsx +0 -139
  216. package/src/vista/surfaces/elicitation-transport.spec.ts +0 -369
  217. package/src/vista/surfaces/elicitation-transport.ts +0 -367
  218. package/src/vista/surfaces/file-surface-utils.ts +0 -69
  219. package/src/vista/surfaces/index.ts +0 -24
  220. package/src/vista/surfaces/register-surfaces.tsx +0 -139
  221. package/src/vista/surfaces/text-surfaces.tsx +0 -132
  222. package/src/vista/use-vista-tabs.ts +0 -196
  223. package/src/vista/vista-code-renderer-context.ts +0 -16
  224. package/src/vista/vista-code-renderer.tsx +0 -35
  225. package/src/vista/vista-file-context.ts +0 -14
  226. package/src/vista/vista-file-source.tsx +0 -141
  227. package/src/vista/vista-form-context.ts +0 -20
  228. package/src/vista/vista-form-host.tsx +0 -48
  229. package/src/vista/vista-model.ts +0 -137
  230. package/src/vista/vista-open-context.tsx +0 -27
  231. package/src/vista/vista-open-state.ts +0 -11
  232. package/src/vista/vista-payloads.ts +0 -635
  233. package/src/vista/vista-tabs-manifest.ts +0 -138
  234. package/src/vista/vista-tools.ts +0 -232
@@ -1,179 +0,0 @@
1
- import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
2
- import { Check, ChevronRight, Circle } from "lucide-react";
3
- import * as React from "react";
4
-
5
- import { cn } from '../cn';
6
-
7
- const DropdownMenu = DropdownMenuPrimitive.Root;
8
-
9
- const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
10
-
11
- const DropdownMenuGroup = DropdownMenuPrimitive.Group;
12
-
13
- const DropdownMenuPortal = DropdownMenuPrimitive.Portal;
14
-
15
- const DropdownMenuSub = DropdownMenuPrimitive.Sub;
16
-
17
- const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
18
-
19
- const DropdownMenuSubTrigger = React.forwardRef<
20
- React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
21
- React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
22
- inset?: boolean;
23
- }
24
- >(({ className, inset, children, ...props }, ref) => (
25
- <DropdownMenuPrimitive.SubTrigger
26
- ref={ref}
27
- className={cn(
28
- "flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-body-1 outline-none data-[state=open]:bg-accent focus:bg-accent",
29
- inset && "pl-8",
30
- className,
31
- )}
32
- {...props}
33
- >
34
- {children}
35
- <ChevronRight className="ml-auto h-4 w-4" />
36
- </DropdownMenuPrimitive.SubTrigger>
37
- ));
38
- DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
39
-
40
- const DropdownMenuSubContent = React.forwardRef<
41
- React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
42
- React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>
43
- >(({ className, ...props }, ref) => (
44
- <DropdownMenuPrimitive.SubContent
45
- ref={ref}
46
- className={cn(
47
- "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
48
- className,
49
- )}
50
- {...props}
51
- />
52
- ));
53
- DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
54
-
55
- const DropdownMenuContent = React.forwardRef<
56
- React.ElementRef<typeof DropdownMenuPrimitive.Content>,
57
- React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
58
- >(({ className, sideOffset = 4, ...props }, ref) => (
59
- <DropdownMenuPrimitive.Portal>
60
- <DropdownMenuPrimitive.Content
61
- ref={ref}
62
- sideOffset={sideOffset}
63
- className={cn(
64
- "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
65
- className,
66
- )}
67
- {...props}
68
- />
69
- </DropdownMenuPrimitive.Portal>
70
- ));
71
- DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
72
-
73
- const DropdownMenuItem = React.forwardRef<
74
- React.ElementRef<typeof DropdownMenuPrimitive.Item>,
75
- React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
76
- inset?: boolean;
77
- }
78
- >(({ className, inset, ...props }, ref) => (
79
- <DropdownMenuPrimitive.Item
80
- ref={ref}
81
- className={cn(
82
- "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-body-1 outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
83
- inset && "pl-8",
84
- className,
85
- )}
86
- {...props}
87
- />
88
- ));
89
- DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
90
-
91
- const DropdownMenuCheckboxItem = React.forwardRef<
92
- React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
93
- React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>
94
- >(({ className, children, checked, ...props }, ref) => (
95
- <DropdownMenuPrimitive.CheckboxItem
96
- ref={ref}
97
- className={cn(
98
- "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-body-1 outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
99
- className,
100
- )}
101
- checked={checked}
102
- {...props}
103
- >
104
- <span className="absolute left-2 flex h-4 w-4 items-center justify-center">
105
- <DropdownMenuPrimitive.ItemIndicator>
106
- <Check className="h-4 w-4" />
107
- </DropdownMenuPrimitive.ItemIndicator>
108
- </span>
109
- {children}
110
- </DropdownMenuPrimitive.CheckboxItem>
111
- ));
112
- DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
113
-
114
- const DropdownMenuRadioItem = React.forwardRef<
115
- React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
116
- React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>
117
- >(({ className, children, ...props }, ref) => (
118
- <DropdownMenuPrimitive.RadioItem
119
- ref={ref}
120
- className={cn(
121
- "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-body-1 outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
122
- className,
123
- )}
124
- {...props}
125
- >
126
- <span className="absolute left-2 flex h-4 w-4 items-center justify-center">
127
- <DropdownMenuPrimitive.ItemIndicator>
128
- <Circle className="h-2 w-2 fill-current" />
129
- </DropdownMenuPrimitive.ItemIndicator>
130
- </span>
131
- {children}
132
- </DropdownMenuPrimitive.RadioItem>
133
- ));
134
- DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
135
-
136
- const DropdownMenuLabel = React.forwardRef<
137
- React.ElementRef<typeof DropdownMenuPrimitive.Label>,
138
- React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
139
- inset?: boolean;
140
- }
141
- >(({ className, inset, ...props }, ref) => (
142
- <DropdownMenuPrimitive.Label
143
- ref={ref}
144
- className={cn("px-2 py-1.5 text-body-1 font-semibold", inset && "pl-8", className)}
145
- {...props}
146
- />
147
- ));
148
- DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
149
-
150
- const DropdownMenuSeparator = React.forwardRef<
151
- React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
152
- React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
153
- >(({ className, ...props }, ref) => (
154
- <DropdownMenuPrimitive.Separator ref={ref} className={cn("-mx-1 my-1 h-px bg-muted", className)} {...props} />
155
- ));
156
- DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
157
-
158
- const DropdownMenuShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => {
159
- return <span className={cn("ml-auto text-body-1 tracking-widest opacity-60", className)} {...props} />;
160
- };
161
- DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
162
-
163
- export {
164
- DropdownMenu,
165
- DropdownMenuTrigger,
166
- DropdownMenuContent,
167
- DropdownMenuItem,
168
- DropdownMenuCheckboxItem,
169
- DropdownMenuRadioItem,
170
- DropdownMenuLabel,
171
- DropdownMenuSeparator,
172
- DropdownMenuShortcut,
173
- DropdownMenuGroup,
174
- DropdownMenuPortal,
175
- DropdownMenuSub,
176
- DropdownMenuSubContent,
177
- DropdownMenuSubTrigger,
178
- DropdownMenuRadioGroup,
179
- };
@@ -1,94 +0,0 @@
1
- import { Check } from 'lucide-react';
2
-
3
- import { cn } from '../cn';
4
- import { FormStepStatus, type FormStep } from './form-stepper.types';
5
-
6
- interface FormStepperProps {
7
- readonly steps: readonly FormStep[];
8
- }
9
-
10
- /**
11
- * Vertical stepper for in-dialog multi-step forms — numbered badges with a
12
- * connector rail. Every step's body is rendered inline (pending steps are
13
- * dimmed and pointer-disabled). The dialog owns the submit button; this
14
- * primitive renders structure only.
15
- */
16
- export function FormStepper({ steps }: FormStepperProps) {
17
- return (
18
- <ol className="space-y-4">
19
- {steps.map((step, index) => (
20
- <FormStepperItem
21
- key={step.key}
22
- step={step}
23
- stepNumber={index + 1}
24
- isLast={index === steps.length - 1}
25
- />
26
- ))}
27
- </ol>
28
- );
29
- }
30
-
31
- interface FormStepperItemProps {
32
- readonly step: FormStep;
33
- readonly stepNumber: number;
34
- readonly isLast: boolean;
35
- }
36
-
37
- function FormStepperItem({ step, stepNumber, isLast }: FormStepperItemProps) {
38
- const isPending = step.status === FormStepStatus.PENDING;
39
- const isDone = step.status === FormStepStatus.DONE;
40
- const isActive = step.status === FormStepStatus.ACTIVE;
41
-
42
- return (
43
- <li className="relative flex gap-3">
44
- {/* Connector rail — hugs the numbered badge column. Hidden on the last
45
- item so the chain doesn't dangle past the final step. */}
46
- {!isLast && (
47
- <span
48
- aria-hidden
49
- className={cn(
50
- 'absolute left-3.5 top-8 bottom-0 w-px -translate-x-1/2',
51
- isDone ? 'bg-primary/30' : 'bg-rule',
52
- )}
53
- />
54
- )}
55
-
56
- <span
57
- className={cn(
58
- 'relative z-[1] mt-0.5 inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-full border text-caption font-semibold',
59
- isDone && 'border-primary/40 bg-primary/15 text-primary',
60
- isActive && 'border-primary bg-primary text-primary-foreground',
61
- isPending && 'border-rule bg-paper-elev text-ink-3',
62
- )}
63
- >
64
- {isDone ? <Check className="h-3.5 w-3.5" strokeWidth={2.5} /> : stepNumber}
65
- </span>
66
-
67
- <div
68
- className={cn(
69
- 'flex-1 min-w-0 rounded-lg border bg-card p-4 transition-opacity',
70
- isActive && 'border-primary/40 shadow-sm',
71
- isDone && 'border-rule',
72
- isPending && 'border-rule opacity-60',
73
- )}
74
- >
75
- <div className="mb-3 space-y-0.5">
76
- <p
77
- className={cn(
78
- 'text-body-1 font-medium',
79
- isPending ? 'text-ink-3' : 'text-foreground',
80
- )}
81
- >
82
- {step.label}
83
- </p>
84
- {step.hint && <p className="text-caption text-ink-3">{step.hint}</p>}
85
- </div>
86
- {/* Keep pointer/keyboard focus out of pending steps without disabling
87
- them globally — every input retains its native disabled semantics. */}
88
- <div className={cn(isPending && 'pointer-events-none select-none')}>
89
- {step.children}
90
- </div>
91
- </div>
92
- </li>
93
- );
94
- }
@@ -1,15 +0,0 @@
1
- import type { ReactNode } from 'react';
2
-
3
- export enum FormStepStatus {
4
- PENDING = 'pending',
5
- ACTIVE = 'active',
6
- DONE = 'done',
7
- }
8
-
9
- export interface FormStep {
10
- readonly key: string;
11
- readonly label: string;
12
- readonly hint?: string;
13
- readonly status: FormStepStatus;
14
- readonly children: ReactNode;
15
- }
@@ -1,22 +0,0 @@
1
- import * as React from "react";
2
-
3
- import { cn } from '../cn';
4
-
5
- const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<"input">>(
6
- ({ className, type, ...props }, ref) => {
7
- return (
8
- <input
9
- type={type}
10
- className={cn(
11
- "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:text-body-1 file:font-medium file:text-foreground placeholder:text-ink-3 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-body-1",
12
- className,
13
- )}
14
- ref={ref}
15
- {...props}
16
- />
17
- );
18
- },
19
- );
20
- Input.displayName = "Input";
21
-
22
- export { Input };
@@ -1,17 +0,0 @@
1
- import * as LabelPrimitive from "@radix-ui/react-label";
2
- import { cva, type VariantProps } from "class-variance-authority";
3
- import * as React from "react";
4
-
5
- import { cn } from '../cn';
6
-
7
- const labelVariants = cva("text-body-1 font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70");
8
-
9
- const Label = React.forwardRef<
10
- React.ElementRef<typeof LabelPrimitive.Root>,
11
- React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> & VariantProps<typeof labelVariants>
12
- >(({ className, ...props }, ref) => (
13
- <LabelPrimitive.Root ref={ref} className={cn(labelVariants(), className)} {...props} />
14
- ));
15
- Label.displayName = LabelPrimitive.Root.displayName;
16
-
17
- export { Label };
@@ -1,331 +0,0 @@
1
- /**
2
- * OverflowTabs — editorial tab strip that auto-collapses overflowing items
3
- * into a "More…" dropdown instead of scrolling horizontally.
4
- *
5
- * Behavior:
6
- * 1. All tabs render off-screen for measurement (visibility: hidden, but
7
- * still laid out so widths are real).
8
- * 2. A ResizeObserver tracks the container width; once known we walk the
9
- * tab widths left-to-right and pick the cutoff where they still fit
10
- * alongside a fixed "More…" trigger.
11
- * 3. Visible tabs render inline; overflow tabs go into a dropdown.
12
- *
13
- * The active tab is always pulled into the visible set, even if its index
14
- * would be in the overflow bucket — users should never lose sight of "where
15
- * am I." Same for tabs marked `pinned: true` (indicator dot is sticky).
16
- */
17
- import { ChevronDown, X } from 'lucide-react';
18
- import {
19
- useEffect,
20
- useLayoutEffect,
21
- useMemo,
22
- useRef,
23
- useState,
24
- type ComponentType,
25
- } from 'react';
26
-
27
- import {
28
- DropdownMenu,
29
- DropdownMenuContent,
30
- DropdownMenuItem,
31
- DropdownMenuTrigger,
32
- } from './dropdown-menu';
33
- import { cn } from '../cn';
34
-
35
- export interface OverflowTab {
36
- readonly value: string;
37
- readonly label: string;
38
- /** Optional warning/indicator dot rendered next to the label. */
39
- readonly indicator?: boolean;
40
- /** Optional numeric badge. */
41
- readonly count?: number;
42
- /**
43
- * A pinned tab is ALWAYS in the visible set (never collapsed into "More…")
44
- * and never renders a close affordance, even when `onClose` is supplied.
45
- * Used for a panel's permanent first tab (e.g. the Vista file browser).
46
- */
47
- readonly pinned?: boolean;
48
- /** Optional leading glyph (a `lucide-react` icon component). */
49
- readonly icon?: ComponentType<{ className?: string }>;
50
- }
51
-
52
- interface OverflowTabsProps {
53
- readonly tabs: readonly OverflowTab[];
54
- readonly value: string;
55
- readonly onChange: (value: string) => void;
56
- /** Reserved px for the "More…" trigger when measuring. Default 88. */
57
- readonly moreTriggerWidth?: number;
58
- readonly className?: string;
59
- /** Each tab's px gap from the next. Matches the visual rendering. Default 4. */
60
- readonly gap?: number;
61
- /**
62
- * When provided, every tab renders a hover `×` that calls this with the
63
- * tab value. Closable tabs (multi-thread surfaces, etc.) opt in by
64
- * passing it; surfaces that just navigate omit it.
65
- */
66
- readonly onClose?: (value: string) => void;
67
- }
68
-
69
- export function OverflowTabs({
70
- tabs,
71
- value,
72
- onChange,
73
- moreTriggerWidth = 88,
74
- className,
75
- gap = 4,
76
- onClose,
77
- }: OverflowTabsProps) {
78
- const containerRef = useRef<HTMLDivElement>(null);
79
- const measureRef = useRef<HTMLDivElement>(null);
80
- const [containerWidth, setContainerWidth] = useState(0);
81
- const [tabWidths, setTabWidths] = useState<readonly number[]>([]);
82
-
83
- // Measure container width and react to resizes.
84
- useEffect(() => {
85
- const el = containerRef.current;
86
- if (!el) {
87
- return;
88
- }
89
- const ro = new ResizeObserver((entries) => {
90
- const w = entries[0]?.contentRect.width ?? el.clientWidth;
91
- setContainerWidth(w);
92
- });
93
- ro.observe(el);
94
- setContainerWidth(el.clientWidth);
95
- return () => ro.disconnect();
96
- }, []);
97
-
98
- // Measure each tab's natural width once after first render. We re-measure
99
- // when the tab list itself changes (new tabs, label edits).
100
- useLayoutEffect(() => {
101
- const el = measureRef.current;
102
- if (!el) {
103
- return;
104
- }
105
- const children = Array.from(el.children) as HTMLElement[];
106
- setTabWidths(children.map((c) => c.getBoundingClientRect().width));
107
- }, [tabs]);
108
-
109
- // Decide split point: walk left-to-right, summing widths + gaps, stopping
110
- // when the next tab would exceed (container - moreTrigger). The active
111
- // tab and any pinned tabs are always pulled into the visible set.
112
- const { visible, overflow } = useMemo(() => {
113
- if (tabWidths.length !== tabs.length || containerWidth === 0) {
114
- return { visible: tabs, overflow: [] as readonly OverflowTab[] };
115
- }
116
- const totalNatural =
117
- tabWidths.reduce((s, w) => s + w, 0) + gap * Math.max(0, tabs.length - 1);
118
- if (totalNatural <= containerWidth) {
119
- return { visible: tabs, overflow: [] as readonly OverflowTab[] };
120
- }
121
- const budget = containerWidth - moreTriggerWidth;
122
- const vis: OverflowTab[] = [];
123
- const over: OverflowTab[] = [];
124
- let used = 0;
125
- for (const [i, tab] of tabs.entries()) {
126
- const natural = tabWidths[i];
127
- if (natural === undefined) {
128
- // Unreachable: the length-parity guard above already returned. Kept as a
129
- // real check because the alternative — treating a missing measurement as
130
- // 0px — would lay tabs out against a budget they don't actually fit.
131
- // Fall back to the same all-visible layout the parity guard renders.
132
- return { visible: tabs, overflow: [] as readonly OverflowTab[] };
133
- }
134
- const w = natural + (vis.length > 0 ? gap : 0);
135
- // A pinned tab is never collapsed — it stays visible whatever the budget
136
- // says, so a panel's permanent first tab can't hide behind "More…".
137
- if (tab.pinned === true || used + w <= budget) {
138
- vis.push(tab);
139
- used += w;
140
- } else {
141
- over.push(tab);
142
- }
143
- }
144
- // Force the active tab into the visible set if it ended up in overflow.
145
- // `find` (not `findIndex` + lookup) so the hit is typed as present.
146
- const activeTab = tabs.find((t) => t.value === value);
147
- if (activeTab !== undefined) {
148
- const inVisible = vis.some((t) => t.value === activeTab.value);
149
- if (!inVisible) {
150
- // Swap the last visible for the active one to keep the budget OK.
151
- const dropped = vis.pop();
152
- if (dropped) {
153
- over.unshift(dropped);
154
- }
155
- vis.push(activeTab);
156
- const removeIdx = over.findIndex((t) => t.value === activeTab.value);
157
- if (removeIdx !== -1) {
158
- over.splice(removeIdx, 1);
159
- }
160
- }
161
- }
162
- return { visible: vis, overflow: over };
163
- }, [tabs, tabWidths, containerWidth, gap, moreTriggerWidth, value]);
164
-
165
- return (
166
- <div
167
- className={cn(
168
- 'relative -mb-px flex items-end border-b border-rule',
169
- className,
170
- )}
171
- >
172
- {/* Off-screen measurement layer — renders ALL tabs so widths are real. */}
173
- <div
174
- ref={measureRef}
175
- aria-hidden
176
- className="pointer-events-none absolute left-0 top-0 flex items-center gap-1 opacity-0"
177
- style={{ visibility: 'hidden' }}
178
- >
179
- {tabs.map((t) => (
180
- <TabPill
181
- key={`measure-${t.value}`}
182
- tab={t}
183
- active={false}
184
- onClick={() => undefined}
185
- />
186
- ))}
187
- </div>
188
-
189
- {/* Live visible row. */}
190
- <div
191
- ref={containerRef}
192
- role="tablist"
193
- className="flex flex-1 items-end gap-1 overflow-hidden"
194
- >
195
- {visible.map((t) => (
196
- <TabPill
197
- key={t.value}
198
- tab={t}
199
- active={t.value === value}
200
- onClick={() => onChange(t.value)}
201
- onClose={
202
- onClose && t.pinned !== true ? () => onClose(t.value) : undefined
203
- }
204
- />
205
- ))}
206
- </div>
207
-
208
- {overflow.length > 0 && (
209
- <DropdownMenu>
210
- <DropdownMenuTrigger asChild>
211
- <button
212
- type="button"
213
- className="ml-1 -mb-px inline-flex shrink-0 items-center gap-1 whitespace-nowrap px-2 py-2 text-body-1 text-ink-3 transition-colors hover:text-ink"
214
- aria-label="More tabs"
215
- >
216
- More
217
- <span className="rounded bg-paper-elev px-1 font-mono text-[10px] leading-4 text-ink-4">
218
- {overflow.length}
219
- </span>
220
- <ChevronDown className="h-3 w-3" strokeWidth={1.6} />
221
- </button>
222
- </DropdownMenuTrigger>
223
- <DropdownMenuContent align="end" className="min-w-[180px]">
224
- {overflow.map((t) => (
225
- <DropdownMenuItem
226
- key={t.value}
227
- onClick={() => onChange(t.value)}
228
- className={cn(
229
- t.value === value && 'bg-accent/60 text-foreground',
230
- )}
231
- >
232
- <span className="flex-1 truncate">{t.label}</span>
233
- {t.count !== undefined && (
234
- <span className="ml-2 text-caption tabular-nums text-ink-4">
235
- {t.count}
236
- </span>
237
- )}
238
- {t.indicator && (
239
- <span
240
- aria-hidden
241
- className="ml-2 inline-block h-1.5 w-1.5 rounded-full bg-warning"
242
- />
243
- )}
244
- {onClose && t.pinned !== true && (
245
- <button
246
- type="button"
247
- aria-label={`Close ${t.label}`}
248
- className="ml-2 rounded p-0.5 text-ink-4 hover:bg-paper-elev hover:text-ink"
249
- onClick={(e) => {
250
- e.stopPropagation();
251
- onClose(t.value);
252
- }}
253
- >
254
- <X className="h-3 w-3" strokeWidth={1.8} />
255
- </button>
256
- )}
257
- </DropdownMenuItem>
258
- ))}
259
- </DropdownMenuContent>
260
- </DropdownMenu>
261
- )}
262
- </div>
263
- );
264
- }
265
-
266
- function TabPill({
267
- tab,
268
- active,
269
- onClick,
270
- onClose,
271
- }: Readonly<{
272
- tab: OverflowTab;
273
- active: boolean;
274
- onClick: () => void;
275
- onClose?: () => void;
276
- }>) {
277
- return (
278
- <div
279
- className={cn(
280
- 'group relative -mb-px inline-flex items-center gap-1.5 whitespace-nowrap rounded-t-md border px-3 py-2 text-body-1 transition-colors',
281
- active
282
- ? 'border-rule border-b-transparent bg-paper-elev text-ink font-medium'
283
- : 'border-transparent text-ink-3 hover:border-rule/40 hover:bg-paper-elev/60 hover:text-ink-2',
284
- )}
285
- >
286
- <button
287
- type="button"
288
- role="tab"
289
- aria-selected={active}
290
- onClick={onClick}
291
- className="inline-flex items-center gap-2 outline-none"
292
- >
293
- {tab.icon && <tab.icon className="h-3.5 w-3.5 shrink-0" />}
294
- {tab.label}
295
- {tab.count !== undefined && (
296
- <span className="rounded bg-paper-elev px-1 font-mono text-[10px] tabular-nums leading-4 text-ink-4">
297
- {tab.count}
298
- </span>
299
- )}
300
- {tab.indicator && (
301
- <span
302
- aria-hidden
303
- className="inline-block h-1.5 w-1.5 rounded-full bg-warning"
304
- />
305
- )}
306
- </button>
307
- {onClose && (
308
- <button
309
- type="button"
310
- aria-label={`Close ${tab.label}`}
311
- onClick={(e) => {
312
- e.stopPropagation();
313
- onClose();
314
- }}
315
- className={cn(
316
- 'rounded p-0.5 text-ink-4 transition-opacity hover:bg-paper hover:text-ink',
317
- active ? 'opacity-70' : 'opacity-0 group-hover:opacity-70',
318
- )}
319
- >
320
- <X className="h-3 w-3" strokeWidth={1.8} />
321
- </button>
322
- )}
323
- {active && (
324
- <span
325
- aria-hidden
326
- className="absolute inset-x-2 bottom-[-1px] h-[2px] rounded-full bg-primary"
327
- />
328
- )}
329
- </div>
330
- );
331
- }
@@ -1,33 +0,0 @@
1
- import * as PopoverPrimitive from "@radix-ui/react-popover";
2
- import * as React from "react";
3
-
4
- import { cn } from '../cn';
5
-
6
- const Popover = PopoverPrimitive.Root;
7
-
8
- const PopoverTrigger = PopoverPrimitive.Trigger;
9
-
10
- type PopoverContentProps = React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content> & {
11
- container?: HTMLElement | null;
12
- };
13
-
14
- const PopoverContent = React.forwardRef<
15
- React.ElementRef<typeof PopoverPrimitive.Content>,
16
- PopoverContentProps
17
- >(({ className, align = "center", sideOffset = 4, container, ...props }, ref) => (
18
- <PopoverPrimitive.Portal container={container ?? undefined}>
19
- <PopoverPrimitive.Content
20
- ref={ref}
21
- align={align}
22
- sideOffset={sideOffset}
23
- className={cn(
24
- "z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
25
- className,
26
- )}
27
- {...props}
28
- />
29
- </PopoverPrimitive.Portal>
30
- ));
31
- PopoverContent.displayName = PopoverPrimitive.Content.displayName;
32
-
33
- export { Popover, PopoverTrigger, PopoverContent };