vunor 0.3.0 → 0.3.2

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 CHANGED
@@ -280,13 +280,15 @@ Button and clickable element design variants:
280
280
  | `c8-outlined` | Border + colored text, transparent fill |
281
281
  | `c8-light` | Light tinted background, colored text |
282
282
 
283
- Each includes hover, active, focus, and disabled states. Apply on any element alongside `scope-{color}`:
283
+ Each includes hover, active, and focus states. Hover and press do not paint on a disabled element: `disabled`, `aria-disabled="true"` or `data-disabled` (the same definition the `disabled-soft` shortcut uses to fade a disabled element). Keyboard focus still paints, so an `aria-disabled` control stays visibly focusable. Apply on any element alongside `scope-{color}`:
284
284
 
285
285
  ```html
286
286
  <button class="scope-primary c8-filled">Save</button>
287
287
  <button class="scope-error c8-flat">Cancel</button>
288
288
  ```
289
289
 
290
+ The `btn` layout primitive fades a disabled element to opacity 0.8. That is a default: `disabled-soft` (0.4) or a `disabled:opacity-*` utility replaces it, whether written on the element or composed with `btn` in your own shortcut (`'my-btn': 'btn disabled-soft'`).
291
+
290
292
  ### Inputable Styles (`i8`)
291
293
 
292
294
  Input field design variants:
package/dist/theme.mjs CHANGED
@@ -29,6 +29,18 @@ const toastShortcuts = defineShortcuts({
29
29
  }
30
30
  });
31
31
  //#endregion
32
+ //#region src/theme/utils/disabled.ts
33
+ const disabledSelectors = ":disabled,[disabled],[aria-disabled=true],[data-disabled]";
34
+ /** Variant prefix that matches while the element is disabled. */
35
+ const whenDisabled = `[&:is(${disabledSelectors})]:`;
36
+ /**
37
+ * Variant prefix for a default disabled paint: matches while the element is
38
+ * disabled and adds no specificity, so any other disabled rule overrides it.
39
+ */
40
+ const whenDisabledDefault = `[&:where(${disabledSelectors})]:`;
41
+ /** Variant prefix that matches only while the element is not disabled. */
42
+ const whenEnabled = `[&:not(${disabledSelectors})]:`;
43
+ //#endregion
32
44
  //#region src/components/Calendar/shortcuts.ts
