@gjsify/adwaita-web 0.41.0 → 0.43.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.
Files changed (97) hide show
  1. package/README.md +98 -3
  2. package/dist/adwaita-web.css +30 -23
  3. package/dist/adwaita-web.css.map +1 -1
  4. package/lib/types/adw-fonts.spec.d.ts +2 -0
  5. package/lib/types/breakpoints.d.ts +10 -1
  6. package/lib/types/connect-lifecycle.spec.d.ts +1 -0
  7. package/lib/types/elements/adw-about-dialog.d.ts +1 -0
  8. package/lib/types/elements/adw-action-row.d.ts +2 -0
  9. package/lib/types/elements/adw-alert-dialog.d.ts +14 -2
  10. package/lib/types/elements/adw-carousel.d.ts +8 -0
  11. package/lib/types/elements/adw-dialog.d.ts +2 -7
  12. package/lib/types/elements/adw-icon.d.ts +17 -1
  13. package/lib/types/elements/adw-navigation-split-view.d.ts +7 -0
  14. package/lib/types/elements/adw-overlay-split-view.d.ts +6 -0
  15. package/lib/types/elements/adw-popover.d.ts +1 -0
  16. package/lib/types/elements/adw-preferences-dialog.d.ts +1 -0
  17. package/lib/types/elements/adw-switch.d.ts +10 -0
  18. package/lib/types/elements/adw-toggle-group.d.ts +2 -0
  19. package/lib/types/elements/modal-surface.d.ts +59 -0
  20. package/lib/types/elements/roving-focus.d.ts +26 -0
  21. package/lib/types/elements/row-activation.d.ts +26 -0
  22. package/lib/types/elements/swipe-drag.d.ts +63 -0
  23. package/lib/types/empty-sections.d.ts +15 -0
  24. package/lib/types/empty-sections.spec.d.ts +1 -0
  25. package/lib/types/fonts.d.ts +1 -0
  26. package/lib/types/icon-registry.d.ts +35 -0
  27. package/lib/types/icon-registry.spec.d.ts +18 -0
  28. package/lib/types/index.d.ts +1 -1
  29. package/lib/types/keyboard-operable.spec.d.ts +1 -0
  30. package/lib/types/styles.generated.d.ts +1 -1
  31. package/package.json +10 -6
  32. package/scss/_banner.scss +1 -1
  33. package/scss/_checks.scss +8 -8
  34. package/scss/_combo_row.scss +1 -1
  35. package/scss/_drop_down.scss +1 -1
  36. package/scss/_expander_row.scss +1 -1
  37. package/scss/_icon.scss +47 -0
  38. package/scss/_icons.generated.scss +18 -6
  39. package/scss/_password_entry_row.scss +1 -1
  40. package/scss/_preferences_dialog.scss +3 -2
  41. package/scss/_progress_bar.scss +1 -1
  42. package/scss/_row.scss +1 -1
  43. package/scss/_status_page.scss +1 -1
  44. package/scss/_tab_view.scss +1 -1
  45. package/scss/_toast.scss +6 -24
  46. package/scss/_variables.scss +23 -3
  47. package/src/adw-action-rows.spec.ts +21 -9
  48. package/src/adw-button-content.spec.ts +11 -6
  49. package/src/adw-fonts.spec.ts +188 -0
  50. package/src/adw-icon.spec.ts +17 -8
  51. package/src/adw-row-state.spec.ts +11 -1
  52. package/src/breakpoints.ts +18 -4
  53. package/src/connect-lifecycle.spec.ts +351 -0
  54. package/src/elements/adw-about-dialog.ts +24 -18
  55. package/src/elements/adw-action-row.ts +14 -2
  56. package/src/elements/adw-alert-dialog.ts +39 -20
  57. package/src/elements/adw-button-row.ts +3 -0
  58. package/src/elements/adw-carousel.ts +86 -5
  59. package/src/elements/adw-clamp.ts +3 -2
  60. package/src/elements/adw-data-grid.ts +5 -2
  61. package/src/elements/adw-dialog.ts +16 -63
  62. package/src/elements/adw-expander-row.ts +18 -4
  63. package/src/elements/adw-header-bar.ts +2 -0
  64. package/src/elements/adw-icon.ts +32 -6
  65. package/src/elements/adw-inline-view-switcher.ts +12 -0
  66. package/src/elements/adw-menu-button.ts +17 -10
  67. package/src/elements/adw-navigation-split-view.ts +30 -7
  68. package/src/elements/adw-overlay-split-view.ts +15 -3
  69. package/src/elements/adw-popover.ts +11 -0
  70. package/src/elements/adw-preferences-dialog.ts +18 -16
  71. package/src/elements/adw-preferences-group.ts +7 -0
  72. package/src/elements/adw-sidebar.ts +15 -0
  73. package/src/elements/adw-status-page.ts +12 -4
  74. package/src/elements/adw-switch-row.ts +7 -0
  75. package/src/elements/adw-switch.ts +19 -1
  76. package/src/elements/adw-tab-view.ts +7 -4
  77. package/src/elements/adw-toast-overlay.ts +8 -1
  78. package/src/elements/adw-toggle-group.ts +94 -2
  79. package/src/elements/adw-toolbar-view.ts +6 -2
  80. package/src/elements/adw-view-switcher-bar.ts +18 -0
  81. package/src/elements/adw-view-switcher.ts +14 -0
  82. package/src/elements/modal-surface.ts +180 -0
  83. package/src/elements/roving-focus.ts +154 -0
  84. package/src/elements/row-activation.ts +92 -0
  85. package/src/elements/swipe-drag.ts +450 -0
  86. package/src/empty-sections.spec.ts +81 -0
  87. package/src/empty-sections.ts +54 -0
  88. package/src/fonts.ts +25 -0
  89. package/src/icon-registry.spec.ts +240 -0
  90. package/src/icon-registry.ts +157 -0
  91. package/src/index.ts +24 -1
  92. package/src/keyboard-operable.spec.ts +755 -0
  93. package/src/source-view/theme.ts +15 -3
  94. package/src/split-button.spec.ts +6 -2
  95. package/src/style-classes.spec.ts +6 -0
  96. package/src/styles.generated.ts +1 -1
  97. package/src/test.browser.mts +14 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gjsify/adwaita-web",
3
- "version": "0.41.0",
3
+ "version": "0.43.0",
4
4
  "description": "Adwaita/Libadwaita web components for browser targets",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
@@ -14,6 +14,10 @@
14
14
  "types": "./lib/types/source-view/index.d.ts",
15
15
  "default": "./src/source-view/index.ts"
16
16
  },
