tailwind-oklch 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.css +2 -0
- package/package.json +1 -1
- package/plugin.js +171 -1
package/index.css
CHANGED
|
@@ -98,6 +98,7 @@
|
|
|
98
98
|
|
|
99
99
|
:root:not(.dark) {
|
|
100
100
|
--lc-dir: -1;
|
|
101
|
+
--lc-flip: 0;
|
|
101
102
|
--lc-range-start: 0.95;
|
|
102
103
|
--lc-range-end: 0.15;
|
|
103
104
|
|
|
@@ -127,6 +128,7 @@
|
|
|
127
128
|
|
|
128
129
|
:root {
|
|
129
130
|
--lc-dir: 1;
|
|
131
|
+
--lc-flip: 1;
|
|
130
132
|
|
|
131
133
|
--bg-l: var(--l-5);
|
|
132
134
|
--bg-c: var(--c-lo);
|
package/package.json
CHANGED
package/plugin.js
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* Load via: @plugin "tailwind-oklch/plugin";
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
module.exports = function ({ addUtilities }) {
|
|
20
|
+
module.exports = function ({ addUtilities, matchUtilities }) {
|
|
21
21
|
const luminances = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'base', 'fore', 'none', 'full'];
|
|
22
22
|
const chromas = ['lo', 'mlo', 'mid', 'mhi', 'hi'];
|
|
23
23
|
const hues = ['primary', 'accent', 'success', 'warning', 'danger', 'info', 'neutral'];
|
|
@@ -97,4 +97,174 @@ module.exports = function ({ addUtilities }) {
|
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
addUtilities(utilities);
|
|
100
|
+
|
|
101
|
+
// ── Arbitrary hue values ────────────────────────────────────────────────
|
|
102
|
+
// hue-[180] → sets all hue properties to 180 (degrees).
|
|
103
|
+
// bg-h-[280] → sets only background hue to 280.
|
|
104
|
+
|
|
105
|
+
const hueVars = ['--bg-h', '--tx-h', '--bd-h', '--bdb-h', '--ac-h', '--gf-h', '--gt-h', '--sh-h'];
|
|
106
|
+
|
|
107
|
+
matchUtilities(
|
|
108
|
+
{
|
|
109
|
+
hue: (value) => Object.fromEntries(hueVars.map((v) => [v, value])),
|
|
110
|
+
},
|
|
111
|
+
{ type: ['integer'] },
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
for (const prop of properties) {
|
|
115
|
+
matchUtilities(
|
|
116
|
+
{
|
|
117
|
+
[`${prop.prefix}-h`]: (value) => ({
|
|
118
|
+
[prop.vars[2]]: value,
|
|
119
|
+
[prop.css]: `oklch(var(${prop.vars[0]}) var(${prop.vars[1]}) var(${prop.vars[2]}))`,
|
|
120
|
+
}),
|
|
121
|
+
},
|
|
122
|
+
{ type: ['integer'] },
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Gradient from/to arbitrary hue
|
|
127
|
+
matchUtilities(
|
|
128
|
+
{
|
|
129
|
+
'from-h': (value) => ({
|
|
130
|
+
'--gf-h': value,
|
|
131
|
+
'--tw-gradient-from': 'oklch(var(--gf-l) var(--gf-c) var(--gf-h))',
|
|
132
|
+
'--tw-gradient-stops': stopsExpr,
|
|
133
|
+
}),
|
|
134
|
+
'to-h': (value) => ({
|
|
135
|
+
'--gt-h': value,
|
|
136
|
+
'--tw-gradient-to': 'oklch(var(--gt-l) var(--gt-c) var(--gt-h))',
|
|
137
|
+
'--tw-gradient-stops': stopsExpr,
|
|
138
|
+
}),
|
|
139
|
+
},
|
|
140
|
+
{ type: ['integer'] },
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
// Shadow arbitrary hue
|
|
144
|
+
matchUtilities(
|
|
145
|
+
{
|
|
146
|
+
'shadow-h': (value) => ({
|
|
147
|
+
'--sh-h': value,
|
|
148
|
+
'--tw-shadow-color': 'oklch(var(--sh-l) var(--sh-c) var(--sh-h))',
|
|
149
|
+
}),
|
|
150
|
+
},
|
|
151
|
+
{ type: ['integer'] },
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
// ── Arbitrary chroma values ───────────────────────────────────────────
|
|
155
|
+
// chroma-[15] → sets all chroma properties to 0.15.
|
|
156
|
+
// bg-c-[20] → sets only background chroma to 0.20.
|
|
157
|
+
|
|
158
|
+
const chromaVars = ['--bg-c', '--tx-c', '--bd-c', '--bdb-c', '--ac-c', '--gf-c', '--gt-c', '--sh-c'];
|
|
159
|
+
|
|
160
|
+
const chromaValue = (value) => {
|
|
161
|
+
const v = Number(value) / 100;
|
|
162
|
+
return `${Math.round(v * 1e6) / 1e6}`;
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
matchUtilities(
|
|
166
|
+
{
|
|
167
|
+
chroma: (value) => {
|
|
168
|
+
const c = chromaValue(value);
|
|
169
|
+
return Object.fromEntries(chromaVars.map((v) => [v, c]));
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
{ type: ['integer'] },
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
for (const prop of properties) {
|
|
176
|
+
matchUtilities(
|
|
177
|
+
{
|
|
178
|
+
[`${prop.prefix}-c`]: (value) => ({
|
|
179
|
+
[prop.vars[1]]: chromaValue(value),
|
|
180
|
+
[prop.css]: `oklch(var(${prop.vars[0]}) var(${prop.vars[1]}) var(${prop.vars[2]}))`,
|
|
181
|
+
}),
|
|
182
|
+
},
|
|
183
|
+
{ type: ['integer'] },
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Gradient from/to arbitrary chroma
|
|
188
|
+
matchUtilities(
|
|
189
|
+
{
|
|
190
|
+
'from-c': (value) => ({
|
|
191
|
+
'--gf-c': chromaValue(value),
|
|
192
|
+
'--tw-gradient-from': 'oklch(var(--gf-l) var(--gf-c) var(--gf-h))',
|
|
193
|
+
'--tw-gradient-stops': stopsExpr,
|
|
194
|
+
}),
|
|
195
|
+
'to-c': (value) => ({
|
|
196
|
+
'--gt-c': chromaValue(value),
|
|
197
|
+
'--tw-gradient-to': 'oklch(var(--gt-l) var(--gt-c) var(--gt-h))',
|
|
198
|
+
'--tw-gradient-stops': stopsExpr,
|
|
199
|
+
}),
|
|
200
|
+
},
|
|
201
|
+
{ type: ['integer'] },
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
// Shadow arbitrary chroma
|
|
205
|
+
matchUtilities(
|
|
206
|
+
{
|
|
207
|
+
'shadow-c': (value) => ({
|
|
208
|
+
'--sh-c': chromaValue(value),
|
|
209
|
+
'--tw-shadow-color': 'oklch(var(--sh-l) var(--sh-c) var(--sh-h))',
|
|
210
|
+
}),
|
|
211
|
+
},
|
|
212
|
+
{ type: ['integer'] },
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
// ── Auto-flip luminance for arbitrary values ──────────────────────────
|
|
216
|
+
// bg-lc-[60] → light mode L=0.60, dark mode L=0.40 (simple 1−x flip).
|
|
217
|
+
// Uses --lc-flip (0 in light, 1 in dark) so the transform is pure CSS.
|
|
218
|
+
// Formula: L = v + flip × (1 − 2v) where v = input / 100
|
|
219
|
+
// flip=0 → v (light: use value as-is)
|
|
220
|
+
// flip=1 → 1−v (dark: reflect around 0.5)
|
|
221
|
+
|
|
222
|
+
const lcFlipValue = (value) => {
|
|
223
|
+
const v = Number(value) / 100;
|
|
224
|
+
const delta = 1 - 2 * v;
|
|
225
|
+
// Round to avoid floating-point noise in the CSS output
|
|
226
|
+
const vR = Math.round(v * 1e6) / 1e6;
|
|
227
|
+
const dR = Math.round(delta * 1e6) / 1e6;
|
|
228
|
+
return `calc(${vR} + var(--lc-flip) * ${dR})`;
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
for (const prop of properties) {
|
|
232
|
+
matchUtilities(
|
|
233
|
+
{
|
|
234
|
+
[`${prop.prefix}-lc`]: (value) => ({
|
|
235
|
+
[prop.vars[0]]: lcFlipValue(value),
|
|
236
|
+
[prop.css]: `oklch(var(${prop.vars[0]}) var(${prop.vars[1]}) var(${prop.vars[2]}))`,
|
|
237
|
+
}),
|
|
238
|
+
},
|
|
239
|
+
{ type: ['integer'] },
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Gradient from/to auto-flip luminance
|
|
244
|
+
matchUtilities(
|
|
245
|
+
{
|
|
246
|
+
'from-lc': (value) => ({
|
|
247
|
+
'--gf-l': lcFlipValue(value),
|
|
248
|
+
'--tw-gradient-from': 'oklch(var(--gf-l) var(--gf-c) var(--gf-h))',
|
|
249
|
+
'--tw-gradient-stops': stopsExpr,
|
|
250
|
+
}),
|
|
251
|
+
'to-lc': (value) => ({
|
|
252
|
+
'--gt-l': lcFlipValue(value),
|
|
253
|
+
'--tw-gradient-to': 'oklch(var(--gt-l) var(--gt-c) var(--gt-h))',
|
|
254
|
+
'--tw-gradient-stops': stopsExpr,
|
|
255
|
+
}),
|
|
256
|
+
},
|
|
257
|
+
{ type: ['integer'] },
|
|
258
|
+
);
|
|
259
|
+
|
|
260
|
+
// Shadow auto-flip luminance
|
|
261
|
+
matchUtilities(
|
|
262
|
+
{
|
|
263
|
+
'shadow-lc': (value) => ({
|
|
264
|
+
'--sh-l': lcFlipValue(value),
|
|
265
|
+
'--tw-shadow-color': 'oklch(var(--sh-l) var(--sh-c) var(--sh-h))',
|
|
266
|
+
}),
|
|
267
|
+
},
|
|
268
|
+
{ type: ['integer'] },
|
|
269
|
+
);
|
|
100
270
|
};
|