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.
@@ -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
+ };
@@ -2,11 +2,15 @@ export type Themes = "dark" | "light" | "default";
2
2
 
3
3
  export type ButtonVariant =
4
4
  | "PrimeStyle"
5
- | "BlueSecStyle"
5
+ | "BluSecStyle"
6
6
  | "YelSecStyle"
7
7
  | "RedSecStyle"
8
8
  | "BorderStyle"
9
9
  | "PrimeContStyle"
10
- | "BlueContStyle"
11
- | "RedContStyle";
12
-
10
+ | "BluContStyle"
11
+ | "RedContStyle"
12
+ | "PrimeColStyle"
13
+ | "BluColStyle"
14
+ | "RedColStyle"
15
+ | "GreenColStyle"
16
+ | "YelColStyle";