17
+ "./fonts": {
18
+ "types": "./lib/types/fonts.d.ts",
19
+ "default": "./src/fonts.ts"
20
+ },
17
21
  "./style.css": {
18
22
  "types": "./style.css.d.ts",
19
23
  "default": "./dist/adwaita-web.css"
@@ -41,14 +45,14 @@
41
45
  "@codemirror/language": "^6.12.4",
42
46
  "@codemirror/state": "^6.7.0",
43
47
  "@codemirror/view": "^6.43.4",
44
- "@gjsify/adwaita-core": "^0.41.0",
45
- "@gjsify/adwaita-fonts": "^0.41.0",
46
- "@gjsify/adwaita-icons": "^0.41.0",
48
+ "@gjsify/adwaita-core": "^0.43.0",
49
+ "@gjsify/adwaita-fonts": "^0.43.0",
50
+ "@gjsify/adwaita-icons": "^0.43.0",
47
51
  "@lezer/highlight": "^1.2.3"
48
52
  },
49
53
  "devDependencies": {
50
- "@gjsify/cli": "^0.41.0",
51
- "@gjsify/unit": "^0.41.0",
54
+ "@gjsify/cli": "^0.43.0",
55
+ "@gjsify/unit": "^0.43.0",
52
56
  "sass": "^1.101.0",
53
57
  "typescript": "^6.0.3"
54
58
  },
package/scss/_banner.scss CHANGED
@@ -1,6 +1,6 @@
1
1
  // _banner.scss — adw-banner styling (full-width accent message strip).
2
2
  // Reference: refs/adwaita-web/adwaita-web/scss/_banner.scss
3
- // Reference: refs/libadwaita/src/stylesheet/widgets/_banner.scss
3
+ // Reference: refs/libadwaita/src/stylesheet/widgets/_toolbars.scss (AdwBanner)
4
4
  // Copyright (c) GNOME contributors (libadwaita). LGPLv2.1+.
5
5
  // Modifications: Adapted for @gjsify/adwaita-web Web Components.
6
6
 
package/scss/_checks.scss CHANGED
@@ -1,13 +1,13 @@
1
1
  // _checks.scss — <adw-checkbox> AND <adw-radio>, in ONE partial.
2
2
  //
3
- // WHY ONE FILE FOR TWO ELEMENTS. `refs/libadwaita/src/stylesheet/widgets/
4
- // _checks.scss` merges them deliberately: everything but the corner radius and
5
- // the glyph is a shared `check, radio { … }` block (:20-65), and the
6
- // indeterminate dash is re-declared for BOTH at the end (:79-81). There is no
7
- // `_radio.scss` upstream to mirror. `refs/adwaita-web` does split them into
8
- // `_checkbox.scss` + `_radio.scss`, and the split is exactly where it drifted:
9
- // its two indicators grew different sizes, different border treatments and
10
- // different selection-mode rules, and only one of them has a hover state.
3
+ // WHY ONE FILE FOR TWO ELEMENTS. Upstream's
4
+ // `refs/libadwaita/src/stylesheet/widgets/_checks.scss` merges them deliberately:
5
+ // everything but the corner radius and the glyph is a shared `check, radio { … }`
6
+ // block (:20-65), and the indeterminate dash is re-declared for BOTH at the end
7
+ // (:79-81). There is no `_radio.scss` upstream to mirror. `refs/adwaita-web` does
8
+ // split them into `_checkbox.scss` + `_radio.scss`, and the split is exactly where
9
+ // it drifted: its two indicators grew different sizes, different border treatments
10
+ // and different selection-mode rules, and only one of them has a hover state.
11
11
  //
12
12
  // TWO PLACES THE VENDORED WEB PORT DISAGREES WITH LIBADWAITA. libadwaita is
13
13
  // followed in both:
@@ -1,6 +1,6 @@
1
1
  // _combo_row.scss — adw-combo-row styling.
2
2
  // Reference: refs/adwaita-web/adwaita-web/scss/_combo_row.scss
3
- // Reference: refs/libadwaita/src/stylesheet/widgets/_combo-row.scss
3
+ // Reference: refs/libadwaita/src/stylesheet/widgets/_lists.scss (AdwComboRow)
4
4
  // Copyright (c) GNOME contributors (libadwaita). LGPLv2.1+.
5
5
  // Copyright (c) 2025 csm (adwaita-web). MIT License.
6
6
  // Modifications: Adapted for @gjsify/adwaita-web Web Components.
@@ -5,7 +5,7 @@
5
5
  // (soft triple shadow), the items its modelbutton rows, matching <adw-menu-button>.
6
6
  // Reference: refs/libadwaita/src/stylesheet/widgets/_popovers.scss (popover > contents)
7
7
  // Reference: refs/libadwaita/src/stylesheet/widgets/_menus.scss (modelbutton rows)
8
- // Reference: refs/libadwaita/src/stylesheet/widgets/_drop-down.scss (dropdown button)
8
+ // Reference: refs/libadwaita/src/stylesheet/widgets/_dropdowns.scss (dropdown button)
9
9
  // Copyright (c) GNOME contributors (libadwaita). LGPLv2.1+.
10
10
  // Modifications: Implemented for @gjsify/adwaita-web Web Components.
11
11
 
@@ -1,6 +1,6 @@
1
1
  // _expander_row.scss — adw-expander-row styling (disclosure header + nested rows).
2
2
  // Reference: refs/adwaita-web/adwaita-web/scss/_expander_row.scss
3
- // Reference: refs/libadwaita/src/stylesheet/widgets/_expander-row.scss
3
+ // Reference: refs/libadwaita/src/stylesheet/widgets/_lists.scss (AdwExpanderRow)
4
4
  // Copyright (c) GNOME contributors (libadwaita). LGPLv2.1+.
5
5
  // Copyright (c) 2025 csm (adwaita-web). MIT License.
6
6
  // Modifications: Adapted for @gjsify/adwaita-web Web Components.
package/scss/_icon.scss CHANGED
@@ -49,3 +49,50 @@
49
49
  display: none;
50
50
  }
51
51
  }
