@css-hooks/core 1.1.0 → 1.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/cjs/index.js +108 -26
- package/esm/index.js +108 -26
- package/package.json +2 -2
- package/types/index.d.ts +4 -2
package/cjs/index.js
CHANGED
|
@@ -15,6 +15,9 @@ function isHookSpec(x) {
|
|
|
15
15
|
if ("or" in x && x.or instanceof Array) {
|
|
16
16
|
return !x.or.some(xx => !isHookSpec(xx));
|
|
17
17
|
}
|
|
18
|
+
if ("and" in x && x.and instanceof Array) {
|
|
19
|
+
return !x.and.some(xx => !isHookSpec(xx));
|
|
20
|
+
}
|
|
18
21
|
}
|
|
19
22
|
return false;
|
|
20
23
|
}
|
|
@@ -74,39 +77,118 @@ function buildHooksSystem(stringify = genericStringify) {
|
|
|
74
77
|
});
|
|
75
78
|
return properties;
|
|
76
79
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
if (!isHookSpec(spec)) {
|
|
90
|
-
return [];
|
|
80
|
+
const css = Object.entries(config)
|
|
81
|
+
.map(([name, definition]) => {
|
|
82
|
+
function nest(input) {
|
|
83
|
+
if (typeof input === "object") {
|
|
84
|
+
if ("and" in input) {
|
|
85
|
+
if (input.and.length > 2) {
|
|
86
|
+
const [left, ...rest] = input.and;
|
|
87
|
+
return { and: [left, nest({ and: rest })] };
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
and: input.and.map(item => typeof item === "string" ? item : nest(item)),
|
|
91
|
+
};
|
|
91
92
|
}
|
|
92
|
-
if (
|
|
93
|
-
if (
|
|
94
|
-
|
|
93
|
+
if ("or" in input) {
|
|
94
|
+
if (input.or.length > 2) {
|
|
95
|
+
const [left, ...rest] = input.or;
|
|
96
|
+
return { or: [left, nest({ or: rest })] };
|
|
95
97
|
}
|
|
98
|
+
return {
|
|
99
|
+
or: input.or.map(item => typeof item === "string" ? item : nest(item)),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return input;
|
|
104
|
+
}
|
|
105
|
+
if (!isHookSpec(definition) || typeof definition !== "object") {
|
|
106
|
+
return [name, definition];
|
|
107
|
+
}
|
|
108
|
+
return [name, nest(definition)];
|
|
109
|
+
})
|
|
110
|
+
.flatMap(function css([name, definition]) {
|
|
111
|
+
if (!isHookSpec(definition)) {
|
|
112
|
+
return [];
|
|
113
|
+
}
|
|
114
|
+
if (typeof definition === "object") {
|
|
115
|
+
let a, operator, b, extraCSS = [];
|
|
116
|
+
if ("or" in definition) {
|
|
117
|
+
operator = "or";
|
|
118
|
+
[a, b] = definition.or;
|
|
119
|
+
if (!a) {
|
|
96
120
|
return [];
|
|
97
121
|
}
|
|
98
|
-
if (
|
|
99
|
-
return
|
|
122
|
+
if (!b) {
|
|
123
|
+
return css.bind(this)([name, a]);
|
|
100
124
|
}
|
|
101
|
-
|
|
102
|
-
|
|
125
|
+
extraCSS = [
|
|
126
|
+
{
|
|
127
|
+
init: (function aorb(x) {
|
|
128
|
+
const a = `${x}A`;
|
|
129
|
+
const b = `${x}B`;
|
|
130
|
+
return [
|
|
131
|
+
`--${x}-0:var(--${a}-0,var(--${b}-0));`,
|
|
132
|
+
`--${x}-1:var(--${a}-1) var(--${b}-1);`,
|
|
133
|
+
].join("");
|
|
134
|
+
})(name),
|
|
135
|
+
},
|
|
136
|
+
];
|
|
137
|
+
}
|
|
138
|
+
else if ("and" in definition) {
|
|
139
|
+
operator = "and";
|
|
140
|
+
[a, b] = definition.and;
|
|
141
|
+
if (!a) {
|
|
142
|
+
return [];
|
|
103
143
|
}
|
|
104
|
-
if (
|
|
105
|
-
return [
|
|
144
|
+
if (!b) {
|
|
145
|
+
return css.bind(this)([name, a]);
|
|
106
146
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
147
|
+
extraCSS = [
|
|
148
|
+
{
|
|
149
|
+
init: (function aandb(x) {
|
|
150
|
+
const a = `${x}A`;
|
|
151
|
+
const b = `${x}B`;
|
|
152
|
+
return [
|
|
153
|
+
`--${x}-0:var(--${a}-0) var(--${b}-0);`,
|
|
154
|
+
`--${x}-1:var(--${a}-1,var(--${b}-1));`,
|
|
155
|
+
].join("");
|
|
156
|
+
})(name),
|
|
157
|
+
},
|
|
158
|
+
];
|
|
159
|
+
}
|
|
160
|
+
if (operator) {
|
|
161
|
+
return [
|
|
162
|
+
...css.bind(this)([`${name}A`, a]),
|
|
163
|
+
...css.bind(this)([`${name}B`, b]),
|
|
164
|
+
...extraCSS,
|
|
165
|
+
];
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
const init = `--${name}-0:initial;--${name}-1: ;`;
|
|
169
|
+
let rule;
|
|
170
|
+
if (typeof definition === "string") {
|
|
171
|
+
if (definition.includes("&")) {
|
|
172
|
+
rule = `${definition.replace(/&/g, "*")}{--${name}-0: ;--${name}-1:initial;}`;
|
|
173
|
+
}
|
|
174
|
+
else if (definition.startsWith(":")) {
|
|
175
|
+
rule = `${definition}{--${name}-0: ;--${name}-1:initial;}`;
|
|
176
|
+
}
|
|
177
|
+
else if (definition.startsWith("@")) {
|
|
178
|
+
rule = `${definition}{*{--${name}-0: ;--${name}-1:initial;}}`;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return rule === undefined ? [] : [{ init, rule }];
|
|
182
|
+
})
|
|
183
|
+
.reduce((acc, { init = "", rule = "" }) => ({
|
|
184
|
+
init: acc.init + init,
|
|
185
|
+
rule: acc.rule + rule,
|
|
186
|
+
}), {
|
|
187
|
+
init: "",
|
|
188
|
+
rule: "",
|
|
189
|
+
});
|
|
190
|
+
return [
|
|
191
|
+
`*{${css.init}}${css.rule}`,
|
|
110
192
|
function hooks(properties) {
|
|
111
193
|
return hooksImpl(JSON.parse(JSON.stringify(properties)));
|
|
112
194
|
},
|
package/esm/index.js
CHANGED
|
@@ -12,6 +12,9 @@ function isHookSpec(x) {
|
|
|
12
12
|
if ("or" in x && x.or instanceof Array) {
|
|
13
13
|
return !x.or.some(xx => !isHookSpec(xx));
|
|
14
14
|
}
|
|
15
|
+
if ("and" in x && x.and instanceof Array) {
|
|
16
|
+
return !x.and.some(xx => !isHookSpec(xx));
|
|
17
|
+
}
|
|
15
18
|
}
|
|
16
19
|
return false;
|
|
17
20
|
}
|
|
@@ -70,39 +73,118 @@ export function buildHooksSystem(stringify = genericStringify) {
|
|
|
70
73
|
});
|
|
71
74
|
return properties;
|
|
72
75
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
if (!isHookSpec(spec)) {
|
|
86
|
-
return [];
|
|
76
|
+
const css = Object.entries(config)
|
|
77
|
+
.map(([name, definition]) => {
|
|
78
|
+
function nest(input) {
|
|
79
|
+
if (typeof input === "object") {
|
|
80
|
+
if ("and" in input) {
|
|
81
|
+
if (input.and.length > 2) {
|
|
82
|
+
const [left, ...rest] = input.and;
|
|
83
|
+
return { and: [left, nest({ and: rest })] };
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
and: input.and.map(item => typeof item === "string" ? item : nest(item)),
|
|
87
|
+
};
|
|
87
88
|
}
|
|
88
|
-
if (
|
|
89
|
-
if (
|
|
90
|
-
|
|
89
|
+
if ("or" in input) {
|
|
90
|
+
if (input.or.length > 2) {
|
|
91
|
+
const [left, ...rest] = input.or;
|
|
92
|
+
return { or: [left, nest({ or: rest })] };
|
|
91
93
|
}
|
|
94
|
+
return {
|
|
95
|
+
or: input.or.map(item => typeof item === "string" ? item : nest(item)),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return input;
|
|
100
|
+
}
|
|
101
|
+
if (!isHookSpec(definition) || typeof definition !== "object") {
|
|
102
|
+
return [name, definition];
|
|
103
|
+
}
|
|
104
|
+
return [name, nest(definition)];
|
|
105
|
+
})
|
|
106
|
+
.flatMap(function css([name, definition]) {
|
|
107
|
+
if (!isHookSpec(definition)) {
|
|
108
|
+
return [];
|
|
109
|
+
}
|
|
110
|
+
if (typeof definition === "object") {
|
|
111
|
+
let a, operator, b, extraCSS = [];
|
|
112
|
+
if ("or" in definition) {
|
|
113
|
+
operator = "or";
|
|
114
|
+
[a, b] = definition.or;
|
|
115
|
+
if (!a) {
|
|
92
116
|
return [];
|
|
93
117
|
}
|
|
94
|
-
if (
|
|
95
|
-
return
|
|
118
|
+
if (!b) {
|
|
119
|
+
return css.bind(this)([name, a]);
|
|
96
120
|
}
|
|
97
|
-
|
|
98
|
-
|
|
121
|
+
extraCSS = [
|
|
122
|
+
{
|
|
123
|
+
init: (function aorb(x) {
|
|
124
|
+
const a = `${x}A`;
|
|
125
|
+
const b = `${x}B`;
|
|
126
|
+
return [
|
|
127
|
+
`--${x}-0:var(--${a}-0,var(--${b}-0));`,
|
|
128
|
+
`--${x}-1:var(--${a}-1) var(--${b}-1);`,
|
|
129
|
+
].join("");
|
|
130
|
+
})(name),
|
|
131
|
+
},
|
|
132
|
+
];
|
|
133
|
+
}
|
|
134
|
+
else if ("and" in definition) {
|
|
135
|
+
operator = "and";
|
|
136
|
+
[a, b] = definition.and;
|
|
137
|
+
if (!a) {
|
|
138
|
+
return [];
|
|
99
139
|
}
|
|
100
|
-
if (
|
|
101
|
-
return [
|
|
140
|
+
if (!b) {
|
|
141
|
+
return css.bind(this)([name, a]);
|
|
102
142
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
143
|
+
extraCSS = [
|
|
144
|
+
{
|
|
145
|
+
init: (function aandb(x) {
|
|
146
|
+
const a = `${x}A`;
|
|
147
|
+
const b = `${x}B`;
|
|
148
|
+
return [
|
|
149
|
+
`--${x}-0:var(--${a}-0) var(--${b}-0);`,
|
|
150
|
+
`--${x}-1:var(--${a}-1,var(--${b}-1));`,
|
|
151
|
+
].join("");
|
|
152
|
+
})(name),
|
|
153
|
+
},
|
|
154
|
+
];
|
|
155
|
+
}
|
|
156
|
+
if (operator) {
|
|
157
|
+
return [
|
|
158
|
+
...css.bind(this)([`${name}A`, a]),
|
|
159
|
+
...css.bind(this)([`${name}B`, b]),
|
|
160
|
+
...extraCSS,
|
|
161
|
+
];
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
const init = `--${name}-0:initial;--${name}-1: ;`;
|
|
165
|
+
let rule;
|
|
166
|
+
if (typeof definition === "string") {
|
|
167
|
+
if (definition.includes("&")) {
|
|
168
|
+
rule = `${definition.replace(/&/g, "*")}{--${name}-0: ;--${name}-1:initial;}`;
|
|
169
|
+
}
|
|
170
|
+
else if (definition.startsWith(":")) {
|
|
171
|
+
rule = `${definition}{--${name}-0: ;--${name}-1:initial;}`;
|
|
172
|
+
}
|
|
173
|
+
else if (definition.startsWith("@")) {
|
|
174
|
+
rule = `${definition}{*{--${name}-0: ;--${name}-1:initial;}}`;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return rule === undefined ? [] : [{ init, rule }];
|
|
178
|
+
})
|
|
179
|
+
.reduce((acc, { init = "", rule = "" }) => ({
|
|
180
|
+
init: acc.init + init,
|
|
181
|
+
rule: acc.rule + rule,
|
|
182
|
+
}), {
|
|
183
|
+
init: "",
|
|
184
|
+
rule: "",
|
|
185
|
+
});
|
|
186
|
+
return [
|
|
187
|
+
`*{${css.init}}${css.rule}`,
|
|
106
188
|
function hooks(properties) {
|
|
107
189
|
return hooksImpl(JSON.parse(JSON.stringify(properties)));
|
|
108
190
|
},
|
package/package.json
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@css-hooks/core",
|
|
3
3
|
"description": "CSS Hooks core library",
|
|
4
|
-
"version": "1.1
|
|
4
|
+
"version": "1.2.1",
|
|
5
5
|
"author": "Nick Saunders",
|
|
6
6
|
"devDependencies": {
|
|
7
|
-
"@tsconfig/node-lts": "^18.12.3",
|
|
8
7
|
"@tsconfig/strictest": "^2.0.1",
|
|
9
8
|
"@types/css-tree": "^2.3.2",
|
|
10
9
|
"@types/jest": "^29.5.3",
|
|
@@ -33,6 +32,7 @@
|
|
|
33
32
|
},
|
|
34
33
|
"scripts": {
|
|
35
34
|
"clean": "rimraf cjs esm types",
|
|
35
|
+
"compile": "tsc",
|
|
36
36
|
"lint": "eslint __tests__ src .*.*js *.*js",
|
|
37
37
|
"prepublishOnly": "tsc -p tsconfig.dist.json --outDir esm --module es6 && tsc -p tsconfig.dist.json --outDir cjs --module commonjs && tsc -p tsconfig.dist.json --outDir types --declaration --emitDeclarationOnly",
|
|
38
38
|
"test": "jest"
|
package/types/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
type UnionToIntersection<T> = (T extends any ? (t: T) => any : never) extends (t: infer U) => any ? U : never;
|
|
2
2
|
type HookSpec = `@${"media" | "container"} ${string}` | `:${string}` | `${string}&${string}` | {
|
|
3
|
-
or: Readonly<
|
|
3
|
+
or: Readonly<HookSpec[]>;
|
|
4
|
+
} | {
|
|
5
|
+
and: Readonly<HookSpec[]>;
|
|
4
6
|
};
|
|
5
7
|
export type WithHooks<HookProperties, Properties> = WithHooksImpl<Properties, HookProperties>;
|
|
6
8
|
type WithHooksImpl<Properties, HookProperties, HookPropertiesSub extends HookProperties = HookProperties> = Properties & Partial<UnionToIntersection<HookPropertiesSub extends string ? {
|
|
@@ -8,7 +10,7 @@ type WithHooksImpl<Properties, HookProperties, HookPropertiesSub extends HookPro
|
|
|
8
10
|
} : never>>;
|
|
9
11
|
/** @internal */
|
|
10
12
|
export declare function genericStringify(_: unknown, value: unknown): string | null;
|
|
11
|
-
export declare function buildHooksSystem<Properties = Record<string, unknown>>(stringify?: (propertyName: keyof Properties, value: unknown) => string | null): <HookProperties extends string
|
|
13
|
+
export declare function buildHooksSystem<Properties = Record<string, unknown>>(stringify?: (propertyName: keyof Properties, value: unknown) => string | null): <HookProperties extends string>(config: Record<HookProperties, HookSpec>) => readonly [`*{${string}}undefined` | `*{${string}}${string}`, (properties: WithHooks<HookProperties, Properties>) => Properties];
|
|
12
14
|
/**
|
|
13
15
|
* A list of hooks offered as a "sensible default" to solve the most common use cases.
|
|
14
16
|
*/
|