actual-css 0.9.0 → 0.9.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.
Files changed (94) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/README.md +2 -1
  3. package/components.json +2 -0
  4. package/dist/actual.css +26 -6
  5. package/dist/actual.full.css +260 -74
  6. package/dist/actual.full.js +1 -1
  7. package/dist/actual.full.min.css +1 -1
  8. package/dist/actual.min.css +1 -1
  9. package/docs/pages/components/table.md +3 -2
  10. package/docs/pages/examples/overview.md +1 -0
  11. package/docs/pages/forms/input-policy.md +59 -0
  12. package/docs/pages/forms/validation.md +37 -1
  13. package/docs/pages/foundations/tokens.md +23 -4
  14. package/docs/pages/foundations/typography.md +10 -0
  15. package/docs/pages/guides/introduction.md +2 -1
  16. package/docs/pages/guides/progressive-enhancement.md +15 -10
  17. package/package.json +160 -159
  18. package/src/css/components/accordion.css +2 -0
  19. package/src/css/components/actions.css +2 -0
  20. package/src/css/components/alert.css +2 -0
  21. package/src/css/components/app-nav.css +2 -0
  22. package/src/css/components/avatar.css +2 -0
  23. package/src/css/components/badge.css +2 -0
  24. package/src/css/components/breadcrumb.css +2 -0
  25. package/src/css/components/busy.css +2 -0
  26. package/src/css/components/button.css +2 -0
  27. package/src/css/components/card.css +2 -0
  28. package/src/css/components/chat.css +2 -0
  29. package/src/css/components/data-list.css +2 -0
  30. package/src/css/components/drawer.css +35 -22
  31. package/src/css/components/fab.css +2 -0
  32. package/src/css/components/flyout.css +2 -0
  33. package/src/css/components/indicator.css +2 -0
  34. package/src/css/components/join.css +2 -0
  35. package/src/css/components/key.css +2 -0
  36. package/src/css/components/list.css +2 -0
  37. package/src/css/components/meter.css +2 -0
  38. package/src/css/components/modal.css +47 -40
  39. package/src/css/components/navbar.css +2 -0
  40. package/src/css/components/pagination.css +2 -0
  41. package/src/css/components/progress.css +2 -0
  42. package/src/css/components/rating.css +2 -0
  43. package/src/css/components/scrollspy.css +2 -0
  44. package/src/css/components/skeleton.css +2 -0
  45. package/src/css/components/spinner.css +2 -0
  46. package/src/css/components/status-bar.css +2 -0
  47. package/src/css/components/steps.css +2 -0
  48. package/src/css/components/tab.css +2 -0
  49. package/src/css/components/table.css +2 -0
  50. package/src/css/components/tooltip.css +2 -0
  51. package/src/css/core/base.css +2 -0
  52. package/src/css/core/print.css +3 -0
  53. package/src/css/core/tokens.css +2 -0
  54. package/src/css/core/variants.css +19 -6
  55. package/src/css/effects/aura.css +2 -0
  56. package/src/css/forms/choice-card.css +4 -0
  57. package/src/css/forms/control.css +2 -0
  58. package/src/css/forms/floating-field.css +5 -1
  59. package/src/css/forms/form-actions.css +2 -0
  60. package/src/css/forms/form.css +8 -0
  61. package/src/css/forms/input-icon.css +2 -0
  62. package/src/css/forms/native.css +2 -0
  63. package/src/css/forms/otp.css +10 -0
  64. package/src/css/forms/range.css +2 -0
  65. package/src/css/forms/select.css +2 -0
  66. package/src/css/forms/switch.css +2 -0
  67. package/src/css/forms/validation.css +2 -0
  68. package/src/css/layout/app-layout.css +2 -0
  69. package/src/css/layout/app-shell.css +5 -1
  70. package/src/css/layout/center.css +2 -0
  71. package/src/css/layout/cluster.css +2 -0
  72. package/src/css/layout/column-layout.css +2 -0
  73. package/src/css/layout/frame.css +2 -0
  74. package/src/css/layout/grid.css +2 -0
  75. package/src/css/layout/media.css +2 -1
  76. package/src/css/layout/scroll-snap.css +2 -0
  77. package/src/css/layout/scroll-target.css +2 -0
  78. package/src/css/layout/sidebar-layout.css +2 -0
  79. package/src/css/layout/stack.css +2 -1
  80. package/src/css/layout/switcher.css +2 -0
  81. package/src/css/layout/topbar.css +2 -0
  82. package/src/css/typography/fluid.css +2 -0
  83. package/src/css/typography/lead.css +2 -1
  84. package/src/css/typography/overline.css +2 -0
  85. package/src/css/typography/prose.css +2 -0
  86. package/src/css/utilities/base.css +6 -1
  87. package/src/js/context-menu.js +56 -15
  88. package/src/js/enhancement-loader.js +5 -1
  89. package/src/js/escape.js +11 -1
  90. package/src/js/flyout.js +6 -1
  91. package/src/js/focus.js +8 -3
  92. package/src/js/surface.js +28 -0
  93. package/src/js/tooltip.js +10 -4
  94. package/src/js/validation.js +31 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,51 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ### Documentation and tooling