52
+
53
+ // THE FALLBACK GLYPH — what a name the stylesheet cannot draw resolves to.
54
+ //
55
+ // Until this rule existed there was no `mask-image` on `.adw-icon` at all, so an
56
+ // icon whose name has no generated class kept `background-color: currentColor`
57
+ // over an empty mask and painted a SOLID 16px square in the widget's text
58
+ // colour. Measured in Firefox: `.adw-icon.adw-icon--dialog-error` reported
59
+ // `mask-image: none`, `background-color: rgb(0, 128, 0)`, box 16x16 — visually a
60
+ // deliberate colour swatch, which is why three renderer-comparison surfaces
61
+ // carried substituted glyphs and nobody read it as a bug.
62
+ //
63
+ // `image-missing` is libadwaita's OWN answer to "I have no icon to draw here":
64
+ // C substitutes exactly that name for a NULL icon-name in three widgets
65
+ // (adw-button-content.c:294,356 · adw-view-switcher-button.c:286,347,405 ·
66
+ // adw-inline-view-switcher.c:142), and GTK's icon theme returns the same
67
+ // broken-image paintable for a name it cannot find. So the three renderers end
68
+ // up on ONE glyph: GTK draws it from the system theme, the web draws it from
69
+ // here, and NativeScript cannot reach the state at all — its AdwIcon takes SVG
70
+ // SOURCE, not a name, so a missing icon there is a missing import the compiler
71
+ // rejects. Nothing THROWS, on any of the three: an icon is decorative and taking
72
+ // an application down over a glyph is a failure mode none of them has.
73
+ //
74
+ // `:where()` and not `.adw-icon`, and that is the load-bearing detail:
75
+ // `adwaita-skin.scss` @uses `icons.generated` BEFORE `icon`, so at equal
76
+ // specificity this rule would come last and override every generated mask class
77
+ // — every icon in the package would draw the broken glyph. `:where()` scores
78
+ // 0,0,0, so ANY `.adw-icon--<name>` rule beats it wherever it sits in the
79
+ // cascade, including one `registerIcon()` inserts at runtime.
80
+ :where(.adw-icon) {
81
+ mask-image: var(--icon-image-missing);
82
+ -webkit-mask-image: var(--icon-image-missing);
83
+ }
84
+
85
+ // …and NO name at all draws nothing, rather than the broken glyph. `<adw-icon>`
86
+ // leaves the node classless only when `icon-name` is ABSENT or EMPTY, which is the
87
+ // state where the HOST decided against an icon — the tab strip's indicator slot,
88
+ // the avatar's fallback while initials show. `Gtk.Image` with a NULL icon-name
89
+ // draws nothing too.
90
+ //
91
+ // A name that was GIVEN never reaches this rule, even an unusable one: the element
92
+ // puts `adw-icon--image-missing` on it, because `gtk_icon_theme_lookup_icon` has no
93
+ // "found nothing" answer either. Until it did, `<adw-button-row start-icon-name="a b">`
94
+ // reserved a VISIBLE 16px slot and painted none of it — this rule turning the
95
+ // pre-existing solid square into an invisible hole.
96
+ .adw-icon:not([class*='adw-icon--']) {
97
+ background-color: transparent;
98
+ }
@@ -2,7 +2,6 @@
2
2
  // DO NOT EDIT — regenerated on every build from @gjsify/adwaita-icons.
3
3
 
