@gjsify/adwaita-web 0.45.0 → 0.47.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 (110) hide show
  1. package/README.md +8 -6
  2. package/dist/adwaita-web.css +96 -96
  3. package/dist/adwaita-web.css.map +1 -1
  4. package/lib/types/elements/adw-entry-row.d.ts +2 -2
  5. package/lib/types/elements/adw-expander-row.d.ts +1 -1
  6. package/lib/types/elements/adw-split-button.d.ts +1 -1
  7. package/lib/types/elements/adw-switch-row.d.ts +1 -1
  8. package/lib/types/elements/adw-wrap-box.d.ts +1 -1
  9. package/lib/types/elements/{adw-checks.d.ts → checks.d.ts} +9 -2
  10. package/lib/types/elements/{adw-button.d.ts → gtk-button.d.ts} +1 -1
  11. package/lib/types/elements/{adw-drop-down.d.ts → gtk-drop-down.d.ts} +6 -6
  12. package/lib/types/elements/{adw-entry.d.ts → gtk-entry.d.ts} +1 -1
  13. package/lib/types/elements/{adw-icon.d.ts → gtk-image.d.ts} +2 -2
  14. package/lib/types/elements/{adw-menu-button.d.ts → gtk-menu-button.d.ts} +13 -4
  15. package/lib/types/elements/{adw-popover.d.ts → gtk-popover.d.ts} +9 -9
  16. package/lib/types/elements/{adw-progress-bar.d.ts → gtk-progress-bar.d.ts} +1 -1
  17. package/lib/types/elements/{adw-switch.d.ts → gtk-switch.d.ts} +2 -2
  18. package/lib/types/elements/view-switcher-dom.d.ts +4 -4
  19. package/lib/types/exported-elements.d.ts +10 -0
  20. package/lib/types/gtk-button.spec.d.ts +1 -0
  21. package/lib/types/gtk-drop-down.spec.d.ts +1 -0
  22. package/lib/types/gtk-entry.spec.d.ts +1 -0
  23. package/lib/types/gtk-image.spec.d.ts +1 -0
  24. package/lib/types/gtk-menu-button.spec.d.ts +1 -0
  25. package/lib/types/gtk-progress-bar.spec.d.ts +1 -0
  26. package/lib/types/gtk-switch.spec.d.ts +1 -0
  27. package/lib/types/icon-registry.d.ts +2 -2
  28. package/lib/types/index.d.ts +13 -51
  29. package/lib/types/namespace/adw.d.ts +44 -0
  30. package/lib/types/namespace/gtk.d.ts +9 -0
  31. package/lib/types/styles.generated.d.ts +1 -1
  32. package/package.json +6 -6
  33. package/scss/_about_dialog.scss +1 -1
  34. package/scss/_button.scss +4 -4
  35. package/scss/_checks.scss +6 -6
  36. package/scss/_drop_down.scss +3 -3
  37. package/scss/_entry.scss +3 -3
  38. package/scss/_expander_row.scss +1 -1
  39. package/scss/_icon.scss +4 -4
  40. package/scss/_menu_button.scss +3 -3
  41. package/scss/_popover.scss +2 -2
  42. package/scss/_progress_bar.scss +4 -4
  43. package/scss/_reset.scss +10 -8
  44. package/scss/_split_button.scss +1 -1
  45. package/scss/_style_classes.scss +9 -9
  46. package/scss/_switch.scss +2 -2
  47. package/scss/_switch_row.scss +1 -1
  48. package/scss/_toast.scss +1 -1
  49. package/scss/adwaita-skin.scss +2 -2
  50. package/src/adw-action-rows.spec.ts +2 -2
  51. package/src/adw-button-content.spec.ts +1 -1
  52. package/src/bottom-sheet.spec.ts +2 -2
  53. package/src/{adw-checks.spec.ts → checks.spec.ts} +11 -11
  54. package/src/chrome.spec.ts +2 -2
  55. package/src/connect-lifecycle.spec.ts +10 -7
  56. package/src/elements/adw-about-dialog.ts +6 -6
  57. package/src/elements/adw-avatar.ts +4 -4
  58. package/src/elements/adw-button-content.ts +6 -6
  59. package/src/elements/adw-button-row.ts +6 -6
  60. package/src/elements/adw-combo-row.ts +1 -1
  61. package/src/elements/adw-entry-row.ts +5 -5
  62. package/src/elements/adw-expander-row.ts +10 -10
  63. package/src/elements/adw-navigation-view.ts +1 -1
  64. package/src/elements/adw-password-entry-row.ts +3 -3
  65. package/src/elements/adw-sidebar.ts +4 -4
  66. package/src/elements/adw-split-button.ts +14 -14
  67. package/src/elements/adw-status-page.ts +4 -4
  68. package/src/elements/adw-switch-row.ts +8 -8
  69. package/src/elements/adw-tab-view.ts +7 -7
  70. package/src/elements/adw-toast-overlay.ts +2 -2
  71. package/src/elements/adw-toggle-group.ts +3 -3
  72. package/src/elements/adw-view-switcher-bar.ts +3 -3
  73. package/src/elements/adw-view-switcher.ts +3 -3
  74. package/src/elements/{adw-checks.ts → checks.ts} +13 -6
  75. package/src/elements/{adw-button.ts → gtk-button.ts} +6 -6
  76. package/src/elements/{adw-drop-down.ts → gtk-drop-down.ts} +18 -18
  77. package/src/elements/{adw-entry.ts → gtk-entry.ts} +4 -4
  78. package/src/elements/{adw-icon.ts → gtk-image.ts} +5 -5
  79. package/src/elements/{adw-menu-button.ts → gtk-menu-button.ts} +27 -18
  80. package/src/elements/{adw-popover.ts → gtk-popover.ts} +18 -18
  81. package/src/elements/{adw-progress-bar.ts → gtk-progress-bar.ts} +5 -5
  82. package/src/elements/{adw-switch.ts → gtk-switch.ts} +4 -4
  83. package/src/elements/view-switcher-dom.ts +5 -5
  84. package/src/exported-elements.ts +50 -0
  85. package/src/{adw-button.spec.ts → gtk-button.spec.ts} +6 -6
  86. package/src/{adw-drop-down.spec.ts → gtk-drop-down.spec.ts} +17 -17
  87. package/src/{adw-entry.spec.ts → gtk-entry.spec.ts} +8 -8
  88. package/src/{adw-icon.spec.ts → gtk-image.spec.ts} +21 -21
  89. package/src/{adw-menu-button.spec.ts → gtk-menu-button.spec.ts} +6 -6
  90. package/src/{adw-progress-bar.spec.ts → gtk-progress-bar.spec.ts} +12 -12
  91. package/src/{adw-switch.spec.ts → gtk-switch.spec.ts} +20 -20
  92. package/src/icon-registry.spec.ts +6 -6
  93. package/src/icon-registry.ts +6 -6
  94. package/src/index.ts +64 -63
  95. package/src/namespace/adw.ts +99 -0
  96. package/src/namespace/gtk.ts +22 -0
  97. package/src/preferences-search.ts +1 -1
  98. package/src/slotted-children.spec.ts +5 -3
  99. package/src/source-view/adw-source-view.ts +2 -2
  100. package/src/split-button.spec.ts +5 -5
  101. package/src/styles.generated.ts +1 -1
  102. package/src/test.browser.mts +15 -15
  103. package/lib/types/adw-button.spec.d.ts +0 -1
  104. package/lib/types/adw-drop-down.spec.d.ts +0 -1
  105. package/lib/types/adw-entry.spec.d.ts +0 -1
  106. package/lib/types/adw-icon.spec.d.ts +0 -1
  107. package/lib/types/adw-menu-button.spec.d.ts +0 -1
  108. package/lib/types/adw-progress-bar.spec.d.ts +0 -1
  109. package/lib/types/adw-switch.spec.d.ts +0 -1
  110. /package/lib/types/{adw-checks.spec.d.ts → checks.spec.d.ts} +0 -0
