nestable-tailwind-variants 0.1.4 → 0.2.1
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 +508 -132
- package/dist/cache.d.ts +6 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +11 -0
- package/dist/cache.js.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/merge.d.ts +59 -0
- package/dist/merge.d.ts.map +1 -0
- package/dist/merge.js +78 -0
- package/dist/merge.js.map +1 -0
- package/dist/ntv.d.ts +40 -42
- package/dist/ntv.d.ts.map +1 -1
- package/dist/ntv.js +47 -100
- package/dist/ntv.js.map +1 -1
- package/dist/resolver.d.ts +11 -0
- package/dist/resolver.d.ts.map +1 -0
- package/dist/resolver.js +50 -0
- package/dist/resolver.js.map +1 -0
- package/dist/types.d.ts +100 -7
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +2 -2
- package/dist/utils.js.map +1 -1
- package/package.json +8 -6
- package/dist/composeNtv.d.ts +0 -47
- package/dist/composeNtv.d.ts.map +0 -1
- package/dist/composeNtv.js +0 -55
- package/dist/composeNtv.js.map +0 -1
package/dist/cache.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { extendTailwindMerge } from 'tailwind-merge';
|
|
2
|
+
import type { TwMergeConfig } from './types.js';
|
|
3
|
+
type TwMergeFn = ReturnType<typeof extendTailwindMerge>;
|
|
4
|
+
export declare function getCachedTwMerge(config: TwMergeConfig): TwMergeFn;
|
|
5
|
+
export {};
|
|
6
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAIxD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,CAOjE"}
|
package/dist/cache.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { extendTailwindMerge } from 'tailwind-merge';
|
|
2
|
+
const cache = new Map();
|
|
3
|
+
export function getCachedTwMerge(config) {
|
|
4
|
+
let cached = cache.get(config);
|
|
5
|
+
if (!cached) {
|
|
6
|
+
cached = extendTailwindMerge(config);
|
|
7
|
+
cache.set(config, cached);
|
|
8
|
+
}
|
|
9
|
+
return cached;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAKrD,MAAM,KAAK,GAAG,IAAI,GAAG,EAA4B,CAAC;AAElD,MAAM,UAAU,gBAAgB,CAAC,MAAqB;IACpD,IAAI,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC/B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;QACrC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
3
|
-
export type {
|
|
1
|
+
export { createMergeNtv, mergeNtv, mergeNtvWithOptions } from './merge.js';
|
|
2
|
+
export { createNtv, ntv } from './ntv.js';
|
|
3
|
+
export type { ClassProp, ClassValue, MergeStyleFunctionProps, NtvOptions, NtvProps, NtvScheme, SchemeFor, StyleFunction, TwMergeConfig, } from './types.js';
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAC3E,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC1C,YAAY,EACV,SAAS,EACT,UAAU,EACV,uBAAuB,EACvB,UAAU,EACV,QAAQ,EACR,SAAS,EACT,SAAS,EACT,aAAa,EACb,aAAa,GACd,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
1
|
+
export { createMergeNtv, mergeNtv, mergeNtvWithOptions } from './merge.js';
|
|
2
|
+
export { createNtv, ntv } from './ntv.js';
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAC3E,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC"}
|
package/dist/merge.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { MergeStyleFunctionProps, NtvOptions, StyleFunction } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Create a merged style function with custom options (curried version).
|
|
4
|
+
*
|
|
5
|
+
* @param styleFns - Style functions to merge
|
|
6
|
+
* @returns A function that accepts options and returns a merged style function
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* const styles = mergeNtvWithOptions(baseStyles, overrideStyles)({ twMerge: false });
|
|
11
|
+
* styles({ variant: 'primary' });
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export declare function mergeNtvWithOptions<T extends readonly StyleFunction<any>[]>(...styleFns: T): (options?: NtvOptions) => StyleFunction<MergeStyleFunctionProps<T>>;
|
|
15
|
+
/**
|
|
16
|
+
* Merge multiple style functions into a single style function.
|
|
17
|
+
* Later functions take precedence over earlier ones (via tailwind-merge).
|
|
18
|
+
*
|
|
19
|
+
* @param styleFns - Style functions to merge
|
|
20
|
+
* @returns A merged style function that accepts combined props from all input functions
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* const colorStyles = ntv<{ color: 'red' | 'blue' }>({
|
|
25
|
+
* color: { red: 'text-red', blue: 'text-blue' },
|
|
26
|
+
* });
|
|
27
|
+
*
|
|
28
|
+
* const sizeStyles = ntv<{ size: 'sm' | 'lg' }>({
|
|
29
|
+
* size: { sm: 'text-sm', lg: 'text-lg' },
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* const styles = mergeNtv(colorStyles, sizeStyles);
|
|
33
|
+
* styles({ color: 'red', size: 'lg' }); // 'text-red text-lg'
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare function mergeNtv<T extends readonly StyleFunction<any>[]>(...styleFns: T): StyleFunction<MergeStyleFunctionProps<T>>;
|
|
37
|
+
/**
|
|
38
|
+
* Create a pre-configured mergeNtv function with fixed options.
|
|
39
|
+
*
|
|
40
|
+
* @param defaultOptions - Default options to apply to all mergeNtv calls
|
|
41
|
+
* @returns A pre-configured mergeNtv function
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```ts
|
|
45
|
+
* const myMergeNtv = createMergeNtv({
|
|
46
|
+
* twMergeConfig: {
|
|
47
|
+
* extend: {
|
|
48
|
+
* classGroups: {
|
|
49
|
+
* 'font-size': [{ text: ['huge', 'tiny'] }],
|
|
50
|
+
* },
|
|
51
|
+
* },
|
|
52
|
+
* },
|
|
53
|
+
* });
|
|
54
|
+
*
|
|
55
|
+
* const styles = myMergeNtv(baseStyles, overrideStyles);
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export declare function createMergeNtv(defaultOptions: NtvOptions): <T extends readonly StyleFunction<any>[]>(...styleFns: T) => StyleFunction<MergeStyleFunctionProps<[...T]>>;
|
|
59
|
+
//# sourceMappingURL=merge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../src/merge.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAa,uBAAuB,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhG;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,SAAS,aAAa,CAAC,GAAG,CAAC,EAAE,EACzE,GAAG,QAAQ,EAAE,CAAC,GACb,CAAC,OAAO,CAAC,EAAE,UAAU,KAAK,aAAa,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAoBrE;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,SAAS,aAAa,CAAC,GAAG,CAAC,EAAE,EAC9D,GAAG,QAAQ,EAAE,CAAC,GACb,aAAa,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAE3C;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,cAAc,CAAC,cAAc,EAAE,UAAU,IACpB,CAAC,SAAS,SAAS,aAAa,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,UAAU,CAAC,oDAG3F"}
|
package/dist/merge.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { twJoin, twMerge } from 'tailwind-merge';
|
|
2
|
+
import { getCachedTwMerge } from './cache.js';
|
|
3
|
+
/**
|
|
4
|
+
* Create a merged style function with custom options (curried version).
|
|
5
|
+
*
|
|
6
|
+
* @param styleFns - Style functions to merge
|
|
7
|
+
* @returns A function that accepts options and returns a merged style function
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* const styles = mergeNtvWithOptions(baseStyles, overrideStyles)({ twMerge: false });
|
|
12
|
+
* styles({ variant: 'primary' });
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export function mergeNtvWithOptions(...styleFns) {
|
|
16
|
+
return function createMergedStyleFn({ twMerge: usesTwMerge = true, twMergeConfig, } = {}) {
|
|
17
|
+
const mergeFn = usesTwMerge
|
|
18
|
+
? twMergeConfig
|
|
19
|
+
? getCachedTwMerge(twMergeConfig)
|
|
20
|
+
: twMerge
|
|
21
|
+
: twJoin;
|
|
22
|
+
return function mergedStyleFn({ class: slotClass, className: slotClassName, ...props } = {}) {
|
|
23
|
+
const styleResults = styleFns.map((fn) => fn(props));
|
|
24
|
+
return mergeFn(...styleResults, slotClass, slotClassName);
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Merge multiple style functions into a single style function.
|
|
30
|
+
* Later functions take precedence over earlier ones (via tailwind-merge).
|
|
31
|
+
*
|
|
32
|
+
* @param styleFns - Style functions to merge
|
|
33
|
+
* @returns A merged style function that accepts combined props from all input functions
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* const colorStyles = ntv<{ color: 'red' | 'blue' }>({
|
|
38
|
+
* color: { red: 'text-red', blue: 'text-blue' },
|
|
39
|
+
* });
|
|
40
|
+
*
|
|
41
|
+
* const sizeStyles = ntv<{ size: 'sm' | 'lg' }>({
|
|
42
|
+
* size: { sm: 'text-sm', lg: 'text-lg' },
|
|
43
|
+
* });
|
|
44
|
+
*
|
|
45
|
+
* const styles = mergeNtv(colorStyles, sizeStyles);
|
|
46
|
+
* styles({ color: 'red', size: 'lg' }); // 'text-red text-lg'
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export function mergeNtv(...styleFns) {
|
|
50
|
+
return mergeNtvWithOptions(...styleFns)();
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Create a pre-configured mergeNtv function with fixed options.
|
|
54
|
+
*
|
|
55
|
+
* @param defaultOptions - Default options to apply to all mergeNtv calls
|
|
56
|
+
* @returns A pre-configured mergeNtv function
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* const myMergeNtv = createMergeNtv({
|
|
61
|
+
* twMergeConfig: {
|
|
62
|
+
* extend: {
|
|
63
|
+
* classGroups: {
|
|
64
|
+
* 'font-size': [{ text: ['huge', 'tiny'] }],
|
|
65
|
+
* },
|
|
66
|
+
* },
|
|
67
|
+
* },
|
|
68
|
+
* });
|
|
69
|
+
*
|
|
70
|
+
* const styles = myMergeNtv(baseStyles, overrideStyles);
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export function createMergeNtv(defaultOptions) {
|
|
74
|
+
return function configuredMergeNtv(...styleFns) {
|
|
75
|
+
return mergeNtvWithOptions(...styleFns)(defaultOptions);
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=merge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge.js","sourceRoot":"","sources":["../src/merge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAEjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,mBAAmB,CACjC,GAAG,QAAW;IAEd,OAAO,SAAS,mBAAmB,CAAC,EAClC,OAAO,EAAE,WAAW,GAAG,IAAI,EAC3B,aAAa,MACC,EAAE;QAChB,MAAM,OAAO,GAAG,WAAW;YACzB,CAAC,CAAC,aAAa;gBACb,CAAC,CAAC,gBAAgB,CAAC,aAAa,CAAC;gBACjC,CAAC,CAAC,OAAO;YACX,CAAC,CAAC,MAAM,CAAC;QAEX,OAAO,SAAS,aAAa,CAAC,EAC5B,KAAK,EAAE,SAAS,EAChB,SAAS,EAAE,aAAa,EACxB,GAAG,KAAK,KAC+B,EAAE;YACzC,MAAM,YAAY,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;YACrD,OAAO,OAAO,CAAC,GAAG,YAAY,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC;QAC5D,CAA8C,CAAC;IACjD,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,QAAQ,CACtB,GAAG,QAAW;IAEd,OAAO,mBAAmB,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC;AAC5C,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,cAAc,CAAC,cAA0B;IACvD,OAAO,SAAS,kBAAkB,CAA0C,GAAG,QAAW;QACxF,OAAO,mBAAmB,CAAC,GAAG,QAAQ,CAAC,CAAC,cAAc,CAAC,CAAC;IAC1D,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/ntv.d.ts
CHANGED
|
@@ -1,61 +1,59 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
type BooleanConditionKey = `is${Capitalize<string>}` | `allows${Capitalize<string>}`;
|
|
3
|
-
type ExtractBooleanKeys<Props> = {
|
|
4
|
-
[K in keyof Props]: K extends BooleanConditionKey ? K : never;
|
|
5
|
-
}[keyof Props];
|
|
6
|
-
type ExtractVariantKeys<Props> = Exclude<keyof Props, ExtractBooleanKeys<Props>>;
|
|
7
|
-
type NestedStyleValue<Props> = string | StyleDefinition<Props>;
|
|
8
|
-
type StyleDefinition<Props> = {
|
|
9
|
-
default?: string;
|
|
10
|
-
} & {
|
|
11
|
-
[K in ExtractBooleanKeys<Props>]?: NestedStyleValue<Props>;
|
|
12
|
-
} & {
|
|
13
|
-
[K in ExtractVariantKeys<Props>]?: {
|
|
14
|
-
[V in Extract<Props[K], string>]?: NestedStyleValue<Props>;
|
|
15
|
-
};
|
|
16
|
-
};
|
|
1
|
+
import type { NtvOptions, NtvProps, NtvScheme, SchemeFor, StyleFunction } from './types.js';
|
|
17
2
|
/**
|
|
18
|
-
*
|
|
3
|
+
* Create a nestable tailwind variants style function.
|
|
4
|
+
*
|
|
5
|
+
* @param scheme - The scheme object defining variants and conditions
|
|
6
|
+
* @param options - Optional settings for tailwind-merge behavior
|
|
7
|
+
* @returns A style function that accepts props and returns merged class names
|
|
19
8
|
*
|
|
20
9
|
* @example
|
|
21
10
|
* ```ts
|
|
22
|
-
*
|
|
23
|
-
* const ntvNoMerge = createNTV({ twMerge: false });
|
|
11
|
+
* type ButtonProps = { variant: 'primary' | 'secondary'; isDisabled: boolean };
|
|
24
12
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* shadow: ['100', '200', '300'],
|
|
31
|
-
* },
|
|
32
|
-
* },
|
|
13
|
+
* const button = ntv<ButtonProps>({
|
|
14
|
+
* $base: 'px-4 py-2 rounded',
|
|
15
|
+
* variant: {
|
|
16
|
+
* primary: 'bg-blue-500 text-white',
|
|
17
|
+
* secondary: 'bg-gray-200 text-gray-800',
|
|
33
18
|
* },
|
|
19
|
+
* isDisabled: 'opacity-50 cursor-not-allowed',
|
|
34
20
|
* });
|
|
21
|
+
*
|
|
22
|
+
* button({ variant: 'primary' }); // 'px-4 py-2 rounded bg-blue-500 text-white'
|
|
23
|
+
* button({ variant: 'primary', isDisabled: true }); // 'px-4 py-2 rounded bg-blue-500 text-white opacity-50 cursor-not-allowed'
|
|
35
24
|
* ```
|
|
36
25
|
*/
|
|
37
|
-
export declare function
|
|
26
|
+
export declare function ntv<TProps extends NtvProps>(scheme: SchemeFor<TProps>, options?: NtvOptions): StyleFunction<TProps>;
|
|
27
|
+
export declare function ntv(scheme: NtvScheme, options?: NtvOptions): StyleFunction<any>;
|
|
38
28
|
/**
|
|
39
|
-
*
|
|
29
|
+
* Create a pre-configured ntv function with fixed options.
|
|
30
|
+
*
|
|
31
|
+
* @param defaultOptions - Default options to apply to all ntv calls
|
|
32
|
+
* @returns A pre-configured ntv function
|
|
40
33
|
*
|
|
41
34
|
* @example
|
|
42
35
|
* ```ts
|
|
43
|
-
* const
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
36
|
+
* const myNtv = createNtv({
|
|
37
|
+
* twMergeConfig: {
|
|
38
|
+
* extend: {
|
|
39
|
+
* classGroups: {
|
|
40
|
+
* 'font-size': [{ text: ['huge', 'tiny'] }],
|
|
41
|
+
* },
|
|
42
|
+
* },
|
|
48
43
|
* },
|
|
49
|
-
* isDisabled: 'opacity-50 cursor-not-allowed',
|
|
50
44
|
* });
|
|
51
45
|
*
|
|
52
|
-
* button({
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
46
|
+
* const button = myNtv({
|
|
47
|
+
* $base: 'text-huge',
|
|
48
|
+
* variant: {
|
|
49
|
+
* primary: 'bg-blue-500',
|
|
50
|
+
* secondary: 'bg-gray-200',
|
|
51
|
+
* },
|
|
52
|
+
* });
|
|
57
53
|
* ```
|
|
58
54
|
*/
|
|
59
|
-
export declare
|
|
60
|
-
|
|
55
|
+
export declare function createNtv(defaultOptions: NtvOptions): {
|
|
56
|
+
<TProps extends NtvProps>(scheme: SchemeFor<TProps>): StyleFunction<TProps>;
|
|
57
|
+
(scheme: NtvScheme): StyleFunction<any>;
|
|
58
|
+
};
|
|
61
59
|
//# sourceMappingURL=ntv.d.ts.map
|
package/dist/ntv.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ntv.d.ts","sourceRoot":"","sources":["../src/ntv.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"ntv.d.ts","sourceRoot":"","sources":["../src/ntv.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,UAAU,EACV,QAAQ,EACR,SAAS,EACT,SAAS,EACT,aAAa,EACd,MAAM,YAAY,CAAC;AAiCpB;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,GAAG,CAAC,MAAM,SAAS,QAAQ,EACzC,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,EACzB,OAAO,CAAC,EAAE,UAAU,GACnB,aAAa,CAAC,MAAM,CAAC,CAAC;AACzB,wBAAgB,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;AAwBjF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,SAAS,CAAC,cAAc,EAAE,UAAU,GAAG;IACrD,CAAC,MAAM,SAAS,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAC5E,CAAC,MAAM,EAAE,SAAS,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;CACzC,CAIA"}
|
package/dist/ntv.js
CHANGED
|
@@ -1,123 +1,70 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
context.classes.push(definition);
|
|
9
|
-
return;
|
|
10
|
-
}
|
|
11
|
-
if (!isStyleDefinition(definition)) {
|
|
12
|
-
return;
|
|
1
|
+
import { twJoin, twMerge } from 'tailwind-merge';
|
|
2
|
+
import { getCachedTwMerge } from './cache.js';
|
|
3
|
+
import { resolveConditions } from './resolver.js';
|
|
4
|
+
import { isPlainObject } from './utils.js';
|
|
5
|
+
function validateScheme(scheme) {
|
|
6
|
+
if ('class' in scheme) {
|
|
7
|
+
throw new Error('The "class" property is not allowed in ntv scheme. Use "$base" instead.');
|
|
13
8
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const conditions = [];
|
|
17
|
-
for (const [key, value] of entries) {
|
|
18
|
-
if (key === 'default') {
|
|
19
|
-
defaultValue = value;
|
|
20
|
-
}
|
|
21
|
-
else {
|
|
22
|
-
conditions.push([key, value]);
|
|
23
|
-
}
|
|
9
|
+
if ('className' in scheme) {
|
|
10
|
+
throw new Error('The "className" property is not allowed in ntv scheme. Use "$base" instead.');
|
|
24
11
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
for (const [key, value] of conditions) {
|
|
34
|
-
if (context.skipConditions.has(key)) {
|
|
35
|
-
continue;
|
|
36
|
-
}
|
|
37
|
-
subSkipConditions.delete(key);
|
|
38
|
-
const propValue = context.props[key];
|
|
39
|
-
if (/^(is|allows)[A-Z]/.test(key) && propValue) {
|
|
40
|
-
const nestedSkipConditions = new Set([...subSkipConditions, key]);
|
|
41
|
-
evaluateDefinition(value, {
|
|
42
|
-
props: context.props,
|
|
43
|
-
skipConditions: nestedSkipConditions,
|
|
44
|
-
classes: context.classes,
|
|
45
|
-
});
|
|
12
|
+
validateNoNestedSpecialKeys(scheme, false);
|
|
13
|
+
}
|
|
14
|
+
function validateNoNestedSpecialKeys(obj, isNested) {
|
|
15
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
16
|
+
// Check if this is a top-level-only key in a nested context
|
|
17
|
+
if (isNested && key === '$base') {
|
|
18
|
+
throw new Error(`The "${key}" property is only allowed at the top level of ntv scheme. It cannot be nested inside variants or conditions.`);
|
|
46
19
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (variantValue !== undefined) {
|
|
51
|
-
const nestedSkipConditions = new Set([...subSkipConditions, key]);
|
|
52
|
-
evaluateDefinition(variantValue, {
|
|
53
|
-
props: context.props,
|
|
54
|
-
skipConditions: nestedSkipConditions,
|
|
55
|
-
classes: context.classes,
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
}
|
|
20
|
+
// Recursively validate nested objects
|
|
21
|
+
if (isPlainObject(value)) {
|
|
22
|
+
validateNoNestedSpecialKeys(value, true);
|
|
59
23
|
}
|
|
60
24
|
}
|
|
61
25
|
}
|
|
26
|
+
export function ntv(scheme, { twMerge: usesTwMerge = true, twMergeConfig } = {}) {
|
|
27
|
+
validateScheme(scheme);
|
|
28
|
+
const { $base, ...conditions } = scheme;
|
|
29
|
+
const mergeFn = usesTwMerge
|
|
30
|
+
? twMergeConfig
|
|
31
|
+
? getCachedTwMerge(twMergeConfig)
|
|
32
|
+
: twMerge
|
|
33
|
+
: twJoin;
|
|
34
|
+
return function styleFn({ class: slotClass, className: slotClassName, ...props } = {}) {
|
|
35
|
+
return mergeFn($base, ...resolveConditions(conditions, props), slotClass, slotClassName);
|
|
36
|
+
};
|
|
37
|
+
}
|
|
62
38
|
/**
|
|
63
|
-
*
|
|
39
|
+
* Create a pre-configured ntv function with fixed options.
|
|
40
|
+
*
|
|
41
|
+
* @param defaultOptions - Default options to apply to all ntv calls
|
|
42
|
+
* @returns A pre-configured ntv function
|
|
64
43
|
*
|
|
65
44
|
* @example
|
|
66
45
|
* ```ts
|
|
67
|
-
*
|
|
68
|
-
* const ntvNoMerge = createNTV({ twMerge: false });
|
|
69
|
-
*
|
|
70
|
-
* // With custom tailwind-merge config
|
|
71
|
-
* const customNTV = createNTV({
|
|
46
|
+
* const myNtv = createNtv({
|
|
72
47
|
* twMergeConfig: {
|
|
73
48
|
* extend: {
|
|
74
|
-
*
|
|
75
|
-
*
|
|
49
|
+
* classGroups: {
|
|
50
|
+
* 'font-size': [{ text: ['huge', 'tiny'] }],
|
|
76
51
|
* },
|
|
77
52
|
* },
|
|
78
53
|
* },
|
|
79
54
|
* });
|
|
80
|
-
* ```
|
|
81
|
-
*/
|
|
82
|
-
export function createNTV(options = {}) {
|
|
83
|
-
const { twMerge: useTwMerge = true, twMergeConfig } = options;
|
|
84
|
-
const mergeClasses = useTwMerge
|
|
85
|
-
? twMergeConfig
|
|
86
|
-
? extendTailwindMerge(twMergeConfig)
|
|
87
|
-
: twMerge
|
|
88
|
-
: joinClasses;
|
|
89
|
-
return function ntv(style) {
|
|
90
|
-
return (props) => {
|
|
91
|
-
const context = {
|
|
92
|
-
props,
|
|
93
|
-
skipConditions: new Set(),
|
|
94
|
-
classes: [],
|
|
95
|
-
};
|
|
96
|
-
evaluateDefinition(style, context);
|
|
97
|
-
return mergeClasses(...context.classes);
|
|
98
|
-
};
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Creates a style function from a nested style definition.
|
|
103
55
|
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
* const button = ntv<{ variant?: 'primary' | 'secondary'; isDisabled?: boolean }>({
|
|
107
|
-
* default: 'px-4 py-2 rounded',
|
|
56
|
+
* const button = myNtv({
|
|
57
|
+
* $base: 'text-huge',
|
|
108
58
|
* variant: {
|
|
109
|
-
* primary: 'bg-blue-500
|
|
110
|
-
* secondary: 'bg-gray-200
|
|
59
|
+
* primary: 'bg-blue-500',
|
|
60
|
+
* secondary: 'bg-gray-200',
|
|
111
61
|
* },
|
|
112
|
-
* isDisabled: 'opacity-50 cursor-not-allowed',
|
|
113
62
|
* });
|
|
114
|
-
*
|
|
115
|
-
* button({ variant: 'primary' });
|
|
116
|
-
* // => 'px-4 py-2 rounded bg-blue-500 text-white'
|
|
117
|
-
*
|
|
118
|
-
* button({ variant: 'primary', isDisabled: true });
|
|
119
|
-
* // => 'px-4 py-2 rounded bg-blue-500 text-white opacity-50 cursor-not-allowed'
|
|
120
63
|
* ```
|
|
121
64
|
*/
|
|
122
|
-
export
|
|
65
|
+
export function createNtv(defaultOptions) {
|
|
66
|
+
return function configuredNtv(scheme) {
|
|
67
|
+
return ntv(scheme, defaultOptions);
|
|
68
|
+
};
|
|
69
|
+
}
|
|
123
70
|
//# sourceMappingURL=ntv.js.map
|
package/dist/ntv.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ntv.js","sourceRoot":"","sources":["../src/ntv.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"ntv.js","sourceRoot":"","sources":["../src/ntv.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AASjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,SAAS,cAAc,CAAC,MAAiB;IACvC,IAAI,OAAO,IAAI,MAAM,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,yEAAyE,CAAC,CAAC;IAC7F,CAAC;IAED,IAAI,WAAW,IAAI,MAAM,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,6EAA6E,CAAC,CAAC;IACjG,CAAC;IAED,2BAA2B,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,2BAA2B,CAAC,GAA4B,EAAE,QAAiB;IAClF,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,4DAA4D;QAC5D,IAAI,QAAQ,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CACb,QAAQ,GAAG,+GAA+G,CAC3H,CAAC;QACJ,CAAC;QAED,sCAAsC;QACtC,IAAI,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,2BAA2B,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;AACH,CAAC;AA+BD,MAAM,UAAU,GAAG,CACjB,MAAiB,EACjB,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI,EAAE,aAAa,KAAiB,EAAE;IAE/D,cAAc,CAAC,MAAM,CAAC,CAAC;IAEvB,MAAM,EAAE,KAAK,EAAE,GAAG,UAAU,EAAE,GAAG,MAAM,CAAC;IAExC,MAAM,OAAO,GAAG,WAAW;QACzB,CAAC,CAAC,aAAa;YACb,CAAC,CAAC,gBAAgB,CAAC,aAAa,CAAC;YACjC,CAAC,CAAC,OAAO;QACX,CAAC,CAAC,MAAM,CAAC;IAEX,OAAO,SAAS,OAAO,CAAC,EACtB,KAAK,EAAE,SAAS,EAChB,SAAS,EAAE,aAAa,EACxB,GAAG,KAAK,KAC+B,EAAE;QACzC,OAAO,OAAO,CAAC,KAAK,EAAE,GAAG,iBAAiB,CAAC,UAAU,EAAE,KAAK,CAAC,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC;IAC3F,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,SAAS,CAAC,cAA0B;IAIlD,OAAO,SAAS,aAAa,CAAC,MAAiB;QAC7C,OAAO,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACrC,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ClassValue } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Resolves conditions from scheme based on provided props to generate class values.
|
|
4
|
+
*
|
|
5
|
+
* $default behavior:
|
|
6
|
+
* - If no conditions match at a level, that level's $default is applied
|
|
7
|
+
* - If a variant matches, only the nested evaluation result is used
|
|
8
|
+
* - When no conditions match, $defaults accumulate from each unmatched level
|
|
9
|
+
*/
|
|
10
|
+
export declare function resolveConditions({ $default, ...conditions }: Record<string, unknown>, props: Record<string, unknown>): ClassValue[];
|
|
11
|
+
//# sourceMappingURL=resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7C;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,EAAE,QAAQ,EAAE,GAAG,UAAU,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,UAAU,EAAE,CA8Cd"}
|
package/dist/resolver.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { isPlainObject } from './utils.js';
|
|
2
|
+
/**
|
|
3
|
+
* Resolves conditions from scheme based on provided props to generate class values.
|
|
4
|
+
*
|
|
5
|
+
* $default behavior:
|
|
6
|
+
* - If no conditions match at a level, that level's $default is applied
|
|
7
|
+
* - If a variant matches, only the nested evaluation result is used
|
|
8
|
+
* - When no conditions match, $defaults accumulate from each unmatched level
|
|
9
|
+
*/
|
|
10
|
+
export function resolveConditions({ $default, ...conditions }, props) {
|
|
11
|
+
const classes = [];
|
|
12
|
+
let hasMatchedCondition = false;
|
|
13
|
+
function addClasses(value) {
|
|
14
|
+
if (isPlainObject(value)) {
|
|
15
|
+
classes.push(...resolveConditions(value, props));
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
classes.push(value);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
for (const [key, value] of Object.entries(conditions)) {
|
|
22
|
+
const propValue = props[key];
|
|
23
|
+
if (propValue === '$default') {
|
|
24
|
+
throw new Error(`The value "$default" cannot be passed as a runtime value for "${key}". "$default" is a reserved keyword.`);
|
|
25
|
+
}
|
|
26
|
+
// Boolean conditions (isXxx or allowsXxx)
|
|
27
|
+
if (/^is[A-Z]/.test(key) || /^allows[A-Z]/.test(key)) {
|
|
28
|
+
if (propValue) {
|
|
29
|
+
hasMatchedCondition = true;
|
|
30
|
+
addClasses(value);
|
|
31
|
+
}
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
// Variant conditions (nested objects)
|
|
35
|
+
if (isPlainObject(value)) {
|
|
36
|
+
if (typeof propValue === 'string' && propValue in value) {
|
|
37
|
+
hasMatchedCondition = true;
|
|
38
|
+
addClasses(value[propValue]);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
classes.push(value['$default']);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (!hasMatchedCondition) {
|
|
46
|
+
classes.unshift($default);
|
|
47
|
+
}
|
|
48
|
+
return classes;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAC/B,EAAE,QAAQ,EAAE,GAAG,UAAU,EAA2B,EACpD,KAA8B;IAE9B,MAAM,OAAO,GAAiB,EAAE,CAAC;IACjC,IAAI,mBAAmB,GAAG,KAAK,CAAC;IAEhC,SAAS,UAAU,CAAC,KAAc;QAChC,IAAI,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,IAAI,CAAC,GAAG,iBAAiB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;QACnD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CAAC,KAAmB,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QACtD,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QAE7B,IAAI,SAAS,KAAK,UAAU,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CACb,iEAAiE,GAAG,sCAAsC,CAC3G,CAAC;QACJ,CAAC;QAED,0CAA0C;QAC1C,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACrD,IAAI,SAAS,EAAE,CAAC;gBACd,mBAAmB,GAAG,IAAI,CAAC;gBAC3B,UAAU,CAAC,KAAK,CAAC,CAAC;YACpB,CAAC;YACD,SAAS;QACX,CAAC;QAED,sCAAsC;QACtC,IAAI,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;gBACxD,mBAAmB,GAAG,IAAI,CAAC;gBAC3B,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;YAC/B,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAe,CAAC,CAAC;YAChD,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,CAAC,mBAAmB,EAAE,CAAC;QACzB,OAAO,CAAC,OAAO,CAAC,QAAsB,CAAC,CAAC;IAC1C,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|