4
4
  :root {
5
- --icon-edit-paste: url("data:image/svg+xml,%3Csvg%20height%3D'16px'%20viewBox%3D'0%200%2016%2016'%20width%3D'16px'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%20%3Cpath%20d%3D'm%207%200%20c%20-0.554688%200%20-1%200.445312%20-1%201%20h%20-2%20c%20-1.644531%200%20-3%201.355469%20-3%203%20v%209%20c%200%201.644531%201.355469%203%203%203%20h%208%20c%201.644531%200%203%20-1.355469%203%20-3%20v%20-9%20c%200%20-1.644531%20-1.355469%20-3%20-3%20-3%20h%20-2%20c%200%20-0.554688%20-0.445312%20-1%20-1%20-1%20z%20m%20-3%203%20h%201%20v%201%20c%200%200.554688%200.445312%201%201%201%20h%204%20c%200.554688%200%201%20-0.445312%201%20-1%20v%20-1%20h%201%20c%200.570312%200%201%200.429688%201%201%20v%209%20c%200%200.570312%20-0.429688%201%20-1%201%20h%20-8%20c%20-0.570312%200%20-1%20-0.429688%20-1%20-1%20v%20-9%20c%200%20-0.570312%200.429688%20-1%201%20-1%20z%20m%200%200'%20fill%3D'currentColor'%2F%3E%20%3C%2Fsvg%3E");
6
5
  --icon-go-down: url("data:image/svg+xml,%3Csvg%20height%3D'16px'%20viewBox%3D'0%200%2016%2016'%20width%3D'16px'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%20%3Cpath%20d%3D'm%201%205%20c%200%20-0.265625%200.105469%20-0.519531%200.292969%20-0.707031%20c%200.390625%20-0.390625%201.023437%20-0.390625%201.414062%200%20l%205.292969%205.292969%20l%205.292969%20-5.292969%20c%200.390625%20-0.390625%201.023437%20-0.390625%201.414062%200%20c%200.1875%200.1875%200.292969%200.441406%200.292969%200.707031%20s%20-0.105469%200.519531%20-0.292969%200.707031%20l%20-6%206%20c%20-0.390625%200.390625%20-1.023437%200.390625%20-1.414062%200%20l%20-6%20-6%20c%20-0.1875%20-0.1875%20-0.292969%20-0.441406%20-0.292969%20-0.707031%20z%20m%200%200'%20fill%3D'currentColor'%2F%3E%20%3C%2Fsvg%3E");
7
6
  --icon-sidebar-show: url("data:image/svg+xml,%3Csvg%20height%3D'16px'%20viewBox%3D'0%200%2016%2016'%20width%3D'16px'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%20%3Cg%20fill%3D'currentColor'%3E%20%3Cpath%20d%3D'm%206%2013%20v%20-10%20h%20-3%20c%20-0.550781%200%20-1%200.449219%20-1%201%20v%208%20c%200%200.550781%200.449219%201%201%201%20z%20m%200%200'%20fill-opacity%3D'0.34902'%2F%3E%20%3Cpath%20d%3D'm%203%201%20c%20-1.644531%200%20-3%201.355469%20-3%203%20v%208%20c%200%201.644531%201.355469%203%203%203%20h%2010%20c%201.644531%200%203%20-1.355469%203%20-3%20v%20-8%20c%200%20-1.644531%20-1.355469%20-3%20-3%20-3%20z%20m%200%202%20h%203%20v%2010%20h%20-3%20c%20-0.570312%200%20-1%20-0.429688%20-1%20-1%20v%20-8%20c%200%20-0.570312%200.429688%20-1%201%20-1%20z%20m%204%200%20h%206%20c%200.570312%200%201%200.429688%201%201%20v%208%20c%200%200.570312%20-0.429688%201%20-1%201%20h%20-6%20z%20m%200%200'%2F%3E%20%3C%2Fg%3E%20%3C%2Fsvg%3E");
8
7
  --icon-go-previous: url("data:image/svg+xml,%3Csvg%20height%3D'16px'%20viewBox%3D'0%200%2016%2016'%20width%3D'16px'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%20%3Cpath%20d%3D'm%2012%202%20c%200%20-0.265625%20-0.105469%20-0.519531%20-0.292969%20-0.707031%20c%20-0.390625%20-0.390625%20-1.023437%20-0.390625%20-1.414062%200%20l%20-6%206%20c%20-0.1875%200.1875%20-0.292969%200.441406%20-0.292969%200.707031%20s%200.105469%200.519531%200.292969%200.707031%20l%206%206%20c%200.390625%200.390625%201.023437%200.390625%201.414062%200%20c%200.1875%20-0.1875%200.292969%20-0.441406%200.292969%20-0.707031%20s%20-0.105469%20-0.519531%20-0.292969%20-0.707031%20l%20-5.292969%20-5.292969%20l%205.292969%20-5.292969%20c%200.1875%20-0.1875%200.292969%20-0.441406%200.292969%20-0.707031%20z%20m%200%200'%20fill%3D'currentColor'%2F%3E%20%3C%2Fsvg%3E");
@@ -27,9 +26,12 @@
27
26
  --icon-document-save: url("data:image/svg+xml,%3Csvg%20height%3D'16px'%20viewBox%3D'0%200%2016%2016'%20width%3D'16px'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%20%3Cpath%20d%3D'm%208%200%20c%20-0.550781%200%20-1%200.449219%20-1%201%20v%208.585938%20l%20-1.292969%20-1.292969%20c%20-0.1875%20-0.1875%20-0.441406%20-0.292969%20-0.707031%20-0.292969%20s%20-0.519531%200.105469%20-0.707031%200.292969%20c%20-0.390625%200.390625%20-0.390625%201.023437%200%201.414062%20l%203%203%20c%200.390625%200.390625%201.023437%200.390625%201.414062%200%20l%203%20-3%20c%200.390625%20-0.390625%200.390625%20-1.023437%200%20-1.414062%20s%20-1.023437%20-0.390625%20-1.414062%200%20l%20-1.292969%201.292969%20v%20-8.585938%20c%200%20-0.550781%20-0.449219%20-1%20-1%20-1%20z%20m%20-7%2014%20v%202%20h%2014%20v%20-2%20z%20m%200%200'%20fill%3D'currentColor'%2F%3E%20%3C%2Fsvg%3E");
28
27
  --icon-mail-send: url("data:image/svg+xml,%3Csvg%20height%3D'16px'%20viewBox%3D'0%200%2016%2016'%20width%3D'16px'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%20%3Cpath%20d%3D'm%208%200%20c%20-0.257812%200%20-0.511719%200.0976562%20-0.707031%200.292969%20l%20-1.25%201.25%20l%20-1.761719%201.730469%20c%20-0.191406%200.199218%20-0.28125%200.441406%20-0.28125%200.75%20c%200%200.976562%201%201%201%201%20c%200.257812%200%200.527344%20-0.128907%200.71875%20-0.3125%20l%201.28125%20-1.28125%20v%203.570312%20s%200%201%201%201%20s%201%20-1%201%20-1%20v%20-3.570312%20l%201.28125%201.28125%20c%200.191406%200.183593%200.410156%200.3125%200.71875%200.3125%20c%200%200%201%20-0.023438%201%20-1%20c%200%20-0.308594%20-0.089844%20-0.550782%20-0.28125%20-0.75%20l%20-1.761719%20-1.730469%20l%20-1.25%20-1.25%20c%20-0.195312%20-0.1953128%20-0.449219%20-0.292969%20-0.707031%20-0.292969%20z%20m%20-5%209%20c%20-1.644531%200%20-3%201.355469%20-3%203%20v%204%20h%202%20v%20-3.800781%20l%204.613281%203.078125%20c%200.835938%200.558594%201.9375%200.558594%202.773438%200%20l%204.613281%20-3.078125%20v%203.800781%20h%202%20v%20-4%20c%200%20-1.644531%20-1.355469%20-3%20-3%20-3%20z%20m%200.800781%202%20h%208.398438%20l%20-3.921875%202.613281%20c%20-0.171875%200.113281%20-0.382813%200.113281%20-0.554688%200%20z%20m%200%200'%20fill%3D'currentColor'%2F%3E%20%3C%2Fsvg%3E");
29
28
  --icon-mail-reply-sender: url("data:image/svg+xml,%3Csvg%20height%3D'16px'%20viewBox%3D'0%200%2016%2016'%20width%3D'16px'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%20%3Cpath%20d%3D'm%205%202%20c%20-0.265625%200%20-0.519531%200.105469%20-0.707031%200.292969%20l%20-4%204%20c%20-0.3906252%200.390625%20-0.3906252%201.023437%200%201.414062%20l%204%204%20c%200.390625%200.390625%201.023437%200.390625%201.414062%200%20s%200.390625%20-1.023437%200%20-1.414062%20l%20-2.292969%20-2.292969%20h%208.585938%20c%201.117188%200%202%200.882812%202%202%20v%203%20c%200%200.550781%200.449219%201%201%201%20s%201%20-0.449219%201%20-1%20v%20-3%20c%200%20-0.023438%200%20-0.046875%20-0.003906%20-0.070312%20c%20-0.035156%20-2.164063%20-1.820313%20-3.929688%20-3.996094%20-3.929688%20h%20-8.585938%20l%202.292969%20-2.292969%20c%200.390625%20-0.390625%200.390625%20-1.023437%200%20-1.414062%20c%20-0.1875%20-0.1875%20-0.441406%20-0.292969%20-0.707031%20-0.292969%20z%20m%200%200'%20fill%3D'currentColor'%2F%3E%20%3C%2Fsvg%3E");
29
+ --icon-folder-documents: url("data:image/svg+xml,%3Csvg%20height%3D'16px'%20viewBox%3D'0%200%2016%2016'%20width%3D'16px'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%20%3Cpath%20d%3D'm%204.96875%201.003906%20c%20-1.644531%200%20-3%201.355469%20-3%203%20v%209%20c%200%201.644532%201.355469%203%203%203%20h%206%20c%201.644531%200%203%20-1.355468%203%20-3%20v%20-7.5%20c%200%20-0.265625%20-0.105469%20-0.519531%20-0.292969%20-0.707031%20l%20-3.5%20-3.5%20c%20-0.1875%20-0.1875%20-0.441406%20-0.292969%20-0.707031%20-0.292969%20z%20m%200%202%20h%204%20v%201.5%20c%200%201%200.5%201.5%201.5%201.5%20h%201.5%20v%207%20c%200%200.570313%20-0.429688%201%20-1%201%20h%20-6%20c%20-0.570312%200%20-1%20-0.429687%20-1%20-1%20v%20-9%20c%200%20-0.570312%200.429688%20-1%201%20-1%20z%20m%200%200'%20fill%3D'currentColor'%2F%3E%20%3C%2Fsvg%3E");
30
30
  --icon-folder-download: url("data:image/svg+xml,%3Csvg%20height%3D'16px'%20viewBox%3D'0%200%2016%2016'%20width%3D'16px'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%20%3Cpath%20d%3D'm%207.984375%200%20c%20-0.550781%200%20-1%200.449219%20-1%201%20v%208.585938%20l%20-2.292969%20-2.292969%20c%20-0.1875%20-0.1875%20-0.441406%20-0.292969%20-0.707031%20-0.292969%20s%20-0.519531%200.105469%20-0.707031%200.292969%20c%20-0.390625%200.390625%20-0.390625%201.023437%200%201.414062%20l%204%204%20c%200.390625%200.390625%201.023437%200.390625%201.414062%200%20l%204%20-4%20c%200.390625%20-0.390625%200.390625%20-1.023437%200%20-1.414062%20s%20-1.023437%20-0.390625%20-1.414062%200%20l%20-2.292969%202.292969%20v%20-8.585938%20c%200%20-0.550781%20-0.449219%20-1%20-1%20-1%20z%20m%20-6%2014%20v%202%20h%2012%20v%20-2%20z%20m%200%200'%20fill%3D'currentColor'%2F%3E%20%3C%2Fsvg%3E");
31
31
  --icon-view-grid: url("data:image/svg+xml,%3Csvg%20height%3D'16px'%20viewBox%3D'0%200%2016%2016'%20width%3D'16px'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%20%3Cpath%20d%3D'm%202%201%20c%20-0.554688%200%20-1%200.445312%20-1%201%20v%204%20c%200%200.554688%200.445312%201%201%201%20h%204%20c%200.554688%200%201%20-0.445312%201%20-1%20v%20-4%20c%200%20-0.554688%20-0.445312%20-1%20-1%20-1%20z%20m%208%200%20c%20-0.554688%200%20-1%200.445312%20-1%201%20v%204%20c%200%200.554688%200.445312%201%201%201%20h%204%20c%200.554688%200%201%20-0.445312%201%20-1%20v%20-4%20c%200%20-0.554688%20-0.445312%20-1%20-1%20-1%20z%20m%20-8%208%20c%20-0.554688%200%20-1%200.445312%20-1%201%20v%204%20c%200%200.554688%200.445312%201%201%201%20h%204%20c%200.554688%200%201%20-0.445312%201%20-1%20v%20-4%20c%200%20-0.554688%20-0.445312%20-1%20-1%20-1%20z%20m%208%200%20c%20-0.554688%200%20-1%200.445312%20-1%201%20v%204%20c%200%200.554688%200.445312%201%201%201%20h%204%20c%200.554688%200%201%20-0.445312%201%20-1%20v%20-4%20c%200%20-0.554688%20-0.445312%20-1%20-1%20-1%20z%20m%200%200'%20fill%3D'currentColor'%2F%3E%20%3C%2Fsvg%3E");
32
32
  --icon-view-list: url("data:image/svg+xml,%3Csvg%20height%3D'16px'%20viewBox%3D'0%200%2016%2016'%20width%3D'16px'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%20%3Cpath%20d%3D'm%202%201%20c%20-0.554688%200%20-1%200.445312%20-1%201%20v%202%20c%200%200.554688%200.445312%201%201%201%20h%202%20c%200.554688%200%201%20-0.445312%201%20-1%20v%20-2%20c%200%20-0.554688%20-0.445312%20-1%20-1%20-1%20z%20m%205%201%20v%202%20h%208%20v%20-2%20z%20m%20-5%204.015625%20c%20-0.554688%200%20-1%200.445313%20-1%201%20v%201.980469%20c%200%200.550781%200.445312%201%201%201%20h%202%20c%200.554688%200%201%20-0.449219%201%20-1%20v%20-1.980469%20c%200%20-0.554687%20-0.445312%20-1%20-1%20-1%20z%20m%205%200.984375%20v%202%20h%208%20v%20-2%20z%20m%20-5%204%20c%20-0.554688%200%20-1%200.445312%20-1%201%20v%201.980469%20c%200%200.550781%200.445312%201%201%201%20h%202%20c%200.554688%200%201%20-0.449219%201%20-1%20v%20-1.980469%20c%200%20-0.554688%20-0.445312%20-1%20-1%20-1%20z%20m%205%200.984375%20v%202%20h%208%20v%20-2%20z%20m%200%200'%20fill%3D'currentColor'%2F%3E%20%3C%2Fsvg%3E");
33
+ --icon-view-more: url("data:image/svg+xml,%3Csvg%20height%3D'16px'%20viewBox%3D'0%200%2016%2016'%20width%3D'16px'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%20%3Cpath%20d%3D'm%207.996094%200%20c%20-1.105469%200%20-2%200.894531%20-2%202%20s%200.894531%202%202%202%20c%201.101562%200%202%20-0.894531%202%20-2%20s%20-0.898438%20-2%20-2%20-2%20z%20m%200%206%20c%20-1.105469%200%20-2%200.894531%20-2%202%20s%200.894531%202%202%202%20c%201.101562%200%202%20-0.894531%202%20-2%20s%20-0.898438%20-2%20-2%20-2%20z%20m%200%206%20c%20-1.105469%200%20-2%200.894531%20-2%202%20s%200.894531%202%202%202%20c%201.101562%200%202%20-0.894531%202%20-2%20s%20-0.898438%20-2%20-2%20-2%20z%20m%200%200'%20fill%3D'currentColor'%2F%3E%20%3C%2Fsvg%3E");
34
+ --icon-view-paged: url("data:image/svg+xml,%3Csvg%20height%3D'16px'%20viewBox%3D'0%200%2016%2016'%20width%3D'16px'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%20%3Cg%20fill%3D'currentColor'%3E%20%3Cpath%20d%3D'm%209%205.5%20v%20-1%20c%200%20-0.277344%20-0.222656%20-0.5%20-0.5%20-0.5%20h%20-3%20c%20-0.277344%200%20-0.5%200.222656%20-0.5%200.5%20v%201%20c%200%200.277344%200.222656%200.5%200.5%200.5%20h%203%20c%200.277344%200%200.5%20-0.222656%200.5%20-0.5%20z%20m%200%200'%20fill-opacity%3D'0.34902'%2F%3E%20%3Cpath%20d%3D'm%204%200%20c%20-1.644531%200%20-3%201.355469%20-3%203%20v%207%20c%200%201.644531%201.355469%203%203%203%20h%206%20c%201.644531%200%203%20-1.355469%203%20-3%20v%20-7%20c%200%20-1.644531%20-1.355469%20-3%20-3%20-3%20z%20m%200%202%20h%206%20c%200.570312%200%201%200.429688%201%201%20v%207%20c%200%200.570312%20-0.429688%201%20-1%201%20h%20-6%20c%20-0.570312%200%20-1%20-0.429688%20-1%20-1%20v%20-7%20c%200%20-0.570312%200.429688%20-1%201%20-1%20z%20m%2011%202%20c%20-0.550781%200%20-1%200.449219%20-1%201%20v%208%20c%200%200.550781%20-0.449219%201%20-1%201%20h%20-7%20c%20-0.550781%200%20-1%200.449219%20-1%201%20s%200.449219%201%201%201%20h%207%20c%201.65625%200%203%20-1.34375%203%20-3%20v%20-8%20c%200%20-0.550781%20-0.449219%20-1%20-1%20-1%20z%20m%200%200'%2F%3E%20%3Cpath%20d%3D'm%209%208.5%20v%20-1%20c%200%20-0.277344%20-0.222656%20-0.5%20-0.5%20-0.5%20h%20-3%20c%20-0.277344%200%20-0.5%200.222656%20-0.5%200.5%20v%201%20c%200%200.277344%200.222656%200.5%200.5%200.5%20h%203%20c%200.277344%200%200.5%20-0.222656%200.5%20-0.5%20z%20m%200%200'%20fill-opacity%3D'0.34902'%2F%3E%20%3C%2Fg%3E%20%3C%2Fsvg%3E");
33
35
  --icon-view-columns: url("data:image/svg+xml,%3Csvg%20height%3D'16px'%20viewBox%3D'0%200%2016%2016'%20width%3D'16px'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%20%3Cpath%20d%3D'm%202%201%20c%20-0.554688%200%20-1%200.445312%20-1%201%20v%2012%20c%200%200.554688%200.445312%201%201%201%20h%202%20c%200.554688%200%201%20-0.445312%201%20-1%20v%20-12%20c%200%20-0.554688%20-0.445312%20-1%20-1%20-1%20z%20m%205%200%20c%20-0.554688%200%20-1%200.445312%20-1%201%20v%2012%20c%200%200.554688%200.445312%201%201%201%20h%202%20c%200.554688%200%201%20-0.445312%201%20-1%20v%20-12%20c%200%20-0.554688%20-0.445312%20-1%20-1%20-1%20z%20m%205%200%20c%20-0.554688%200%20-1%200.445312%20-1%201%20v%2012%20c%200%200.554688%200.445312%201%201%201%20h%202%20c%200.554688%200%201%20-0.445312%201%20-1%20v%20-12%20c%200%20-0.554688%20-0.445312%20-1%20-1%20-1%20z%20m%200%200'%20fill%3D'currentColor'%2F%3E%20%3C%2Fsvg%3E");
34
36
  --icon-list-remove: url("data:image/svg+xml,%3Csvg%20height%3D'16px'%20viewBox%3D'0%200%2016%2016'%20width%3D'16px'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%20%3Cpath%20d%3D'm%201%207%20h%2014%20v%202%20h%20-14%20z%20m%200%200'%20fill%3D'currentColor'%2F%3E%20%3C%2Fsvg%3E");
35
37
  --icon-send-to: url("data:image/svg+xml,%3Csvg%20height%3D'16px'%20viewBox%3D'0%200%2016%2016'%20width%3D'16px'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%20%3Cpath%20d%3D'm%208%200%20c%20-0.257812%200%20-0.511719%200.0976562%20-0.707031%200.292969%20l%20-1.246094%201.25%20l%20-1.765625%201.730469%20c%20-0.191406%200.199218%20-0.28125%200.441406%20-0.28125%200.75%20c%200%200.976562%201%201%201%201%20c%200.257812%200%200.527344%20-0.128907%200.71875%20-0.3125%20l%201.28125%20-1.28125%20v%207.570312%20s%200%201%201%201%20s%201%20-1%201%20-1%20v%20-7.570312%20l%201.28125%201.28125%20c%200.191406%200.183593%200.410156%200.3125%200.71875%200.3125%20c%200%200%201%20-0.023438%201%20-1%20c%200%20-0.308594%20-0.089844%20-0.550782%20-0.28125%20-0.75%20l%20-1.765625%20-1.730469%20l%20-1.246094%20-1.25%20c%20-0.195312%20-0.1953128%20-0.449219%20-0.292969%20-0.707031%20-0.292969%20z%20m%20-3.96875%206.964844%20c%20-1.660156%20-0.027344%20-3.03125%201.371094%20-3.03125%203.035156%20v%202.972656%20c%200%201.664063%201.371094%203.035156%203.03125%203.035156%20h%207.9375%20c%201.664062%200%203.03125%20-1.371093%203.03125%20-3.035156%20v%20-2.972656%20c%200%20-1.664062%20-1.367188%20-3.0625%20-3.03125%20-3.035156%20l%20-1.96875%200.035156%20v%202%20l%201.96875%20-0.035156%20c%200.589844%20-0.007813%201.03125%200.445312%201.03125%201.035156%20v%202.972656%20c%200%200.589844%20-0.441406%201.035156%20-1.03125%201.035156%20h%20-7.9375%20c%20-0.585938%200%20-1.03125%20-0.445312%20-1.03125%20-1.035156%20v%20-2.972656%20c%200%20-0.589844%200.445312%20-1.042969%201.03125%20-1.035156%20l%201.96875%200.035156%20v%20-2%20z%20m%200%200'%20fill%3D'currentColor'%2F%3E%20%3C%2Fsvg%3E");
@@ -44,11 +46,6 @@
44
46
  --icon-image-missing: url("data:image/svg+xml,%3Csvg%20height%3D'16px'%20viewBox%3D'0%200%2016%2016'%20width%3D'16px'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%20%3Cpath%20d%3D'm%204.015625%201.03125%20c%20-1.644531%200%20-3%201.355469%20-3%203%20v%201%20h%201%20v%20-1%20c%200%20-1.109375%200.890625%20-2%202%20-2%20h%201%20v%20-1%20z%20m%202%200%20v%201%20h%204%20v%20-1%20z%20m%205%200%20v%201%20h%201%20c%201.109375%200%202%200.890625%202%202%20v%201%20h%201%20v%20-1%20c%200%20-1.644531%20-1.355469%20-3%20-3%20-3%20z%20m%20-5%204%20c%20-0.550781%200%20-1%200.449219%20-1%201%20s%200.449219%201%201%201%20s%201%20-0.449219%201%20-1%20s%20-0.449219%20-1%20-1%20-1%20z%20m%20-5%201%20v%204%20h%201%20v%20-4%20z%20m%2013%200%20v%204%20h%201%20v%20-4%20z%20m%20-4.5%202%20l%20-2%202%20l%20-1.5%20-1%20l%20-2%202%20v%200.5%20c%200%200.5%200.5%200.5%200.5%200.5%20h%207%20s%200.472656%20-0.035156%200.5%20-0.5%20v%20-1%20z%20m%20-8.5%203%20v%201%20c%200%201.644531%201.355469%203%203%203%20h%201%20v%20-1%20h%20-1%20c%20-1.109375%200%20-2%20-0.890625%20-2%20-2%20v%20-1%20z%20m%2013%200%20v%201%20c%200%201.109375%20-0.890625%202%20-2%202%20h%20-1%20v%201%20h%201%20c%201.644531%200%203%20-1.355469%203%20-3%20v%20-1%20z%20m%20-8%203%20v%201%20h%204%20v%20-1%20z%20m%200%200'%20fill%3D'currentColor'%20fill-opacity%3D'0.34902'%2F%3E%20%3C%2Fsvg%3E");
45
47
  }
