raft-ui 0.0.6 → 0.0.8

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 (138) hide show
  1. package/CHANGELOG.md +7 -5
  2. package/dist/index.d.mts +618 -2
  3. package/dist/index.mjs +1205 -12
  4. package/{src → dist}/styles.css +0 -2
  5. package/{src/lib/styled-props.ts → dist/tv-UUMwNowu.d.mts} +6 -1
  6. package/dist/use-theme-Y_h1DKll.mjs +34 -0
  7. package/dist/wip.d.mts +15 -133
  8. package/dist/wip.mjs +23 -296
  9. package/package.json +4 -4
  10. package/dist/button-CJqMhTPQ.mjs +0 -621
  11. package/dist/index-CpGciYPW.d.mts +0 -267
  12. package/src/components/alert-dialog/alert-dialog.tsx +0 -215
  13. package/src/components/alert-dialog/index.ts +0 -30
  14. package/src/components/avatar/avatar.tsx +0 -375
  15. package/src/components/avatar/index.ts +0 -17
  16. package/src/components/badge/badge.tsx +0 -393
  17. package/src/components/badge/index.ts +0 -2
  18. package/src/components/banner/banner.tsx +0 -269
  19. package/src/components/banner/index.ts +0 -8
  20. package/src/components/bottom-sheet/bottom-sheet.tsx +0 -152
  21. package/src/components/bottom-sheet/index.ts +0 -22
  22. package/src/components/button/button.tsx +0 -499
  23. package/src/components/button/index.ts +0 -2
  24. package/src/components/checkbox/checkbox-indicator.tsx +0 -128
  25. package/src/components/checkbox/checkbox.tsx +0 -350
  26. package/src/components/checkbox/index.ts +0 -2
  27. package/src/components/combobox/combobox.tsx +0 -603
  28. package/src/components/combobox/index.ts +0 -52
  29. package/src/components/context-menu/context-menu.tsx +0 -380
  30. package/src/components/context-menu/index.ts +0 -34
  31. package/src/components/conversation-preview-card/conversation-preview-card.tsx +0 -336
  32. package/src/components/conversation-preview-card/index.ts +0 -32
  33. package/src/components/description-list/description-list.tsx +0 -116
  34. package/src/components/description-list/index.ts +0 -14
  35. package/src/components/dialog/dialog.tsx +0 -152
  36. package/src/components/dialog/index.ts +0 -26
  37. package/src/components/dropdown-menu/dropdown-menu.tsx +0 -405
  38. package/src/components/dropdown-menu/index.ts +0 -38
  39. package/src/components/empty-state/empty-state.tsx +0 -177
  40. package/src/components/empty-state/index.ts +0 -16
  41. package/src/components/field/field.tsx +0 -125
  42. package/src/components/field/index.ts +0 -18
  43. package/src/components/inline-code/index.ts +0 -2
  44. package/src/components/inline-code/inline-code.tsx +0 -35
  45. package/src/components/input/index.ts +0 -2
  46. package/src/components/input/input.tsx +0 -76
  47. package/src/components/input-group/index.ts +0 -7
  48. package/src/components/input-group/input-group.tsx +0 -215
  49. package/src/components/kbd/index.ts +0 -2
  50. package/src/components/kbd/kbd.tsx +0 -43
  51. package/src/components/label/index.ts +0 -2
  52. package/src/components/label/label.tsx +0 -99
  53. package/src/components/lightbox/index.ts +0 -24
  54. package/src/components/lightbox/lightbox.tsx +0 -245
  55. package/src/components/list-item/index.ts +0 -20
  56. package/src/components/list-item/list-item.tsx +0 -263
  57. package/src/components/media-list-item/index.ts +0 -20
  58. package/src/components/media-list-item/media-list-item.tsx +0 -169
  59. package/src/components/notification-center/index.ts +0 -39
  60. package/src/components/notification-center/notification-center.tsx +0 -558
  61. package/src/components/panel-header/index.ts +0 -22
  62. package/src/components/panel-header/panel-header.tsx +0 -199
  63. package/src/components/popover/index.ts +0 -30
  64. package/src/components/popover/popover.tsx +0 -248
  65. package/src/components/preview-shell/index.ts +0 -2
  66. package/src/components/preview-shell/preview-shell.tsx +0 -51
  67. package/src/components/quoted-message-card/index.ts +0 -36
  68. package/src/components/quoted-message-card/quoted-message-card.tsx +0 -391
  69. package/src/components/radio-group/index.ts +0 -2
  70. package/src/components/radio-group/radio-group.tsx +0 -119
  71. package/src/components/section-header/index.ts +0 -16
  72. package/src/components/section-header/section-header.tsx +0 -117
  73. package/src/components/section-label/index.ts +0 -2
  74. package/src/components/section-label/section-label.tsx +0 -38
  75. package/src/components/segmented-control/index.ts +0 -12
  76. package/src/components/segmented-control/segmented-control.tsx +0 -129
  77. package/src/components/select/index.ts +0 -40
  78. package/src/components/select/select.tsx +0 -382
  79. package/src/components/separator/index.ts +0 -2
  80. package/src/components/separator/separator.tsx +0 -40
  81. package/src/components/spinner/index.ts +0 -2
  82. package/src/components/spinner/spinner.tsx +0 -228
  83. package/src/components/status/index.ts +0 -2
  84. package/src/components/status/status.tsx +0 -152
  85. package/src/components/tabs/index.ts +0 -24
  86. package/src/components/tabs/tabs.tsx +0 -451
  87. package/src/components/text/index.ts +0 -2
  88. package/src/components/text/text.tsx +0 -131
  89. package/src/components/textarea/index.ts +0 -2
  90. package/src/components/textarea/textarea.tsx +0 -136
  91. package/src/components/toggle-group/index.ts +0 -7
  92. package/src/components/toggle-group/toggle-group.tsx +0 -111
  93. package/src/components/tooltip/index.ts +0 -8
  94. package/src/components/tooltip/tooltip.tsx +0 -212
  95. package/src/index.ts +0 -429
  96. package/src/legacy/AttentionDot.tsx +0 -28
  97. package/src/legacy/AvatarListRow.tsx +0 -87
  98. package/src/legacy/AvatarSlot.tsx +0 -157
  99. package/src/legacy/Badge.tsx +0 -95
  100. package/src/legacy/Banner.tsx +0 -74
  101. package/src/legacy/BottomSheet.tsx +0 -76
  102. package/src/legacy/CheckMarker.tsx +0 -72
  103. package/src/legacy/Checkbox.tsx +0 -81
  104. package/src/legacy/ConversationPreviewCard.tsx +0 -169
  105. package/src/legacy/DismissBackdrop.tsx +0 -68
  106. package/src/legacy/EmptyState.tsx +0 -63
  107. package/src/legacy/ExperimentalBadge.tsx +0 -19
  108. package/src/legacy/FormField.tsx +0 -106
  109. package/src/legacy/KeyValueRow.tsx +0 -67
  110. package/src/legacy/Lightbox.tsx +0 -119
  111. package/src/legacy/NotificationCenter.tsx +0 -217
  112. package/src/legacy/PanelHeader.tsx +0 -94
  113. package/src/legacy/PreviewShell.tsx +0 -40
  114. package/src/legacy/QuotedMessageCard.tsx +0 -181
  115. package/src/legacy/ReorderablePanelTabs.tsx +0 -156
  116. package/src/legacy/SandboxedPreviewFrame.tsx +0 -59
  117. package/src/legacy/SearchInput.tsx +0 -23
  118. package/src/legacy/SectionEyebrow.tsx +0 -60
  119. package/src/legacy/SectionHeader.tsx +0 -68
  120. package/src/legacy/SegmentedControl.tsx +0 -74
  121. package/src/legacy/SlugInput.tsx +0 -29
  122. package/src/legacy/Spinner.tsx +0 -89
  123. package/src/legacy/StatusDot.tsx +0 -51
  124. package/src/legacy/SurfaceListItem.tsx +0 -32
  125. package/src/legacy/Textarea.tsx +0 -137
  126. package/src/legacy/button.tsx +0 -100
  127. package/src/legacy/context-menu-divider.tsx +0 -12
  128. package/src/legacy/menu-item.tsx +0 -66
  129. package/src/legacy/selection-popover.tsx +0 -212
  130. package/src/legacy/server-switcher-menu.tsx +0 -203
  131. package/src/legacy/source.css +0 -240
  132. package/src/lib/cn.ts +0 -1
  133. package/src/lib/theme/theme-context.ts +0 -28
  134. package/src/lib/theme/theme-provider.tsx +0 -181
  135. package/src/lib/theme/use-theme.ts +0 -12
  136. package/src/lib/tv.ts +0 -29
  137. package/src/lib/without-children.ts +0 -6
  138. package/src/wip.ts +0 -291
