clava 0.0.1 → 0.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/CHANGELOG.md +13 -0
- package/dist/index.d.ts +133 -0
- package/dist/index.js +534 -0
- package/dist/index.js.map +1 -0
- package/license +21 -0
- package/package.json +31 -14
- package/rolldown.config.ts +12 -0
- package/src/index.ts +692 -0
- package/src/test.ts +2039 -0
- package/src/types.ts +325 -0
- package/src/utils.ts +164 -0
- package/tsconfig.json +7 -0
package/CHANGELOG.md
ADDED
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { ClassValue as ClassValue$1 } from "clsx";
|
|
2
|
+
import * as CSS from "csstype";
|
|
3
|
+
|
|
4
|
+
//#region src/types.d.ts
|
|
5
|
+
type ClassValue = string | number | boolean | null | undefined | void | ClassValue[];
|
|
6
|
+
type JSXCSSProperties = CSS.Properties<string | number>;
|
|
7
|
+
type HTMLCSSProperties = CSS.PropertiesHyphen<string | number>;
|
|
8
|
+
interface JSXProps {
|
|
9
|
+
className: string;
|
|
10
|
+
style: JSXCSSProperties;
|
|
11
|
+
}
|
|
12
|
+
interface HTMLProps {
|
|
13
|
+
class: string;
|
|
14
|
+
style: string;
|
|
15
|
+
}
|
|
16
|
+
interface HTMLObjProps {
|
|
17
|
+
class: string;
|
|
18
|
+
style: HTMLCSSProperties;
|
|
19
|
+
}
|
|
20
|
+
interface StyleProps {
|
|
21
|
+
jsx: JSXProps;
|
|
22
|
+
html: HTMLProps;
|
|
23
|
+
htmlObj: HTMLObjProps;
|
|
24
|
+
}
|
|
25
|
+
type ComponentResult = JSXProps | HTMLProps | HTMLObjProps;
|
|
26
|
+
type ComponentProps<V$1 = {}> = VariantValues<V$1> & Partial<ComponentResult>;
|
|
27
|
+
type GetVariants<V$1> = (variants?: VariantValues<V$1>) => VariantValues<V$1>;
|
|
28
|
+
type KeySourceArray = readonly string[];
|
|
29
|
+
type KeySourceComponent = {
|
|
30
|
+
keys: readonly (string | number | symbol)[];
|
|
31
|
+
getVariants: () => Record<string, unknown>;
|
|
32
|
+
};
|
|
33
|
+
type KeySource = KeySourceArray | KeySourceComponent;
|
|
34
|
+
type SourceKeys<S> = S extends readonly (infer K)[] ? K : S extends {
|
|
35
|
+
keys: readonly (infer K)[];
|
|
36
|
+
} ? K : never;
|
|
37
|
+
type SourceDefaults<S> = S extends {
|
|
38
|
+
getVariants: () => infer Defaults;
|
|
39
|
+
} ? Defaults : {};
|
|
40
|
+
type SourceResult<T, S> = Pick<T, Extract<keyof T, SourceKeys<S>>> & Omit<SourceDefaults<S>, keyof T>;
|
|
41
|
+
type SplitPropsFunction = <const T extends Record<string, unknown>, const S1 extends KeySource, const Sources extends readonly KeySource[]>(props: T, source1: S1, ...sources: Sources) => SplitPropsFunctionResult<T, S1, Sources>;
|
|
42
|
+
type SplitPropsFunctionResult<T, S1 extends KeySource, Sources extends readonly KeySource[]> = Sources extends readonly [] ? [SourceResult<T, S1>, Omit<T, SourceKeys<S1>>] : Sources extends readonly [infer S2 extends KeySource] ? [SourceResult<T, S1>, SourceResult<T, S2>, Omit<T, SourceKeys<S1> | SourceKeys<S2>>] : Sources extends readonly [infer S2 extends KeySource, infer S3 extends KeySource] ? [SourceResult<T, S1>, SourceResult<T, S2>, SourceResult<T, S3>, Omit<T, SourceKeys<S1> | SourceKeys<S2> | SourceKeys<S3>>] : Sources extends readonly [infer S2 extends KeySource, infer S3 extends KeySource, infer S4 extends KeySource] ? [SourceResult<T, S1>, SourceResult<T, S2>, SourceResult<T, S3>, SourceResult<T, S4>, Omit<T, SourceKeys<S1> | SourceKeys<S2> | SourceKeys<S3> | SourceKeys<S4>>] : Sources extends readonly [infer S2 extends KeySource, infer S3 extends KeySource, infer S4 extends KeySource, infer S5 extends KeySource] ? [SourceResult<T, S1>, SourceResult<T, S2>, SourceResult<T, S3>, SourceResult<T, S4>, SourceResult<T, S5>, Omit<T, SourceKeys<S1> | SourceKeys<S2> | SourceKeys<S3> | SourceKeys<S4> | SourceKeys<S5>>] : Sources extends readonly [infer S2 extends KeySource, infer S3 extends KeySource, infer S4 extends KeySource, infer S5 extends KeySource, infer S6 extends KeySource] ? [SourceResult<T, S1>, SourceResult<T, S2>, SourceResult<T, S3>, SourceResult<T, S4>, SourceResult<T, S5>, SourceResult<T, S6>, Omit<T, SourceKeys<S1> | SourceKeys<S2> | SourceKeys<S3> | SourceKeys<S4> | SourceKeys<S5> | SourceKeys<S6>>] : Sources extends readonly [infer S2 extends KeySource, infer S3 extends KeySource, infer S4 extends KeySource, infer S5 extends KeySource, infer S6 extends KeySource, infer S7 extends KeySource] ? [SourceResult<T, S1>, SourceResult<T, S2>, SourceResult<T, S3>, SourceResult<T, S4>, SourceResult<T, S5>, SourceResult<T, S6>, SourceResult<T, S7>, Omit<T, SourceKeys<S1> | SourceKeys<S2> | SourceKeys<S3> | SourceKeys<S4> | SourceKeys<S5> | SourceKeys<S6> | SourceKeys<S7>>] : Sources extends readonly [infer S2 extends KeySource, infer S3 extends KeySource, infer S4 extends KeySource, infer S5 extends KeySource, infer S6 extends KeySource, infer S7 extends KeySource, infer S8 extends KeySource] ? [SourceResult<T, S1>, SourceResult<T, S2>, SourceResult<T, S3>, SourceResult<T, S4>, SourceResult<T, S5>, SourceResult<T, S6>, SourceResult<T, S7>, SourceResult<T, S8>, Omit<T, SourceKeys<S1> | SourceKeys<S2> | SourceKeys<S3> | SourceKeys<S4> | SourceKeys<S5> | SourceKeys<S6> | SourceKeys<S7> | SourceKeys<S8>>] : unknown[];
|
|
43
|
+
interface OnlyVariantsComponent<V$1> {
|
|
44
|
+
getVariants: GetVariants<V$1>;
|
|
45
|
+
keys: (keyof V$1)[];
|
|
46
|
+
}
|
|
47
|
+
interface ModalComponent<V$1, R extends ComponentResult> {
|
|
48
|
+
(props?: ComponentProps<V$1>): R;
|
|
49
|
+
class: (props?: ComponentProps<V$1>) => string;
|
|
50
|
+
style: (props?: ComponentProps<V$1>) => R["style"];
|
|
51
|
+
getVariants: GetVariants<V$1>;
|
|
52
|
+
keys: (keyof V$1 | keyof R)[];
|
|
53
|
+
onlyVariants: OnlyVariantsComponent<V$1>;
|
|
54
|
+
/** @internal Base class without variants */
|
|
55
|
+
_baseClass: string;
|
|
56
|
+
}
|
|
57
|
+
interface Component<V$1 extends Variants = {}, CV$1 extends ComputedVariants = {}, E$1 extends AnyComponent[] = [], R extends ComponentResult = ComponentResult> extends ModalComponent<MergeVariants<V$1, CV$1, E$1>, R> {
|
|
58
|
+
jsx: ModalComponent<MergeVariants<V$1, CV$1, E$1>, JSXProps>;
|
|
59
|
+
html: ModalComponent<MergeVariants<V$1, CV$1, E$1>, HTMLProps>;
|
|
60
|
+
htmlObj: ModalComponent<MergeVariants<V$1, CV$1, E$1>, HTMLObjProps>;
|
|
61
|
+
}
|
|
62
|
+
type AnyComponent = Component<any, any, any, any> | ModalComponent<any, any>;
|
|
63
|
+
type MergeExtendedVariants<T> = T extends readonly [infer First, ...infer Rest] ? ExtractVariants<First> & MergeExtendedVariants<Rest> : {};
|
|
64
|
+
type MergeExtendedComputedVariants<T> = T extends readonly [infer First, ...infer Rest] ? ExtractComputedVariants<First> & MergeExtendedComputedVariants<Rest> : {};
|
|
65
|
+
type ExtractVariants<T> = T extends Component<infer V, any, infer E, any> ? V & MergeExtendedVariants<E> : {};
|
|
66
|
+
type ExtractComputedVariants<T> = T extends Component<any, infer CV, infer E, any> ? CV & Omit<MergeExtendedComputedVariants<E>, keyof CV> : {};
|
|
67
|
+
type MergeVariants<V$1, CV$1, E$1 extends AnyComponent[]> = NoInfer<CV$1> & Omit<NoInfer<V$1>, keyof CV$1> & Omit<MergeExtendedVariants<E$1>, keyof CV$1> & Omit<MergeExtendedComputedVariants<E$1>, keyof CV$1>;
|
|
68
|
+
type StringToBoolean<T> = T extends "true" | "false" ? boolean : T;
|
|
69
|
+
type VariantValue = ClassValue | StyleClassValue;
|
|
70
|
+
type ExtractVariantValue<T> = T extends ((value: infer V) => any) ? V : T extends ClassValue ? boolean : T extends Record<infer K, any> ? StringToBoolean<K> : never;
|
|
71
|
+
type VariantValues<V$1> = { [K in keyof V$1]?: ExtractVariantValue<V$1[K]> };
|
|
72
|
+
type StyleValue = CSS.Properties & {
|
|
73
|
+
[key: `--${string}`]: string;
|
|
74
|
+
};
|
|
75
|
+
type StyleClassValue = StyleValue & {
|
|
76
|
+
class?: ClassValue;
|
|
77
|
+
};
|
|
78
|
+
interface ComputedContext<V$1> {
|
|
79
|
+
variants: VariantValues<V$1>;
|
|
80
|
+
setVariants: (variants: VariantValues<V$1>) => void;
|
|
81
|
+
setDefaultVariants: (variants: VariantValues<V$1>) => void;
|
|
82
|
+
}
|
|
83
|
+
type Computed<V$1> = (context: ComputedContext<V$1>) => VariantValue;
|
|
84
|
+
type ComputedVariant = (value: any) => VariantValue;
|
|
85
|
+
type ComputedVariants = Record<string, ComputedVariant>;
|
|
86
|
+
type Variant = ClassValue | Record<string, VariantValue>;
|
|
87
|
+
type Variants = Record<string, Variant>;
|
|
88
|
+
type ExtendedVariants<E$1 extends AnyComponent[]> = MergeExtendedVariants<E$1> & MergeExtendedComputedVariants<E$1>;
|
|
89
|
+
type ExtendableVariants<V$1 extends Variants, E$1 extends AnyComponent[]> = V$1 & { [K in keyof ExtendedVariants<E$1>]?: Partial<ExtendedVariants<E$1>[K]> | Variant };
|
|
90
|
+
//#endregion
|
|
91
|
+
//#region src/index.d.ts
|
|
92
|
+
declare const MODES: readonly ["jsx", "html", "htmlObj"];
|
|
93
|
+
type Mode = (typeof MODES)[number];
|
|
94
|
+
type VariantProps<T extends Pick<AnyComponent, "getVariants">> = ReturnType<T["getVariants"]>;
|
|
95
|
+
interface CVConfig<V$1 extends Variants = {}, CV$1 extends ComputedVariants = {}, E$1 extends AnyComponent[] = []> {
|
|
96
|
+
extend?: E$1;
|
|
97
|
+
class?: ClassValue;
|
|
98
|
+
style?: StyleValue;
|
|
99
|
+
variants?: ExtendableVariants<V$1, E$1>;
|
|
100
|
+
computedVariants?: CV$1;
|
|
101
|
+
defaultVariants?: VariantValues<MergeVariants<V$1, CV$1, E$1>>;
|
|
102
|
+
computed?: Computed<MergeVariants<V$1, CV$1, E$1>>;
|
|
103
|
+
}
|
|
104
|
+
interface CreateParams<M extends Mode> {
|
|
105
|
+
defaultMode?: M;
|
|
106
|
+
transformClass?: (className: string) => string;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Splits props into multiple groups based on key sources.
|
|
110
|
+
* Each source gets its own result object containing all its matching keys.
|
|
111
|
+
* The last element is always the "rest" containing keys not claimed by any source.
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* ```ts
|
|
115
|
+
* const [buttonProps, inputProps, rest] = splitProps(
|
|
116
|
+
* props,
|
|
117
|
+
* buttonComponent,
|
|
118
|
+
* inputComponent.onlyVariants,
|
|
119
|
+
* );
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
declare const splitProps: SplitPropsFunction;
|
|
123
|
+
declare function create<M extends Mode>({
|
|
124
|
+
defaultMode,
|
|
125
|
+
transformClass
|
|
126
|
+
}?: CreateParams<M>): {
|
|
127
|
+
cv: <V$1 extends Variants = {}, CV$1 extends ComputedVariants = {}, const E$1 extends AnyComponent[] = []>(config?: CVConfig<V$1, CV$1, E$1>) => Component<V$1, CV$1, E$1, StyleProps[M]>;
|
|
128
|
+
cx: (...classes: ClassValue$1[]) => string;
|
|
129
|
+
};
|
|
130
|
+
declare const cv: <V$1 extends Variants = {}, CV$1 extends ComputedVariants = {}, const E$1 extends AnyComponent[] = []>(config?: CVConfig<V$1, CV$1, E$1>) => Component<V$1, CV$1, E$1, JSXProps | HTMLProps | HTMLObjProps>, cx: (...classes: ClassValue$1[]) => string;
|
|
131
|
+
//#endregion
|
|
132
|
+
export { CVConfig, type ClassValue, type StyleClassValue, type StyleValue, VariantProps, create, cv, cx, splitProps };
|
|
133
|
+
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,534 @@
|
|
|
1
|
+
//#region ../../node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
|
|
2
|
+
function r(e) {
|
|
3
|
+
var t, f, n = "";
|
|
4
|
+
if ("string" == typeof e || "number" == typeof e) n += e;
|
|
5
|
+
else if ("object" == typeof e) if (Array.isArray(e)) {
|
|
6
|
+
var o = e.length;
|
|
7
|
+
for (t = 0; t < o; t++) e[t] && (f = r(e[t])) && (n && (n += " "), n += f);
|
|
8
|
+
} else for (f in e) e[f] && (n && (n += " "), n += f);
|
|
9
|
+
return n;
|
|
10
|
+
}
|
|
11
|
+
function clsx() {
|
|
12
|
+
for (var e, t, f = 0, n = "", o = arguments.length; f < o; f++) (e = arguments[f]) && (t = r(e)) && (n && (n += " "), n += t);
|
|
13
|
+
return n;
|
|
14
|
+
}
|
|
15
|
+
var clsx_default = clsx;
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
//#region src/utils.ts
|
|
19
|
+
/**
|
|
20
|
+
* Converts a hyphenated CSS property name to camelCase.
|
|
21
|
+
* @example
|
|
22
|
+
* hyphenToCamel("background-color") // "backgroundColor"
|
|
23
|
+
* hyphenToCamel("--custom-var") // "--custom-var" (CSS variables are preserved)
|
|
24
|
+
*/
|
|
25
|
+
function hyphenToCamel(str) {
|
|
26
|
+
if (str.startsWith("--")) return str;
|
|
27
|
+
return str.replace(/-([a-z])/gi, (_, letter) => letter.toUpperCase());
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Converts a camelCase CSS property name to hyphenated form.
|
|
31
|
+
* @example
|
|
32
|
+
* camelToHyphen("backgroundColor") // "background-color"
|
|
33
|
+
* camelToHyphen("--customVar") // "--customVar" (CSS variables are preserved)
|
|
34
|
+
*/
|
|
35
|
+
function camelToHyphen(str) {
|
|
36
|
+
if (str.startsWith("--")) return str;
|
|
37
|
+
return str.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Parses a length value, adding "px" if it's a number.
|
|
41
|
+
* @example
|
|
42
|
+
* parseLengthValue(16); // "16px"
|
|
43
|
+
* parseLengthValue("2em"); // "2em"
|
|
44
|
+
*/
|
|
45
|
+
function parseLengthValue(value) {
|
|
46
|
+
if (typeof value === "string") return value;
|
|
47
|
+
return `${value}px`;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Parses a CSS style string into a StyleValue object.
|
|
51
|
+
* @example
|
|
52
|
+
* htmlStyleToStyleValue("background-color: red; font-size: 16px;");
|
|
53
|
+
* // { backgroundColor: "red", fontSize: "16px" }
|
|
54
|
+
*/
|
|
55
|
+
function htmlStyleToStyleValue(styleString) {
|
|
56
|
+
if (!styleString) return {};
|
|
57
|
+
const result = {};
|
|
58
|
+
const declarations = styleString.split(";");
|
|
59
|
+
for (const declaration of declarations) {
|
|
60
|
+
const trimmed = declaration.trim();
|
|
61
|
+
if (!trimmed) continue;
|
|
62
|
+
const colonIndex = trimmed.indexOf(":");
|
|
63
|
+
if (colonIndex === -1) continue;
|
|
64
|
+
const property = trimmed.slice(0, colonIndex).trim();
|
|
65
|
+
const value = trimmed.slice(colonIndex + 1).trim();
|
|
66
|
+
if (!property) continue;
|
|
67
|
+
if (!value) continue;
|
|
68
|
+
const camelProperty = hyphenToCamel(property);
|
|
69
|
+
result[camelProperty] = value;
|
|
70
|
+
}
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Converts a hyphenated style object to a camelCase StyleValue object.
|
|
75
|
+
* @example
|
|
76
|
+
* htmlObjStyleToStyleValue({ "background-color": "red", "font-size": "16px" });
|
|
77
|
+
* // { backgroundColor: "red", fontSize: "16px" }
|
|
78
|
+
*/
|
|
79
|
+
function htmlObjStyleToStyleValue(style) {
|
|
80
|
+
const result = {};
|
|
81
|
+
for (const [key, value] of Object.entries(style)) {
|
|
82
|
+
if (value == null) continue;
|
|
83
|
+
const property = hyphenToCamel(key);
|
|
84
|
+
result[property] = parseLengthValue(value);
|
|
85
|
+
}
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Converts a camelCase style object to a StyleValue object.
|
|
90
|
+
* @example
|
|
91
|
+
* jsxStyleToStyleValue({ backgroundColor: "red", fontSize: 16 });
|
|
92
|
+
* // { backgroundColor: "red", fontSize: "16px" }
|
|
93
|
+
*/
|
|
94
|
+
function jsxStyleToStyleValue(style) {
|
|
95
|
+
const result = {};
|
|
96
|
+
for (const [key, value] of Object.entries(style)) {
|
|
97
|
+
if (value == null) continue;
|
|
98
|
+
result[key] = parseLengthValue(value);
|
|
99
|
+
}
|
|
100
|
+
return result;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Converts a StyleValue object to a CSS style string.
|
|
104
|
+
* @example
|
|
105
|
+
* styleValueToHTMLStyle({ backgroundColor: "red", fontSize: "16px" });
|
|
106
|
+
* // "background-color: red; font-size: 16px;"
|
|
107
|
+
*/
|
|
108
|
+
function styleValueToHTMLStyle(style) {
|
|
109
|
+
const parts = [];
|
|
110
|
+
for (const [key, value] of Object.entries(style)) {
|
|
111
|
+
if (value == null) continue;
|
|
112
|
+
parts.push(`${camelToHyphen(key)}: ${value}`);
|
|
113
|
+
}
|
|
114
|
+
if (!parts.length) return "";
|
|
115
|
+
return `${parts.join("; ")};`;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Converts a StyleValue object to a hyphenated style object.
|
|
119
|
+
* @example
|
|
120
|
+
* styleValueToHTMLObjStyle({ backgroundColor: "red", fontSize: "16px" });
|
|
121
|
+
* // { "background-color": "red", "font-size": "16px" }
|
|
122
|
+
*/
|
|
123
|
+
function styleValueToHTMLObjStyle(style) {
|
|
124
|
+
const result = {};
|
|
125
|
+
for (const [key, value] of Object.entries(style)) {
|
|
126
|
+
if (value == null) continue;
|
|
127
|
+
const property = camelToHyphen(key);
|
|
128
|
+
result[property] = value;
|
|
129
|
+
}
|
|
130
|
+
return result;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Converts a StyleValue object to a camelCase style object.
|
|
134
|
+
* @example
|
|
135
|
+
* styleValueToJSXStyle({ backgroundColor: "red", fontSize: "16px" });
|
|
136
|
+
* // { backgroundColor: "red", fontSize: "16px" }
|
|
137
|
+
*/
|
|
138
|
+
function styleValueToJSXStyle(style) {
|
|
139
|
+
return style;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Type guard to check if a style object has hyphenated keys.
|
|
143
|
+
* @example
|
|
144
|
+
* isHTMLObjStyle({ "background-color": "red" }); // true
|
|
145
|
+
* isHTMLObjStyle({ backgroundColor: "red" }); // false
|
|
146
|
+
*/
|
|
147
|
+
function isHTMLObjStyle(style) {
|
|
148
|
+
return Object.keys(style).some((key) => key.includes("-") && !key.startsWith("--"));
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
//#endregion
|
|
152
|
+
//#region src/index.ts
|
|
153
|
+
/**
|
|
154
|
+
* Checks if a value is a style-class object (has style properties, not just a
|
|
155
|
+
* class value).
|
|
156
|
+
*/
|
|
157
|
+
function isStyleClassValue(value) {
|
|
158
|
+
if (typeof value !== "object") return false;
|
|
159
|
+
if (value == null) return false;
|
|
160
|
+
if (Array.isArray(value)) return false;
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Converts any style input (string, JSX object, or HTML object) to a
|
|
165
|
+
* normalized StyleValue.
|
|
166
|
+
*/
|
|
167
|
+
function normalizeStyle(style) {
|
|
168
|
+
if (typeof style === "string") return htmlStyleToStyleValue(style);
|
|
169
|
+
if (typeof style === "object" && style != null) {
|
|
170
|
+
if (isHTMLObjStyle(style)) return htmlObjStyleToStyleValue(style);
|
|
171
|
+
return jsxStyleToStyleValue(style);
|
|
172
|
+
}
|
|
173
|
+
return {};
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Extracts class and style from a style-class value object.
|
|
177
|
+
*/
|
|
178
|
+
function extractStyleClass(value) {
|
|
179
|
+
const { class: cls, ...style } = value;
|
|
180
|
+
return {
|
|
181
|
+
class: cls,
|
|
182
|
+
style
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Processes a variant value to extract class and style.
|
|
187
|
+
*/
|
|
188
|
+
function processVariantValue(value) {
|
|
189
|
+
if (isStyleClassValue(value)) return extractStyleClass(value);
|
|
190
|
+
return {
|
|
191
|
+
class: value,
|
|
192
|
+
style: {}
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Gets all variant keys from a component's config, including extended
|
|
197
|
+
* components.
|
|
198
|
+
*/
|
|
199
|
+
function collectVariantKeys(config) {
|
|
200
|
+
const keys = /* @__PURE__ */ new Set();
|
|
201
|
+
if (config.extend) for (const ext of config.extend) for (const key of ext.onlyVariants.keys) keys.add(key);
|
|
202
|
+
if (config.variants) for (const key of Object.keys(config.variants)) keys.add(key);
|
|
203
|
+
if (config.computedVariants) for (const key of Object.keys(config.computedVariants)) keys.add(key);
|
|
204
|
+
return Array.from(keys);
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Collects default variants from extended components and the current config.
|
|
208
|
+
* Also handles implicit boolean defaults (when only `false` key exists).
|
|
209
|
+
*/
|
|
210
|
+
function collectDefaultVariants(config) {
|
|
211
|
+
let defaults = {};
|
|
212
|
+
if (config.extend) for (const ext of config.extend) {
|
|
213
|
+
const extDefaults = ext.getVariants();
|
|
214
|
+
defaults = {
|
|
215
|
+
...defaults,
|
|
216
|
+
...extDefaults
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
if (config.variants) {
|
|
220
|
+
for (const [variantName, variantDef] of Object.entries(config.variants)) if (isStyleClassValue(variantDef)) {
|
|
221
|
+
const keys = Object.keys(variantDef);
|
|
222
|
+
if (keys.includes("false") && !keys.includes("true") && defaults[variantName] === void 0) defaults[variantName] = false;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
if (config.defaultVariants) defaults = {
|
|
226
|
+
...defaults,
|
|
227
|
+
...config.defaultVariants
|
|
228
|
+
};
|
|
229
|
+
return defaults;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Resolves variant values by merging defaults with provided props.
|
|
233
|
+
*/
|
|
234
|
+
function resolveVariants(config, props = {}) {
|
|
235
|
+
return {
|
|
236
|
+
...collectDefaultVariants(config),
|
|
237
|
+
...props
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Gets the value for a single variant based on the variant definition and the
|
|
242
|
+
* selected value.
|
|
243
|
+
*/
|
|
244
|
+
function getVariantResult(variantDef, selectedValue) {
|
|
245
|
+
if (!isStyleClassValue(variantDef)) {
|
|
246
|
+
if (selectedValue === true) return processVariantValue(variantDef);
|
|
247
|
+
return {
|
|
248
|
+
class: null,
|
|
249
|
+
style: {}
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
const value = variantDef[String(selectedValue)];
|
|
253
|
+
if (value === void 0) return {
|
|
254
|
+
class: null,
|
|
255
|
+
style: {}
|
|
256
|
+
};
|
|
257
|
+
return processVariantValue(value);
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Processes extended components and returns base classes and variant classes separately.
|
|
261
|
+
* Base classes should come before current component's base, variant classes come after.
|
|
262
|
+
* When overrideVariantKeys is provided, those variant keys are excluded from the extended
|
|
263
|
+
* component's result (used when current component's computedVariants overrides them).
|
|
264
|
+
*/
|
|
265
|
+
function processExtended(config, resolvedVariants, overrideVariantKeys = /* @__PURE__ */ new Set()) {
|
|
266
|
+
const baseClasses = [];
|
|
267
|
+
const variantClasses = [];
|
|
268
|
+
let style = {};
|
|
269
|
+
if (config.extend) for (const ext of config.extend) {
|
|
270
|
+
const filteredVariants = { ...resolvedVariants };
|
|
271
|
+
for (const key of overrideVariantKeys) delete filteredVariants[key];
|
|
272
|
+
const extResult = ext({ ...filteredVariants });
|
|
273
|
+
const extStyle = normalizeStyle(extResult.style);
|
|
274
|
+
style = {
|
|
275
|
+
...style,
|
|
276
|
+
...extStyle
|
|
277
|
+
};
|
|
278
|
+
const baseClass = ext._baseClass;
|
|
279
|
+
baseClasses.push(baseClass);
|
|
280
|
+
const fullClass = "className" in extResult ? extResult.className : extResult.class;
|
|
281
|
+
if (fullClass && baseClass) {
|
|
282
|
+
const baseClassSet = new Set(baseClass.split(" ").filter(Boolean));
|
|
283
|
+
const variantPortion = fullClass.split(" ").filter((c) => c && !baseClassSet.has(c)).join(" ");
|
|
284
|
+
if (variantPortion) variantClasses.push(variantPortion);
|
|
285
|
+
} else if (fullClass && !baseClass) variantClasses.push(fullClass);
|
|
286
|
+
}
|
|
287
|
+
return {
|
|
288
|
+
baseClasses,
|
|
289
|
+
variantClasses,
|
|
290
|
+
style
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Processes all variants (not extended) and returns accumulated class and
|
|
295
|
+
* style.
|
|
296
|
+
*/
|
|
297
|
+
function processVariants(config, resolvedVariants) {
|
|
298
|
+
const classes = [];
|
|
299
|
+
let style = {};
|
|
300
|
+
if (config.variants) for (const [variantName, variantDef] of Object.entries(config.variants)) {
|
|
301
|
+
const selectedValue = resolvedVariants[variantName];
|
|
302
|
+
if (selectedValue === void 0) continue;
|
|
303
|
+
const result = getVariantResult(variantDef, selectedValue);
|
|
304
|
+
classes.push(result.class);
|
|
305
|
+
style = {
|
|
306
|
+
...style,
|
|
307
|
+
...result.style
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
if (config.computedVariants) for (const [variantName, computeFn] of Object.entries(config.computedVariants)) {
|
|
311
|
+
const selectedValue = resolvedVariants[variantName];
|
|
312
|
+
if (selectedValue === void 0) continue;
|
|
313
|
+
const result = processVariantValue(computeFn(selectedValue));
|
|
314
|
+
classes.push(result.class);
|
|
315
|
+
style = {
|
|
316
|
+
...style,
|
|
317
|
+
...result.style
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
return {
|
|
321
|
+
classes,
|
|
322
|
+
style
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Processes the computed function if present.
|
|
327
|
+
*/
|
|
328
|
+
function processComputed(config, resolvedVariants) {
|
|
329
|
+
const classes = [];
|
|
330
|
+
let style = {};
|
|
331
|
+
let updatedVariants = { ...resolvedVariants };
|
|
332
|
+
if (config.computed) {
|
|
333
|
+
const context = {
|
|
334
|
+
variants: resolvedVariants,
|
|
335
|
+
setVariants: (newVariants) => {
|
|
336
|
+
updatedVariants = {
|
|
337
|
+
...updatedVariants,
|
|
338
|
+
...newVariants
|
|
339
|
+
};
|
|
340
|
+
},
|
|
341
|
+
setDefaultVariants: (newDefaults) => {
|
|
342
|
+
for (const [key, value] of Object.entries(newDefaults)) if (resolvedVariants[key] === void 0) updatedVariants[key] = value;
|
|
343
|
+
}
|
|
344
|
+
};
|
|
345
|
+
const computedResult = config.computed(context);
|
|
346
|
+
if (computedResult != null) {
|
|
347
|
+
const result = processVariantValue(computedResult);
|
|
348
|
+
classes.push(result.class);
|
|
349
|
+
style = {
|
|
350
|
+
...style,
|
|
351
|
+
...result.style
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
return {
|
|
356
|
+
classes,
|
|
357
|
+
style,
|
|
358
|
+
updatedVariants
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Normalizes a key source (array or component) to an object with keys and defaults.
|
|
363
|
+
*/
|
|
364
|
+
function normalizeKeySource(source) {
|
|
365
|
+
if (Array.isArray(source)) return {
|
|
366
|
+
keys: source,
|
|
367
|
+
defaults: {}
|
|
368
|
+
};
|
|
369
|
+
if (source && (typeof source === "object" || typeof source === "function") && "keys" in source) return {
|
|
370
|
+
keys: [...source.keys],
|
|
371
|
+
defaults: "getVariants" in source ? source.getVariants() : {}
|
|
372
|
+
};
|
|
373
|
+
return {
|
|
374
|
+
keys: [],
|
|
375
|
+
defaults: {}
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Splits props into multiple groups based on key sources.
|
|
380
|
+
*/
|
|
381
|
+
function splitPropsImpl(selfKeys, selfDefaults, props, sources) {
|
|
382
|
+
const allUsedKeys = new Set(selfKeys);
|
|
383
|
+
const results = [];
|
|
384
|
+
const selfResult = {};
|
|
385
|
+
for (const [key, value] of Object.entries(selfDefaults)) if (selfKeys.includes(key)) selfResult[key] = value;
|
|
386
|
+
for (const key of selfKeys) if (key in props) selfResult[key] = props[key];
|
|
387
|
+
results.push(selfResult);
|
|
388
|
+
for (const source of sources) {
|
|
389
|
+
const sourceResult = {};
|
|
390
|
+
for (const [key, value] of Object.entries(source.defaults)) if (source.keys.includes(key)) sourceResult[key] = value;
|
|
391
|
+
for (const key of source.keys) {
|
|
392
|
+
allUsedKeys.add(key);
|
|
393
|
+
if (key in props) sourceResult[key] = props[key];
|
|
394
|
+
}
|
|
395
|
+
results.push(sourceResult);
|
|
396
|
+
}
|
|
397
|
+
const rest = {};
|
|
398
|
+
for (const [key, value] of Object.entries(props)) if (!allUsedKeys.has(key)) rest[key] = value;
|
|
399
|
+
results.push(rest);
|
|
400
|
+
return results;
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Splits props into multiple groups based on key sources.
|
|
404
|
+
* Each source gets its own result object containing all its matching keys.
|
|
405
|
+
* The last element is always the "rest" containing keys not claimed by any source.
|
|
406
|
+
*
|
|
407
|
+
* @example
|
|
408
|
+
* ```ts
|
|
409
|
+
* const [buttonProps, inputProps, rest] = splitProps(
|
|
410
|
+
* props,
|
|
411
|
+
* buttonComponent,
|
|
412
|
+
* inputComponent.onlyVariants,
|
|
413
|
+
* );
|
|
414
|
+
* ```
|
|
415
|
+
*/
|
|
416
|
+
const splitProps = ((props, source1, ...sources) => {
|
|
417
|
+
const normalizedSource1 = normalizeKeySource(source1);
|
|
418
|
+
const normalizedSources = sources.map(normalizeKeySource);
|
|
419
|
+
return splitPropsImpl(normalizedSource1.keys, normalizedSource1.defaults, props, normalizedSources);
|
|
420
|
+
});
|
|
421
|
+
function create({ defaultMode = "jsx", transformClass = (className) => className } = {}) {
|
|
422
|
+
const cx$1 = (...classes) => transformClass(clsx_default(...classes));
|
|
423
|
+
const cv$1 = (config = {}) => {
|
|
424
|
+
const variantKeys = collectVariantKeys(config);
|
|
425
|
+
const getClassPropertyName = (mode) => mode === "jsx" ? "className" : "class";
|
|
426
|
+
const getPropsKeys = (mode) => [
|
|
427
|
+
getClassPropertyName(mode),
|
|
428
|
+
"style",
|
|
429
|
+
...variantKeys
|
|
430
|
+
];
|
|
431
|
+
const computeResult = (props = {}) => {
|
|
432
|
+
const allClasses = [];
|
|
433
|
+
let allStyle = {};
|
|
434
|
+
const variantProps = {};
|
|
435
|
+
for (const key of variantKeys) if (key in props) variantProps[key] = props[key];
|
|
436
|
+
let resolvedVariants = resolveVariants(config, variantProps);
|
|
437
|
+
const computedResult = processComputed(config, resolvedVariants);
|
|
438
|
+
resolvedVariants = computedResult.updatedVariants;
|
|
439
|
+
const computedVariantKeys = new Set(config.computedVariants ? Object.keys(config.computedVariants) : []);
|
|
440
|
+
const extendedResult = processExtended(config, resolvedVariants, computedVariantKeys);
|
|
441
|
+
allClasses.push(...extendedResult.baseClasses);
|
|
442
|
+
allStyle = {
|
|
443
|
+
...allStyle,
|
|
444
|
+
...extendedResult.style
|
|
445
|
+
};
|
|
446
|
+
allClasses.push(config.class);
|
|
447
|
+
if (config.style) allStyle = {
|
|
448
|
+
...allStyle,
|
|
449
|
+
...config.style
|
|
450
|
+
};
|
|
451
|
+
allClasses.push(...extendedResult.variantClasses);
|
|
452
|
+
const variantsResult = processVariants(config, resolvedVariants);
|
|
453
|
+
allClasses.push(...variantsResult.classes);
|
|
454
|
+
allStyle = {
|
|
455
|
+
...allStyle,
|
|
456
|
+
...variantsResult.style
|
|
457
|
+
};
|
|
458
|
+
allClasses.push(...computedResult.classes);
|
|
459
|
+
allStyle = {
|
|
460
|
+
...allStyle,
|
|
461
|
+
...computedResult.style
|
|
462
|
+
};
|
|
463
|
+
if ("class" in props) allClasses.push(props.class);
|
|
464
|
+
if ("className" in props) allClasses.push(props.className);
|
|
465
|
+
if (props.style != null) allStyle = {
|
|
466
|
+
...allStyle,
|
|
467
|
+
...normalizeStyle(props.style)
|
|
468
|
+
};
|
|
469
|
+
return {
|
|
470
|
+
className: cx$1(...allClasses),
|
|
471
|
+
style: allStyle
|
|
472
|
+
};
|
|
473
|
+
};
|
|
474
|
+
const createModalComponent = (mode) => {
|
|
475
|
+
const propsKeys = getPropsKeys(mode);
|
|
476
|
+
const component$1 = ((props = {}) => {
|
|
477
|
+
const { className, style } = computeResult(props);
|
|
478
|
+
if (mode === "jsx") return {
|
|
479
|
+
className,
|
|
480
|
+
style: styleValueToJSXStyle(style)
|
|
481
|
+
};
|
|
482
|
+
if (mode === "html") return {
|
|
483
|
+
class: className,
|
|
484
|
+
style: styleValueToHTMLStyle(style)
|
|
485
|
+
};
|
|
486
|
+
return {
|
|
487
|
+
class: className,
|
|
488
|
+
style: styleValueToHTMLObjStyle(style)
|
|
489
|
+
};
|
|
490
|
+
});
|
|
491
|
+
component$1.class = (props = {}) => {
|
|
492
|
+
return computeResult(props).className;
|
|
493
|
+
};
|
|
494
|
+
component$1.style = ((props = {}) => {
|
|
495
|
+
const { style } = computeResult(props);
|
|
496
|
+
if (mode === "jsx") return styleValueToJSXStyle(style);
|
|
497
|
+
if (mode === "html") return styleValueToHTMLStyle(style);
|
|
498
|
+
return styleValueToHTMLObjStyle(style);
|
|
499
|
+
});
|
|
500
|
+
component$1.getVariants = (variants) => {
|
|
501
|
+
return resolveVariants(config, variants);
|
|
502
|
+
};
|
|
503
|
+
component$1.keys = propsKeys;
|
|
504
|
+
component$1.onlyVariants = {
|
|
505
|
+
getVariants: (variants) => {
|
|
506
|
+
return resolveVariants(config, variants);
|
|
507
|
+
},
|
|
508
|
+
keys: variantKeys
|
|
509
|
+
};
|
|
510
|
+
const extendedBaseClasses = [];
|
|
511
|
+
if (config.extend) for (const ext of config.extend) extendedBaseClasses.push(ext._baseClass);
|
|
512
|
+
component$1._baseClass = cx$1(...extendedBaseClasses, config.class);
|
|
513
|
+
return component$1;
|
|
514
|
+
};
|
|
515
|
+
const defaultComponent = createModalComponent(defaultMode);
|
|
516
|
+
const jsxComponent = createModalComponent("jsx");
|
|
517
|
+
const htmlComponent = createModalComponent("html");
|
|
518
|
+
const htmlObjComponent = createModalComponent("htmlObj");
|
|
519
|
+
const component = defaultComponent;
|
|
520
|
+
component.jsx = jsxComponent;
|
|
521
|
+
component.html = htmlComponent;
|
|
522
|
+
component.htmlObj = htmlObjComponent;
|
|
523
|
+
return component;
|
|
524
|
+
};
|
|
525
|
+
return {
|
|
526
|
+
cv: cv$1,
|
|
527
|
+
cx: cx$1
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
const { cv, cx } = create();
|
|
531
|
+
|
|
532
|
+
//#endregion
|
|
533
|
+
export { create, cv, cx, splitProps };
|
|
534
|
+
//# sourceMappingURL=index.js.map
|