46
48
 
47
- .adw-icon--edit-paste {
48
- mask-image: var(--icon-edit-paste);
49
- -webkit-mask-image: var(--icon-edit-paste);
50
- }
51
-
52
49
  .adw-icon--go-down {
53
50
  mask-image: var(--icon-go-down);
54
51
  -webkit-mask-image: var(--icon-go-down);
@@ -169,6 +166,11 @@
169
166
  -webkit-mask-image: var(--icon-mail-reply-sender);
170
167
  }
171
168
 
169
+ .adw-icon--folder-documents {
170
+ mask-image: var(--icon-folder-documents);
171
+ -webkit-mask-image: var(--icon-folder-documents);
172
+ }
173
+
172
174
  .adw-icon--folder-download {
173
175
  mask-image: var(--icon-folder-download);
174
176
  -webkit-mask-image: var(--icon-folder-download);
@@ -184,6 +186,16 @@
184
186
  -webkit-mask-image: var(--icon-view-list);
185
187
  }
186
188
 
189
+ .adw-icon--view-more {
190
+ mask-image: var(--icon-view-more);
191
+ -webkit-mask-image: var(--icon-view-more);
192
+ }
193
+
194
+ .adw-icon--view-paged {
195
+ mask-image: var(--icon-view-paged);
196
+ -webkit-mask-image: var(--icon-view-paged);
197
+ }
198
+
187
199
  .adw-icon--view-columns {
188
200
  mask-image: var(--icon-view-columns);
189
201
  -webkit-mask-image: var(--icon-view-columns);
@@ -1,7 +1,7 @@
1
1
  // _password_entry_row.scss — adw-password-entry-row styling (masked entry row
2
2
  // with a trailing peek toggle). Mirrors _entry_row.scss (the password row is a
3
3
  // specialization of the entry row) and adds the flat peek button.
4
- // Reference: refs/adwaita-web/adwaita-web/scss/_password_entry_row.scss
4
+ // Reference: refs/adwaita-web/adwaita-web/scss/_entry_row.scss (no password variant upstream)
5
5
  // Reference: refs/libadwaita/src/adw-password-entry-row.c
6
6
  // Copyright (c) GNOME contributors (libadwaita). LGPLv2.1+.
7
7
  // Copyright (c) 2025 csm (adwaita-web). MIT License.
@@ -83,8 +83,9 @@ adw-preferences-dialog {
83
83
  padding: 0 6px;
84
84
  }
85
85
 
86
- // Round flat close button drawing a CSS "×" glyph (no symbolic close icon
87
- // ships in @gjsify/adwaita-icons — same approach as <adw-tab-view>).
86
+ // Round flat close button drawing a CSS "×" glyph — same approach as
87
+ // <adw-tab-view>, and for the sizing reason recorded there. `windowCloseSymbolic`
88
+ // does ship, and is compiled.
88
89
  .adw-preferences-dialog-close {
89
90
  appearance: none;
90
91
  border: none;
@@ -29,7 +29,7 @@
29
29
  // rule that rots.
30
30
  //
31
31
  // Reference: refs/libadwaita/src/stylesheet/widgets/_progress-bar.scss:5-6,17-21,23-25,27-35,59-85
32
- // Reference: refs/libadwaita/src/stylesheet/_scale.scss:1-17 (%scale_trough, %scale_highlight)
32
+ // Reference: refs/libadwaita/src/stylesheet/widgets/_scale.scss:1-17 (%scale_trough, %scale_highlight)
33
33
  // Reference: refs/libadwaita/src/stylesheet/_colors.scss:280-286 (the trough colours)
34
34
  // Reference: refs/adwaita-web/adwaita-web/scss/_progressbar.scss:25-66 (indeterminate keyframes + reduced-motion fallback ONLY)
35
35
  // Copyright (c) GNOME contributors (libadwaita). LGPLv2.1+.
package/scss/_row.scss CHANGED
@@ -1,6 +1,6 @@
1
1
  // _row.scss — Shared base styling for rows in preferences groups.
2
2
  // Reference: refs/adwaita-web/adwaita-web/scss/_row_types.scss
3
- // Reference: refs/libadwaita/src/stylesheet/widgets/_action-row.scss
3
+ // Reference: refs/libadwaita/src/stylesheet/widgets/_lists.scss (AdwActionRow)
4
4
  // Copyright (c) GNOME contributors (libadwaita). LGPLv2.1+.
5
5
  // Copyright (c) 2025 csm (adwaita-web). MIT License.
6
6
  // Modifications: Adapted for @gjsify/adwaita-web Web Components.
@@ -1,6 +1,6 @@
1
1
  // _status_page.scss — adw-status-page styling (centered empty state).
2
2
  // Reference: refs/adwaita-web/adwaita-web/scss/_status_page.scss
3
- // Reference: refs/libadwaita/src/stylesheet/widgets/_status-page.scss
3
+ // Reference: refs/libadwaita/src/stylesheet/widgets/_misc.scss (AdwStatusPage)
4
4
  // Copyright (c) GNOME contributors (libadwaita). LGPLv2.1+.
5
5
  // Modifications: Adapted for @gjsify/adwaita-web Web Components.
6
6
 
@@ -183,7 +183,7 @@ adw-tab-view {
183
183
  background-color: var(--accent-bg-color);
184
184
  }
185
185
 
186
- // --- Close affordance (CSS-drawn "×", no symbolic icon ships) ---
186
+ // --- Close affordance (CSS-drawn "×"; `window-close` ships, see adw-tab-view.ts) ---
187
187
  // Presence is decided in JS by `tabCloseVisible` — `(hovering && fullyVisible)
188
188
  // || selected || dragging`, and never on a pinned tab (adw-tab.c:124, :645-650)
189
189
  // — which is why the `[hidden]` rule below is load-bearing rather than cosmetic.
package/scss/_toast.scss CHANGED
@@ -5,7 +5,7 @@
5
5
  // up on show / down on dismiss (mirroring Adw.Toast).
6
6
  // Reference: refs/adwaita-web/adwaita-web/scss/_toast.scss
7
7
  // Reference: refs/adwaita-web/adwaita-web/scss/_toast_overlay.scss
8
- // Reference: refs/libadwaita/src/stylesheet/widgets/_toast.scss
8
+ // Reference: refs/libadwaita/src/stylesheet/widgets/_misc.scss (Toasts)
9
9
  // Copyright (c) GNOME contributors (libadwaita). LGPLv2.1+.
10
10
  // Copyright (c) 2025 csm (adwaita-web). MIT License.
11
11
  // Modifications: Adapted for @gjsify/adwaita-web Web Components.
@@ -120,12 +120,14 @@ adw-toast-overlay {
120
120
  }
121
121
  }
122
122
 
123
- // Close affordance — a CSS-drawn "×" (mirrors adw-tab-view's .adw-tab-close;
124
- // no symbolic close icon ships in the curated adwaita-web icon set).
123
+ // Close affordance — `window-close-symbolic` in a 24px circle, as upstream builds it
124
+ // (adw-toast-widget.ui:64). The element supplies the <adw-icon>; this only places it.
125
125
  .adw-toast-close-button {
126
126
  box-sizing: border-box;
127
127
  flex-shrink: 0;
128
- position: relative;
128
+ display: flex;
129
+ align-items: center;
130
+ justify-content: center;
129
131
  width: 24px;
130
132
  height: 24px;
131
133
  margin: 0;
@@ -149,25 +151,5 @@ adw-toast-overlay {
149
151
  outline: 2px solid var(--accent-color);
150
152
  outline-offset: 1px;
151
153
  }
152
-
153
- &::before,
154
- &::after {
155
- content: '';
156
- position: absolute;
157
- top: 50%;
158
- left: 50%;
159
- width: 11px;
160
- height: 1.5px;
161
- background-color: currentColor;
162
- border-radius: 1px;
163
- }
164
-
165
- &::before {
166
- transform: translate(-50%, -50%) rotate(45deg);
167
- }
168
-
169
- &::after {
170
- transform: translate(-50%, -50%) rotate(-45deg);
171
- }
172
154
  }
173
155
  }