6
+
7
+ - Pushing a version tag publishes the GitHub release: `.npmrc` keeps `npm version` on the bare tag format, `bun run release:notes` extracts (and validates) the dated changelog section, and the CI `release` job attaches `dist/`.
8
+
9
+
10
+ ## [0.9.2] - 2026-09-22
11
+
12
+ ### Added
13
+
14
+ - `--font-width` and `--font-width-dense` typography hooks: `.compact` applies the denser width through `font-stretch` (variable `wdth` axis when available, width-face matching otherwise), `.spacious` restores the normal width. Themes without a useful width axis opt out with `--font-width-dense: 100%`.
15
+ - `starts-with` and `ends-with` built-in `data-validation-rules` rules: the trimmed value must begin or end with one of the literal tokens, case-sensitive.
16
+ - `tel-prefix` built-in `data-validation-rules` rule: dialing digits are required, local numbers pass, explicit international numbers (`+`, `00`) must match an allowed prefix, and no prefix means local-only. It is an origin policy, not phone validation, and never rewrites the value.
17
+
18
+ ### Fixed
19
+
20
+ - `.field` packs its rows to the start (`align-content: start`), so a field stretched by a taller grid row — a neighbour revealing its `.field-error` — no longer inflates its own control.
21
+
22
+
23
+ ## [0.9.1] - 2026-09-16
24
+
25
+ ### Fixed
26
+
27
+ - `.modal.scrollable` and `.drawer` body scrollports reserve inline focus-ring space without changing header, body, or footer alignment, so full-width controls no longer clip their focus indicator.
28
+ - `:where(dialog).modal` and `:where(dialog).drawer` roots now have 0-1-0 specificity like other components, allowing a later application class to override their defaults and documented hooks normally.
29
+ - `[data-context-menu]` resolves its menu per interaction: a target declared before its `<menu>` exists and a same-id menu replacement now open correctly instead of staying dead.
30
+ - `escape.js` ignores `Escape` presses already consumed (`defaultPrevented`) or chorded with `metaKey`.
31
+ - `isElementVisible()` in `focus.js` passes `visibilityProperty` to `checkVisibility()`, so `visibility:hidden` content is no longer reported focusable on modern engines.
32
+ - A flyout `<a>` trigger calls `preventDefault()` once its panel resolved — clicking it no longer navigates, while an unresolved trigger still navigates and bubbles.
33
+ - `data-tooltip` triggers containing focusable children now hide correctly: the non-bubbling `blur` listener was replaced by `focusout` with a `relatedTarget` containment check.
34
+ - `--dismiss` on an open surface finalizes the surface lifecycle — `.is-open`, the Escape entry, position tracking — and restores focus to the opener; the surface consumes `actual:dismiss` itself, keeping `dismiss.js` generic.
35
+ - `.link-muted:hover` and `.link-muted:focus-visible` are separate rules, so the hover color survives browsers without `:focus-visible`.
36
+ - `.choice-card` and `.floating-field` participate in `.sm` / `.lg` (and `.choice-card` consumes `--control-font-size`), so their documented size modifiers actually work.
37
+ - The `.floating-field` label rests on `--control-pad-x`, the same geometry as the control's text — both now share an inline start edge at every size.
38
+ - `.modal` header/footer resets are bounded to the dialog's structural `form` / `.stack` slots, so a header or footer inside the content keeps its own rhythm.
39
+ - `.otp` forced-colors styling covers the `:user-invalid` route.
40
+ - `print.css` forces `[data-theme]` islands to `color-scheme: light` with a white background and black text, so a dark-themed section no longer prints dark.
41
+ - The 11 paired themes declare `color-scheme: light` in their fallback block and `light dark` under `@supports (color: light-dark(...))` — dark UA controls no longer appear on the light fallback palette.
42
+
43
+ ### Documentation and tooling
44
+
45
+ - Public CSS sources carry a `Docs:` pointer to their canonical usage page, verified by `check:architecture`.
46
+ - `check:compat` rejects selector lists mixing an above-floor pseudo with baseline selectors.
47
+ - Docs TOC and search headings decode HTML entities, so a heading like `Linting role="menu"` no longer shows `&quot;` in the sidebar.
48
+ - `tokens.md` describes the actual forced-colors contract; `enhancement-loader` documents that manifests are trusted application configuration.
49
+
5
50
 
6
51
  ## [0.9.0] - 2026-09-13
7
52
 
package/README.md CHANGED
@@ -69,7 +69,8 @@ Variants such as `.solid`, `.soft`, `.outline`, and `.surface` are shared by com
69
69
 
70
70
  Size variants `.sm` and `.lg` scale typography and participating component
71
71
  geometry consistently. Density contexts `.compact` and `.spacious` change
