responsive-class-variants 1.0.1 → 1.1.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/README.md +286 -7
- package/dist/index.d.ts +33 -47
- package/dist/index.js +113 -65
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# Responsive Class Variants
|
|
2
2
|
|
|
3
|
-
rcv helps you create responsive class variants
|
|
3
|
+
rcv helps you create responsive class variants. It handles the logic of generating the classes and prefixes them with the breakpoint name. You will still need to make sure, that the CSS is available for the breakpoints you use.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Handles the logic of generating the classes and prefixes them with the breakpoint name.
|
|
8
|
+
- You just need to provide the base classes, the variants and optionally compound variants.
|
|
9
|
+
- **Slots support**: Create multiple class-generating functions for different parts of a component.
|
|
10
|
+
- You can use the default breakpoints (sm, md, lg, xl) or provide your own.
|
|
11
|
+
- You can pass an optional onComplete callback to the createRcv function. This callback will be called with the generated classes. Helpful if you want to pass your classes to a library like twMerge.
|
|
4
12
|
|
|
5
13
|
## Installation
|
|
6
14
|
|
|
@@ -10,6 +18,19 @@ pnpm add responsive-class-variants
|
|
|
10
18
|
|
|
11
19
|
## Usage
|
|
12
20
|
|
|
21
|
+
rcv is a function that takes a config object and returns a function that takes a props object and returns a string of classes. The props object is an object with the keys of the variants and the values are the values of the variants.
|
|
22
|
+
|
|
23
|
+
The config object has the following properties:
|
|
24
|
+
|
|
25
|
+
- base: The base classes that are always applied.
|
|
26
|
+
- variants: An object with the keys of the variants and the values are the values of the variants.
|
|
27
|
+
- compoundVariants: An array of compound variants that apply additional classes when multiple variants have specific values.
|
|
28
|
+
- onComplete: An optional callback function that receives the generated classes and returns the final classes.
|
|
29
|
+
|
|
30
|
+
rcv works very well with tailwindcss but it can be used with any CSS solution.
|
|
31
|
+
|
|
32
|
+
### Basic Usage (Single Component):
|
|
33
|
+
|
|
13
34
|
```ts
|
|
14
35
|
const getButtonVariants = rcv({
|
|
15
36
|
base: "px-4 py-2 rounded",
|
|
@@ -19,21 +40,236 @@ const getButtonVariants = rcv({
|
|
|
19
40
|
secondary: "bg-gray-200 text-gray-800"
|
|
20
41
|
},
|
|
21
42
|
size: {
|
|
22
|
-
|
|
23
|
-
|
|
43
|
+
small: "text-sm",
|
|
44
|
+
large: "text-lg"
|
|
24
45
|
},
|
|
25
46
|
disabled: {
|
|
26
47
|
true: "opacity-50 cursor-not-allowed"
|
|
48
|
+
},
|
|
49
|
+
error: {
|
|
50
|
+
true: "bg-red-500 text-white"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
compoundVariants: [
|
|
54
|
+
{
|
|
55
|
+
disabled: true,
|
|
56
|
+
error: true,
|
|
57
|
+
className: "opacity-50 cursor-not-allowed"
|
|
27
58
|
}
|
|
28
|
-
|
|
59
|
+
]
|
|
29
60
|
});
|
|
30
61
|
|
|
31
62
|
// Usage:
|
|
32
|
-
getButtonVariants({ intent: "primary", size: "
|
|
63
|
+
getButtonVariants({ intent: "primary", size: "large", disabled: true })
|
|
33
64
|
// Or with responsive values:
|
|
34
65
|
getButtonVariants({ intent: { initial: "primary", md: "secondary" } })
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Slots (Multi-Part Components):
|
|
69
|
+
|
|
70
|
+
When you need to style multiple parts of a component, you can use slots. This is perfect for complex components like cards, alerts, or modals.
|
|
71
|
+
|
|
72
|
+
#### Simple Slots
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
const getCardVariants = rcv({
|
|
76
|
+
slots: {
|
|
77
|
+
base: "rounded-xl p-8 bg-white dark:bg-gray-900",
|
|
78
|
+
title: "text-xl font-bold text-gray-900 dark:text-white",
|
|
79
|
+
content: "text-gray-700 dark:text-gray-300"
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// Usage - destructure the slot functions
|
|
84
|
+
const { base, title, content } = getCardVariants;
|
|
85
|
+
|
|
86
|
+
// Apply to your JSX - no arguments needed for simple slots!
|
|
87
|
+
<div className={base()}>
|
|
88
|
+
<h2 className={title()}>Card Title</h2>
|
|
89
|
+
<p className={content()}>Card content goes here</p>
|
|
90
|
+
</div>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
#### Slots with Variants
|
|
94
|
+
|
|
95
|
+
Variants can target specific slots by using objects instead of strings:
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
const getCardVariants = rcv({
|
|
99
|
+
slots: {
|
|
100
|
+
base: "rounded-xl p-8 bg-white dark:bg-gray-900",
|
|
101
|
+
title: "text-xl font-bold text-gray-900 dark:text-white",
|
|
102
|
+
content: "text-gray-700 dark:text-gray-300"
|
|
103
|
+
},
|
|
104
|
+
variants: {
|
|
105
|
+
shadow: {
|
|
106
|
+
none: {},
|
|
107
|
+
sm: { base: "shadow-sm" },
|
|
108
|
+
md: { base: "shadow-md" },
|
|
109
|
+
lg: { base: "shadow-lg" }
|
|
110
|
+
},
|
|
111
|
+
size: {
|
|
112
|
+
sm: {
|
|
113
|
+
title: "text-lg",
|
|
114
|
+
content: "text-sm"
|
|
115
|
+
},
|
|
116
|
+
lg: {
|
|
117
|
+
title: "text-2xl",
|
|
118
|
+
content: "text-lg"
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
const { base, title, content } = getCardVariants;
|
|
125
|
+
|
|
126
|
+
// Usage with variants
|
|
127
|
+
<div className={base({ shadow: "md", size: "lg" })}>
|
|
128
|
+
<h2 className={title({ shadow: "md", size: "lg" })}>Large Card Title</h2>
|
|
129
|
+
<p className={content({ shadow: "md", size: "lg" })}>Larger content text</p>
|
|
130
|
+
</div>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
#### Slots with Compound Variants
|
|
134
|
+
|
|
135
|
+
Compound variants can also target specific slots using the `class` property:
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
const getAlertVariants = rcv({
|
|
139
|
+
slots: {
|
|
140
|
+
root: "rounded py-3 px-5 mb-4",
|
|
141
|
+
title: "font-bold mb-1",
|
|
142
|
+
message: "text-sm"
|
|
143
|
+
},
|
|
144
|
+
variants: {
|
|
145
|
+
variant: {
|
|
146
|
+
outlined: { root: "border" },
|
|
147
|
+
filled: {}
|
|
148
|
+
},
|
|
149
|
+
severity: {
|
|
150
|
+
error: {},
|
|
151
|
+
success: {},
|
|
152
|
+
warning: {}
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
compoundVariants: [
|
|
156
|
+
{
|
|
157
|
+
variant: "outlined",
|
|
158
|
+
severity: "error",
|
|
159
|
+
class: {
|
|
160
|
+
root: "border-red-700 dark:border-red-500",
|
|
161
|
+
title: "text-red-700 dark:text-red-500",
|
|
162
|
+
message: "text-red-600 dark:text-red-500"
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
variant: "filled",
|
|
167
|
+
severity: "success",
|
|
168
|
+
class: {
|
|
169
|
+
root: "bg-green-100 dark:bg-green-800",
|
|
170
|
+
title: "text-green-900 dark:text-green-50",
|
|
171
|
+
message: "text-green-700 dark:text-green-200"
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
]
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
const { root, title, message } = getAlertVariants;
|
|
178
|
+
|
|
179
|
+
// Usage
|
|
180
|
+
<div className={root({ variant: "outlined", severity: "error" })}>
|
|
181
|
+
<h3 className={title({ variant: "outlined", severity: "error" })}>Error!</h3>
|
|
182
|
+
<p className={message({ variant: "outlined", severity: "error" })}>Something went wrong</p>
|
|
183
|
+
</div>
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
#### Slots with Responsive Values
|
|
35
187
|
|
|
36
|
-
|
|
188
|
+
Slots work seamlessly with responsive values:
|
|
189
|
+
|
|
190
|
+
```ts
|
|
191
|
+
const getCardVariants = rcv({
|
|
192
|
+
slots: {
|
|
193
|
+
base: "rounded-xl p-4 bg-white",
|
|
194
|
+
title: "font-bold text-gray-900"
|
|
195
|
+
},
|
|
196
|
+
variants: {
|
|
197
|
+
size: {
|
|
198
|
+
sm: {
|
|
199
|
+
base: "p-2",
|
|
200
|
+
title: "text-sm"
|
|
201
|
+
},
|
|
202
|
+
lg: {
|
|
203
|
+
base: "p-8",
|
|
204
|
+
title: "text-2xl"
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
const { base, title } = getCardVariants;
|
|
211
|
+
|
|
212
|
+
// Responsive usage
|
|
213
|
+
<div className={base({ size: { initial: "sm", md: "lg" } })}>
|
|
214
|
+
<h2 className={title({ size: { initial: "sm", md: "lg" } })}>Responsive Card</h2>
|
|
215
|
+
</div>
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### With css classes (like BEM or any other naming convention):
|
|
219
|
+
|
|
220
|
+
```ts
|
|
221
|
+
const getButtonVariants = rcv({
|
|
222
|
+
base: "btn",
|
|
223
|
+
variants: {
|
|
224
|
+
intent: {
|
|
225
|
+
primary: "btn--primary",
|
|
226
|
+
secondary: "btn--secondary"
|
|
227
|
+
},
|
|
228
|
+
size: {
|
|
229
|
+
small: "btn--sm",
|
|
230
|
+
large: "btn--lg"
|
|
231
|
+
},
|
|
232
|
+
disabled: {
|
|
233
|
+
true: "btn--disabled"
|
|
234
|
+
},
|
|
235
|
+
error: {
|
|
236
|
+
true: "btn--error"
|
|
237
|
+
}
|
|
238
|
+
},
|
|
239
|
+
compoundVariants: [
|
|
240
|
+
{
|
|
241
|
+
disabled: true,
|
|
242
|
+
error: true,
|
|
243
|
+
className: "btn--disabled--error"
|
|
244
|
+
}
|
|
245
|
+
]
|
|
246
|
+
});
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Because of the tailwind JIT compiler, you need to make sure, that all possible classes are available with your component. Let's say you have a button component and you want to use the `size` variant responsively. You need to make sure, that the `small` and `large` classes are available with your component. You can e.g. define a `SIZES` object to define the classes for each size and breakpoints. This example assumes you have the default breakpoints (sm, md, lg, xl).
|
|
250
|
+
|
|
251
|
+
```ts
|
|
252
|
+
const SIZES = {
|
|
253
|
+
sm: {
|
|
254
|
+
sm: "sm:text-sm",
|
|
255
|
+
lg: "sm:text-lg"
|
|
256
|
+
},
|
|
257
|
+
md: {
|
|
258
|
+
sm: "md:text-sm",
|
|
259
|
+
lg: "md:text-lg"
|
|
260
|
+
},
|
|
261
|
+
lg: {
|
|
262
|
+
sm: "lg:text-sm",
|
|
263
|
+
lg: "lg:text-lg"
|
|
264
|
+
},
|
|
265
|
+
xl: {
|
|
266
|
+
sm: "xl:text-sm",
|
|
267
|
+
lg: "xl:text-lg"
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
The structure doesn't really matter, the classes just need to be in the compiled javascript to be picked up by the JIT compiler.
|
|
37
273
|
|
|
38
274
|
## Custom breakpoints (via createRcv)
|
|
39
275
|
|
|
@@ -52,12 +288,55 @@ const getButtonVariants = rcv({
|
|
|
52
288
|
|
|
53
289
|
// Usage with custom breakpoints:
|
|
54
290
|
getButtonVariants({ intent: { initial: "primary", mobile: "secondary", desktop: "primary" } })
|
|
291
|
+
|
|
292
|
+
// Works with slots too:
|
|
293
|
+
const getCardVariants = rcv({
|
|
294
|
+
slots: {
|
|
295
|
+
base: "rounded-xl p-4 bg-white",
|
|
296
|
+
title: "font-bold text-gray-900"
|
|
297
|
+
},
|
|
298
|
+
variants: {
|
|
299
|
+
size: {
|
|
300
|
+
sm: { base: "p-2", title: "text-sm" },
|
|
301
|
+
lg: { base: "p-8", title: "text-2xl" }
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
});
|
|
55
305
|
```
|
|
56
306
|
|
|
57
307
|
## onComplete callback (via createRcv)
|
|
58
308
|
|
|
59
|
-
You can pass an optional onComplete callback to the createRcv function. This callback will be called with the generated classes. Helpful if you want to pass your classes to a library like
|
|
309
|
+
You can pass an optional onComplete callback to the createRcv function. This callback will be called with the generated classes. Helpful if you want to pass your classes to a library like tailwind Merge.
|
|
60
310
|
|
|
61
311
|
```ts
|
|
62
312
|
const rcv = createRcv(['mobile', 'tablet', 'desktop'], (classes) => twMerge(classes));
|
|
63
313
|
```
|
|
314
|
+
|
|
315
|
+
## Typescript helpers
|
|
316
|
+
|
|
317
|
+
rcv provides a helper type to make it easier to type your component props.
|
|
318
|
+
|
|
319
|
+
If you use the default breakpoints (sm, md, lg, xl), you can use the `ResponsiveValue` type to make existing props responsive.
|
|
320
|
+
|
|
321
|
+
```ts
|
|
322
|
+
type ButtonProps = {
|
|
323
|
+
intent: "primary" | "secondary";
|
|
324
|
+
size: ResponsiveValue<"sm" | "lg">;
|
|
325
|
+
disabled: boolean;
|
|
326
|
+
error: boolean;
|
|
327
|
+
};
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
If you use custom breakpoints you need to pass the breakpoints to the `ResponsiveValue` type.
|
|
331
|
+
|
|
332
|
+
```ts
|
|
333
|
+
import { createRcv, type ResponsiveValue as RcvResponsiveValue } from "responsive-class-variants";
|
|
334
|
+
|
|
335
|
+
const breakpoints = ["tablet", "desktop", "wide"] as const;
|
|
336
|
+
|
|
337
|
+
export const customRcv = createRcv(breakpoints);
|
|
338
|
+
|
|
339
|
+
type Breakpoints = (typeof breakpoints)[number];
|
|
340
|
+
|
|
341
|
+
export type ResponsiveValue<T> = RcvResponsiveValue<T, Breakpoints>;
|
|
342
|
+
```
|
package/dist/index.d.ts
CHANGED
|
@@ -42,63 +42,36 @@ export declare const mapResponsiveValue: <V, T, B extends string = DefaultBreakp
|
|
|
42
42
|
/**
|
|
43
43
|
* Start of rcv and types
|
|
44
44
|
*/
|
|
45
|
-
type VariantValue = Record<string, string
|
|
45
|
+
type VariantValue = Record<string, string | Record<string, string>>;
|
|
46
46
|
type VariantConfig = Record<string, VariantValue>;
|
|
47
47
|
type StringBoolean = "true" | "false";
|
|
48
|
-
type BooleanVariant = Partial<Record<StringBoolean, string
|
|
48
|
+
type BooleanVariant = Partial<Record<StringBoolean, string | Record<string, string>>>;
|
|
49
49
|
type VariantPropValue<T, B extends string> = T extends BooleanVariant ? ResponsiveValue<boolean, B> | undefined : T extends Record<string, unknown> ? ResponsiveValue<keyof T, B> : never;
|
|
50
50
|
type VariantProps<T extends VariantConfig, B extends string> = {
|
|
51
|
-
[K in keyof T]
|
|
51
|
+
[K in keyof T]?: VariantPropValue<T[K], B>;
|
|
52
52
|
} & {
|
|
53
53
|
className?: string;
|
|
54
54
|
};
|
|
55
|
-
type
|
|
55
|
+
type SlotConfig = string;
|
|
56
|
+
type SlotsConfig<S extends string> = Record<S, SlotConfig>;
|
|
57
|
+
type CompoundVariantWithSlots<T extends VariantConfig, S extends string, B extends string> = Partial<VariantProps<T, B>> & {
|
|
58
|
+
class?: Partial<Record<S, string>>;
|
|
59
|
+
className?: string;
|
|
60
|
+
};
|
|
61
|
+
export declare function rcv<T extends VariantConfig, B extends string = DefaultBreakpoints>(config: {
|
|
62
|
+
slots: SlotsConfig<string>;
|
|
63
|
+
variants?: T;
|
|
64
|
+
compoundVariants?: CompoundVariantWithSlots<T, string, B>[];
|
|
65
|
+
onComplete?: (classes: string) => string;
|
|
66
|
+
}): {
|
|
67
|
+
[K in keyof typeof config.slots]: (props?: VariantProps<T, B>) => string;
|
|
68
|
+
};
|
|
69
|
+
export declare function rcv<T extends VariantConfig, B extends string = DefaultBreakpoints>(config: {
|
|
56
70
|
base: string;
|
|
57
71
|
variants?: T;
|
|
58
72
|
compoundVariants?: Partial<VariantProps<T, B>>[];
|
|
59
73
|
onComplete?: (classes: string) => string;
|
|
60
|
-
};
|
|
61
|
-
/**
|
|
62
|
-
* Creates a function that generates classes based on variant configurations and responsive props
|
|
63
|
-
*
|
|
64
|
-
* @template T - Type extending VariantConfig (Record of variant names to their possible values and corresponding classes)
|
|
65
|
-
* @template B - The breakpoints type
|
|
66
|
-
*
|
|
67
|
-
* @param config - Configuration object for variants
|
|
68
|
-
* @param config.base - Base classes that are always applied
|
|
69
|
-
* @param config.variants - Object containing variant definitions where each key is a variant name
|
|
70
|
-
* and value is either a string of class names, an object mapping variant values to class names,
|
|
71
|
-
* or an object with true/false keys for boolean variants
|
|
72
|
-
* @param config.compoundVariants - Optional array of compound variants that apply additional classes
|
|
73
|
-
* when multiple variants have specific values
|
|
74
|
-
* @param config.onComplete - Optional callback function that receives the generated classes and returns the final classes
|
|
75
|
-
*
|
|
76
|
-
* @returns A function that accepts variant props and returns classes with twMerge
|
|
77
|
-
*
|
|
78
|
-
* @example
|
|
79
|
-
* const getButtonVariants = rcv({
|
|
80
|
-
* base: "px-4 py-2 rounded",
|
|
81
|
-
* variants: {
|
|
82
|
-
* intent: {
|
|
83
|
-
* primary: "bg-blue-500 text-white",
|
|
84
|
-
* secondary: "bg-gray-200 text-gray-800"
|
|
85
|
-
* },
|
|
86
|
-
* size: {
|
|
87
|
-
* sm: "text-sm",
|
|
88
|
-
* lg: "text-lg"
|
|
89
|
-
* },
|
|
90
|
-
* disabled: {
|
|
91
|
-
* true: "opacity-50 cursor-not-allowed"
|
|
92
|
-
* }
|
|
93
|
-
* }
|
|
94
|
-
* });
|
|
95
|
-
*
|
|
96
|
-
* // Usage:
|
|
97
|
-
* getButtonVariants({ intent: "primary", size: "lg", disabled: true })
|
|
98
|
-
* // Or with responsive values:
|
|
99
|
-
* getButtonVariants({ intent: { initial: "primary", md: "secondary" } })
|
|
100
|
-
*/
|
|
101
|
-
export declare const rcv: <T extends VariantConfig, B extends string = DefaultBreakpoints>({ base, variants, compoundVariants, onComplete, }: ResponsiveClassesConfig<T, B>) => ({ className, ...props }: VariantProps<T, B>) => string;
|
|
74
|
+
}): (props: VariantProps<T, B>) => string;
|
|
102
75
|
/**
|
|
103
76
|
* Creates a custom rcv function with custom breakpoints and an optional onComplete callback
|
|
104
77
|
*
|
|
@@ -123,5 +96,18 @@ export declare const rcv: <T extends VariantConfig, B extends string = DefaultBr
|
|
|
123
96
|
* // Usage with custom breakpoints:
|
|
124
97
|
* getButtonVariants({ intent: { initial: "primary", mobile: "secondary", desktop: "primary" } })
|
|
125
98
|
*/
|
|
126
|
-
export declare const createRcv: <B extends string>(_breakpoints?: readonly B[], onComplete?: (classes: string) => string) =>
|
|
99
|
+
export declare const createRcv: <B extends string>(_breakpoints?: readonly B[], onComplete?: (classes: string) => string) => {
|
|
100
|
+
<T extends VariantConfig>(config: {
|
|
101
|
+
slots: SlotsConfig<string>;
|
|
102
|
+
variants?: T;
|
|
103
|
+
compoundVariants?: CompoundVariantWithSlots<T, string, B>[];
|
|
104
|
+
onComplete?: (classes: string) => string;
|
|
105
|
+
}): { [K in keyof typeof config.slots]: (props?: VariantProps<T, B>) => string; };
|
|
106
|
+
<T extends VariantConfig>(config: {
|
|
107
|
+
base: string;
|
|
108
|
+
variants?: T;
|
|
109
|
+
compoundVariants?: Partial<VariantProps<T, B>>[];
|
|
110
|
+
onComplete?: (classes: string) => string;
|
|
111
|
+
}): (props: VariantProps<T, B>) => string;
|
|
112
|
+
};
|
|
127
113
|
export {};
|
package/dist/index.js
CHANGED
|
@@ -39,87 +39,121 @@ export const mapResponsiveValue = (value, mapper) => isSingularValue(value)
|
|
|
39
39
|
breakpoint,
|
|
40
40
|
mapper(value),
|
|
41
41
|
]));
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
42
|
+
// Helper functions for slots
|
|
43
|
+
const isSlotsConfig = (config) => {
|
|
44
|
+
return "slots" in config;
|
|
45
|
+
};
|
|
46
|
+
const prefixClasses = (classes, prefix) => classes
|
|
47
|
+
.split(" ")
|
|
48
|
+
.map((className) => `${prefix}:${className}`)
|
|
49
|
+
.join(" ");
|
|
50
|
+
// Helper function to get variant value for a specific slot or base
|
|
51
|
+
const getVariantValue = (variants, key, value, slotName) => {
|
|
52
|
+
const variant = variants?.[key];
|
|
53
|
+
const variantValue = variant?.[value];
|
|
54
|
+
// Handle string values
|
|
55
|
+
if (typeof variantValue === "string") {
|
|
56
|
+
return variantValue;
|
|
57
|
+
}
|
|
58
|
+
// Handle object values (slot-specific classes)
|
|
59
|
+
if (typeof variantValue === "object" &&
|
|
60
|
+
variantValue !== null &&
|
|
61
|
+
slotName &&
|
|
62
|
+
slotName in variantValue) {
|
|
63
|
+
const slotSpecificValue = variantValue[slotName];
|
|
64
|
+
if (typeof slotSpecificValue === "string") {
|
|
65
|
+
return slotSpecificValue;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return undefined;
|
|
69
|
+
};
|
|
70
|
+
// Helper function to process responsive values
|
|
71
|
+
const processResponsiveValue = (variants, key, value, slotName) => {
|
|
72
|
+
return Object.entries(value)
|
|
73
|
+
.map(([breakpoint, breakpointValue]) => {
|
|
74
|
+
const variantValue = getVariantValue(variants, key, breakpointValue, slotName);
|
|
75
|
+
if (!variantValue)
|
|
76
|
+
return undefined;
|
|
77
|
+
// If the breakpoint is initial, return without prefix
|
|
78
|
+
if (breakpoint === "initial") {
|
|
79
|
+
return variantValue;
|
|
80
|
+
}
|
|
81
|
+
// Otherwise, return with breakpoint prefix
|
|
82
|
+
return prefixClasses(variantValue, breakpoint);
|
|
83
|
+
})
|
|
84
|
+
.filter(Boolean)
|
|
85
|
+
.join(" ");
|
|
86
|
+
};
|
|
87
|
+
// Helper function to process variant props into classes
|
|
88
|
+
const processVariantProps = (props, variants, slotName) => {
|
|
89
|
+
return Object.entries(props)
|
|
84
90
|
.map(([key, propValue]) => {
|
|
85
|
-
const variant = variants?.[key];
|
|
86
91
|
const value = typeof propValue === "boolean" ? String(propValue) : propValue;
|
|
87
92
|
// Handle undefined values
|
|
88
93
|
if (!value)
|
|
89
94
|
return undefined;
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
return variantValue;
|
|
95
|
+
// Handle singular values
|
|
96
|
+
if (typeof value === "string") {
|
|
97
|
+
return getVariantValue(variants, key, value, slotName);
|
|
94
98
|
}
|
|
95
99
|
// Handle responsive values
|
|
96
|
-
return
|
|
97
|
-
.map(([breakpoint, value]) => {
|
|
98
|
-
// If the breakpoint is initial, return the variant value without breakpoint prefix
|
|
99
|
-
if (breakpoint === "initial") {
|
|
100
|
-
return variants?.[key]?.[value];
|
|
101
|
-
}
|
|
102
|
-
// Otherwise, return the variant value with the breakpoint prefix
|
|
103
|
-
return variants?.[key]?.[value]
|
|
104
|
-
?.split(" ")
|
|
105
|
-
.map((className) => `${breakpoint}:${className}`)
|
|
106
|
-
.join(" ");
|
|
107
|
-
})
|
|
108
|
-
.join(" ");
|
|
100
|
+
return processResponsiveValue(variants, key, value, slotName);
|
|
109
101
|
})
|
|
110
102
|
.filter(Boolean)
|
|
111
103
|
.join(" ");
|
|
104
|
+
};
|
|
105
|
+
// Helper function to match compound variants
|
|
106
|
+
const matchesCompoundVariant = (compound, props) => {
|
|
107
|
+
return Object.entries(compound).every(([key, value]) => props[key] === String(value) ||
|
|
108
|
+
props[key] === value);
|
|
109
|
+
};
|
|
110
|
+
const createSlotFunction = (slotConfig, variants, compoundVariants, onComplete, slotName) => ({ className, ...props } = {}) => {
|
|
111
|
+
const responsiveClasses = processVariantProps(props, variants, slotName);
|
|
112
112
|
const compoundClasses = compoundVariants
|
|
113
|
-
?.map(({ className, ...compound }) => {
|
|
114
|
-
if (
|
|
115
|
-
|
|
113
|
+
?.map(({ class: slotClasses, className: compoundClassName, ...compound }) => {
|
|
114
|
+
if (matchesCompoundVariant(compound, props)) {
|
|
115
|
+
// If compound variant has slot-specific classes, use those for this slot
|
|
116
|
+
if (slotClasses &&
|
|
117
|
+
typeof slotClasses === "object" &&
|
|
118
|
+
slotClasses[slotName]) {
|
|
119
|
+
return slotClasses[slotName];
|
|
120
|
+
}
|
|
121
|
+
// Otherwise use the general className
|
|
122
|
+
return compoundClassName;
|
|
116
123
|
}
|
|
117
124
|
return undefined;
|
|
118
125
|
})
|
|
119
126
|
.filter(Boolean);
|
|
120
|
-
const classes = clsx(
|
|
127
|
+
const classes = clsx(slotConfig, responsiveClasses, compoundClasses, className);
|
|
121
128
|
return onComplete ? onComplete(classes) : classes;
|
|
122
129
|
};
|
|
130
|
+
export function rcv(config) {
|
|
131
|
+
// Check if config is a slots config
|
|
132
|
+
if (isSlotsConfig(config)) {
|
|
133
|
+
const { slots, variants, compoundVariants, onComplete } = config;
|
|
134
|
+
const slotFunctions = {};
|
|
135
|
+
// Create slot functions for each slot
|
|
136
|
+
for (const [slotName, slotConfig] of Object.entries(slots)) {
|
|
137
|
+
slotFunctions[slotName] = createSlotFunction(slotConfig, variants, compoundVariants, onComplete, slotName);
|
|
138
|
+
}
|
|
139
|
+
return slotFunctions;
|
|
140
|
+
}
|
|
141
|
+
// If config is not a slots config, create a base function
|
|
142
|
+
const { base, variants, compoundVariants, onComplete } = config;
|
|
143
|
+
return ({ className, ...props }) => {
|
|
144
|
+
const responsiveClasses = processVariantProps(props, variants);
|
|
145
|
+
const compoundClasses = compoundVariants
|
|
146
|
+
?.map(({ className: compoundClassName, ...compound }) => {
|
|
147
|
+
if (matchesCompoundVariant(compound, props)) {
|
|
148
|
+
return compoundClassName;
|
|
149
|
+
}
|
|
150
|
+
return undefined;
|
|
151
|
+
})
|
|
152
|
+
.filter(Boolean);
|
|
153
|
+
const classes = clsx(base, responsiveClasses, compoundClasses, className);
|
|
154
|
+
return onComplete ? onComplete(classes) : classes;
|
|
155
|
+
};
|
|
156
|
+
}
|
|
123
157
|
/**
|
|
124
158
|
* Creates a custom rcv function with custom breakpoints and an optional onComplete callback
|
|
125
159
|
*
|
|
@@ -145,6 +179,20 @@ export const rcv = ({ base, variants, compoundVariants, onComplete, }) => ({ cla
|
|
|
145
179
|
* getButtonVariants({ intent: { initial: "primary", mobile: "secondary", desktop: "primary" } })
|
|
146
180
|
*/
|
|
147
181
|
export const createRcv = (_breakpoints, onComplete) => {
|
|
148
|
-
|
|
182
|
+
function customRcv(config) {
|
|
183
|
+
if (isSlotsConfig(config)) {
|
|
184
|
+
return rcv({
|
|
185
|
+
...config,
|
|
186
|
+
onComplete: onComplete || config.onComplete,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
return rcv({
|
|
191
|
+
...config,
|
|
192
|
+
onComplete: onComplete || config.onComplete,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return customRcv;
|
|
149
197
|
};
|
|
150
198
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"/","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["import { clsx } from \"clsx\";\n\nexport type DefaultBreakpoints = \"sm\" | \"md\" | \"lg\" | \"xl\";\nexport type Breakpoints = DefaultBreakpoints;\n\nexport type BreakpointsMap<V, B extends string = DefaultBreakpoints> = {\n\tinitial: V;\n} & Partial<{\n\t[breakpoint in B]: V;\n}>;\n\nexport type ResponsiveValue<T, B extends string = DefaultBreakpoints> =\n\t| T\n\t| BreakpointsMap<T, B>;\n\nconst isSingularValue = <A, B extends string>(\n\tvalue: ResponsiveValue<A, B>,\n): value is A => !isBreakpointsMap(value);\n\nconst isBreakpointsMap = <A, B extends string>(\n\tvalue: ResponsiveValue<A, B>,\n): value is BreakpointsMap<A, B> =>\n\ttypeof value === \"object\" && value != null && !Array.isArray(value);\n\n/**\n * Maps a ResponsiveValue to a new ResponsiveValue using the provided mapper function. Singular values are passed through as is.\n *\n * @template V The type of the original value\n * @template T The type of the mapped value\n * @template B The type of breakpoints\n * @param {ResponsiveValue<V, B>} value - The original ResponsiveValue to be mapped\n * @param {function(V): T} mapper - A function that maps a ResponsiveValue to a new ResponsiveValue\n * @returns {ResponsiveValue<T, B>} A new ResponsiveValue with the mapped values\n *\n *\n * @example\n * const sizes = {\n * initial: 'md',\n * sm: 'lg',\n * }\n *\n * const output = mapResponsiveValue(sizes, size => {\n *\tswitch (size) {\n *\t\tcase 'initial':\n *\t\treturn 'sm';\n *\t\tcase 'sm':\n *\t\t\treturn 'md';\n *\t\t}\n *\t});\n *\n * // console.log(output)\n * {\n *\tinitial: 'sm',\n *\tsm: 'md',\n * }\n */\nexport const mapResponsiveValue = <V, T, B extends string = DefaultBreakpoints>(\n\tvalue: ResponsiveValue<V, B>,\n\tmapper: (value: V) => T,\n): ResponsiveValue<T, B> =>\n\tisSingularValue(value)\n\t\t? mapper(value)\n\t\t: (Object.fromEntries(\n\t\t\t\tObject.entries(value).map(([breakpoint, value]) => [\n\t\t\t\t\tbreakpoint,\n\t\t\t\t\tmapper(value),\n\t\t\t\t]),\n\t\t\t) as BreakpointsMap<T, B>);\n\n/**\n * Start of rcv and types\n */\n\ntype VariantValue = Record<string, string>;\ntype VariantConfig = Record<string, VariantValue>;\n\ntype StringBoolean = \"true\" | \"false\";\ntype BooleanVariant = Partial<Record<StringBoolean, string>>;\n\ntype VariantPropValue<T, B extends string> = T extends BooleanVariant\n\t? ResponsiveValue<boolean, B> | undefined\n\t: T extends Record<string, unknown>\n\t\t? ResponsiveValue<keyof T, B>\n\t\t: never;\n\ntype VariantProps<T extends VariantConfig, B extends string> = {\n\t[K in keyof T]: VariantPropValue<T[K], B>;\n} & {\n\tclassName?: string;\n};\n\ntype ResponsiveClassesConfig<T extends VariantConfig, B extends string> = {\n\tbase: string;\n\tvariants?: T;\n\tcompoundVariants?: Partial<VariantProps<T, B>>[];\n\tonComplete?: (classes: string) => string;\n};\n\n/**\n * Creates a function that generates classes based on variant configurations and responsive props\n *\n * @template T - Type extending VariantConfig (Record of variant names to their possible values and corresponding classes)\n * @template B - The breakpoints type\n *\n * @param config - Configuration object for variants\n * @param config.base - Base classes that are always applied\n * @param config.variants - Object containing variant definitions where each key is a variant name\n * and value is either a string of class names, an object mapping variant values to class names,\n * or an object with true/false keys for boolean variants\n * @param config.compoundVariants - Optional array of compound variants that apply additional classes\n * when multiple variants have specific values\n * @param config.onComplete - Optional callback function that receives the generated classes and returns the final classes\n *\n * @returns A function that accepts variant props and returns classes with twMerge\n *\n * @example\n * const getButtonVariants = rcv({\n * base: \"px-4 py-2 rounded\",\n * variants: {\n * intent: {\n * primary: \"bg-blue-500 text-white\",\n * secondary: \"bg-gray-200 text-gray-800\"\n * },\n * size: {\n * sm: \"text-sm\",\n * lg: \"text-lg\"\n * },\n * disabled: {\n * true: \"opacity-50 cursor-not-allowed\"\n * }\n * }\n * });\n *\n * // Usage:\n * getButtonVariants({ intent: \"primary\", size: \"lg\", disabled: true })\n * // Or with responsive values:\n * getButtonVariants({ intent: { initial: \"primary\", md: \"secondary\" } })\n */\nexport const rcv =\n\t<T extends VariantConfig, B extends string = DefaultBreakpoints>({\n\t\tbase,\n\t\tvariants,\n\t\tcompoundVariants,\n\t\tonComplete,\n\t}: ResponsiveClassesConfig<T, B>) =>\n\t({ className, ...props }: VariantProps<T, B>) => {\n\t\tconst responsiveClasses = Object.entries(props)\n\t\t\t.map(([key, propValue]: [keyof T, VariantPropValue<T[keyof T], B>]) => {\n\t\t\t\tconst variant = variants?.[key];\n\t\t\t\tconst value =\n\t\t\t\t\ttypeof propValue === \"boolean\" ? String(propValue) : propValue;\n\n\t\t\t\t// Handle undefined values\n\t\t\t\tif (!value) return undefined;\n\n\t\t\t\tconst variantValue = variant?.[value as keyof VariantValue];\n\n\t\t\t\t// Handle string values\n\t\t\t\tif (typeof variantValue === \"string\") {\n\t\t\t\t\treturn variantValue;\n\t\t\t\t}\n\n\t\t\t\t// Handle responsive values\n\t\t\t\treturn Object.entries(value as Partial<BreakpointsMap<T, B>>)\n\t\t\t\t\t.map(([breakpoint, value]) => {\n\t\t\t\t\t\t// If the breakpoint is initial, return the variant value without breakpoint prefix\n\t\t\t\t\t\tif (breakpoint === \"initial\") {\n\t\t\t\t\t\t\treturn variants?.[key]?.[value as keyof typeof variant];\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Otherwise, return the variant value with the breakpoint prefix\n\t\t\t\t\t\treturn variants?.[key]?.[value as keyof typeof variant]\n\t\t\t\t\t\t\t?.split(\" \")\n\t\t\t\t\t\t\t.map((className) => `${breakpoint}:${className}`)\n\t\t\t\t\t\t\t.join(\" \");\n\t\t\t\t\t})\n\t\t\t\t\t.join(\" \");\n\t\t\t})\n\t\t\t.filter(Boolean)\n\t\t\t.join(\" \");\n\n\t\tconst compoundClasses = compoundVariants\n\t\t\t?.map(({ className, ...compound }) => {\n\t\t\t\tif (\n\t\t\t\t\tObject.entries(compound).every(\n\t\t\t\t\t\t([key, value]) =>\n\t\t\t\t\t\t\tprops[key] === String(value) || props[key] === value,\n\t\t\t\t\t)\n\t\t\t\t) {\n\t\t\t\t\treturn className;\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t})\n\t\t\t.filter(Boolean);\n\n\t\tconst classes = clsx(base, responsiveClasses, compoundClasses, className);\n\t\treturn onComplete ? onComplete(classes) : classes;\n\t};\n\n/**\n * Creates a custom rcv function with custom breakpoints and an optional onComplete callback\n *\n * @template B - The custom breakpoints type\n * @param breakpoints - Optional array of custom breakpoint names\n * @param onComplete - Optional callback function that receives the generated classes and returns the final classes\n * @returns A function that creates rcv with custom breakpoints\n *\n * @example\n * const customRcv = createRcv(['mobile', 'tablet', 'desktop']);\n *\n * const getButtonVariants = customRcv({\n * base: \"px-4 py-2 rounded\",\n * variants: {\n * intent: {\n * primary: \"bg-blue-500 text-white\",\n * secondary: \"bg-gray-200 text-gray-800\"\n * }\n * }\n * });\n *\n * // Usage with custom breakpoints:\n * getButtonVariants({ intent: { initial: \"primary\", mobile: \"secondary\", desktop: \"primary\" } })\n */\n\nexport const createRcv = <B extends string>(\n\t_breakpoints?: readonly B[],\n\tonComplete?: (classes: string) => string,\n) => {\n\treturn <T extends VariantConfig>(config: ResponsiveClassesConfig<T, B>) =>\n\t\trcv<T, B>({ ...config, onComplete });\n};\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"/","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["import { clsx } from \"clsx\";\n\nexport type DefaultBreakpoints = \"sm\" | \"md\" | \"lg\" | \"xl\";\nexport type Breakpoints = DefaultBreakpoints;\n\nexport type BreakpointsMap<V, B extends string = DefaultBreakpoints> = {\n\tinitial: V;\n} & Partial<{\n\t[breakpoint in B]: V;\n}>;\n\nexport type ResponsiveValue<T, B extends string = DefaultBreakpoints> =\n\t| T\n\t| BreakpointsMap<T, B>;\n\nconst isSingularValue = <A, B extends string>(\n\tvalue: ResponsiveValue<A, B>,\n): value is A => !isBreakpointsMap(value);\n\nconst isBreakpointsMap = <A, B extends string>(\n\tvalue: ResponsiveValue<A, B>,\n): value is BreakpointsMap<A, B> =>\n\ttypeof value === \"object\" && value != null && !Array.isArray(value);\n\n/**\n * Maps a ResponsiveValue to a new ResponsiveValue using the provided mapper function. Singular values are passed through as is.\n *\n * @template V The type of the original value\n * @template T The type of the mapped value\n * @template B The type of breakpoints\n * @param {ResponsiveValue<V, B>} value - The original ResponsiveValue to be mapped\n * @param {function(V): T} mapper - A function that maps a ResponsiveValue to a new ResponsiveValue\n * @returns {ResponsiveValue<T, B>} A new ResponsiveValue with the mapped values\n *\n *\n * @example\n * const sizes = {\n * initial: 'md',\n * sm: 'lg',\n * }\n *\n * const output = mapResponsiveValue(sizes, size => {\n *\tswitch (size) {\n *\t\tcase 'initial':\n *\t\treturn 'sm';\n *\t\tcase 'sm':\n *\t\t\treturn 'md';\n *\t\t}\n *\t});\n *\n * // console.log(output)\n * {\n *\tinitial: 'sm',\n *\tsm: 'md',\n * }\n */\nexport const mapResponsiveValue = <V, T, B extends string = DefaultBreakpoints>(\n\tvalue: ResponsiveValue<V, B>,\n\tmapper: (value: V) => T,\n): ResponsiveValue<T, B> =>\n\tisSingularValue(value)\n\t\t? mapper(value)\n\t\t: (Object.fromEntries(\n\t\t\t\tObject.entries(value).map(([breakpoint, value]) => [\n\t\t\t\t\tbreakpoint,\n\t\t\t\t\tmapper(value),\n\t\t\t\t]),\n\t\t\t) as BreakpointsMap<T, B>);\n\n/**\n * Start of rcv and types\n */\n\ntype VariantValue = Record<string, string | Record<string, string>>;\ntype VariantConfig = Record<string, VariantValue>;\n\ntype StringBoolean = \"true\" | \"false\";\ntype BooleanVariant = Partial<\n\tRecord<StringBoolean, string | Record<string, string>>\n>;\n\ntype VariantPropValue<T, B extends string> = T extends BooleanVariant\n\t? ResponsiveValue<boolean, B> | undefined\n\t: T extends Record<string, unknown>\n\t\t? ResponsiveValue<keyof T, B>\n\t\t: never;\n\ntype VariantProps<T extends VariantConfig, B extends string> = {\n\t[K in keyof T]?: VariantPropValue<T[K], B>;\n} & {\n\tclassName?: string;\n};\n\n// Slot configuration types\ntype SlotConfig = string;\n\ntype SlotsConfig<S extends string> = Record<S, SlotConfig>;\n\ntype CompoundVariantWithSlots<\n\tT extends VariantConfig,\n\tS extends string,\n\tB extends string,\n> = Partial<VariantProps<T, B>> & {\n\tclass?: Partial<Record<S, string>>;\n\tclassName?: string;\n};\n\ntype ResponsiveClassesConfigBase<T extends VariantConfig, B extends string> = {\n\tbase: string;\n\tvariants?: T;\n\tcompoundVariants?: Partial<VariantProps<T, B>>[];\n\tonComplete?: (classes: string) => string;\n};\n\ntype ResponsiveClassesConfigSlots<T extends VariantConfig, B extends string> = {\n\tslots: SlotsConfig<string>;\n\tvariants?: T;\n\tcompoundVariants?: CompoundVariantWithSlots<T, string, B>[];\n\tonComplete?: (classes: string) => string;\n};\n\ntype ResponsiveClassesConfig<T extends VariantConfig, B extends string> =\n\t| ResponsiveClassesConfigBase<T, B>\n\t| ResponsiveClassesConfigSlots<T, B>;\n\n// Helper functions for slots\nconst isSlotsConfig = <T extends VariantConfig, B extends string>(\n\tconfig: ResponsiveClassesConfig<T, B>,\n): config is {\n\tslots: SlotsConfig<string>;\n\tvariants?: T;\n\tcompoundVariants?: CompoundVariantWithSlots<T, string, B>[];\n\tonComplete?: (classes: string) => string;\n} => {\n\treturn \"slots\" in config;\n};\n\nconst prefixClasses = (classes: string, prefix: string) =>\n\tclasses\n\t\t.split(\" \")\n\t\t.map((className) => `${prefix}:${className}`)\n\t\t.join(\" \");\n\n// Helper function to get variant value for a specific slot or base\nconst getVariantValue = <T extends VariantConfig>(\n\tvariants: T | undefined,\n\tkey: keyof T,\n\tvalue: string,\n\tslotName?: string,\n) => {\n\tconst variant = variants?.[key];\n\tconst variantValue = variant?.[value as keyof VariantValue];\n\n\t// Handle string values\n\tif (typeof variantValue === \"string\") {\n\t\treturn variantValue;\n\t}\n\n\t// Handle object values (slot-specific classes)\n\tif (\n\t\ttypeof variantValue === \"object\" &&\n\t\tvariantValue !== null &&\n\t\tslotName &&\n\t\tslotName in variantValue\n\t) {\n\t\tconst slotSpecificValue = variantValue[slotName];\n\t\tif (typeof slotSpecificValue === \"string\") {\n\t\t\treturn slotSpecificValue;\n\t\t}\n\t}\n\n\treturn undefined;\n};\n\n// Helper function to process responsive values\nconst processResponsiveValue = <T extends VariantConfig, B extends string>(\n\tvariants: T | undefined,\n\tkey: keyof T,\n\tvalue: Partial<BreakpointsMap<T, B>>,\n\tslotName?: string,\n) => {\n\treturn Object.entries(value)\n\t\t.map(([breakpoint, breakpointValue]) => {\n\t\t\tconst variantValue = getVariantValue(\n\t\t\t\tvariants,\n\t\t\t\tkey,\n\t\t\t\tbreakpointValue as string,\n\t\t\t\tslotName,\n\t\t\t);\n\n\t\t\tif (!variantValue) return undefined;\n\n\t\t\t// If the breakpoint is initial, return without prefix\n\t\t\tif (breakpoint === \"initial\") {\n\t\t\t\treturn variantValue;\n\t\t\t}\n\n\t\t\t// Otherwise, return with breakpoint prefix\n\t\t\treturn prefixClasses(variantValue, breakpoint);\n\t\t})\n\t\t.filter(Boolean)\n\t\t.join(\" \");\n};\n\n// Helper function to process variant props into classes\nconst processVariantProps = <T extends VariantConfig, B extends string>(\n\tprops: Omit<VariantProps<T, B>, \"className\">,\n\tvariants: T | undefined,\n\tslotName?: string,\n) => {\n\treturn Object.entries(props)\n\t\t.map(([key, propValue]: [keyof T, VariantPropValue<T[keyof T], B>]) => {\n\t\t\tconst value =\n\t\t\t\ttypeof propValue === \"boolean\" ? String(propValue) : propValue;\n\n\t\t\t// Handle undefined values\n\t\t\tif (!value) return undefined;\n\n\t\t\t// Handle singular values\n\t\t\tif (typeof value === \"string\") {\n\t\t\t\treturn getVariantValue(variants, key, value, slotName);\n\t\t\t}\n\n\t\t\t// Handle responsive values\n\t\t\treturn processResponsiveValue(\n\t\t\t\tvariants,\n\t\t\t\tkey,\n\t\t\t\tvalue as Partial<BreakpointsMap<T, B>>,\n\t\t\t\tslotName,\n\t\t\t);\n\t\t})\n\t\t.filter(Boolean)\n\t\t.join(\" \");\n};\n\n// Helper function to match compound variants\nconst matchesCompoundVariant = <T extends VariantConfig, B extends string>(\n\tcompound: Omit<CompoundVariantWithSlots<T, string, B>, \"className\" | \"class\">,\n\tprops: Omit<VariantProps<T, B>, \"className\">,\n) => {\n\treturn Object.entries(compound).every(\n\t\t([key, value]) =>\n\t\t\tprops[key as keyof typeof props] === String(value) ||\n\t\t\tprops[key as keyof typeof props] === value,\n\t);\n};\n\nconst createSlotFunction =\n\t<T extends VariantConfig, B extends string>(\n\t\tslotConfig: SlotConfig,\n\t\tvariants: T | undefined,\n\t\tcompoundVariants: CompoundVariantWithSlots<T, string, B>[] | undefined,\n\t\tonComplete: ((classes: string) => string) | undefined,\n\t\tslotName: string,\n\t) =>\n\t({ className, ...props }: VariantProps<T, B> = {} as VariantProps<T, B>) => {\n\t\tconst responsiveClasses = processVariantProps(props, variants, slotName);\n\n\t\tconst compoundClasses = compoundVariants\n\t\t\t?.map(\n\t\t\t\t({ class: slotClasses, className: compoundClassName, ...compound }) => {\n\t\t\t\t\tif (matchesCompoundVariant(compound, props)) {\n\t\t\t\t\t\t// If compound variant has slot-specific classes, use those for this slot\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tslotClasses &&\n\t\t\t\t\t\t\ttypeof slotClasses === \"object\" &&\n\t\t\t\t\t\t\tslotClasses[slotName]\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\treturn slotClasses[slotName];\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Otherwise use the general className\n\t\t\t\t\t\treturn compoundClassName;\n\t\t\t\t\t}\n\t\t\t\t\treturn undefined;\n\t\t\t\t},\n\t\t\t)\n\t\t\t.filter(Boolean);\n\n\t\tconst classes = clsx(\n\t\t\tslotConfig,\n\t\t\tresponsiveClasses,\n\t\t\tcompoundClasses,\n\t\t\tclassName,\n\t\t);\n\t\treturn onComplete ? onComplete(classes) : classes;\n\t};\n\n// Function overloads for rcv\nexport function rcv<\n\tT extends VariantConfig,\n\tB extends string = DefaultBreakpoints,\n>(config: {\n\tslots: SlotsConfig<string>;\n\tvariants?: T;\n\tcompoundVariants?: CompoundVariantWithSlots<T, string, B>[];\n\tonComplete?: (classes: string) => string;\n}): {\n\t[K in keyof typeof config.slots]: (props?: VariantProps<T, B>) => string;\n};\n\nexport function rcv<\n\tT extends VariantConfig,\n\tB extends string = DefaultBreakpoints,\n>(config: {\n\tbase: string;\n\tvariants?: T;\n\tcompoundVariants?: Partial<VariantProps<T, B>>[];\n\tonComplete?: (classes: string) => string;\n}): (props: VariantProps<T, B>) => string;\n\nexport function rcv<\n\tT extends VariantConfig,\n\tB extends string = DefaultBreakpoints,\n>(config: ResponsiveClassesConfig<T, B>) {\n\t// Check if config is a slots config\n\tif (isSlotsConfig(config)) {\n\t\tconst { slots, variants, compoundVariants, onComplete } = config;\n\t\tconst slotFunctions: Record<string, (props: VariantProps<T, B>) => string> =\n\t\t\t{};\n\n\t\t// Create slot functions for each slot\n\t\tfor (const [slotName, slotConfig] of Object.entries(slots)) {\n\t\t\tslotFunctions[slotName] = createSlotFunction<T, B>(\n\t\t\t\tslotConfig,\n\t\t\t\tvariants,\n\t\t\t\tcompoundVariants,\n\t\t\t\tonComplete,\n\t\t\t\tslotName,\n\t\t\t);\n\t\t}\n\n\t\treturn slotFunctions as {\n\t\t\t[K in keyof typeof slots]: (props?: VariantProps<T, B>) => string;\n\t\t};\n\t}\n\n\t// If config is not a slots config, create a base function\n\tconst { base, variants, compoundVariants, onComplete } = config;\n\treturn ({ className, ...props }: VariantProps<T, B>) => {\n\t\tconst responsiveClasses = processVariantProps(props, variants);\n\n\t\tconst compoundClasses = compoundVariants\n\t\t\t?.map(({ className: compoundClassName, ...compound }) => {\n\t\t\t\tif (\n\t\t\t\t\tmatchesCompoundVariant(\n\t\t\t\t\t\tcompound as Omit<\n\t\t\t\t\t\t\tCompoundVariantWithSlots<T, string, B>,\n\t\t\t\t\t\t\t\"className\" | \"class\"\n\t\t\t\t\t\t>,\n\t\t\t\t\t\tprops,\n\t\t\t\t\t)\n\t\t\t\t) {\n\t\t\t\t\treturn compoundClassName;\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t})\n\t\t\t.filter(Boolean);\n\n\t\tconst classes = clsx(base, responsiveClasses, compoundClasses, className);\n\t\treturn onComplete ? onComplete(classes) : classes;\n\t};\n}\n\n/**\n * Creates a custom rcv function with custom breakpoints and an optional onComplete callback\n *\n * @template B - The custom breakpoints type\n * @param breakpoints - Optional array of custom breakpoint names\n * @param onComplete - Optional callback function that receives the generated classes and returns the final classes\n * @returns A function that creates rcv with custom breakpoints\n *\n * @example\n * const customRcv = createRcv(['mobile', 'tablet', 'desktop']);\n *\n * const getButtonVariants = customRcv({\n * base: \"px-4 py-2 rounded\",\n * variants: {\n * intent: {\n * primary: \"bg-blue-500 text-white\",\n * secondary: \"bg-gray-200 text-gray-800\"\n * }\n * }\n * });\n *\n * // Usage with custom breakpoints:\n * getButtonVariants({ intent: { initial: \"primary\", mobile: \"secondary\", desktop: \"primary\" } })\n */\n\nexport const createRcv = <B extends string>(\n\t_breakpoints?: readonly B[],\n\tonComplete?: (classes: string) => string,\n) => {\n\tfunction customRcv<T extends VariantConfig>(config: {\n\t\tslots: SlotsConfig<string>;\n\t\tvariants?: T;\n\t\tcompoundVariants?: CompoundVariantWithSlots<T, string, B>[];\n\t\tonComplete?: (classes: string) => string;\n\t}): {\n\t\t[K in keyof typeof config.slots]: (props?: VariantProps<T, B>) => string;\n\t};\n\n\tfunction customRcv<T extends VariantConfig>(config: {\n\t\tbase: string;\n\t\tvariants?: T;\n\t\tcompoundVariants?: Partial<VariantProps<T, B>>[];\n\t\tonComplete?: (classes: string) => string;\n\t}): (props: VariantProps<T, B>) => string;\n\n\tfunction customRcv<T extends VariantConfig>(\n\t\tconfig: ResponsiveClassesConfig<T, B>,\n\t) {\n\t\tif (isSlotsConfig(config)) {\n\t\t\treturn rcv<T, B>({\n\t\t\t\t...config,\n\t\t\t\tonComplete: onComplete || config.onComplete,\n\t\t\t});\n\t\t} else {\n\t\t\treturn rcv<T, B>({\n\t\t\t\t...config,\n\t\t\t\tonComplete: onComplete || config.onComplete,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn customRcv;\n};\n"]}
|