@@ -144,9 +144,29 @@
144
144
  // by AdwStyleManager from the desktop's font settings
145
145
  // (adw-style-manager.c:169-218), defaulting to `Sans 10` / `Monospace 10`
146
146
  // (:50-56). A browser has no style manager, so they are ordinary tokens here
147
- // — same names, so re-theming goes through the documented contract. The
148
- // monospace stack is the one `_data_grid.scss` used to inline; it has ONE home
149
- // now, and Adwaita Mono heads it because `@gjsify/adwaita-fonts` ships it.
147
+ // — same names, so re-theming goes through the documented contract.
148
+ //
149
+ // The monospace stack has ONE home, and did not until recently: `_data_grid.scss`
150
+ // used to inline it, and `source-view/theme.ts` carried a SECOND, longer copy in
151
+ // a TS string literal (measured on one page, `.cm-scroller` resolved to
152
+ // 'Adwaita Mono', 'Cascadia Code', 'JetBrains Mono', … while a `.monospace`
153
+ // label beside it resolved to this token — two typefaces, same document).
154
+ // A literal in TS is also outside the `stylesheet-font-families` rule, which
155
+ // reads `.css`/`.scss`. Both now read this token; its consumers are
156
+ // `.monospace` (_labels.scss:128), `_action_row.scss:94`, the data-grid mono
157
+ // cell (via `@extend .monospace`) and `<adw-source-view>`.
158
+ //
159
+ // Adwaita Mono heads the stack as a PROGRESSIVE ENHANCEMENT, not because
160
+ // anything here ships it: `@gjsify/adwaita-fonts` vendors two Sans TTFs and no
161
+ // mono face at all (the upstream mono faces are 1.4-1.5 MB each). This comment
162
+ // used to claim the package ships it — a claim the NativeScript theme, which
163
+ // carries the same stack, already contradicted in prose
164
+ // (`nativescript-bridge/adwaita/src/theme/adwaita.css:769`). So on a GNOME
165
+ // desktop the system `adwaita-mono-fonts` resolves it; anywhere else the
166
+ // generic tail is what renders, which is the correct outcome and the reason the
167
+ // tail exists. Held honest by the `stylesheet-font-families` conformance rule,
168
+ // whose ledger carries this reason — never delete one without the other.
169
+ //
150
170
  // `'Cantarell'` is dropped from that stack on the way here: Cantarell is