72
- spacing and geometry without changing typography or icons.
72
+ spacing and geometry without changing font size or icons; `.compact` may
73
+ slightly narrow typefaces that support a width axis.
73
74
 
74
75
  ## Public Class Grammar
75
76
 
package/components.json CHANGED
@@ -266,6 +266,7 @@
266
266
  ],
267
267
  "internalHooks": [
268
268
  "--drawer-closed-translate",
269
+ "--drawer-focus-bleed",
269
270
  "--drawer-motion-duration"
270
271
  ],
271
272
  "states": [
@@ -446,6 +447,7 @@
446
447
  ],
447
448
  "internalHooks": [
448
449
  "--dialog-close-icon-size",
450
+ "--dialog-focus-bleed",
449
451
  "--dialog-viewport-block",
450
452
  "--dialog-viewport-gap-default",
451
453
  "--dialog-viewport-gap-2x"
package/dist/actual.css CHANGED
@@ -67,6 +67,8 @@ select {
67
67
  /* Typography */
68
68
  --font-sans: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
69
69
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
70
+ --font-width: 100%;
71
+ --font-width-dense: 95%;
70
72
  --line-height: 1.5;
71
73
  --line-height-tight: 1.25;
72
74
  --line-height-relaxed: 1.75;
@@ -515,12 +517,14 @@ select {
515
517
  * Public hooks:
516
518
  * --link
517
519
  * --hr-space
520
+ * --font-width / --font-width-dense (see variants.css for the dense application)
518
521
  */
519
522
 
520
523
  body {
521
524
  background: var(--surface);
522
525
  color: var(--text);
523
526
  font-family: var(--font-sans);
527
+ font-stretch: var(--font-width);
524
528
  line-height: var(--line-height);
525
529
  }
526
530
 
@@ -668,9 +672,16 @@ small {
668
672
  * components/alert.css — .alert default soft behind explicit --ui-*
669
673
  *
670
674
  * .compact/.spacious set inherited density tokens: spacing rhythm and geometry
671
- * only. Density never changes typography or icon size. Controls consume
672
- * --control-size; non-control components may consume --density-* when the
673
- * context should affect their local rhythm.
675
+ * only, plus a slight typographic width bonus. Density never changes font size
676
+ * or icon size. Controls consume --control-size; non-control components may
677
+ * consume --density-* when the context should affect their local rhythm.
678
+ * .compact applies --font-width-dense through font-stretch (a variable wdth
679
+ * axis when available, otherwise normal width-face matching); layout must
680
+ * never depend on the narrowing being available. .spacious restores
681
+ * --font-width, so a spacious island inside a compact context returns to the
682
+ * normal width exactly as it restores its own gap, spacing, and control size.
683
+ * Themes whose typeface has no useful width axis opt out with
684
+ * --font-width-dense: 100%.
674
685
  *
675
686
  * .sm/.lg are local size roles, not shared measurements. Shared control
676
687
  * participants below map both typography and geometry; components with
@@ -735,18 +746,20 @@ small {
735
746
  --gap: var(--space-20);
736
747
  --density-space: var(--space-20);
737
748
  --control-size: var(--control-size-sm);
749
+ font-stretch: var(--font-width-dense);
738
750
  }
739
751
 
740
752
  .spacious {
741
753
  --gap: var(--space-50);
742
754
  --density-space: var(--space-50);
743
755
  --control-size: var(--control-size-lg);
756
+ font-stretch: var(--font-width);
744
757
  }
745
758
 
746
759
  /* Shared control scale. Wrappers are listed when their descendants form one
747
- component (field, input-icon, join, pagination, tabs, flyout). A local size
748
- declaration beats inherited density because it is declared on the sized
749
- component itself. */
760
+ component (field, choice-card, floating-field, input-icon, join, pagination,
761
+ tabs, flyout). A local size declaration beats inherited density because it
762
+ is declared on the sized component itself. */
750
763
  :where(
751
764
  .btn,
752
765
  .input,
@@ -756,7 +769,9 @@ small {
756
769
  .file,
757
770
  .field,
758
771
  .choice,
772
+ .choice-card,
759
773
  .input-icon,
774
+ .floating-field,
760
775
  .otp,
761
776
  .join,
762
777
  .pagination,
@@ -778,7 +793,9 @@ small {
778
793
  .file,
779
794
  .field,
780
795
  .choice,
796
+ .choice-card,
781
797
  .input-icon,
798
+ .floating-field,
782
799
  .otp,
783
800
  .join,
784
801
  .pagination,
@@ -838,6 +855,9 @@ small {
838
855
 
839
856
  @media print {
840
857
  :root,
858
+ /* The doubled attribute intentionally outranks single-attribute preset
859
+ islands (data-theme="dark", paired themes) loaded after the core. */
860
+ [data-theme][data-theme],
841
861
  body {
842
862
  /* Save some ink in dark mode */
843
863
  color-scheme: light;