@@ -1,4 +1,4 @@
1
- // What an icon actually DRAWS — the assertion `adw-icon.spec.ts` did not make.
1
+ // What an icon actually DRAWS — the assertion `gtk-image.spec.ts` did not make.
2
2
  //
3
3
  // THE INCIDENT. `_icon.scss` set `background-color: currentColor` plus mask sizing and no
4
4
  // `mask-image`, so a name outside the compiled `.adw-icon--<name>` set painted a solid 16px
@@ -15,7 +15,7 @@
15
15
  import { describe, expect, it } from '@gjsify/unit';
16
16
 
17
17
  import { isIconAvailable, registerIcon } from './icon-registry.js';
18
- import type { AdwIcon } from './elements/adw-icon.js';
18
+ import type { GtkImage } from './elements/gtk-image.js';
19
19
 
20
20
  /** A name no compiled entry can collide with, for the "not shipped" arm. */
21
21
  const ABSENT = 'gjsify-registry-probe';
@@ -25,10 +25,10 @@ const PROBE_SVG = `<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="ht
25
25
  <path d="m 4 4 h 8 v 8 h -8 z m 0 0" fill="currentColor"/>
26
26
  </svg>`;
27
27
 
28
- function mount(iconName: string | null): { el: AdwIcon; host: HTMLElement } {
28
+ function mount(iconName: string | null): { el: GtkImage; host: HTMLElement } {
29
29
  const host = document.createElement('div');
30
30
  document.body.appendChild(host);
31
- const el = document.createElement('adw-icon') as AdwIcon;
31
+ const el = document.createElement('gtk-image') as GtkImage;
32
32
  if (iconName !== null) el.iconName = iconName;
33
33
  host.appendChild(el);
34
34
  return { el, host };
@@ -56,7 +56,7 @@ export function fallbackMask(): string {
56
56
  }
57
57
 
58
58
  export const AdwIconRegistryTest = async () => {
59
- await describe('<adw-icon> resolves a name to a real mask', async () => {
59
+ await describe('<gtk-image> resolves a name to a real mask', async () => {
60
60
  await it('a compiled name draws its OWN glyph, not the fallback', () => {
61
61
  const { el, host } = mount('go-next');
62
62
  const mask = maskOf(el);
@@ -111,7 +111,7 @@ export const AdwIconRegistryTest = async () => {
111
111
 
112
112
  await describe('a name carried by STATE still resolves', async () => {
113
113
  await it("the password row's peek toggle draws both of its glyphs", () => {
114
- // These two reach `<adw-icon>.iconName` as `state.peekIconName`, a property of
114
+ // These two reach `<gtk-image>.iconName` as `state.peekIconName`, a property of
115
115
  // the core's `PasswordEntryRowState`, so no literal spells them at the point of
116
116
  // use. `check-adwaita-icon-masks.mjs` reads their DECLARATIONS
117
117
  // (`PASSWORD_REVEAL_ICON_NAME`), which proves the map entry exists — never that
@@ -10,16 +10,16 @@
10
10
  // That is this module. `registerIcon` writes the SAME pair the generator writes — the
11
11
  // custom property on the document element, the mask class into a stylesheet this module
12
12
  // owns — so a registered icon is indistinguishable from a compiled one at every later
13
- // point: `<adw-icon icon-name="…">`, a hand-written `class="adw-icon adw-icon--…"`, a
13
+ // point: `<gtk-image icon-name="…">`, a hand-written `class="adw-icon adw-icon--…"`, a
14
14
  // widget attribute, `var(--icon-…)` in the consumer's own CSS.
15
15
  //
16
16
  // import { registerIcon } from '@gjsify/adwaita-web';
17
17
  // import { dialogErrorSymbolic } from '@gjsify/adwaita-icons/status';
18
18
  //
19
19
  // registerIcon('dialog-error-symbolic', dialogErrorSymbolic);
20
- // // …then anywhere: <adw-icon icon-name="dialog-error-symbolic"></adw-icon>
20
+ // // …then anywhere: <gtk-image icon-name="dialog-error-symbolic"></gtk-image>
21
21
  //
22
- // Register BEFORE the icon is mounted where you can. An `<adw-icon>` already in the
22
+ // Register BEFORE the icon is mounted where you can. A `<gtk-image>` already in the
23
23
  // document draws the `image-missing` fallback (see `_icon.scss`) until the registration
24
24
  // lands; the CSS is live, so it corrects itself on the next style recalculation with no
25
25
  // re-render, but there is a visible frame in between.
@@ -30,7 +30,7 @@
30
30
  import { normalizeIconName } from '@gjsify/adwaita-core';
31
31
  import { toDataUri } from '@gjsify/adwaita-icons/utils';
32
32
 
33
- import { MASK_CLASS_PREFIX } from './elements/adw-icon.js';
33
+ import { MASK_CLASS_PREFIX } from './elements/gtk-image.js';
34
34
 
35
35
  /** Marks the one `<style>` element this module owns, so a reload reuses it. */
36
36
  const REGISTRY_STYLE_ID = 'adwaita-web-icon-registry';
@@ -96,8 +96,8 @@ function svgRootOf(source: string): Element {
96
96
  * BOTH arguments are checked and a wrong one THROWS rather than registering nothing: unlike
97
97
  * a render, this is an explicit call with a wrong argument, and silently doing nothing is
98
98
  * the failure mode this whole area exists to end. The name is normalized exactly as
99
- * `<adw-icon icon-name>` normalizes it — a single `-symbolic` suffix comes off, and the rest
100
- * must be one CSS token; the SVG has to parse to an `<svg>` root. `<adw-icon>` draws
99
+ * `<gtk-image icon-name>` normalizes it — a single `-symbolic` suffix comes off, and the rest
100
+ * must be one CSS token; the SVG has to parse to an `<svg>` root. `<gtk-image>` draws
101
101
  * `image-missing` for the same unusable name instead — there it came from markup, and
102
102
  * taking the page down over a typo is not proportionate.
103
103
  *
package/src/index.ts CHANGED
@@ -63,8 +63,42 @@ export type { AdwUndershootEdges } from './scroll-shading.js';
63
63
  // `icon-registry.ts` for the full recipe.
64
64
  export { isIconAvailable, registerIcon } from './icon-registry.js';
65
65
 
66
- export { AdwAvatar } from './elements/adw-avatar.js';
67
- export { AdwBanner } from './elements/adw-banner.js';
66
+ // THE WIDGET CLASSES ARE REACHABLE ONLY AS `Adw.<Name>` / `Gtk.<Name>` (ADR 0034
67
+ // clause 2 + § Amendment 6). The namespace used to be the LAST line in the file, under a
68
+ // run of `export { AdwActionRow } …` re-exports it duplicated one for one; those are
69
+ // gone, and with them the second spelling. `<adw-action-row>` and `<gtk-entry>` are
70
+ // unchanged — this was never about the tags.
71
+ //
72
+ // IT IS ALSO WHAT PULLS THE ELEMENT MODULES IN, so importing this barrel still
73
+ // registers everything. The old order comment ("exported before the widgets that build
74
+ // them") described a sequence that is not load-bearing and never was: every host
75
+ // imports its prerequisite itself (`import './gtk-switch.js'` in the switch rows,
76
+ // `createGtkImage` from `./gtk-image.js` in every widget that draws an icon), so the
77
+ // module graph fixes the order whatever a barrel does. The order that IS load-bearing
78
+ // is the one inside a single module, and `scripts/check-adwaita-upgrade-order.mjs`
79
+ // holds that.
80
+ //
81
+ // `export * as`, NOT an object literal, and that is a bundler constraint rather than a
82
+ // preference: a module namespace carries the TYPE meaning of every name in it, so
83
+ // `as Adw.HeaderBar` works with no second list of instance types — and the merge that
84
+ // would have produced those types (`export const Adw` beside `export namespace Adw`) is
85
+ // a PARSE_ERROR in rolldown's oxc parser even though `tsc` accepts it. The reasoning is
86
+ // in `namespace/adw.ts`.
87
+ export * as Adw from './namespace/adw.js';
88
+ export * as Gtk from './namespace/gtk.js';
89
+
90
+ // WHAT DID NOT MOVE INTO THE NAMESPACE, and the rule that decides it. A member exists
91
+ // for an element whose GIR tag names a real widget; `WEB_ELEMENT_ALIGNMENT` declares the
92
+ // rest `webOnly`, meaning no widget in the reference vocabulary stands behind it, so
93
+ // there is no GIR name to export it under and inventing one would be held against
94
+ // nothing but prose (ADR 0034 § 5). Those classes therefore keep their flat name, and
95
+ // that is not a second spelling: it is their only one.
96
+ //
97
+ // Everything else below is not a widget class at all — a factory, a helper, or a type —
98
+ // and a type has no namespace member to move to.
99
+
100
+ // Two elements with no GTK counterpart: `.adw-card` is a style class here and a styled
101
+ // container on GTK, and the grid is presentational where GTK would use a plain Gtk.Grid.
68
102
  export { AdwCard } from './elements/adw-card.js';
69
103
  export { AdwDataGrid } from './elements/adw-data-grid.js';
70
104
  export type {
@@ -73,66 +107,33 @@ export type {
73
107
  AdwDataGridRow,
74
108
  AdwDataGridRowVariant,
75
109
  } from './elements/adw-data-grid.js';
76
- export { AdwClamp } from './elements/adw-clamp.js';
77
- export { AdwSpinner } from './elements/adw-spinner.js';
78
- export { AdwStatusPage } from './elements/adw-status-page.js';
79
- export { AdwWindow } from './elements/adw-window.js';
80
- export { AdwHeaderBar } from './elements/adw-header-bar.js';
81
- export { AdwWindowTitle } from './elements/adw-window-title.js';
82
- export { AdwButton } from './elements/adw-button.js';
83
- export { AdwButtonContent } from './elements/adw-button-content.js';
84
- // The ONE symbolic-icon node and the ONE toggle, exported before the widgets that build
85
- // them so the barrel's definition order matches theirs. Each host ALSO imports them
86
- // directly, which is what actually guarantees the tags are defined before a
87
- // server-rendered host upgrades.
88
- export { AdwIcon, createAdwIcon } from './elements/adw-icon.js';
89
- export { AdwSwitch } from './elements/adw-switch.js';
90
- // The two form-control primitives. ONE module, because upstream merges their
91
- // stylesheet (`_checks.scss`; there is no `_radio.scss` in libadwaita) and
92
- // everything but the corner radius, the glyph and the group is shared.
93
- export { AdwCheckbox, AdwRadio } from './elements/adw-checks.js';
94
- // The determinate progress indicator — <adw-spinner> covers only the indeterminate case.
95
- export { AdwProgressBar } from './elements/adw-progress-bar.js';
96
- // A keyboard shortcut, drawn as keycaps. The accelerator GRAMMAR lives in
97
- // @gjsify/adwaita-core; this element only builds the nodes.
98
- export { AdwShortcutLabel } from './elements/adw-shortcut-label.js';
99
- // The ONE popover surface, exported before its three hosts for the same reason as
100
- // <adw-icon> above.
101
- export { AdwPopover } from './elements/adw-popover.js';
102
- export type { AdwPopoverAlign, AdwPopoverPosition, AdwPopoverRole } from './elements/adw-popover.js';
103
- export { AdwSplitButton } from './elements/adw-split-button.js';
104
- export { AdwToggle, AdwToggleGroup } from './elements/adw-toggle-group.js';
105
- export { AdwEntry } from './elements/adw-entry.js';
106
- export { AdwPreferencesGroup } from './elements/adw-preferences-group.js';
107
- export { AdwActionRow } from './elements/adw-action-row.js';
108
- export { AdwEntryRow } from './elements/adw-entry-row.js';
109
- export { AdwSwitchRow } from './elements/adw-switch-row.js';
110
- export { AdwComboRow } from './elements/adw-combo-row.js';
111
- export { AdwSpinRow } from './elements/adw-spin-row.js';
112
- export { AdwButtonRow } from './elements/adw-button-row.js';
113
- export { AdwExpanderRow } from './elements/adw-expander-row.js';
114
- export { AdwPasswordEntryRow } from './elements/adw-password-entry-row.js';
115
- export { AdwToastOverlay } from './elements/adw-toast-overlay.js';
116
- export { AdwToolbarView } from './elements/adw-toolbar-view.js';
117
- export { AdwWrapBox } from './elements/adw-wrap-box.js';
118
- export { AdwOverlaySplitView } from './elements/adw-overlay-split-view.js';
119
- export { AdwNavigationSplitView } from './elements/adw-navigation-split-view.js';
120
- export { AdwCarousel, AdwCarouselIndicatorDots, AdwCarouselIndicatorLines } from './elements/adw-carousel.js';
121
- export { AdwTabPage, AdwTabView } from './elements/adw-tab-view.js';
122
- export { AdwViewSwitcher, AdwViewSwitcherPage } from './elements/adw-view-switcher.js';
123
- export { AdwInlineViewSwitcher, AdwViewStackPage } from './elements/adw-inline-view-switcher.js';
124
- export { AdwViewStack } from './elements/adw-view-stack.js';
110
+
111
+ // The symbolic-icon FACTORY. `Gtk.Image` is the element; this builds one without a tag,
112
+ // which the icon-drawing element modules use internally and a consumer with its own
113
+ // chrome needs.
114
+ export { createGtkImage } from './elements/gtk-image.js';
115
+
116
+ // GTK4 has no radio TYPE — a radio is a GtkCheckButton with its `group` set — so
117
+ // `Gtk.CheckButton` is the plain form and the grouped one has only this name.
118
+ export { AdwRadio } from './elements/checks.js';
119
+
120
+ // The declarative children of four composites. Each descends from `GObject.Object` and
121
+ // not `GtkWidget` on GTK, so the table of concrete widgets has no row for them; the day
122
+ // it grows one, its member appears in `namespace.ts` by itself.
123
+ export { AdwTabPage } from './elements/adw-tab-view.js';
124
+ export { AdwViewSwitcherPage } from './elements/adw-view-switcher.js';
125
+ export { AdwViewStackPage } from './elements/adw-inline-view-switcher.js';
126
+ export { AdwSidebarItem, AdwSidebarSection } from './elements/adw-sidebar.js';
127
+
128
+ // Slot wrappers and a declarative response: on GTK these are `set_content()`,
129
+ // `set_sheet()` and `add_response()` — calls, not widgets.
130
+ export { AdwBottomSheetContent, AdwBottomSheetSheet } from './elements/adw-bottom-sheet.js';
131
+ export { AdwAlertResponse } from './elements/adw-alert-dialog.js';
132
+
133
+ // Supporting types — the option bags, enums and unions the widgets above take and
134
+ // return. Not widgets, so clause 2 has nothing to say about them.
135
+ export type { GtkPopoverAlign, GtkPopoverPosition, GtkPopoverRole } from './elements/gtk-popover.js';
125
136
  export type { AdwViewStackPageInfo } from './elements/adw-view-stack.js';
126
- export { AdwViewSwitcherBar } from './elements/adw-view-switcher-bar.js';
127
- export { AdwMenuButton } from './elements/adw-menu-button.js';
128
- export type { AdwMenuItem } from './elements/adw-menu-button.js';
129
- export { AdwDropDown } from './elements/adw-drop-down.js';
130
- export type { AdwDropDownOption } from './elements/adw-drop-down.js';
131
- export { AdwNavigationPage, AdwNavigationView } from './elements/adw-navigation-view.js';
132
- export { AdwBottomSheet, AdwBottomSheetContent, AdwBottomSheetSheet } from './elements/adw-bottom-sheet.js';
133
- export { AdwSidebar, AdwSidebarItem, AdwSidebarSection } from './elements/adw-sidebar.js';
134
- export { AdwAboutDialog } from './elements/adw-about-dialog.js';
135
- export { AdwAlertDialog, AdwAlertResponse } from './elements/adw-alert-dialog.js';
136
- export { AdwPreferencesDialog, AdwPreferencesPage } from './elements/adw-preferences-dialog.js';
137
- export { AdwDialog } from './elements/adw-dialog.js';
137
+ export type { AdwMenuItem } from './elements/gtk-menu-button.js';
138
+ export type { GtkDropDownOption } from './elements/gtk-drop-down.js';
138
139
  export type { AdwDialogPresentationMode } from './elements/adw-dialog.js';
@@ -0,0 +1,99 @@
1
+ // The libadwaita half of `@gjsify/adwaita-web`'s vocabulary — `Adw.ActionRow`,
2
+ // `Adw.Clamp`, one member per element whose own tag is an `adw-*` tag in the GIR.
3
+ // `export * as Adw from './namespace/adw.js'` in `src/index.ts` turns this module into
4
+ // the namespace object.
5
+ //
6
+ // ADR 0034 clause 2, and since § Amendment 6 this is the ONLY way to reach one of these
7
+ // widget classes: the prefixed `AdwActionRow` / `GtkEntry` exports are gone from the
8
+ // package root. The TAGS are untouched — `<adw-action-row>` and `<gtk-entry>` are what
9
+ // they were, and nothing here changes a registration.
10
+ //
11
+ // It landed additive, and the amendment says why that could not be the end state: a
12
+ // second spelling that never goes away is a permanent second vocabulary, which is the
13
+ // thing clause 2 exists to remove.
14
+ //
15
+ // WHICH NAMESPACE A MEMBER LANDS IN IS NOT A CHOICE MADE HERE. It is read off the GIR tag
16
+ // the element already answers to, which is clause 1 applied rather than restated:
17
+ //
18
+ // * the element's own spelling IS a tag in gtk-host's generated widget table
19
+ // (`adw-action-row`) -> libadwaita owns the GType -> `Adw.ActionRow`, this file;
20
+ // * the element is declared in `WEB_ELEMENT_ALIGNMENT` as an alias of a `gtk-*` tag
21
+ // (`<adw-entry>` is `gtk-entry`) -> GTK owns the GType -> `Gtk.Entry`, `./gtk.ts`.
22
+ // On those the `adw-` prefix names the design system and not the widget, which is
23
+ // what each entry's `why` already says; exporting them under `Adw` would carry the
24
+ // flattening this ADR exists to undo one indirection further in.
25
+ //
26
+ // THE `webOnly` ELEMENTS GET NO MEMBER, and that absence IS the declaration. A
27
+ // `webOnly` entry says no widget in the reference vocabulary stands behind the element,
28
+ // so there is no GIR name to export it under; a member invented for one could only ever
29
+ // be held against this repository's own prose, which ADR 0034 § 5 names as the half that
30
+ // cannot go red. Some of them do name a real libadwaita GType — `AdwTabPage`,
31
+ // `AdwViewStackPage`, `AdwSidebarItem`, `AdwSidebarSection` descend from `GObject.Object`
32
+ // and not `GtkWidget`, so a table of concrete widgets has no row for them — and they are
33
+ // why this is worth stating: the day the reference table starts carrying one, its member
34
+ // appears here by itself, because the derivation reads that table. `<adw-toggle>` already
35
+ // made that move (ADR 0028 § Amendment, 2026-08-28) and needed no edit here.
36
+ //
37
+ // WHY A RE-EXPORT BARREL AND NOT AN OBJECT LITERAL. It was `export const Adw = { … }`
38
+ // beside a merged `export namespace Adw { … }` of instance types, so that `Adw.HeaderBar`
39
+ // could annotate as well as construct — every call site in this repository imports these
40
+ // classes with `import type`. `tsc` accepts that merge; ROLLDOWN'S oxc PARSER DOES NOT,
41
+ // and it fails at PARSE time — `Identifier \`Adw\` has already been declared`, a
42
+ // PARSE_ERROR out of `Bundler::generate` that took every showcase importing this package
43
+ // with it while `gjsify tsc` stayed green. The two check different things and the bundler
44
+ // is the stricter one. An `export { X as Y } from` line needs no merge and no TypeScript
45
+ // construct at all: a module namespace carries the value AND the type meaning of every
46
+ // name in it, so `new Adw.HeaderBar()` and `as Adw.HeaderBar` both work off ONE list.
47
+ // A second list of instance types could drift from the first; this one cannot exist.
48
+ //
49
+ // WHAT HOLDS IT: the namespace half of `scripts/check-vocabulary-alignment.mjs`. It
50
+ // derives the members from the elements `customElements.define` registers and the
51
+ // alignment table, and compares in both directions — an element with no member fails, a
52
+ // member with no element fails, and a member bound to a class that is not that element's
53
+ // fails. `namespaceExport` in `scripts/adwaita-elements.mjs` follows the one hop from
54
+ // `src/index.ts` to this file and reads the LEFT side of each `as` as the binding.
55
+
56
+ export { AdwAboutDialog as AboutDialog } from '../elements/adw-about-dialog.js';
57
+ export { AdwActionRow as ActionRow } from '../elements/adw-action-row.js';
58
+ export { AdwAlertDialog as AlertDialog } from '../elements/adw-alert-dialog.js';
59
+ export { AdwAvatar as Avatar } from '../elements/adw-avatar.js';
60
+ export { AdwBanner as Banner } from '../elements/adw-banner.js';
61
+ export { AdwBottomSheet as BottomSheet } from '../elements/adw-bottom-sheet.js';
62
+ export { AdwButtonContent as ButtonContent } from '../elements/adw-button-content.js';
63
+ export { AdwButtonRow as ButtonRow } from '../elements/adw-button-row.js';
64
+ export { AdwCarousel as Carousel } from '../elements/adw-carousel.js';
65
+ export { AdwCarouselIndicatorDots as CarouselIndicatorDots } from '../elements/adw-carousel.js';
66
+ export { AdwCarouselIndicatorLines as CarouselIndicatorLines } from '../elements/adw-carousel.js';
67
+ export { AdwClamp as Clamp } from '../elements/adw-clamp.js';
68
+ export { AdwComboRow as ComboRow } from '../elements/adw-combo-row.js';
69
+ export { AdwDialog as Dialog } from '../elements/adw-dialog.js';
70
+ export { AdwEntryRow as EntryRow } from '../elements/adw-entry-row.js';
71
+ export { AdwExpanderRow as ExpanderRow } from '../elements/adw-expander-row.js';
72
+ export { AdwHeaderBar as HeaderBar } from '../elements/adw-header-bar.js';
73
+ export { AdwInlineViewSwitcher as InlineViewSwitcher } from '../elements/adw-inline-view-switcher.js';
74
+ export { AdwNavigationPage as NavigationPage } from '../elements/adw-navigation-view.js';
75
+ export { AdwNavigationSplitView as NavigationSplitView } from '../elements/adw-navigation-split-view.js';
76
+ export { AdwNavigationView as NavigationView } from '../elements/adw-navigation-view.js';
77
+ export { AdwOverlaySplitView as OverlaySplitView } from '../elements/adw-overlay-split-view.js';
78
+ export { AdwPasswordEntryRow as PasswordEntryRow } from '../elements/adw-password-entry-row.js';
79
+ export { AdwPreferencesDialog as PreferencesDialog } from '../elements/adw-preferences-dialog.js';
80
+ export { AdwPreferencesGroup as PreferencesGroup } from '../elements/adw-preferences-group.js';
81
+ export { AdwPreferencesPage as PreferencesPage } from '../elements/adw-preferences-dialog.js';
82
+ export { AdwShortcutLabel as ShortcutLabel } from '../elements/adw-shortcut-label.js';
83
+ export { AdwSidebar as Sidebar } from '../elements/adw-sidebar.js';
84
+ export { AdwSpinRow as SpinRow } from '../elements/adw-spin-row.js';
85
+ export { AdwSpinner as Spinner } from '../elements/adw-spinner.js';
86
+ export { AdwSplitButton as SplitButton } from '../elements/adw-split-button.js';
87
+ export { AdwStatusPage as StatusPage } from '../elements/adw-status-page.js';
88
+ export { AdwSwitchRow as SwitchRow } from '../elements/adw-switch-row.js';
89
+ export { AdwTabView as TabView } from '../elements/adw-tab-view.js';
90
+ export { AdwToastOverlay as ToastOverlay } from '../elements/adw-toast-overlay.js';
91
+ export { AdwToggle as Toggle } from '../elements/adw-toggle-group.js';
92
+ export { AdwToggleGroup as ToggleGroup } from '../elements/adw-toggle-group.js';
93
+ export { AdwToolbarView as ToolbarView } from '../elements/adw-toolbar-view.js';
94
+ export { AdwViewStack as ViewStack } from '../elements/adw-view-stack.js';
95
+ export { AdwViewSwitcher as ViewSwitcher } from '../elements/adw-view-switcher.js';
96
+ export { AdwViewSwitcherBar as ViewSwitcherBar } from '../elements/adw-view-switcher-bar.js';
97
+ export { AdwWindow as Window } from '../elements/adw-window.js';
98
+ export { AdwWindowTitle as WindowTitle } from '../elements/adw-window-title.js';
99
+ export { AdwWrapBox as WrapBox } from '../elements/adw-wrap-box.js';
@@ -0,0 +1,22 @@
1
+ // The GTK half of `@gjsify/adwaita-web`'s vocabulary — `Gtk.Entry`, `Gtk.Button`, one
2
+ // member per element that `WEB_ELEMENT_ALIGNMENT` declares an alias of a `gtk-*` tag.
3
+ // `export * as Gtk from './namespace/gtk.js'` in `src/index.ts` makes it the namespace.
4
+ //
5
+ // The derivation, the reason these are NOT `Adw.*`, why the `webOnly` elements have no
6
+ // member, and why this is a re-export barrel rather than an object literal are all in
7
+ // `./adw.ts`. One statement of it, because a second copy is the one that drifts.
8
+ //
9
+ // `Gtk.CheckButton` IS `GtkCheckButton`, NOT `AdwRadio` — the one GIR name two elements
10
+ // declare. GTK4 has no radio type: a radio is a GtkCheckButton with its `group` set,
11
+ // which is what `<adw-radio>`'s own `why` in the ledger says. So the plain form takes the
12
+ // GIR name and the grouped one keeps its flat export in `src/index.ts`.
13
+
14
+ export { GtkButton as Button } from '../elements/gtk-button.js';
15
+ export { GtkCheckButton as CheckButton } from '../elements/checks.js';
16
+ export { GtkDropDown as DropDown } from '../elements/gtk-drop-down.js';
17
+ export { GtkEntry as Entry } from '../elements/gtk-entry.js';
18
+ export { GtkImage as Image } from '../elements/gtk-image.js';
19
+ export { GtkMenuButton as MenuButton } from '../elements/gtk-menu-button.js';
20
+ export { GtkPopover as Popover } from '../elements/gtk-popover.js';
21
+ export { GtkProgressBar as ProgressBar } from '../elements/gtk-progress-bar.js';
22
+ export { GtkSwitch as Switch } from '../elements/gtk-switch.js';
@@ -41,7 +41,7 @@ const ACTION_ROW_TAGS: ReadonlySet<string> = new Set([
41
41
  /**
42
42
  * `ADW_IS_PREFERENCES_ROW` for the browser elements — the first clause of
43
43
  * `row_has_title`. Spelled out rather than inferred from the `adw-` prefix, because a
44
- * group's boxed list legitimately holds other things: a bare `<adw-button>` dropped in as
44
+ * group's boxed list legitimately holds other things: a bare `<gtk-button>` dropped in as
45
45
  * a footer is not a preferences row and must not be searchable.
46
46
  */
47
47
  const PREFERENCES_ROW_TAGS: ReadonlySet<string> = new Set([
@@ -16,6 +16,9 @@
16
16
  import { describe, expect, it } from '@gjsify/unit';
17
17
 
18
18
  import * as adwaitaWeb from './index.js';
19
+ // See `exported-elements.ts`: the widget classes live inside the exported `Adw`/`Gtk`
20
+ // objects, so a top-level `Object.values` finds only the web-only stragglers.
21
+ import { exportedElementClasses } from './exported-elements.js';
19
22
  import { bindSlottedChildren, slottedChildrenOf } from './slotted-children.js';
20
23
 
21
24
  /** One microtask checkpoint — where a MutationObserver callback lands. */
@@ -164,9 +167,8 @@ export const AdwSlottedChildrenTest = async () => {
164
167
  // declared child and an appended one in the same place.
165
168
  await describe('every slotted element adopts a late child where it adopts a declared one', async () => {
166
169
  const tags: string[] = [];
167
- for (const exported of Object.values(adwaitaWeb)) {
168
- if (typeof exported !== 'function' || !(exported.prototype instanceof HTMLElement)) continue;
169
- const tag = customElements.getName(exported as CustomElementConstructor);
170
+ for (const exported of exportedElementClasses(adwaitaWeb)) {
171
+ const tag = customElements.getName(exported);
170
172
  if (tag !== null) tags.push(tag);
171
173
  }
172
174
  tags.sort();
@@ -34,7 +34,7 @@ import { defaultKeymap, history, historyKeymap } from '@codemirror/commands';
34
34
  import { asm6502 } from './asm6502.js';
35
35
  import { adwaitaEditorTheme, adwaitaHighlightStyle, ensureSourceViewStyleInjected } from './theme.js';
36
36
  import { formatHexAddress, formatLineNumber, stripWhitespace } from './hex.js';
37
- import { createAdwIcon } from '../elements/adw-icon.js';
37
+ import { createGtkImage } from '../elements/gtk-image.js';
38
38
 
39
39
  /** A recognisable copy glyph rendered inline so the subpath needs no icon CSS. */
40
40
  const COPY_SVG =
@@ -405,7 +405,7 @@ export class AdwSourceView extends HTMLElement {
405
405
  }
406
406
  // A non-default icon uses the adwaita-web mask class (requires the main
407
407
  // bundle's icon CSS to be present).
408
- this._copyButton.replaceChildren(createAdwIcon(name));
408
+ this._copyButton.replaceChildren(createGtkImage(name));
409
409
  }
410
410
 
411
411
  private _readDeclarativeAttributes(): void {
@@ -328,8 +328,8 @@ export const AdwSplitButtonTest = async () => {
328
328
 
329
329
  // The two behaviours a hand-rolled popover with only an outside-click handler cannot
330
330
  // give: leaving by keyboard, and reaching the items with the arrow keys. Both come
331
- // from `<adw-popover>`, and these cases prove the lift was a lift, not a move.
332
- await describe('adw-split-button menu keyboard (gained with <adw-popover>)', async () => {
331
+ // from `<gtk-popover>`, and these cases prove the lift was a lift, not a move.
332
+ await describe('adw-split-button menu keyboard (gained with <gtk-popover>)', async () => {
333
333
  await it('Escape dismisses the menu and returns focus to the dropdown half', () => {
334
334
  const { el, host } = mount({ menu: '[{"label":"Print"},{"label":"Export"}]' });
335
335
  dropdownHalf(el).click();
@@ -370,7 +370,7 @@ export const AdwSplitButtonTest = async () => {
370
370
  // Opening focuses the first row — without that there is nothing to move from.
371
371
  expect(document.activeElement).toBe(items[0]);
372
372
 
373
- const menu = el.querySelector('adw-popover') as HTMLElement;
373
+ const menu = el.querySelector('gtk-popover') as HTMLElement;
374
374
  const press = (key: string) => menu.dispatchEvent(new KeyboardEvent('keydown', { key, bubbles: true }));
375
375
 
376
376
  press('ArrowDown');
@@ -396,7 +396,7 @@ export const AdwSplitButtonTest = async () => {
396
396
  el.addEventListener('menu-activated', (event) => seen.push((event as CustomEvent).detail.index));
397
397
 
398
398
  dropdownHalf(el).click();
399
- const menu = el.querySelector('adw-popover') as HTMLElement;
399
+ const menu = el.querySelector('gtk-popover') as HTMLElement;
400
400
  menu.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true }));
401
401
  menu.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true }));
402
402
 
@@ -425,7 +425,7 @@ export const AdwSplitButtonTest = async () => {
425
425
  await it(`draws a ${menuVector?.borderRadius}px surface with ${menuVector?.padding}px padding and a THREE-layer shadow`, () => {
426
426
  const { el, host } = mount({ menu: '[{"label":"Print"}]' });
427
427
  dropdownHalf(el).click();
428
- const surface = el.querySelector('adw-popover') as HTMLElement;
428
+ const surface = el.querySelector('gtk-popover') as HTMLElement;
429
429
  const style = getComputedStyle(surface);
430
430
 
431
431
  expect(style.paddingTop).toBe(`${menuVector?.padding}px`);