151
171
  // GNOME's PROPORTIONAL UI font, so a monospace fallback chain that reaches it
152
172
  // second lands on a font whose figures do not line up — the exact property
@@ -26,6 +26,9 @@ import {
26
26
 
27
27
  import { normalizeIconName } from '@gjsify/adwaita-core';
28
28
 
29
+ import { isIconAvailable } from './icon-registry.js';
30
+ import { fallbackMask, maskOf } from './icon-registry.spec.js';
31
+
29
32
  import type { AdwActionRow } from './elements/adw-action-row.js';
30
33
  import type { AdwSwitchRow } from './elements/adw-switch-row.js';
31
34
  import type { AdwWindowTitle } from './elements/adw-window-title.js';
@@ -259,15 +262,24 @@ export const AdwActionRowsTest = async () => {
259
262
  // The mask class is the NORMALIZED name — the generated classes never
260
263
  // carry `-symbolic`, so interpolating the raw one asks for a class that has
261
264
  // never existed and draws an empty box.
262
- if (vector.startIconVisible) {
263
- expect(icons[0]!.classList.contains(`adw-icon--${normalizeIconName(vector.startIconName)}`)).toBe(
264
- true,
265
- );
266
- }
267
- if (vector.endIconVisible) {
268
- expect(icons[1]!.classList.contains(`adw-icon--${normalizeIconName(vector.endIconName)}`)).toBe(
269
- true,
270
- );
265
+ //
266
+ // And the class is only HALF the answer. `external-link-symbolic` in these
267
+ // vectors is well formed, normalizes cleanly and gets its class — while no
268
+ // mask class of that name exists (it is in neither the Adwaita icon theme
269
+ // nor `@gjsify/adwaita-icons`), so it paints the image-missing glyph. This
270
+ // suite was green on that: the class-string assertion the icon work exists
271
+ // to end. `isIconAvailable` reads the live cascade, so it decides which of
272
+ // the two answers is right for THIS name instead of the test guessing.
273
+ for (const [index, declared, visible] of [
274
+ [0, vector.startIconName, vector.startIconVisible],
275
+ [1, vector.endIconName, vector.endIconVisible],
276
+ ] as const) {
277
+ if (!visible) continue;
278
+ const icon = icons[index]!;
279
+ const resolved = normalizeIconName(declared);
280
+ expect(icon.classList.contains(`adw-icon--${resolved}`)).toBe(true);
281
+ expect(maskOf(icon)).not.toBe('none');
282
+ expect(maskOf(icon) === fallbackMask()).toBe(!isIconAvailable(resolved));
271
283
  }
272
284
  host.remove();
273
285
  });
@@ -20,6 +20,7 @@ import {
20
20
  BUTTON_CONTENT_TEXT_VECTORS,
21
21
  } from '@gjsify/adwaita-core/conformance';
22
22
  import type { AdwButtonContent } from './elements/adw-button-content.js';
23
+ import { fallbackMask, maskOf } from './icon-registry.spec.js';
23
24
 
24
25
  /** Mount a button content inside a plain Adwaita button, the way the stories do. */
25
26
  function mount(attributes: Record<string, string> = {}): {
@@ -123,13 +124,17 @@ export const AdwButtonContentTest = async () => {
123
124
  // asked for `.adw-icon--folder-download-symbolic`, a class that has
124
125
  // never existed, and drew an empty 16px box. `<adw-icon>` applies
125
126
  // `normalizeIconName`, which also makes the `' '` row assertable
126
- // instead of skipped: a space is not one CSS token, so it draws
127
- // nothing rather than injecting a second class.
127
+ // instead of skipped: a space is not one CSS token, so it lands on
128
+ // `image-missing` — the missing icon that row's own rule records GTK
129
+ // drawing there, by lookup failure rather than by this branch.
128
130
  const maskName = normalizeIconName(resolved);
129
- expect(icon.classList.contains(`adw-icon--${maskName}`)).toBe(maskName !== '');
130
- expect([...icon.classList].filter((c) => c.startsWith('adw-icon--')).length).toBe(
131
- maskName === '' ? 0 : 1,
132
- );
131
+ const drawn = maskName === '' ? 'image-missing' : maskName;
132
+ expect(icon.classList.contains(`adw-icon--${drawn}`)).toBe(true);
133
+ expect([...icon.classList].filter((c) => c.startsWith('adw-icon--')).length).toBe(1);
134
+ // …and it DRAWS that. The class alone is what the original bug survived:
135
+ // applied correctly, to a name with no glyph behind it.
136
+ expect(maskOf(icon)).not.toBe('none');
137
+ expect(maskOf(icon) === fallbackMask()).toBe(drawn === 'image-missing');
133
138
  // The image node is never hidden — `gtk_widget_set_visible` is
134
139
  // called on the LABEL only.
135
140
  expect(icon.hidden).toBe(false);