raft-ui 0.0.5 → 0.0.7
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.
- package/CHANGELOG.md +5 -0
- package/dist/button-CJqMhTPQ.mjs +621 -0
- package/dist/index-CpGciYPW.d.mts +267 -0
- package/dist/index.d.mts +11 -253
- package/dist/index.mjs +32 -587
- package/{src → dist}/styles.css +0 -2
- package/dist/wip.d.mts +133 -15
- package/dist/wip.mjs +289 -16
- package/package.json +7 -10
- package/dist/styled-props-B3SNekJg.d.mts +0 -16
- package/dist/use-theme-Y_h1DKll.mjs +0 -34
- package/src/components/avatar/avatar.tsx +0 -375
- package/src/components/avatar/index.ts +0 -17
- package/src/components/badge/badge.tsx +0 -393
- package/src/components/badge/index.ts +0 -2
- package/src/components/banner/banner.tsx +0 -269
- package/src/components/banner/index.ts +0 -8
- package/src/components/bottom-sheet/bottom-sheet.tsx +0 -152
- package/src/components/bottom-sheet/index.ts +0 -22
- package/src/components/button/button.tsx +0 -497
- package/src/components/button/index.ts +0 -2
- package/src/components/checkbox/checkbox-indicator.tsx +0 -128
- package/src/components/checkbox/checkbox.tsx +0 -350
- package/src/components/checkbox/index.ts +0 -2
- package/src/components/combobox/combobox.tsx +0 -603
- package/src/components/combobox/index.ts +0 -52
- package/src/components/context-menu/context-menu.tsx +0 -380
- package/src/components/context-menu/index.ts +0 -34
- package/src/components/conversation-preview-card/conversation-preview-card.tsx +0 -336
- package/src/components/conversation-preview-card/index.ts +0 -32
- package/src/components/description-list/description-list.tsx +0 -116
- package/src/components/description-list/index.ts +0 -14
- package/src/components/dropdown-menu/dropdown-menu.tsx +0 -405
- package/src/components/dropdown-menu/index.ts +0 -38
- package/src/components/empty-state/empty-state.tsx +0 -177
- package/src/components/empty-state/index.ts +0 -16
- package/src/components/field/field.tsx +0 -125
- package/src/components/field/index.ts +0 -18
- package/src/components/inline-code/index.ts +0 -2
- package/src/components/inline-code/inline-code.tsx +0 -35
- package/src/components/input/index.ts +0 -2
- package/src/components/input/input.tsx +0 -76
- package/src/components/input-group/index.ts +0 -7
- package/src/components/input-group/input-group.tsx +0 -215
- package/src/components/kbd/index.ts +0 -2
- package/src/components/kbd/kbd.tsx +0 -43
- package/src/components/label/index.ts +0 -7
- package/src/components/label/label.tsx +0 -99
- package/src/components/lightbox/index.ts +0 -24
- package/src/components/lightbox/lightbox.tsx +0 -245
- package/src/components/list-item/index.ts +0 -20
- package/src/components/list-item/list-item.tsx +0 -263
- package/src/components/media-list-item/index.ts +0 -20
- package/src/components/media-list-item/media-list-item.tsx +0 -169
- package/src/components/notification-center/index.ts +0 -39
- package/src/components/notification-center/notification-center.tsx +0 -558
- package/src/components/panel-header/index.ts +0 -22
- package/src/components/panel-header/panel-header.tsx +0 -199
- package/src/components/popover/index.ts +0 -30
- package/src/components/popover/popover.tsx +0 -248
- package/src/components/preview-shell/index.ts +0 -2
- package/src/components/preview-shell/preview-shell.tsx +0 -51
- package/src/components/quoted-message-card/index.ts +0 -36
- package/src/components/quoted-message-card/quoted-message-card.tsx +0 -391
- package/src/components/radio-group/index.ts +0 -6
- package/src/components/radio-group/radio-group.tsx +0 -119
- package/src/components/section-header/index.ts +0 -16
- package/src/components/section-header/section-header.tsx +0 -117
- package/src/components/section-label/index.ts +0 -2
- package/src/components/section-label/section-label.tsx +0 -38
- package/src/components/segmented-control/index.ts +0 -12
- package/src/components/segmented-control/segmented-control.tsx +0 -129
- package/src/components/select/index.ts +0 -40
- package/src/components/select/select.tsx +0 -382
- package/src/components/spinner/index.ts +0 -2
- package/src/components/spinner/spinner.tsx +0 -228
- package/src/components/status/index.ts +0 -2
- package/src/components/status/status.tsx +0 -152
- package/src/components/tabs/index.ts +0 -24
- package/src/components/tabs/tabs.tsx +0 -451
- package/src/components/text/index.ts +0 -2
- package/src/components/text/text.tsx +0 -131
- package/src/components/textarea/index.ts +0 -2
- package/src/components/textarea/textarea.tsx +0 -136
- package/src/components/toggle-group/index.ts +0 -12
- package/src/components/toggle-group/toggle-group.tsx +0 -111
- package/src/components/tooltip/index.ts +0 -14
- package/src/components/tooltip/tooltip.tsx +0 -212
- package/src/index.ts +0 -426
- package/src/legacy/AttentionDot.tsx +0 -28
- package/src/legacy/AvatarListRow.tsx +0 -87
- package/src/legacy/AvatarSlot.tsx +0 -157
- package/src/legacy/Badge.tsx +0 -95
- package/src/legacy/Banner.tsx +0 -74
- package/src/legacy/BottomSheet.tsx +0 -76
- package/src/legacy/CheckMarker.tsx +0 -72
- package/src/legacy/Checkbox.tsx +0 -81
- package/src/legacy/ConversationPreviewCard.tsx +0 -169
- package/src/legacy/DismissBackdrop.tsx +0 -68
- package/src/legacy/EmptyState.tsx +0 -63
- package/src/legacy/ExperimentalBadge.tsx +0 -19
- package/src/legacy/FormField.tsx +0 -106
- package/src/legacy/KeyValueRow.tsx +0 -67
- package/src/legacy/Lightbox.tsx +0 -119
- package/src/legacy/NotificationCenter.tsx +0 -217
- package/src/legacy/PanelHeader.tsx +0 -94
- package/src/legacy/PreviewShell.tsx +0 -40
- package/src/legacy/QuotedMessageCard.tsx +0 -181
- package/src/legacy/ReorderablePanelTabs.tsx +0 -156
- package/src/legacy/SandboxedPreviewFrame.tsx +0 -59
- package/src/legacy/SearchInput.tsx +0 -23
- package/src/legacy/SectionEyebrow.tsx +0 -60
- package/src/legacy/SectionHeader.tsx +0 -68
- package/src/legacy/SegmentedControl.tsx +0 -74
- package/src/legacy/SlugInput.tsx +0 -29
- package/src/legacy/Spinner.tsx +0 -89
- package/src/legacy/StatusDot.tsx +0 -51
- package/src/legacy/SurfaceListItem.tsx +0 -32
- package/src/legacy/Textarea.tsx +0 -137
- package/src/legacy/button.tsx +0 -100
- package/src/legacy/context-menu-divider.tsx +0 -12
- package/src/legacy/menu-item.tsx +0 -66
- package/src/legacy/selection-popover.tsx +0 -212
- package/src/legacy/server-switcher-menu.tsx +0 -203
- package/src/legacy/source.css +0 -240
- package/src/lib/cn.ts +0 -1
- package/src/lib/styled-props.ts +0 -11
- package/src/lib/theme/theme-context.ts +0 -28
- package/src/lib/theme/theme-provider.tsx +0 -181
- package/src/lib/theme/use-theme.ts +0 -12
- package/src/lib/tv.ts +0 -29
- package/src/lib/without-children.ts +0 -6
- package/src/wip.ts +0 -233
|
@@ -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.ts";
|
|
28
|
-
import type { StyledProps } from "../../lib/styled-props.ts";
|
|
29
|
-
import { useThemeFamily } from "../../lib/theme/use-theme.ts";
|
|
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,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.ts";
|
|
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
|
-
};
|