@@ -1,451 +0,0 @@
1
- import {
2
- createContext,
3
- use,
4
- useCallback,
5
- useMemo,
6
- useState,
7
- type ComponentPropsWithRef,
8
- type CSSProperties,
9
- } from "react";
10
- import { Tabs as BaseTabs } from "@base-ui/react/tabs";
11
- import {
12
- closestCenter,
13
- DndContext,
14
- PointerSensor,
15
- TouchSensor,
16
- useSensor,
17
- useSensors,
18
- type DragEndEvent,
19
- type DragStartEvent,
20
- } from "@dnd-kit/core";
21
- import {
22
- arrayMove,
23
- horizontalListSortingStrategy,
24
- SortableContext,
25
- useSortable,
26
- } from "@dnd-kit/sortable";
27
- import { tv, type VariantProps } from "../../lib/tv";
28
- import type { StyledProps } from "../../lib/styled-props";
29
- import { useThemeFamily } from "../../lib/theme/use-theme";
30
-
31
- const tabs = tv({
32
- slots: {
33
- root: ["w-full"],
34
- list: [""],
35
- background: [""],
36
- tab: [
37
- "relative z-10 flex shrink-0 touch-manipulation items-center gap-1.5 whitespace-nowrap outline-none",
38
- "data-[reorderable=true]:cursor-grab data-[reorderable=true]:active:cursor-grabbing",
39
- ],
40
- content: ["relative z-10 inline-flex items-center gap-[inherit]"],
41
- label: [""],
42
- panel: ["outline-none"],
43
- indicator: [""],
44
- },
45
- variants: {
46
- theme: {
47
- brutal: {
48
- list: [
49
- "flex w-max max-w-full overflow-x-auto border-2 border-line-strong bg-layer-panel",
50
- "data-[sorting=true]:[overflow-x:hidden]",
51
- "[scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
52
- ],
53
- background: "hidden",
54
- tab: [
55
- "bg-layer-panel px-4 py-1.5 text-xs font-semibold transition-colors",
56
- "hover:bg-[color-mix(in_oklch,var(--line-strong)_6%,var(--layer-panel))]",
57
- "[&+&]:before:absolute [&+&]:before:inset-y-0 [&+&]:before:left-0 [&+&]:before:w-0.5 [&+&]:before:bg-line-strong",
58
- "data-[dragging-source=true]:before:hidden",
59
- "[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:[stroke-width:1.5] [&_svg:not([class*='size-'])]:size-3.5",
60
- "data-[active]:bg-primary-400 data-[active]:hover:bg-primary-400",
61
- "data-[disabled]:pointer-events-none data-[disabled]:opacity-40",
62
- "data-[dragging-source=true]:cursor-grabbing",
63
- ],
64
- },
65
- elegant: {},
66
- },
67
- variant: {
68
- default: {},
69
- underline: {},
70
- },
71
- },
72
- defaultVariants: {
73
- variant: "default",
74
- },
75
- compoundVariants: [
76
- {
77
- theme: "elegant",
78
- variant: "underline",
79
- class: {
80
- list: [
81
- "group/tabs-list relative flex h-12 w-max max-w-full items-center gap-6 px-4",
82
- "overflow-x-auto overflow-y-hidden overscroll-contain whitespace-nowrap",
83
- "border-b border-line-muted",
84
- "data-[sorting=true]:[overflow-x:hidden]",
85
- "data-[sorting=true]:[&_[data-slot=tabs-indicator]]:opacity-0 data-[sorting=true]:[&_[data-slot=tabs-indicator]]:transition-none",
86
- "[scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
87
- ],
88
- background: ["pointer-events-none absolute inset-x-0 top-0 z-0 h-px bg-line-muted"],
89
- tab: [
90
- "group/tabs-tab h-12 justify-center px-3 pb-3 pt-3.5",
91
- "text-[0.8125rem] font-medium tracking-[-0.005em] text-foreground-placeholder",
92
- "transition-colors duration-200 ease-out",
93
- "hover:text-foreground-muted",
94
- "data-[active]:text-foreground-strong",
95
- "data-[active]:hover:text-foreground-strong",
96
- "[&_svg]:pointer-events-none [&_svg]:size-3.5 [&_svg]:shrink-0 [&_svg]:[stroke-width:1.5]",
97
- "[&_svg]:text-foreground-placeholder [&_svg]:transition-colors [&_svg]:duration-200 [&_svg]:ease-out",
98
- "hover:[&_svg]:text-foreground-muted",
99
- "data-[active]:[&_svg]:text-foreground-strong",
100
- "data-[active]:hover:[&_svg]:text-foreground-strong",
101
- "data-[disabled]:pointer-events-none data-[disabled]:opacity-40",
102
- "data-[dragging-source=true]:cursor-grabbing",
103
- ],
104
- indicator: [
105
- "absolute bottom-0 left-[var(--active-tab-left)] z-10 h-0.5",
106
- "w-[var(--active-tab-width)] bg-foreground-strong",
107
- "transition-[left,width] duration-300 ease-[cubic-bezier(0.65,0,0.35,1)]",
108
- ],
109
- },
110
- },
111
- {
112
- theme: "elegant",
113
- variant: "default",
114
- class: {
115
- list: [
116
- "group/tabs-list relative isolate flex h-auto w-max max-w-full items-center gap-1",
117
- "overflow-x-auto overflow-y-visible overscroll-contain whitespace-nowrap",
118
- "p-px",
119
- "data-[sorting=true]:[overflow-x:hidden]",
120
- "data-[sorting=true]:[&_[data-slot=tabs-indicator]]:opacity-0 data-[sorting=true]:[&_[data-slot=tabs-indicator]]:transition-none",
121
- "[scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
122
- ],
123
- background: ["pointer-events-none absolute inset-0 z-0 rounded-[7px] bg-layer-muted"],
124
- tab: [
125
- "group/tabs-tab h-9 justify-center gap-1.5 rounded-md px-3.5 py-2",
126
- "text-[0.8125rem] font-medium tracking-[-0.005em] text-foreground-placeholder",
127
- "transition-[background-color,box-shadow,color] duration-150 ease-out",
128
- "hover:text-[oklch(42%_.006_285)]",
129
- "data-[active]:text-[oklch(38%_.006_285)]",
130
- "data-[active]:hover:text-[oklch(38%_.006_285)]",
131
- "data-[active]:[&_[data-slot=tabs-label]]:text-[0.8125rem]",
132
- "data-[reorderable=true]:data-[active]:bg-layer-panel",
133
- "data-[reorderable=true]:data-[active]:shadow-[0_0_0_1px_oklch(0%_0_0/.1),0_1px_1px_-1px_oklch(0%_0_0/.04),0_1px_2px_oklch(0%_0_0/.03)]",
134
- "group-has-[>[data-slot=tabs-background]]/tabs-list:data-[reorderable=true]:data-[active]:shadow-[0_0_0_1px_oklch(0%_0_0/.045),0_1px_1px_-1px_oklch(0%_0_0/.025),0_1px_2px_oklch(0%_0_0/.02)]",
135
- "data-[dragging-active=true]:bg-layer-panel",
136
- "data-[dragging-active=true]:shadow-[0_0_0_1px_oklch(0%_0_0/.1),0_1px_1px_-1px_oklch(0%_0_0/.04),0_1px_2px_oklch(0%_0_0/.03)]",
137
- "[&_svg]:pointer-events-none [&_svg]:size-3.5 [&_svg]:shrink-0 [&_svg]:[stroke-width:1.5]",
138
- "[&_svg]:text-foreground-placeholder [&_svg]:transition-colors [&_svg]:duration-150 [&_svg]:ease-out",
139
- "hover:[&_svg]:text-[oklch(42%_.006_285)]",
140
- "data-[active]:[&_svg]:text-[oklch(38%_.006_285)]",
141
- "data-[disabled]:pointer-events-none data-[disabled]:opacity-40",
142
- "data-[dragging-source=true]:cursor-grabbing",
143
- ],
144
- indicator: [
145
- "absolute z-0 rounded-md bg-layer-panel",
146
- "[left:calc(var(--active-tab-left)+1px)] [top:calc(var(--active-tab-top)+1.671875px)]",
147
- "[height:calc(var(--active-tab-height)-3.34375px)] [width:calc(var(--active-tab-width)-2px)]",
148
- "shadow-[0_0_0_1px_oklch(0%_0_0/.1),0_1px_1px_-1px_oklch(0%_0_0/.04),0_1px_2px_oklch(0%_0_0/.03)]",
149
- "group-has-[>[data-slot=tabs-background]]/tabs-list:shadow-[0_0_0_1px_oklch(0%_0_0/.045),0_1px_1px_-1px_oklch(0%_0_0/.025),0_1px_2px_oklch(0%_0_0/.02)]",
150
- "transition-[left,width] duration-300 ease-[cubic-bezier(0.65,0,0.35,1)]",
151
- ],
152
- },
153
- },
154
- ],
155
- });
156
-
157
- type TabsReorderContextValue = {
158
- enabled: boolean;
159
- activeId?: string | undefined;
160
- };
161
-
162
- const TabsReorderContext = createContext<TabsReorderContextValue>({ enabled: false });
163
- const TabsValueContext = createContext<string | undefined>(undefined);
164
- type TabsListVariant = "default" | "underline";
165
-
166
- const TabsListVariantContext = createContext<TabsListVariant>("default");
167
-
168
- export type TabsProps<T extends string = string> = StyledProps<
169
- Omit<BaseTabs.Root.Props, "defaultValue" | "onValueChange" | "value">
170
- > &
171
- Omit<VariantProps<typeof tabs>, "theme"> & {
172
- value?: T;
173
- defaultValue?: T;
174
- onValueChange?: (value: T, eventDetails: BaseTabs.Root.ChangeEventDetails) => void;
175
- };
176
-
177
- export function Tabs<T extends string = string>({
178
- value,
179
- defaultValue,
180
- onValueChange,
181
- className,
182
- ...props
183
- }: TabsProps<T>) {
184
- const [uncontrolledValue, setUncontrolledValue] = useState<T | undefined>(defaultValue);
185
- const resolvedValue = value ?? uncontrolledValue;
186
- const { root } = tabs();
187
-
188
- return (
189
- <TabsValueContext.Provider value={resolvedValue == null ? undefined : String(resolvedValue)}>
190
- <BaseTabs.Root
191
- value={value}
192
- defaultValue={defaultValue}
193
- onValueChange={(nextValue, eventDetails) => {
194
- if (nextValue == null) return;
195
- const typedValue = String(nextValue) as T;
196
- if (value === undefined) setUncontrolledValue(typedValue);
197
- onValueChange?.(typedValue, eventDetails);
198
- }}
199
- data-slot="tabs"
200
- className={root({ className })}
201
- {...props}
202
- />
203
- </TabsValueContext.Provider>
204
- );
205
- }
206
-
207
- export type TabsListProps = StyledProps<BaseTabs.List.Props> & {
208
- variant?: TabsListVariant;
209
- };
210
-
211
- export function TabsList({ className, children, variant = "default", ...props }: TabsListProps) {
212
- const theme = useThemeFamily();
213
- const reorder = use(TabsReorderContext);
214
- const resolvedVariant = theme === "elegant" ? variant : "underline";
215
- const { list } = tabs({ theme, variant: resolvedVariant });
216
-
217
- return (
218
- <TabsListVariantContext.Provider value={resolvedVariant}>
219
- <BaseTabs.List
220
- data-slot="tabs-list"
221
- data-variant={resolvedVariant}
222
- className={list({ className })}
223
- {...props}
224
- >
225
- {children}
226
- {theme === "elegant" && !reorder.enabled ? <TabsIndicator /> : null}
227
- </BaseTabs.List>
228
- </TabsListVariantContext.Provider>
229
- );
230
- }
231
-
232
- export type SortableTabsListProps<T extends string = string> = TabsListProps & {
233
- value: readonly T[];
234
- onReorder: (value: T[]) => void;
235
- };
236
-
237
- export function SortableTabsList<T extends string = string>({
238
- value,
239
- onReorder,
240
- children,
241
- variant = "default",
242
- ...props
243
- }: SortableTabsListProps<T>) {
244
- const [activeId, setActiveId] = useState<string | undefined>(undefined);
245
- const sensors = useSensors(
246
- useSensor(PointerSensor, { activationConstraint: { distance: 6 } }),
247
- useSensor(TouchSensor, { activationConstraint: { delay: 350, tolerance: 8 } }),
248
- );
249
- const tabIds = useMemo(() => value.map(String), [value]);
250
- const reorderContext = useMemo(
251
- () => ({ enabled: true, activeId }) as const satisfies TabsReorderContextValue,
252
- [activeId],
253
- );
254
- const handleDragStart = useCallback(({ active }: DragStartEvent) => {
255
- setActiveId(String(active.id));
256
- }, []);
257
- const handleDragCancel = useCallback(() => {
258
- setActiveId(undefined);
259
- }, []);
260
- const handleDragEnd = useCallback(
261
- ({ active, over }: DragEndEvent) => {
262
- setActiveId(undefined);
263
- if (!over || active.id === over.id) return;
264
- const oldIndex = tabIds.indexOf(String(active.id));
265
- const newIndex = tabIds.indexOf(String(over.id));
266
- if (oldIndex === -1 || newIndex === -1) return;
267
- onReorder(arrayMove([...value], oldIndex, newIndex) as T[]);
268
- },
269
- [onReorder, tabIds, value],
270
- );
271
-
272
- return (
273
- <DndContext
274
- autoScroll={false}
275
- sensors={sensors}
276
- collisionDetection={closestCenter}
277
- onDragStart={handleDragStart}
278
- onDragCancel={handleDragCancel}
279
- onDragEnd={handleDragEnd}
280
- >
281
- <SortableContext items={tabIds} strategy={horizontalListSortingStrategy}>
282
- <TabsReorderContext.Provider value={reorderContext}>
283
- <TabsList variant={variant} {...props} data-sorting={activeId ? "true" : undefined}>
284
- {children}
285
- </TabsList>
286
- </TabsReorderContext.Provider>
287
- </SortableContext>
288
- </DndContext>
289
- );
290
- }
291
-
292
- export type TabsTabProps<T extends string = string> = StyledProps<BaseTabs.Tab.Props> & {
293
- value: T;
294
- };
295
-
296
- export function TabsTab<T extends string = string>({ value, ...props }: TabsTabProps<T>) {
297
- return <TabsTabButton value={value} {...props} />;
298
- }
299
-
300
- export type SortableTabsTabProps<T extends string = string> = TabsTabProps<T>;
301
-
302
- export function SortableTabsTab<T extends string = string>({
303
- value,
304
- ...props
305
- }: SortableTabsTabProps<T>) {
306
- const reorder = use(TabsReorderContext);
307
- const activeValue = use(TabsValueContext);
308
- const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
309
- id: value,
310
- disabled: !reorder.enabled,
311
- });
312
- const isDraggingActive = isDragging && activeValue === String(value);
313
-
314
- if (!reorder.enabled) {
315
- return <TabsTabButton value={value} {...props} />;
316
- }
317
-
318
- const { role: _sortableRole, tabIndex: _sortableTabIndex, ...sortableAttributes } = attributes;
319
- const baseStyle = typeof props.style === "function" ? undefined : props.style;
320
- const style: CSSProperties = {
321
- ...baseStyle,
322
- transform: transform ? `translate3d(${transform.x}px, 0, 0)` : undefined,
323
- transition,
324
- zIndex: isDragging ? 20 : baseStyle?.zIndex,
325
- };
326
-
327
- return (
328
- <TabsTabButton
329
- value={value}
330
- sortableRef={setNodeRef}
331
- {...props}
332
- data-dragging-active={isDraggingActive ? "true" : undefined}
333
- data-dragging-source={isDragging ? "true" : undefined}
334
- data-reorderable="true"
335
- style={style}
336
- {...sortableAttributes}
337
- {...listeners}
338
- />
339
- );
340
- }
341
-
342
- function TabsTabButton<T extends string = string>({
343
- value,
344
- sortableRef,
345
- className,
346
- children,
347
- ...props
348
- }: TabsTabProps<T> & {
349
- sortableRef?: (node: HTMLElement | null) => void;
350
- }) {
351
- const theme = useThemeFamily();
352
- const variant = use(TabsListVariantContext);
353
- const { content, tab } = tabs({ theme, variant: theme === "elegant" ? variant : "underline" });
354
-
355
- return (
356
- <BaseTabs.Tab
357
- ref={(node) => {
358
- sortableRef?.(node);
359
- }}
360
- value={value}
361
- data-slot="tabs-tab"
362
- className={tab({ className })}
363
- {...props}
364
- >
365
- <span data-slot="tabs-tab-content" className={content()}>
366
- {children}
367
- </span>
368
- </BaseTabs.Tab>
369
- );
370
- }
371
-
372
- export type TabsLabelProps = ComponentPropsWithRef<"span">;
373
-
374
- export function TabsLabel({ className, ...props }: TabsLabelProps) {
375
- const { label } = tabs();
376
- return <span data-slot="tabs-label" className={label({ className })} {...props} />;
377
- }
378
-
379
- export type TabsPanelProps = StyledProps<BaseTabs.Panel.Props>;
380
-
381
- export function TabsPanel({ className, ...props }: TabsPanelProps) {
382
- const { panel } = tabs();
383
- return <BaseTabs.Panel data-slot="tabs-panel" className={panel({ className })} {...props} />;
384
- }
385
-
386
- export type TabsBackgroundProps = ComponentPropsWithRef<"span">;
387
-
388
- export function TabsBackground({ className, ...props }: TabsBackgroundProps) {
389
- const theme = useThemeFamily();
390
- const variant = use(TabsListVariantContext);
391
- const { background } = tabs({ theme, variant: theme === "elegant" ? variant : "underline" });
392
-
393
- return (
394
- <span
395
- aria-hidden="true"
396
- data-slot="tabs-background"
397
- className={background({ className })}
398
- {...props}
399
- />
400
- );
401
- }
402
-
403
- export type TabsIndicatorProps = StyledProps<BaseTabs.Indicator.Props>;
404
-
405
- export function TabsIndicator({ className, ...props }: TabsIndicatorProps) {
406
- const theme = useThemeFamily();
407
- const variant = use(TabsListVariantContext);
408
- const { indicator } = tabs({ theme, variant: theme === "elegant" ? variant : "underline" });
409
- return (
410
- <BaseTabs.Indicator
411
- data-slot="tabs-indicator"
412
- className={indicator({ className })}
413
- {...props}
414
- />
415
- );
416
- }
417
-
418
- export type OrderedTabItem<T extends string = string> = {
419
- id: T;
420
- };
421
-
422
- export function useOrderedTabs<T extends OrderedTabItem<string>>(
423
- items: readonly T[],
424
- storedOrder: readonly string[],
425
- ): T[] {
426
- return useMemo(() => reconcileTabOrder(items, storedOrder), [items, storedOrder]);
427
- }
428
-
429
- function reconcileTabOrder<T extends OrderedTabItem<string>>(
430
- items: readonly T[],
431
- order: readonly string[],
432
- ): T[] {
433
- const byId = new Map(items.map((item) => [item.id, item]));
434
- const next: T[] = [];
435
- const seen = new Set<string>();
436
-
437
- for (const id of order) {
438
- const item = byId.get(id);
439
- if (!item || seen.has(item.id)) continue;
440
- next.push(item);
441
- seen.add(item.id);
442
- }
443
-
444
- for (const item of items) {
445
- if (seen.has(item.id)) continue;
446
- next.push(item);
447
- seen.add(item.id);
448
- }
449
-
450
- return next;
451
- }
@@ -1,2 +0,0 @@
1
- export { Text, TextHeading, TextMono, TextSans } from "./text";
2
- export type { TextHeadingProps, TextMonoProps, TextSansProps } from "./text";
@@ -1,131 +0,0 @@
1
- import { mergeProps } from "@base-ui/react/merge-props";
2
- import { useRender } from "@base-ui/react/use-render";
3
- import { tv, type VariantProps } from "../../lib/tv";
4
-
5
- const textColorVariants = {
6
- default: ["text-foreground-strong"],
7
- primary: ["text-primary-700"],
8
- information: ["text-info-dark"],
9
- muted: ["text-foreground-muted"],
10
- placeholder: ["text-foreground-placeholder"],
11
- accent: ["text-accent-700"],
12
- success: ["text-success-base"],
13
- warning: ["text-warning-base"],
14
- danger: ["text-danger-base"],
15
- };
16
-
17
- const heading = tv({
18
- base: ["m-0 font-heading font-medium text-foreground-strong"],
19
- variants: {
20
- level: {
21
- 1: ["text-[3.5rem] tracking-[-0.01em] leading-[64px]"],
22
- 2: ["text-[3rem] tracking-[-0.01em] leading-[56px]"],
23
- 3: ["text-[2.5rem] tracking-[-0.01em] leading-[48px]"],
24
- 4: ["text-[2rem] tracking-[-0.005em] leading-[40px]"],
25
- 5: ["text-[1.5rem] leading-8"],
26
- 6: ["text-[1.25rem] leading-7"],
27
- },
28
- variant: textColorVariants,
29
- },
30
- defaultVariants: {
31
- level: 1,
32
- },
33
- });
34
-
35
- const sans = tv({
36
- base: ["m-0 font-sans font-normal"],
37
- variants: {
38
- size: {
39
- large: ["text-lg leading-7 text-foreground"],
40
- body: ["text-base leading-6 text-foreground"],
41
- small: ["text-sm leading-5 text-foreground-muted"],
42
- caption: ["text-xs leading-4 text-foreground-muted"],
43
- },
44
- variant: textColorVariants,
45
- },
46
- defaultVariants: {
47
- size: "body",
48
- },
49
- });
50
-
51
- const mono = tv({
52
- base: ["m-0 font-mono font-normal"],
53
- variants: {
54
- size: {
55
- code: ["text-sm leading-5 text-foreground"],
56
- meta: ["text-xs leading-4 text-foreground-muted"],
57
- eyebrow: [
58
- "text-[10px] font-medium uppercase tracking-wide leading-none",
59
- "text-foreground-placeholder",
60
- ],
61
- tabular: ["text-sm tabular-nums leading-5 text-foreground"],
62
- },
63
- variant: textColorVariants,
64
- },
65
- defaultVariants: {
66
- size: "code",
67
- },
68
- });
69
-
70
- export type TextHeadingProps = useRender.ComponentProps<"h1"> & VariantProps<typeof heading>;
71
-
72
- export function TextHeading({ level = 1, variant, className, render, ...props }: TextHeadingProps) {
73
- const defaultProps: useRender.ElementProps<"h1"> = {
74
- className: heading({ level, variant, className }),
75
- };
76
-
77
- return useRender({
78
- defaultTagName: `h${level}`,
79
- render,
80
- props: mergeProps<"h1">(defaultProps, props),
81
- state: {
82
- slot: "text-heading",
83
- level,
84
- variant,
85
- },
86
- });
87
- }
88
-
89
- export type TextSansProps = useRender.ComponentProps<"p"> & VariantProps<typeof sans>;
90
-
91
- export function TextSans({ size = "body", variant, className, render, ...props }: TextSansProps) {
92
- const defaultProps: useRender.ElementProps<"p"> = {
93
- className: sans({ size, variant, className }),
94
- };
95
-
96
- return useRender({
97
- defaultTagName: "p",
98
- render,
99
- props: mergeProps<"p">(defaultProps, props),
100
- state: {
101
- slot: "text-sans",
102
- size,
103
- variant,
104
- },
105
- });
106
- }
107
-
108
- export type TextMonoProps = useRender.ComponentProps<"p"> & VariantProps<typeof mono>;
109
-
110
- export function TextMono({ size = "code", variant, className, render, ...props }: TextMonoProps) {
111
- const defaultProps: useRender.ElementProps<"p"> = {
112
- className: mono({ size, variant, className }),
113
- };
114
-
115
- return useRender({
116
- defaultTagName: "p",
117
- render,
118
- props: mergeProps<"p">(defaultProps, props),
119
- state: {
120
- slot: "text-mono",
121
- size,
122
- variant,
123
- },
124
- });
125
- }
126
-
127
- export const Text = {
128
- Heading: TextHeading,
129
- Sans: TextSans,
130
- Mono: TextMono,
131
- };
@@ -1,2 +0,0 @@
1
- export { Textarea, TextareaCounter, TextareaGroup } from "./textarea";
2
- export type { TextareaCounterProps, TextareaGroupProps, TextareaProps } from "./textarea";