33
45
  const calendarShortcuts = defineShortcuts({
34
46
  "calendar-root": "inline-block",
@@ -42,7 +54,7 @@ const calendarShortcuts = defineShortcuts({
42
54
  "before:": "absolute bottom-[0.6em] w-[1.5em] h-[2px] bg-scope-color-500/75 block",
43
55
  "[&[data-today]::before]:": "content-['']",
44
56
  "[&[data-today][data-selected]::before]:": "bg-white",
45
- "hover:": {
57
+ [`${whenEnabled}hover:`]: {
46
58
  "": "bg-scope-color-200",
47
59
  "dark:": "bg-scope-color-700"
48
60
  },
@@ -82,8 +94,8 @@ const checkboxShortcuts = defineShortcuts({
82
94
  },
83
95
  "checkbox": {
84
96
  "": "cursor-default shrink-0 select-none rounded-r0 transition-all transition-duration-100 flex size-1.5em appearance-none items-center justify-center bg-current/0 border-current border-[0.16em] current-icon-white",
85
- "group-active/cb:enabled:": "current-bg-scope-color-500 bg-current/20 current-icon-scope-color-500",
86
- "disabled:": "cursor-not-allowed border-1px",
97
+ [`group-active/cb:${whenEnabled}`]: "current-bg-scope-color-500 bg-current/20 current-icon-scope-color-500",
98
+ [whenDisabled]: "cursor-not-allowed border-1px",
87
99
  "group-[[data-error=true]]/cb:enabled:": "current-border-error-500 border-current",
88
100
  "data-[state=unchecked]": "current-border-grey-500 border-current/40"
89
101
  },
@@ -168,7 +180,7 @@ const shortcuts = [
168
180
  "": "disabled-soft select-none shrink-0 current-bg-scope-color-500 bg-current/0 size-1.25em rounded-full cursor-default current-border-grey-500 border-current/40 border-[0.16em] transition-none",
169
181
  "data-[state=checked]:not-[[data-error='true']]:": "current-border-scope-color-500 border-current",
170
182
  "data-[state=checked]:": "bg-current",
171
- "active:enabled:": "bg-current/20",
183
+ [`${whenEnabled}active:`]: "bg-current/20",
172
184
  "aria-[disabled=true]:": "scope-grey",
173
185
  "data-[error=true]:": "current-border-error-500 current-bg-error-500"
174
186
  },
@@ -209,7 +221,7 @@ const shortcuts = [
209
221
  "slider-thumb": {
210
222
  "": "block w-[1.5em] h-[1.5em] bg-scope-color-500 rounded-full border-scope-light-0 border-[3px] outline-scope-color-500/10 outline-0px outline-solid",
211
223
  "dark:": "border-scope-dark-0",
212
- "not-[[disabled]]:": {
224
+ [whenEnabled]: {
213
225
  "": "cursor-grab",
214
226
  "hover:": "shadow-md",
215
227
  "active:": "cursor-grabbing",
@@ -237,7 +249,8 @@ const btn = defineShortcuts({
237
249
  "[&.btn-round]:": btnRound,
238
250
  "[&.btn-square]:": btnSquare,
239
251
  "[&.btn-round.btn-square]:": "px-0 [--btn-icon-pull:0]",
240
- "disabled:": "opacity-80 cursor-not-allowed",
252
+ [whenDisabledDefault]: "opacity-80",
253
+ [whenDisabled]: "cursor-not-allowed",
241
254
  "[&>span]:data-[loading]:": "opacity-0 pointer-events-none",
242
255
  "[&>div:not(.loading-indicator-wrapper)]:data-[loading]:": "opacity-0 pointer-events-none",
243
256
  "[&>.loading-indicator-wrapper]:": "absolute left-0 top-0 right-0 bottom-0 flex items-center justify-center cursor-wait"
@@ -254,35 +267,39 @@ const btn = defineShortcuts({
254
267
  const c8 = defineShortcuts({
255
268
  "c8-filled": {
256
269
  "": "current-bg-scope-color-500 rounded-r1 current-text-white current-icon-white icon-current/100 bg-current text-current",
257
- "hover:": "c8-filled-hover",
258
270
  "focus-visible:": "c8-filled-hover",
259
- "data-[highlighted]:": "c8-filled-hover",
260
- "active:": "c8-filled-active",
261
- "data-[active]:": "c8-filled-active"
271
+ [whenEnabled]: {
272
+ "hover:": "c8-filled-hover",
273
+ "data-[highlighted]:": "c8-filled-hover",
274
+ "active:": "c8-filled-active",
275
+ "data-[active]:": "c8-filled-active"
276
+ }
262
277
  },
263
278
  "c8-filled-hover": {
264
- "not-([disabled]):": "current-bg-scope-color-600",
265
- "dark:not-([disabled]):": "current-bg-scope-color-400"
279
+ "": "current-bg-scope-color-600",
280
+ "dark:": "current-bg-scope-color-400"
266
281
  },
267
282
  "c8-filled-active": {
268
- "not-([disabled]):": "current-bg-scope-color-700",
269
- "dark:not-([disabled]):": "current-bg-scope-color-300"
283
+ "": "current-bg-scope-color-700",
284
+ "dark:": "current-bg-scope-color-300"
270
285
  },
271
286
  "c8-flat": {
272
287
  "": "current-bg-scope-color-500 rounded-r1 current-text-black current-icon-black bg-current/0 text-current/80 icon-current/50",
273
288
  "dark:": "current-text-white current-icon-white",
274
- "hover:": "c8-flat-hover",
275
289
  "focus-visible:": "c8-flat-hover",
276
- "data-[highlighted]:": "c8-flat-hover",
277
- "active:": "c8-flat-active",
278
- "data-[active]:": "c8-flat-active",
290
+ [whenEnabled]: {
291
+ "hover:": "c8-flat-hover",
292
+ "data-[highlighted]:": "c8-flat-hover",
293
+ "active:": "c8-flat-active",
294
+ "data-[active]:": "c8-flat-active"
295
+ },
279
296
  "data-[selected=true]:": "c8-flat-selected",
280
297
  "data-[on=true]:": "c8-flat-selected",
281
298
  "aria-[selected=true]:": "c8-flat-selected",
282
299
  "aria-[pressed=true]:": "c8-flat-selected"
283
300
  },
284
- "c8-flat-hover": { "not-([disabled]):": "bg-current/10" },
285
- "c8-flat-active": { "not-([disabled]):": "bg-current/15" },
301
+ "c8-flat-hover": "bg-current/10",
302
+ "c8-flat-active": "bg-current/15",
286
303
  "c8-flat-selected": {
287
304
  "": "c8-flat-hover current-text-scope-color-500 text-current current-icon-scope-color-500 icon-current/100",
288
305
  "dark:": "current-text-scope-color-400 current-icon-scope-color-400"
@@ -290,33 +307,37 @@ const c8 = defineShortcuts({
290
307
  "c8-outlined": {
291
308
  "": "c8-flat border-scope-color-500 rounded-r1 border current-text-scope-color-500 current-icon-scope-color-500 icon-current/100",
292
309
  "dark:": "current-text-scope-color-400 current-icon-scope-color-400",
293
- "hover:": "c8-outlined-hover",
294
310
  "focus-visible:": "c8-outlined-hover",
295
- "data-[highlighted]:": "c8-outlined-hover",
296
- "active:": "c8-outlined-active",
297
- "data-[active]:": "c8-outlined-active"
311
+ [whenEnabled]: {
312
+ "hover:": "c8-outlined-hover",
313
+ "data-[highlighted]:": "c8-outlined-hover",
314
+ "active:": "c8-outlined-active",
315
+ "data-[active]:": "c8-outlined-active"
316
+ }
298
317
  },
299
318
  "c8-outlined-hover": "c8-flat-hover",
300
319
  "c8-outlined-active": "c8-flat-active",
301
320
  "c8-chrome": {
302
321
  "": "surface-0 rounded-r1 border",
303
- "hover:": "c8-chrome-hover",
304
322
  "focus-visible:": "c8-chrome-hover",
305
- "data-[highlighted]:": "c8-chrome-hover",
306
- "active:": "c8-chrome-active",
307
- "data-[active]:": "c8-chrome-active",
323
+ [whenEnabled]: {
324
+ "hover:": "c8-chrome-hover",
325
+ "data-[highlighted]:": "c8-chrome-hover",
326
+ "active:": "c8-chrome-active",
327
+ "data-[active]:": "c8-chrome-active"
328
+ },
308
329
  "data-[selected=true]:": "c8-chrome-selected",
309
330
  "data-[on=true]:": "c8-chrome-selected",
310
331
  "aria-[selected=true]:": "c8-chrome-selected",
311
332
  "aria-[pressed=true]:": "c8-chrome-selected"
312
333
  },
313
334
  "c8-chrome-hover": {
314
- "not-([disabled]):": "current-bg-scope-light-1 bg-current",
315
- "dark:not-([disabled]):": "current-bg-scope-dark-1"
335
+ "": "current-bg-scope-light-1 bg-current",
336
+ "dark:": "current-bg-scope-dark-1"
316
337
  },
317
338
  "c8-chrome-active": {
318
- "not-([disabled]):": "current-bg-scope-light-2 bg-current",
319
- "dark:not-([disabled]):": "current-bg-scope-dark-2"
339
+ "": "current-bg-scope-light-2 bg-current",
340
+ "dark:": "current-bg-scope-dark-2"
320
341
  },
321
342
  "c8-chrome-selected": {
322
343
  "": "current-bg-scope-light-1 bg-current current-text-scope-color-500 text-current current-icon-scope-color-500 icon-current/100",
@@ -325,18 +346,20 @@ const c8 = defineShortcuts({
325
346
  "c8-light": {
326
347
  "": "current-bg-scope-color-500 rounded-r1 current-text-scope-color-500 current-icon-scope-color-500 bg-current/10 text-current icon-current/80",
327
348
  "dark:": "current-text-scope-color-400 current-icon-scope-color-400",
328
- "hover:": "c8-light-hover",
329
349
  "focus-visible:": "c8-light-hover",
330
- "data-[highlighted]:": "c8-light-hover",
331
- "active:": "c8-light-active",
332
- "data-[active]:": "c8-light-active",
350
+ [whenEnabled]: {
351
+ "hover:": "c8-light-hover",
352
+ "data-[highlighted]:": "c8-light-hover",
353
+ "active:": "c8-light-active",
354
+ "data-[active]:": "c8-light-active"
355
+ },
333
356
  "data-[selected=true]:": "c8-light-hover",
334
357
  "data-[on=true]:": "c8-light-hover",
335
358
  "aria-[selected=true]:": "c8-light-hover",
336
359
  "aria-[pressed=true]:": "c8-light-hover"
337
360
  },
338
- "c8-light-hover": { "not-([disabled]):": "bg-current/20" },
339
- "c8-light-active": { "not-([disabled]):": "bg-current/30" }
361
+ "c8-light-hover": "bg-current/20",
362
+ "c8-light-active": "bg-current/30"
340
363
  });
341
364
  //#endregion
342
365
  //#region src/theme/shortcuts/extras.ts
@@ -344,12 +367,7 @@ const popupCard = defineShortcuts({
344
367
  "shadow-popup": "shadow-[0_0_10px_rgba(0,0,0,0.1),0_4px_20px_rgba(0,0,0,0.15)]",
345
368
  "popup-card": { "": "surface-0 bg-current rounded-r2 overflow-hidden shadow-popup z-[100] border current-border-grey-400 border-current/20" }
346
369
  });
347
- const disabledPaint = "opacity-40 cursor-not-allowed";
348
- const disabledSoft = defineShortcuts({ "disabled-soft": {
349
- "disabled:": disabledPaint,
350
- "aria-[disabled=true]:": disabledPaint,
351
- "data-[disabled]:": disabledPaint
352
- } });
370
+ const disabledSoft = defineShortcuts({ "disabled-soft": { [whenDisabled]: "opacity-40 cursor-not-allowed" } });
353
371
  //#endregion
354
372
  //#region src/theme/shortcuts/i8.ts
355
373
  const M = "1em";
@@ -386,7 +404,7 @@ const rawVunorShortcuts = [
386
404
  "i8-transparent": "bg-transparent!",
387
405
  "i8-bare": {
388
406
  "": "i8-apply-bg i8-apply-border current-outline-hl rounded-r1 outline-none text-current placeholder:text-current/50 disabled-soft",
389
- "hover:": "border-current-hover",
407
+ [`${whenEnabled}hover:`]: "border-current-hover",
390
408
  "focus:": "current-border-hl outline i8-apply-outline",
391
409
  "data-[error=true]:": "current-border-error-500 current-outline-error-500 border-current"
392
410
  },
@@ -874,6 +892,7 @@ const componentClasses = {
874
892
  "h6",
875
893
  "i8",
876
894
  "i8-append",
895
+ "i8-filled",
877
896
  "i8-icon-clickable",
878
897
  "i8-icon-wrap",
879
898
  "i8-input",
@@ -882,6 +901,7 @@ const componentClasses = {
882
901
  "i8-label-wrapper",
883
902
  "i8-loading",
884
903
  "i8-prepend",
904
+ "i8-round",
885
905
  "i8-ta-wrapper",
886
906
  "i8-textarea",
887
907
  "i8-underline",
@@ -1288,6 +1308,7 @@ const componentClasses = {
1288
1308
  "btn-icon-left",
1289
1309
  "btn-square",
1290
1310
  "c8-flat",
1311
+ "disabled-soft",
1291
1312
  "flex",
1292
1313
  "gap-1",
1293
1314
  "icon-color",
@@ -1735,13 +1756,13 @@ function multiplySaturation(colors, m = .5) {
1735
1756
  return newObj;
1736
1757
  }
1737
1758
  const layerN = (n, reverse) => reverse ? 4 - n : n;
1759
+ const sideTemplate = (bg, n) => {
1760
+ const fg = bg === "light" ? "dark" : "light";
1761
+ return `current-bg-scope-${bg}-${n} current-text-scope-${fg}-0 current-icon-scope-${fg}-0 current-text-muted-scope-${fg}-2 current-icon-muted-scope-${fg}-2 current-bg-hover-scope-${bg}-${Math.min(n + 1, 4)} current-border-hover-scope-${bg}-3 current-text-hover-scope-${fg}-0`;
1762
+ };
1738
1763
  function getPaletteShortcuts() {
1739
1764
  return [
1740
1765
  [/^layer-([0-4])$/, ([, a], { theme }) => {
1741
- const sideTemplate = (bg, n) => {
1742
- const fg = bg === "light" ? "dark" : "light";
1743
- return `current-bg-scope-${bg}-${n} current-text-scope-${fg}-0 current-icon-scope-${fg}-0 current-text-muted-scope-${fg}-2 current-icon-muted-scope-${fg}-2 current-bg-hover-scope-${bg}-${Math.min(n + 1, 4)} current-border-hover-scope-${bg}-3 current-text-hover-scope-${fg}-0`;
1744
- };
1745
1766
  const d = layerN(Number(a), theme.reverseDarkLayers);
1746
1767
  const l = layerN(Number(a), theme.reverseLightLayers);
1747
1768
  const dark = sideTemplate("dark", d);
@@ -2442,6 +2463,13 @@ const defaultOptions = {
2442
2463
  }
2443
2464
  }
2444
2465
  };
2466
+ const DISABLED_SOFT = "disabled-soft";
2467
+ const DISABLED_SOFT_LITERAL = "__vunor-disabled-soft";
2468
+ const disabledSoftLiteral = {
2469
+ name: "vunor:disabled-soft-literal",
2470
+ order: -1e3,
2471
+ match: (matcher, { generator }) => matcher === DISABLED_SOFT && generator.config.shortcuts.some((sc) => sc[0] === DISABLED_SOFT) ? { matcher: DISABLED_SOFT_LITERAL } : void 0
2472
+ };
2445
2473
  const presetVunor = (_opts) => {
2446
2474
  const opts = defu(_opts, defaultOptions);
2447
2475
  const wind = getFixedWind();
@@ -2460,7 +2488,8 @@ const presetVunor = (_opts) => {
2460
2488
  ...wind,
2461
2489
  name: "vunor",
2462
2490
  theme: defu(theme.theme, wind.theme),
2463
- shortcuts: paletteShortcuts,
2491
+ variants: [disabledSoftLiteral, ...wind.variants ?? []],
2492
+ shortcuts: [...paletteShortcuts, [DISABLED_SOFT_LITERAL, DISABLED_SOFT]],
2464
2493
  extractors: [createVunorExtractor()],
2465
2494
  layers: {
2466
2495
  preflights: 0,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vunor",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "files": [
5
5
  "dist"
6
6
  ],
@@ -215,4 +215,4 @@
215
215
  "vue-router": "^5.0.4",
216
216
  "vue-tsc": "^3.2.6"
217
217
  }
218
- }
218
+ }