torch-glare 1.3.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apps/lib/components/Button.tsx +115 -64
- package/apps/lib/components/Drawer.tsx +368 -84
- package/apps/lib/components/SectionBlock.tsx +71 -0
- package/apps/lib/components/Stepper.tsx +374 -0
- package/apps/lib/components/Timeline.tsx +283 -0
- package/apps/lib/utils/types.ts +8 -4
- package/docs/components/alert-dialog.md +160 -0
- package/docs/components/date-picker.md +78 -0
- package/docs/components/dialog.md +189 -0
- package/docs/components/input-field.md +36 -0
- package/docs/components/section-block.md +275 -0
- package/docs/components/select.md +24 -0
- package/docs/components/simple-select.md +34 -0
- package/docs/components/table.md +75 -0
- package/docs/components/textarea.md +40 -0
- package/docs/components/toggle.md +59 -0
- package/docs/how-to/form-and-list-recipes.md +379 -0
- package/package.json +1 -1
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import React, {
|
|
4
|
+
forwardRef,
|
|
5
|
+
HTMLAttributes,
|
|
6
|
+
ReactNode,
|
|
7
|
+
createContext,
|
|
8
|
+
useContext,
|
|
9
|
+
} from "react";
|
|
10
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
11
|
+
import { cn } from "../utils/cn";
|
|
12
|
+
import { Themes } from "../utils/types";
|
|
13
|
+
|
|
14
|
+
// ─── Context ─────────────────────────────────────────────────────────────────
|
|
15
|
+
|
|
16
|
+
interface StepperContextValue {
|
|
17
|
+
activeStep: number;
|
|
18
|
+
orientation: "horizontal" | "vertical";
|
|
19
|
+
size: "S" | "M" | "L";
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const StepperContext = createContext<StepperContextValue>({
|
|
23
|
+
activeStep: 0,
|
|
24
|
+
orientation: "horizontal",
|
|
25
|
+
size: "M",
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const useStepperContext = () => useContext(StepperContext);
|
|
29
|
+
|
|
30
|
+
// ─── Stepper Root ────────────────────────────────────────────────────────────
|
|
31
|
+
|
|
32
|
+
const stepperStyles = cva(["flex gap-0"], {
|
|
33
|
+
variants: {
|
|
34
|
+
orientation: {
|
|
35
|
+
horizontal: "flex-row items-start",
|
|
36
|
+
vertical: "flex-col",
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
defaultVariants: {
|
|
40
|
+
orientation: "horizontal",
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
interface StepperProps
|
|
45
|
+
extends HTMLAttributes<HTMLDivElement>, VariantProps<typeof stepperStyles> {
|
|
46
|
+
theme?: Themes;
|
|
47
|
+
activeStep?: number;
|
|
48
|
+
size?: "S" | "M" | "L";
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const Stepper = forwardRef<HTMLDivElement, StepperProps>(
|
|
52
|
+
(
|
|
53
|
+
{
|
|
54
|
+
className,
|
|
55
|
+
orientation = "horizontal",
|
|
56
|
+
theme,
|
|
57
|
+
activeStep = 0,
|
|
58
|
+
size = "M",
|
|
59
|
+
...props
|
|
60
|
+
},
|
|
61
|
+
ref,
|
|
62
|
+
) => (
|
|
63
|
+
<StepperContext.Provider
|
|
64
|
+
value={{
|
|
65
|
+
activeStep,
|
|
66
|
+
orientation: orientation ?? "horizontal",
|
|
67
|
+
size: size ?? "M",
|
|
68
|
+
}}
|
|
69
|
+
>
|
|
70
|
+
<div
|
|
71
|
+
ref={ref}
|
|
72
|
+
data-theme={theme}
|
|
73
|
+
data-orientation={orientation}
|
|
74
|
+
className={cn(stepperStyles({ orientation }), className)}
|
|
75
|
+
{...props}
|
|
76
|
+
/>
|
|
77
|
+
</StepperContext.Provider>
|
|
78
|
+
),
|
|
79
|
+
);
|
|
80
|
+
Stepper.displayName = "Stepper";
|
|
81
|
+
|
|
82
|
+
// ─── Step ────────────────────────────────────────────────────────────────────
|
|
83
|
+
|
|
84
|
+
interface StepProps extends HTMLAttributes<HTMLDivElement> {
|
|
85
|
+
index?: number;
|
|
86
|
+
isCompleted?: boolean;
|
|
87
|
+
isActive?: boolean;
|
|
88
|
+
isError?: boolean;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const Step = forwardRef<HTMLDivElement, StepProps>(
|
|
92
|
+
(
|
|
93
|
+
{
|
|
94
|
+
className,
|
|
95
|
+
index = 0,
|
|
96
|
+
isCompleted,
|
|
97
|
+
isActive,
|
|
98
|
+
isError,
|
|
99
|
+
children,
|
|
100
|
+
...props
|
|
101
|
+
},
|
|
102
|
+
ref,
|
|
103
|
+
) => {
|
|
104
|
+
const { activeStep, orientation } = useStepperContext();
|
|
105
|
+
|
|
106
|
+
const computedActive = isActive ?? index === activeStep;
|
|
107
|
+
const computedCompleted = isCompleted ?? index < activeStep;
|
|
108
|
+
const computedError = isError ?? false;
|
|
109
|
+
|
|
110
|
+
return (
|
|
111
|
+
<div
|
|
112
|
+
ref={ref}
|
|
113
|
+
data-active={computedActive || undefined}
|
|
114
|
+
data-completed={computedCompleted || undefined}
|
|
115
|
+
data-error={computedError || undefined}
|
|
116
|
+
data-orientation={orientation}
|
|
117
|
+
className={cn(
|
|
118
|
+
"flex group/step",
|
|
119
|
+
orientation === "horizontal"
|
|
120
|
+
? "shrink-0 flex-col items-center gap-2"
|
|
121
|
+
: "flex-row gap-3",
|
|
122
|
+
className,
|
|
123
|
+
)}
|
|
124
|
+
{...props}
|
|
125
|
+
>
|
|
126
|
+
{React.Children.map(children, (child) => {
|
|
127
|
+
if (!React.isValidElement(child)) return child;
|
|
128
|
+
return React.cloneElement(child as React.ReactElement<any>, {
|
|
129
|
+
_active: computedActive,
|
|
130
|
+
_completed: computedCompleted,
|
|
131
|
+
_error: computedError,
|
|
132
|
+
_index: index,
|
|
133
|
+
});
|
|
134
|
+
})}
|
|
135
|
+
</div>
|
|
136
|
+
);
|
|
137
|
+
},
|
|
138
|
+
);
|
|
139
|
+
Step.displayName = "Step";
|
|
140
|
+
|
|
141
|
+
// ─── Step Indicator ──────────────────────────────────────────────────────────
|
|
142
|
+
|
|
143
|
+
const stepIndicatorStyles = cva(
|
|
144
|
+
[
|
|
145
|
+
"flex items-center justify-center shrink-0 rounded-full",
|
|
146
|
+
"border",
|
|
147
|
+
"transition-all duration-200 ease-in-out",
|
|
148
|
+
"typography-body-small-medium",
|
|
149
|
+
"[&_i]:leading-none [&_i]:flex [&_i]:items-center [&_i]:justify-center",
|
|
150
|
+
],
|
|
151
|
+
{
|
|
152
|
+
variants: {
|
|
153
|
+
state: {
|
|
154
|
+
pending: [
|
|
155
|
+
"bg-background-presentation-action-disabled",
|
|
156
|
+
"border-border-presentation-action-disabled",
|
|
157
|
+
"text-content-presentation-state-disabled",
|
|
158
|
+
],
|
|
159
|
+
active: [
|
|
160
|
+
"bg-background-presentation-state-information-primary",
|
|
161
|
+
"border-border-presentation-state-focus",
|
|
162
|
+
"text-content-presentation-state-information",
|
|
163
|
+
],
|
|
164
|
+
completed: [
|
|
165
|
+
"bg-background-presentation-state-success-primary",
|
|
166
|
+
"border-border-presentation-state-success",
|
|
167
|
+
"text-content-presentation-state-success",
|
|
168
|
+
],
|
|
169
|
+
error: [
|
|
170
|
+
"bg-background-presentation-state-negative-primary",
|
|
171
|
+
"border-border-presentation-state-negative",
|
|
172
|
+
"text-content-presentation-state-negative",
|
|
173
|
+
],
|
|
174
|
+
},
|
|
175
|
+
size: {
|
|
176
|
+
S: "w-[22px] h-[22px] text-[10px] [&_i]:text-[12px]",
|
|
177
|
+
M: "w-[28px] h-[28px] text-[12px] [&_i]:text-[14px]",
|
|
178
|
+
L: "w-[34px] h-[34px] text-[14px] [&_i]:text-[16px]",
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
defaultVariants: {
|
|
182
|
+
state: "pending",
|
|
183
|
+
size: "M",
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
interface StepIndicatorProps extends HTMLAttributes<HTMLDivElement> {
|
|
189
|
+
icon?: ReactNode;
|
|
190
|
+
completedIcon?: ReactNode;
|
|
191
|
+
errorIcon?: ReactNode;
|
|
192
|
+
_active?: boolean;
|
|
193
|
+
_completed?: boolean;
|
|
194
|
+
_error?: boolean;
|
|
195
|
+
_index?: number;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const StepIndicator = forwardRef<HTMLDivElement, StepIndicatorProps>(
|
|
199
|
+
(
|
|
200
|
+
{
|
|
201
|
+
className,
|
|
202
|
+
icon,
|
|
203
|
+
completedIcon,
|
|
204
|
+
errorIcon,
|
|
205
|
+
_active,
|
|
206
|
+
_completed,
|
|
207
|
+
_error,
|
|
208
|
+
_index = 0,
|
|
209
|
+
children,
|
|
210
|
+
...props
|
|
211
|
+
},
|
|
212
|
+
ref,
|
|
213
|
+
) => {
|
|
214
|
+
const { size } = useStepperContext();
|
|
215
|
+
|
|
216
|
+
const state = _error
|
|
217
|
+
? "error"
|
|
218
|
+
: _completed
|
|
219
|
+
? "completed"
|
|
220
|
+
: _active
|
|
221
|
+
? "active"
|
|
222
|
+
: "pending";
|
|
223
|
+
|
|
224
|
+
const renderContent = () => {
|
|
225
|
+
if (_error && errorIcon) return errorIcon;
|
|
226
|
+
if (_error) return <i className="ri-close-line" />;
|
|
227
|
+
if (_completed && completedIcon) return completedIcon;
|
|
228
|
+
if (_completed) return <i className="ri-check-line" />;
|
|
229
|
+
if (icon) return icon;
|
|
230
|
+
if (children) return children;
|
|
231
|
+
return _index + 1;
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
return (
|
|
235
|
+
<div
|
|
236
|
+
ref={ref}
|
|
237
|
+
className={cn(stepIndicatorStyles({ state, size }), className)}
|
|
238
|
+
{...props}
|
|
239
|
+
>
|
|
240
|
+
{renderContent()}
|
|
241
|
+
</div>
|
|
242
|
+
);
|
|
243
|
+
},
|
|
244
|
+
);
|
|
245
|
+
StepIndicator.displayName = "StepIndicator";
|
|
246
|
+
|
|
247
|
+
// ─── Step Connector (the line between steps) ────────────────────────────────
|
|
248
|
+
|
|
249
|
+
const connectorStyles = cva(["transition-all duration-200 ease-in-out"], {
|
|
250
|
+
variants: {
|
|
251
|
+
orientation: {
|
|
252
|
+
horizontal: "h-[2px] flex-1 mx-2 mt-[13px]",
|
|
253
|
+
vertical: "w-[2px] flex-1 min-h-[24px] my-2",
|
|
254
|
+
},
|
|
255
|
+
state: {
|
|
256
|
+
pending: "bg-border-presentation-action-disabled",
|
|
257
|
+
completed: "bg-border-presentation-state-focus",
|
|
258
|
+
},
|
|
259
|
+
},
|
|
260
|
+
defaultVariants: {
|
|
261
|
+
orientation: "horizontal",
|
|
262
|
+
state: "pending",
|
|
263
|
+
},
|
|
264
|
+
compoundVariants: [
|
|
265
|
+
{
|
|
266
|
+
orientation: "horizontal",
|
|
267
|
+
className: "self-start",
|
|
268
|
+
},
|
|
269
|
+
],
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
interface StepConnectorProps extends HTMLAttributes<HTMLDivElement> {
|
|
273
|
+
_completed?: boolean;
|
|
274
|
+
_active?: boolean;
|
|
275
|
+
_error?: boolean;
|
|
276
|
+
_index?: number;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
const StepConnector = forwardRef<HTMLDivElement, StepConnectorProps>(
|
|
280
|
+
(
|
|
281
|
+
{ className, _completed, _active: _a, _error: _e, _index: _i, ...props },
|
|
282
|
+
ref,
|
|
283
|
+
) => {
|
|
284
|
+
const { orientation } = useStepperContext();
|
|
285
|
+
|
|
286
|
+
return (
|
|
287
|
+
<div
|
|
288
|
+
ref={ref}
|
|
289
|
+
className={cn(
|
|
290
|
+
connectorStyles({
|
|
291
|
+
orientation,
|
|
292
|
+
state: _completed ? "completed" : "pending",
|
|
293
|
+
}),
|
|
294
|
+
className,
|
|
295
|
+
)}
|
|
296
|
+
{...props}
|
|
297
|
+
/>
|
|
298
|
+
);
|
|
299
|
+
},
|
|
300
|
+
);
|
|
301
|
+
StepConnector.displayName = "StepConnector";
|
|
302
|
+
|
|
303
|
+
// ─── Step Label ──────────────────────────────────────────────────────────────
|
|
304
|
+
|
|
305
|
+
interface StepLabelProps extends HTMLAttributes<HTMLDivElement> {
|
|
306
|
+
_active?: boolean;
|
|
307
|
+
_completed?: boolean;
|
|
308
|
+
_error?: boolean;
|
|
309
|
+
_index?: number;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
const StepLabel = forwardRef<HTMLDivElement, StepLabelProps>(
|
|
313
|
+
({ className, _active, _completed, _error, _index: _i, ...props }, ref) => (
|
|
314
|
+
<div
|
|
315
|
+
ref={ref}
|
|
316
|
+
className={cn(
|
|
317
|
+
"typography-body-small-medium transition-colors duration-200 ease-in-out",
|
|
318
|
+
_active
|
|
319
|
+
? "text-content-presentation-state-information"
|
|
320
|
+
: _error
|
|
321
|
+
? "text-content-presentation-state-negative"
|
|
322
|
+
: _completed
|
|
323
|
+
? "text-content-presentation-global-primary"
|
|
324
|
+
: "text-content-presentation-state-disabled",
|
|
325
|
+
className,
|
|
326
|
+
)}
|
|
327
|
+
{...props}
|
|
328
|
+
/>
|
|
329
|
+
),
|
|
330
|
+
);
|
|
331
|
+
StepLabel.displayName = "StepLabel";
|
|
332
|
+
|
|
333
|
+
// ─── Step Description ────────────────────────────────────────────────────────
|
|
334
|
+
|
|
335
|
+
interface StepDescriptionProps extends HTMLAttributes<HTMLDivElement> {
|
|
336
|
+
_active?: boolean;
|
|
337
|
+
_completed?: boolean;
|
|
338
|
+
_error?: boolean;
|
|
339
|
+
_index?: number;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
const StepDescription = forwardRef<HTMLDivElement, StepDescriptionProps>(
|
|
343
|
+
(
|
|
344
|
+
{ className, _active, _completed: _c, _error: _e, _index: _i, ...props },
|
|
345
|
+
ref,
|
|
346
|
+
) => (
|
|
347
|
+
<div
|
|
348
|
+
ref={ref}
|
|
349
|
+
className={cn(
|
|
350
|
+
"typography-body-small-regular",
|
|
351
|
+
_active
|
|
352
|
+
? "text-content-presentation-global-secondary"
|
|
353
|
+
: "text-content-presentation-state-disabled",
|
|
354
|
+
className,
|
|
355
|
+
)}
|
|
356
|
+
{...props}
|
|
357
|
+
/>
|
|
358
|
+
),
|
|
359
|
+
);
|
|
360
|
+
StepDescription.displayName = "StepDescription";
|
|
361
|
+
|
|
362
|
+
// ─── Exports ─────────────────────────────────────────────────────────────────
|
|
363
|
+
|
|
364
|
+
export {
|
|
365
|
+
Stepper,
|
|
366
|
+
Step,
|
|
367
|
+
StepIndicator,
|
|
368
|
+
StepConnector,
|
|
369
|
+
StepLabel,
|
|
370
|
+
StepDescription,
|
|
371
|
+
stepperStyles,
|
|
372
|
+
stepIndicatorStyles,
|
|
373
|
+
connectorStyles,
|
|
374
|
+
};
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import React, { forwardRef, HTMLAttributes, ReactNode } from "react";
|
|
2
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
3
|
+
import { cn } from "../utils/cn";
|
|
4
|
+
import { Themes } from "../utils/types";
|
|
5
|
+
|
|
6
|
+
// ─── Timeline Root ───────────────────────────────────────────────────────────
|
|
7
|
+
|
|
8
|
+
const timelineStyles = cva(["flex gap-0"], {
|
|
9
|
+
variants: {
|
|
10
|
+
orientation: {
|
|
11
|
+
vertical: "flex-col",
|
|
12
|
+
horizontal: "flex-row items-start",
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
defaultVariants: {
|
|
16
|
+
orientation: "vertical",
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
interface TimelineProps
|
|
21
|
+
extends HTMLAttributes<HTMLDivElement>,
|
|
22
|
+
VariantProps<typeof timelineStyles> {
|
|
23
|
+
theme?: Themes;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const Timeline = forwardRef<HTMLDivElement, TimelineProps>(
|
|
27
|
+
({ className, orientation, theme, ...props }, ref) => (
|
|
28
|
+
<div
|
|
29
|
+
ref={ref}
|
|
30
|
+
data-theme={theme}
|
|
31
|
+
data-orientation={orientation ?? "vertical"}
|
|
32
|
+
className={cn(timelineStyles({ orientation }), className)}
|
|
33
|
+
{...props}
|
|
34
|
+
/>
|
|
35
|
+
)
|
|
36
|
+
);
|
|
37
|
+
Timeline.displayName = "Timeline";
|
|
38
|
+
|
|
39
|
+
// ─── Timeline Item ───────────────────────────────────────────────────────────
|
|
40
|
+
|
|
41
|
+
const timelineItemStyles = cva(["flex group/item"], {
|
|
42
|
+
variants: {
|
|
43
|
+
orientation: {
|
|
44
|
+
vertical: "flex-row gap-3",
|
|
45
|
+
horizontal: "flex-col items-center gap-3",
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
defaultVariants: {
|
|
49
|
+
orientation: "vertical",
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
interface TimelineItemProps extends HTMLAttributes<HTMLDivElement> {
|
|
54
|
+
orientation?: "vertical" | "horizontal";
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const TimelineItem = forwardRef<HTMLDivElement, TimelineItemProps>(
|
|
58
|
+
({ className, orientation = "vertical", ...props }, ref) => (
|
|
59
|
+
<div
|
|
60
|
+
ref={ref}
|
|
61
|
+
data-orientation={orientation}
|
|
62
|
+
className={cn(timelineItemStyles({ orientation }), className)}
|
|
63
|
+
{...props}
|
|
64
|
+
/>
|
|
65
|
+
)
|
|
66
|
+
);
|
|
67
|
+
TimelineItem.displayName = "TimelineItem";
|
|
68
|
+
|
|
69
|
+
// ─── Timeline Indicator ──────────────────────────────────────────────────────
|
|
70
|
+
|
|
71
|
+
const indicatorStyles = cva(
|
|
72
|
+
[
|
|
73
|
+
"flex items-center justify-center shrink-0 rounded-full",
|
|
74
|
+
"border",
|
|
75
|
+
"transition-all duration-200 ease-in-out",
|
|
76
|
+
"[&_i]:leading-none [&_i]:flex [&_i]:items-center [&_i]:justify-center",
|
|
77
|
+
],
|
|
78
|
+
{
|
|
79
|
+
variants: {
|
|
80
|
+
variant: {
|
|
81
|
+
default: [
|
|
82
|
+
"bg-background-presentation-action-secondary",
|
|
83
|
+
"border-border-presentation-action-primary",
|
|
84
|
+
"text-content-presentation-action-light-primary",
|
|
85
|
+
],
|
|
86
|
+
active: [
|
|
87
|
+
"bg-background-presentation-state-information-primary",
|
|
88
|
+
"border-border-presentation-state-focus",
|
|
89
|
+
"text-content-presentation-state-information",
|
|
90
|
+
],
|
|
91
|
+
completed: [
|
|
92
|
+
"bg-background-presentation-state-success-primary",
|
|
93
|
+
"border-border-presentation-state-success",
|
|
94
|
+
"text-content-presentation-state-success",
|
|
95
|
+
],
|
|
96
|
+
error: [
|
|
97
|
+
"bg-background-presentation-state-negative-primary",
|
|
98
|
+
"border-border-presentation-state-negative",
|
|
99
|
+
"text-content-presentation-state-negative",
|
|
100
|
+
],
|
|
101
|
+
warning: [
|
|
102
|
+
"bg-background-presentation-state-warning-primary",
|
|
103
|
+
"border-border-presentation-state-warning",
|
|
104
|
+
"text-content-presentation-state-warning",
|
|
105
|
+
],
|
|
106
|
+
},
|
|
107
|
+
size: {
|
|
108
|
+
S: "w-[22px] h-[22px] [&_i]:text-[12px]",
|
|
109
|
+
M: "w-[28px] h-[28px] [&_i]:text-[14px]",
|
|
110
|
+
L: "w-[34px] h-[34px] [&_i]:text-[16px]",
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
defaultVariants: {
|
|
114
|
+
variant: "default",
|
|
115
|
+
size: "M",
|
|
116
|
+
},
|
|
117
|
+
}
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
interface TimelineIndicatorProps
|
|
121
|
+
extends HTMLAttributes<HTMLDivElement>,
|
|
122
|
+
VariantProps<typeof indicatorStyles> {
|
|
123
|
+
icon?: ReactNode;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const TimelineIndicator = forwardRef<HTMLDivElement, TimelineIndicatorProps>(
|
|
127
|
+
({ className, variant, size, icon, children, ...props }, ref) => {
|
|
128
|
+
const renderContent = () => {
|
|
129
|
+
if (icon) return icon;
|
|
130
|
+
if (children) return children;
|
|
131
|
+
if (variant === "completed") return <i className="ri-check-line" />;
|
|
132
|
+
if (variant === "error") return <i className="ri-close-line" />;
|
|
133
|
+
if (variant === "warning") return <i className="ri-alert-line" />;
|
|
134
|
+
return <span className="block w-[6px] h-[6px] rounded-full bg-current" />;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
return (
|
|
138
|
+
<div
|
|
139
|
+
ref={ref}
|
|
140
|
+
className={cn(indicatorStyles({ variant, size }), className)}
|
|
141
|
+
{...props}
|
|
142
|
+
>
|
|
143
|
+
{renderContent()}
|
|
144
|
+
</div>
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
);
|
|
148
|
+
TimelineIndicator.displayName = "TimelineIndicator";
|
|
149
|
+
|
|
150
|
+
// ─── Timeline Separator (the connecting line) ────────────────────────────────
|
|
151
|
+
|
|
152
|
+
const separatorStyles = cva(
|
|
153
|
+
[
|
|
154
|
+
"bg-border-presentation-global-primary",
|
|
155
|
+
"transition-all duration-200 ease-in-out",
|
|
156
|
+
],
|
|
157
|
+
{
|
|
158
|
+
variants: {
|
|
159
|
+
orientation: {
|
|
160
|
+
vertical: "w-[1px] flex-1 min-h-[24px] mx-auto",
|
|
161
|
+
horizontal: "h-[1px] flex-1 min-w-[24px] my-auto",
|
|
162
|
+
},
|
|
163
|
+
active: {
|
|
164
|
+
true: "bg-border-presentation-state-focus",
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
defaultVariants: {
|
|
168
|
+
orientation: "vertical",
|
|
169
|
+
active: false,
|
|
170
|
+
},
|
|
171
|
+
}
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
interface TimelineSeparatorProps
|
|
175
|
+
extends HTMLAttributes<HTMLDivElement>,
|
|
176
|
+
VariantProps<typeof separatorStyles> {}
|
|
177
|
+
|
|
178
|
+
const TimelineSeparator = forwardRef<HTMLDivElement, TimelineSeparatorProps>(
|
|
179
|
+
({ className, orientation = "vertical", active, ...props }, ref) => (
|
|
180
|
+
<div
|
|
181
|
+
ref={ref}
|
|
182
|
+
className={cn(separatorStyles({ orientation, active }), className)}
|
|
183
|
+
{...props}
|
|
184
|
+
/>
|
|
185
|
+
)
|
|
186
|
+
);
|
|
187
|
+
TimelineSeparator.displayName = "TimelineSeparator";
|
|
188
|
+
|
|
189
|
+
// ─── Timeline Connector (indicator + line container) ─────────────────────────
|
|
190
|
+
|
|
191
|
+
interface TimelineConnectorProps extends HTMLAttributes<HTMLDivElement> {
|
|
192
|
+
orientation?: "vertical" | "horizontal";
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const TimelineConnector = forwardRef<HTMLDivElement, TimelineConnectorProps>(
|
|
196
|
+
({ className, orientation = "vertical", children, ...props }, ref) => (
|
|
197
|
+
<div
|
|
198
|
+
ref={ref}
|
|
199
|
+
className={cn(
|
|
200
|
+
"flex items-center",
|
|
201
|
+
orientation === "vertical"
|
|
202
|
+
? "flex-col"
|
|
203
|
+
: "flex-row",
|
|
204
|
+
className
|
|
205
|
+
)}
|
|
206
|
+
{...props}
|
|
207
|
+
>
|
|
208
|
+
{children}
|
|
209
|
+
</div>
|
|
210
|
+
)
|
|
211
|
+
);
|
|
212
|
+
TimelineConnector.displayName = "TimelineConnector";
|
|
213
|
+
|
|
214
|
+
// ─── Timeline Content ────────────────────────────────────────────────────────
|
|
215
|
+
|
|
216
|
+
interface TimelineContentProps extends HTMLAttributes<HTMLDivElement> {}
|
|
217
|
+
|
|
218
|
+
const TimelineContent = forwardRef<HTMLDivElement, TimelineContentProps>(
|
|
219
|
+
({ className, ...props }, ref) => (
|
|
220
|
+
<div
|
|
221
|
+
ref={ref}
|
|
222
|
+
className={cn(
|
|
223
|
+
"flex flex-col gap-1 pb-6 pt-[2px]",
|
|
224
|
+
"group-last/item:pb-0",
|
|
225
|
+
className
|
|
226
|
+
)}
|
|
227
|
+
{...props}
|
|
228
|
+
/>
|
|
229
|
+
)
|
|
230
|
+
);
|
|
231
|
+
TimelineContent.displayName = "TimelineContent";
|
|
232
|
+
|
|
233
|
+
// ─── Timeline Heading ────────────────────────────────────────────────────────
|
|
234
|
+
|
|
235
|
+
interface TimelineHeadingProps extends HTMLAttributes<HTMLDivElement> {}
|
|
236
|
+
|
|
237
|
+
const TimelineHeading = forwardRef<HTMLDivElement, TimelineHeadingProps>(
|
|
238
|
+
({ className, ...props }, ref) => (
|
|
239
|
+
<div
|
|
240
|
+
ref={ref}
|
|
241
|
+
className={cn(
|
|
242
|
+
"typography-body-medium-medium text-content-presentation-global-primary",
|
|
243
|
+
className
|
|
244
|
+
)}
|
|
245
|
+
{...props}
|
|
246
|
+
/>
|
|
247
|
+
)
|
|
248
|
+
);
|
|
249
|
+
TimelineHeading.displayName = "TimelineHeading";
|
|
250
|
+
|
|
251
|
+
// ─── Timeline Description ────────────────────────────────────────────────────
|
|
252
|
+
|
|
253
|
+
interface TimelineDescriptionProps extends HTMLAttributes<HTMLDivElement> {}
|
|
254
|
+
|
|
255
|
+
const TimelineDescription = forwardRef<HTMLDivElement, TimelineDescriptionProps>(
|
|
256
|
+
({ className, ...props }, ref) => (
|
|
257
|
+
<div
|
|
258
|
+
ref={ref}
|
|
259
|
+
className={cn(
|
|
260
|
+
"typography-body-small-regular text-content-presentation-global-secondary",
|
|
261
|
+
className
|
|
262
|
+
)}
|
|
263
|
+
{...props}
|
|
264
|
+
/>
|
|
265
|
+
)
|
|
266
|
+
);
|
|
267
|
+
TimelineDescription.displayName = "TimelineDescription";
|
|
268
|
+
|
|
269
|
+
// ─── Exports ─────────────────────────────────────────────────────────────────
|
|
270
|
+
|
|
271
|
+
export {
|
|
272
|
+
Timeline,
|
|
273
|
+
TimelineItem,
|
|
274
|
+
TimelineIndicator,
|
|
275
|
+
TimelineSeparator,
|
|
276
|
+
TimelineConnector,
|
|
277
|
+
TimelineContent,
|
|
278
|
+
TimelineHeading,
|
|
279
|
+
TimelineDescription,
|
|
280
|
+
timelineStyles,
|
|
281
|
+
indicatorStyles,
|
|
282
|
+
separatorStyles,
|
|
283
|
+
};
|
package/apps/lib/utils/types.ts
CHANGED
|
@@ -2,11 +2,15 @@ export type Themes = "dark" | "light" | "default";
|
|
|
2
2
|
|
|
3
3
|
export type ButtonVariant =
|
|
4
4
|
| "PrimeStyle"
|
|
5
|
-
| "
|
|
5
|
+
| "BluSecStyle"
|
|
6
6
|
| "YelSecStyle"
|
|
7
7
|
| "RedSecStyle"
|
|
8
8
|
| "BorderStyle"
|
|
9
9
|
| "PrimeContStyle"
|
|
10
|
-
| "
|
|
11
|
-
| "RedContStyle"
|
|
12
|
-
|
|
10
|
+
| "BluContStyle"
|
|
11
|
+
| "RedContStyle"
|
|
12
|
+
| "PrimeColStyle"
|
|
13
|
+
| "BluColStyle"
|
|
14
|
+
| "RedColStyle"
|
|
15
|
+
| "GreenColStyle"
|
|
16
|
+
| "YelColStyle";
|