@gjsify/adwaita-web 0.51.1 → 0.52.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 (103) hide show
  1. package/dist/adwaita-web.css +255 -27
  2. package/dist/adwaita-web.css.map +1 -1
  3. package/lib/types/blueprint-layout.spec.d.ts +1 -0
  4. package/lib/types/blueprint-markup.spec.d.ts +4 -0
  5. package/lib/types/blueprint-tree.spec.d.ts +1 -0
  6. package/lib/types/elements/adw-bottom-sheet.d.ts +31 -13
  7. package/lib/types/elements/adw-carousel.d.ts +5 -0
  8. package/lib/types/elements/adw-header-bar.d.ts +15 -0
  9. package/lib/types/elements/adw-inline-view-switcher.d.ts +1 -0
  10. package/lib/types/elements/adw-navigation-view.d.ts +1 -0
  11. package/lib/types/elements/adw-sidebar.d.ts +10 -0
  12. package/lib/types/elements/adw-tab-view.d.ts +1 -0
  13. package/lib/types/elements/adw-toggle-group.d.ts +11 -0
  14. package/lib/types/elements/gtk-action-bar.d.ts +19 -0
  15. package/lib/types/elements/gtk-box.d.ts +17 -0
  16. package/lib/types/elements/gtk-button.d.ts +2 -0
  17. package/lib/types/elements/gtk-label.d.ts +122 -0
  18. package/lib/types/gio-menu.spec.d.ts +1 -0
  19. package/lib/types/gtk-box.spec.d.ts +1 -0
  20. package/lib/types/gtk-label.spec.d.ts +1 -0
  21. package/lib/types/gtk-value-doors.spec.d.ts +1 -0
  22. package/lib/types/index.d.ts +4 -1
  23. package/lib/types/namespace/gio.d.ts +1 -0
  24. package/lib/types/namespace/gtk.d.ts +5 -0
  25. package/lib/types/shared-tree-builder.d.ts +64 -0
  26. package/lib/types/source-view/asm6502.d.ts +1 -20
  27. package/lib/types/source-view/index.d.ts +3 -2
  28. package/lib/types/source-view/theme.d.ts +1 -1
  29. package/lib/types/string-list-slot.d.ts +4 -0
  30. package/lib/types/styles.generated.d.ts +1 -1
  31. package/lib/types/tags.spec.d.ts +1 -0
  32. package/lib/types/value-lists.spec.d.ts +1 -0
  33. package/package.json +8 -6
  34. package/scss/_action_bar.scss +51 -0
  35. package/scss/_banner.scss +8 -1
  36. package/scss/_bottom_sheet.scss +57 -0
  37. package/scss/_box.scss +23 -0
  38. package/scss/_button.scss +29 -7
  39. package/scss/_button_content.scss +6 -1
  40. package/scss/_button_row.scss +5 -2
  41. package/scss/_carousel.scss +6 -0
  42. package/scss/_labels.scss +126 -12
  43. package/scss/_navigation_split_view.scss +18 -0
  44. package/scss/_overlay_split_view.scss +5 -0
  45. package/scss/_reset.scss +29 -4
  46. package/scss/_split_button.scss +5 -2
  47. package/scss/_status_page.scss +31 -17
  48. package/scss/_theme.scss +11 -3
  49. package/scss/_toolbar_view.scss +10 -0
  50. package/scss/_variables.scss +1 -0
  51. package/scss/_widget.scss +55 -0
  52. package/scss/_window_title.scss +9 -0
  53. package/scss/adwaita-skin.scss +8 -2
  54. package/src/adw-banner.spec.ts +16 -0
  55. package/src/adw-button-row.spec.ts +8 -0
  56. package/src/adw-header-bar.spec.ts +17 -0
  57. package/src/blueprint-layout.spec.ts +223 -0
  58. package/src/blueprint-markup.spec.ts +155 -0
  59. package/src/blueprint-tree.spec.ts +174 -0
  60. package/src/bottom-sheet.spec.ts +166 -1
  61. package/src/chrome.spec.ts +5 -2
  62. package/src/elements/adw-bottom-sheet.ts +166 -59
  63. package/src/elements/adw-carousel.ts +10 -5
  64. package/src/elements/adw-clamp.ts +12 -0
  65. package/src/elements/adw-combo-row.ts +13 -4
  66. package/src/elements/adw-header-bar.ts +46 -3
  67. package/src/elements/adw-inline-view-switcher.ts +11 -0
  68. package/src/elements/adw-navigation-view.ts +10 -0
  69. package/src/elements/adw-sidebar.ts +22 -0
  70. package/src/elements/adw-spin-row.ts +44 -5
  71. package/src/elements/adw-status-page.ts +12 -6
  72. package/src/elements/adw-tab-view.ts +20 -3
  73. package/src/elements/adw-toggle-group.ts +45 -4
  74. package/src/elements/adw-toolbar-view.ts +9 -0
  75. package/src/elements/gtk-action-bar.ts +90 -0
  76. package/src/elements/gtk-box.ts +87 -0
  77. package/src/elements/gtk-button.ts +60 -13
  78. package/src/elements/gtk-drop-down.ts +10 -1
  79. package/src/elements/gtk-label.ts +415 -0
  80. package/src/gio-menu.spec.ts +125 -0
  81. package/src/globals.d.ts +7 -0
  82. package/src/gtk-box.spec.ts +168 -0
  83. package/src/gtk-button.spec.ts +123 -1
  84. package/src/gtk-label.spec.ts +595 -0
  85. package/src/gtk-value-doors.spec.ts +104 -0
  86. package/src/index.ts +14 -1
  87. package/src/keyboard-operable.spec.ts +2 -1
  88. package/src/namespace/gio.ts +19 -0
  89. package/src/namespace/gtk.ts +14 -0
  90. package/src/shared-tree-builder.ts +268 -0
  91. package/src/shared-trees.spec.ts +296 -32
  92. package/src/source-view/adw-source-view.ts +3 -3
  93. package/src/source-view/asm6502.ts +11 -191
  94. package/src/source-view/index.ts +17 -11
  95. package/src/source-view/theme.ts +16 -16
  96. package/src/split-button.spec.ts +7 -0
  97. package/src/string-list-slot.ts +21 -0
  98. package/src/styles.generated.ts +1 -1
  99. package/src/tags.spec.ts +51 -0
  100. package/src/test.browser.mts +18 -0
  101. package/src/value-lists.spec.ts +93 -0
  102. package/lib/types/source-view/hex.d.ts +0 -21
  103. package/src/source-view/hex.ts +0 -37
@@ -0,0 +1 @@
1
+ export declare const AdwBlueprintLayoutTest: () => Promise<void>;
@@ -0,0 +1,4 @@
1
+ import type { SharedTreeNode } from '@gjsify/adwaita-core/conformance';
2
+ /** Every one-Blueprint `.blp` of the gallery, by its path under `website/src/blueprints/`. */
3
+ export declare const GALLERY_BLUEPRINTS: Readonly<Record<string, SharedTreeNode>>;
4
+ export declare const AdwBlueprintMarkupTest: () => Promise<void>;
@@ -0,0 +1 @@
1
+ export declare const AdwBlueprintTreeTest: () => Promise<void>;
@@ -1,16 +1,23 @@
1
- import type { BottomSheetCloseOutcome, BottomSheetCloseSource } from '@gjsify/adwaita-core';
1
+ import type { BottomSheetCloseOutcome, BottomSheetCloseSource, BottomSheetOpenOutcome, BottomSheetOpenSource } from '@gjsify/adwaita-core';
2
2
  /** The persistent content. Child of <adw-bottom-sheet>; consumed at connect time. */
3
3
  export declare class AdwBottomSheetContent extends HTMLElement {
4
4
  }
5
5
  /** The slide-up sheet. Child of <adw-bottom-sheet>; consumed at connect time. */
6
6
  export declare class AdwBottomSheetSheet extends HTMLElement {
7
7
  }
8
+ /** The collapsed bar the sheet morphs out of. Child of <adw-bottom-sheet>. */
9
+ export declare class AdwBottomSheetBottomBar extends HTMLElement {
10
+ }
8
11
  export declare class AdwBottomSheet extends HTMLElement {
9
12
  private _initialized;
10
13
  private _contentEl;
11
14
  private _dimmingEl;
12
15
  private _sheetEl;
16
+ private _sheetBodyEl;
17
+ private _bottomBarEl;
13
18
  private _dragHandleEl;
19
+ /** A bar set through {@link setBottomBar} before the element upgraded. */
20
+ private _pendingBottomBar;
14
21
  /** The shared open/can-close model — the single source of truth for both. */
15
22
  private readonly _state;
16
23
  /** Set while the element writes `open` back, so the write does not re-enter. */
@@ -18,13 +25,36 @@ export declare class AdwBottomSheet extends HTMLElement {
18
25
  static get observedAttributes(): string[];
19
26
  get open(): boolean;
20
27
  set open(value: boolean);
28
+ /** Whether the content is dimmed and blocked while the sheet is open (`AdwBottomSheet:modal`). */
21
29
  get modal(): boolean;
22
30
  set modal(value: boolean);
23
31
  /** Whether the user can dismiss the sheet (dimming / Escape / sheet.close). */
24
32
  get canClose(): boolean;
25
33
  set canClose(value: boolean);
34
+ /** Whether the user can open the sheet from its bottom bar (`Adw.BottomSheet:can-open`). */
35
+ get canOpen(): boolean;
36
+ set canOpen(value: boolean);
37
+ /** Whether the bottom bar is shown while the sheet is closed. */
38
+ get revealBottomBar(): boolean;
39
+ set revealBottomBar(value: boolean);
26
40
  get showDragHandle(): boolean;
27
41
  set showDragHandle(value: boolean);
42
+ /** The bar's content, or `null` when the sheet has none — the read-back for {@link setBottomBar}. */
43
+ get bottomBar(): Node | null;
44
+ /**
45
+ * Give the sheet a bottom bar, or take it away — `adw_bottom_sheet_set_bottom_bar`.
46
+ *
47
+ * Presence is an INPUT to the open gate, not decoration: removing the bar removes every
48
+ * way a user has of opening this sheet, which is why the state hears about it rather
49
+ * than only the DOM.
50
+ */
51
+ setBottomBar(child: Node | null): void;
52
+ /**
53
+ * Route an open affordance through the shared gate. `'ignored'` is silent by design:
54
+ * libadwaita has no `open-attempt` counterpart to `close-attempt`, so a refused open
55
+ * emits nothing at all.
56
+ */
57
+ requestOpen(source: BottomSheetOpenSource): BottomSheetOpenOutcome;
28
58
  /**
29
59
  * Route a dismissal affordance through the shared gate and act on the verdict: close,
30
60
  * raise `close-attempt`, forward `sheet.close` to an ancestor, or do nothing. Called
@@ -44,16 +74,4 @@ export declare class AdwBottomSheet extends HTMLElement {
44
74
  /** Read a boolean attribute: absent → `fallback`, explicit `="false"` → off. */
45
75
  private _boolAttr;
46
76
  private _setBoolAttr;
47
- /**
48
- * Collect the nodes declared for one slot, in DOCUMENT order, marking every
49
- * consumed child in `claimed`.
50
- *
51
- * The `<adw-bottom-sheet-sheet>` / `<adw-bottom-sheet-content>` wrappers are
52
- * markup, not widgets — GtkBuilder's `<child type="sheet">` leaves nothing in
53
- * the tree — so the wrapper itself is claimed
54
- * too. It used to fall through to `unslotted` and be appended to the content
55
- * layer, leaving an empty custom element behind after its children were
56
- * pulled out.
57
- */
58
- private _collectSlot;
59
77
  }
@@ -183,6 +183,11 @@ declare abstract class AdwCarouselIndicator extends HTMLElement {
183
183
  connectedCallback(): void;
184
184
  disconnectedCallback(): void;
185
185
  attributeChangedCallback(name: string): void;
186
+ /**
187
+ * The carousel named by id. `carousel` is the GTK property's own name, and what a
188
+ * projected `.blp` writes for `carousel: carousel`; `for` is the markup spelling this
189
+ * element had first, kept as the fallback.
190
+ */
186
191
  private _resolveForAttr;
187
192
  private _attach;
188
193
  private _detach;
@@ -12,6 +12,13 @@ export declare class AdwHeaderBar extends HTMLElement {
12
12
  * see the divergence at the top of this file.
13
13
  */
14
14
  private _titleEl;
15
+ /**
16
+ * The `<adw-navigation-page>` this bar sits in, and the observer that follows its
17
+ * title. `update_title` (adw-header-bar.c:488) asks that page FIRST, which is how a
18
+ * bare `Adw.HeaderBar {}` in a `.blp` page shows "Mailboxes" with no title of its own.
19
+ */
20
+ private _page;
21
+ private _pageObserver;
15
22
  static get observedAttributes(): string[];
16
23
  /** The start (left) section container — append buttons/widgets here. */
17
24
  get startSection(): HTMLDivElement | null;
@@ -21,6 +28,14 @@ export declare class AdwHeaderBar extends HTMLElement {
21
28
  /** The end (right) section container — append buttons/widgets here. */
22
29
  get endSection(): HTMLDivElement | null;
23
30
  connectedCallback(): void;
31
+ disconnectedCallback(): void;
32
+ /**
33
+ * Find the enclosing navigation page and re-render when its title moves, as GTK does:
34
+ * `root` looks the ancestor up (adw-header-bar.c:586) and a `notify::title` on it re-runs
35
+ * `update_title`. Looked up on every connect, since a bar moved into another page has a
36
+ * new ancestor, which is why C does it in `root` and drops it in `unroot`.
37
+ */
38
+ private _followPage;
24
39
  /**
25
40
  * `title` used to be read ONCE, in `connectedCallback`, so every later write
26
41
  * was a silent no-op — a header bar whose title tracked the open document
@@ -3,6 +3,7 @@ import type { AdwInlineViewSwitcherDisplayMode, AdwViewSwitcherPage } from '@gjs
3
3
  /** A single page. Children of <adw-inline-view-switcher>; consumed at connect time. */
4
4
  export declare class AdwViewStackPage extends HTMLElement {
5
5
  static get observedAttributes(): string[];
6
+ connectedCallback(): void;
6
7
  }
7
8
  export declare class AdwInlineViewSwitcher extends HTMLElement {
8
9
  /**
@@ -3,6 +3,7 @@ export declare class AdwNavigationPage extends HTMLElement {
3
3
  /** Set while the owning view writes an attribute back, so the sync cannot recurse. */
4
4
  private _syncing;
5
5
  static get observedAttributes(): string[];
6
+ connectedCallback(): void;
6
7
  get title(): string;
7
8
  set title(value: string);
8
9
  get tag(): string | null;
@@ -2,6 +2,16 @@ import { type AdwSidebarItemSpec, type AdwSidebarSectionSpec, type SidebarItemFi
2
2
  /** A single sidebar item. Child of <adw-sidebar-section>; consumed at connect time. */
3
3
  export declare class AdwSidebarItem extends HTMLElement {
4
4
  static get observedAttributes(): string[];
5
+ /**
6
+ * `AdwSidebarItem:enabled`, under the GIR name — the `disabled` attribute inverted. The
7
+ * property is what lets an authored `enabled: false` reach this item through the
8
+ * shared-tree builder, which writes a `false` through the element's own property.
9
+ */
10
+ get enabled(): boolean;
11
+ set enabled(value: boolean);
12
+ /** `AdwSidebarItem:visible` — the `hidden` attribute inverted, for the same reason. */
13
+ get visible(): boolean;
14
+ set visible(value: boolean);
5
15
  attributeChangedCallback(name: string, _oldValue: string | null, newValue: string | null): void;
6
16
  }
7
17
  /** A titled group of items. Child of <adw-sidebar>; consumed at connect time. */
@@ -9,6 +9,7 @@ export type AdwTabViewPageSpec = AdwTabPageSpec<HTMLElement>;
9
9
  */
10
10
  export declare class AdwTabPage extends HTMLElement {
11
11
  static get observedAttributes(): string[];
12
+ connectedCallback(): void;
12
13
  attributeChangedCallback(name: string, _old: string | null, value: string | null): void;
13
14
  }
14
15
  export declare class AdwTabView extends HTMLElement {
@@ -10,12 +10,23 @@ export declare class AdwToggleGroup extends HTMLElement {
10
10
  private _initialized;
11
11
  /** `aria-checked` under `radio`, `aria-selected` under `tab` — decided at connect. */
12
12
  private _stateAttr;
13
+ /** Each toggle's `name`, in order — what `active-name` resolves against. */
14
+ private _names;
13
15
  static get observedAttributes(): string[];
14
16
  /** Zero-based index of the active toggle. */
15
17
  get active(): number;
16
18
  set active(value: number);
19
+ /** `Adw.ToggleGroup:active-name` — the `name` of the active toggle, or `null`. */
20
+ get activeName(): string | null;
21
+ set activeName(value: string | null);
17
22
  connectedCallback(): void;
18
23
  attributeChangedCallback(name: string): void;
24
+ /**
25
+ * `adw_toggle_group_set_active_name`: the toggle carrying the name becomes active, and
26
+ * a name nothing carries leaves the selection where it was — the C's `g_critical` and
27
+ * return (:2001). Which toggle a name means is the core's answer, not this element's.
28
+ */
29
+ private _applyActiveName;
19
30
  private _readActiveAttr;
20
31
  private _selectIndex;
21
32
  private _render;
@@ -0,0 +1,19 @@
1
+ export declare class GtkActionBar extends HTMLElement {
2
+ private _initialized;
3
+ private _startEl;
4
+ private _centerEl;
5
+ private _endEl;
6
+ static get observedAttributes(): string[];
7
+ /** `GtkActionBar:revealed` — whether the bar shows its contents. */
8
+ get revealed(): boolean;
9
+ set revealed(value: boolean);
10
+ /** The start box — what `pack_start` appends to. */
11
+ get startSection(): HTMLDivElement | null;
12
+ /** The centre — what `gtk_action_bar_set_center_widget` sets. */
13
+ get centerSection(): HTMLDivElement | null;
14
+ /** The end box — what `pack_end` prepends to. */
15
+ get endSection(): HTMLDivElement | null;
16
+ connectedCallback(): void;
17
+ attributeChangedCallback(): void;
18
+ private _renderRevealed;
19
+ }
@@ -0,0 +1,17 @@
1
+ import { type BoxOrientation } from '@gjsify/adwaita-core';
2
+ export declare class GtkBox extends HTMLElement {
3
+ static get observedAttributes(): ("spacing" | "orientation" | "homogeneous")[];
4
+ /** `GtkOrientable:orientation` — `horizontal` (the default) or `vertical`. */
5
+ get orientation(): BoxOrientation;
6
+ set orientation(value: BoxOrientation);
7
+ /** `Gtk.Box:spacing` — the gap between children, in px. Defaults to 0. */
8
+ get spacing(): number;
9
+ set spacing(value: number);
10
+ /** `Gtk.Box:homogeneous` — whether every child gets the same size along the axis. */
11
+ get homogeneous(): boolean;
12
+ set homogeneous(value: boolean);
13
+ connectedCallback(): void;
14
+ attributeChangedCallback(name: string, old: string | null, value: string | null): void;
15
+ private _normalized;
16
+ private _sync;
17
+ }
@@ -2,6 +2,8 @@ export declare class GtkButton extends HTMLElement {
2
2
  private _button;
3
3
  private _label;
4
4
  private _initialized;
5
+ /** `Gtk.Button:child`, or `null` while the icon and the label fill the button. */
6
+ private _child;
5
7
  static get observedAttributes(): string[];
6
8
  /** The inner native button (for focus/imperative access). */
7
9
  get button(): HTMLButtonElement;
@@ -0,0 +1,122 @@
1
+ import { type LabelEllipsizeMode, type LabelJustification, type LabelWrapMode } from '@gjsify/adwaita-core';
2
+ export declare class GtkLabel extends HTMLElement {
3
+ /**
4
+ * The rendered text's own box — present while {@link wrap} is set (so it can be pinned
5
+ * to its measured wrap width, see `_remeasure`) OR while {@link ellipsize} is not
6
+ * `none` (so `overflow`/`text-overflow` have a box of their own to clip, rather than
7
+ * the label's flex container, which also holds the `xalign` spacer pseudo-elements).
8
+ * `null` the rest of the time so a single-line, non-ellipsized label keeps the plain
9
+ * text node `childElementCount` asserts on (`gtk-label.spec.ts`'s XSS note: "the DOM
10
+ * gets one text node").
11
+ */
12
+ private _wrapSpan;
13
+ private _resizes;
14
+ static get observedAttributes(): ("label" | "use-markup" | "use-underline" | "justify" | "wrap" | "xalign" | "yalign" | "wrap-mode" | "ellipsize" | "lines" | "width-chars" | "max-width-chars" | "selectable")[];
15
+ /** `Gtk.Label:label` — the text as written, before markup and the mnemonic come out. */
16
+ get label(): string;
17
+ set label(value: string);
18
+ /** `Gtk.Label:use-markup` — whether {@link label} is Pango markup (shown as its text). */
19
+ get useMarkup(): boolean;
20
+ set useMarkup(value: boolean);
21
+ /** `Gtk.Label:use-underline` — whether an `_` marks a mnemonic (stripped, not bound). */
22
+ get useUnderline(): boolean;
23
+ set useUnderline(value: boolean);
24
+ /** `Gtk.Label:justify` — how the lines align with each other. Defaults to `left`. */
25
+ get justify(): LabelJustification;
26
+ set justify(value: LabelJustification);
27
+ /** `Gtk.Label:xalign` — where the text sits in the label's box, 0…1. Defaults to 0.5. */
28
+ get xalign(): number;
29
+ set xalign(value: number);
30
+ /**
31
+ * `Gtk.Label:yalign` — where the text sits vertically in the label's box, 0…1.
32
+ * Defaults to 0.5. Exact at 0, 0.5 and 1; a DECLARED divergence between them — see
33
+ * `_labels.scss`'s header for why `align-items` has no continuum the way `xalign`'s
34
+ * flex-grow ratio does.
35
+ */
36
+ get yalign(): number;
37
+ set yalign(value: number);
38
+ /** `Gtk.Label:wrap` — whether the text breaks into lines rather than overflowing. */
39
+ get wrap(): boolean;
40
+ set wrap(value: boolean);
41
+ /**
42
+ * `Gtk.Label:wrap-mode` — where a wrapping line may break. Defaults to `word`. Only
43
+ * affects the formatting while the layout can actually span more than one line —
44
+ * {@link wrap}, or {@link ellipsize} being active (`ellipsize`, not just `wrap`, is
45
+ * what gives GTK's own Pango layout a width to break within: `label.ts`'s header in
46
+ * `@gjsify/adwaita-core`).
47
+ */
48
+ get wrapMode(): LabelWrapMode;
49
+ set wrapMode(value: LabelWrapMode);
50
+ /**
51
+ * `Gtk.Label:ellipsize` — where the string is trimmed when it does not fit. Defaults
52
+ * to `none`. `start` and `middle` are HELD faithfully — read `ellipsize` back and it
53
+ * is exactly what was set — but DRAWN as an end-ellipsis: `labelEllipsizeOverflowValue`
54
+ * (`@gjsify/adwaita-core`) says why.
55
+ */
56
+ get ellipsize(): LabelEllipsizeMode;
57
+ set ellipsize(value: LabelEllipsizeMode);
58
+ /**
59
+ * `Gtk.Label:lines` — the line count an ellipsized label is held to. Defaults to -1
60
+ * ("unset"), which still caps at ONE line the moment {@link ellipsize} is active —
61
+ * Pango's own default, not "unlimited". Has no effect at all while ellipsize is
62
+ * `none`, `wrap` or not — `labelEffectiveLines` (`@gjsify/adwaita-core`) is that
63
+ * MEASURED guard, and its own doc comment carries the numbers.
64
+ */
65
+ get lines(): number;
66
+ set lines(value: number);
67
+ /**
68
+ * `Gtk.Label:width-chars` — the label's minimum width, in characters. Defaults to -1
69
+ * (calculated automatically, i.e. unset here).
70
+ */
71
+ get widthChars(): number;
72
+ set widthChars(value: number);
73
+ /**
74
+ * `Gtk.Label:max-width-chars` — the label's natural (maximum) width, in characters.
75
+ * Defaults to -1 (calculated automatically, i.e. unset here).
76
+ */
77
+ get maxWidthChars(): number;
78
+ set maxWidthChars(value: number);
79
+ /** `Gtk.Label:selectable` — whether the text can be selected. GTK's default is not. */
80
+ get selectable(): boolean;
81
+ set selectable(value: boolean);
82
+ /** `gtk_label_get_text` — the text as SHOWN, markup reduced and the marker removed. */
83
+ getText(): string;
84
+ connectedCallback(): void;
85
+ disconnectedCallback(): void;
86
+ private _remeasure;
87
+ attributeChangedCallback(name: string, old: string | null, value: string | null): void;
88
+ private _normalized;
89
+ private _render;
90
+ private _renderSingleLine;
91
+ /**
92
+ * A WRAPPED OR ELLIPSIZED label centres its BLOCK by `xalign` (`gtklabel.c`,
93
+ * `gtk_label_get_layout_location`), not just each line — `_labels.scss`'s two spacer
94
+ * pseudo-elements split the label's FREE space by `xalign`, and a flex item only has
95
+ * free space to give them once it FITS. `flex-basis: auto` sizes the plain text node to
96
+ * its max-content (single-line) width; once that overflows, `flex-shrink` collapses the
97
+ * zero-basis spacers to nothing and stretches the text item to the full container width
98
+ * instead — which is where the offset was lost (the defect this method fixes).
99
+ *
100
+ * NO PURE-CSS FIX EXISTS: `width: fit-content` clamps to that SAME full-container width
101
+ * the moment its content no longer fits one line — CSS shrink-to-fit is
102
+ * `min(max(min-content, available), max-content)`, and `available` IS the container
103
+ * here, not the narrower width GTK's Pango layout actually wrapped to. So this measures
104
+ * instead, in two passes: first let {@link _wrapSpan} wrap at the FULL container width
105
+ * (`width: ''`, the same collapse above, which is exactly the width GTK's own
106
+ * allocation wraps against), then pin the span to its widest resulting line via
107
+ * `Range.getClientRects()`, which gives the pseudo spacers real free space to split.
108
+ * Approximate on purpose, and cheap: one synchronous reflow per render. The pinned
109
+ * width goes stale whenever the available width or the font changes, and a page does
110
+ * both (a rotated phone, an opened sidebar, a web font arriving late), so
111
+ * {@link connectedCallback} re-measures on each resize and once the fonts have loaded.
112
+ *
113
+ * AN ELLIPSIZED SPAN NEEDS THIS TOO, MEASURED THE HARD WAY: an earlier version of this
114
+ * method skipped it for `ellipsize` without `wrap`, reasoning that `white-space: nowrap`
115
+ * text has one width whichever way it is measured. That reasoning stopped applying the
116
+ * moment `ellipsize` alone started wrapping onto MULTIPLE lines to match GTK
117
+ * (`label.ts`'s header) — `white-space: normal` multi-word text has a real
118
+ * min-content/max-content gap, the exact shrink-to-fit collapse the wrapped case above
119
+ * was already written for. One code path now, for both.
120
+ */
121
+ private _renderSpan;
122
+ }
@@ -0,0 +1 @@
1
+ export declare const GioMenuTest: () => Promise<void>;
@@ -0,0 +1 @@
1
+ export declare const GtkBoxTest: () => Promise<void>;
@@ -0,0 +1 @@
1
+ export declare const GtkLabelTest: () => Promise<void>;
@@ -0,0 +1 @@
1
+ export declare const GtkValueDoorsTest: () => Promise<void>;
@@ -3,9 +3,12 @@ export { ACCENT_BG_PROPERTY, ACCENT_PROPERTY, applyAdwaitaAccent, clearAdwaitaAc
3
3
  export type { ApplyAccentOptions } from './accent.js';
4
4
  export { AdwScrollShading } from './scroll-shading.js';
5
5
  export type { AdwUndershootEdges } from './scroll-shading.js';
6
+ export { buildSharedTree, mountSharedTree } from './shared-tree-builder.js';
7
+ export type { MountedSharedTree } from './shared-tree-builder.js';
6
8
  export { isIconAvailable, registerIcon } from './icon-registry.js';
7
9
  export * as Adw from './namespace/adw.js';
8
10
  export * as Gtk from './namespace/gtk.js';
11
+ export * as Gio from './namespace/gio.js';
9
12
  export { AdwCard } from './elements/adw-card.js';
10
13
  export { AdwDataGrid } from './elements/adw-data-grid.js';
11
14
  export type { AdwDataGridAlign, AdwDataGridColumn, AdwDataGridRow, AdwDataGridRowVariant, } from './elements/adw-data-grid.js';
@@ -15,7 +18,7 @@ export { AdwTabPage } from './elements/adw-tab-view.js';
15
18
  export { AdwViewSwitcherPage } from './elements/adw-view-switcher.js';
16
19
  export { AdwViewStackPage } from './elements/adw-inline-view-switcher.js';
17
20
  export { AdwSidebarItem, AdwSidebarSection } from './elements/adw-sidebar.js';
18
- export { AdwBottomSheetContent, AdwBottomSheetSheet } from './elements/adw-bottom-sheet.js';
21
+ export { AdwBottomSheetBottomBar, AdwBottomSheetContent, AdwBottomSheetSheet } from './elements/adw-bottom-sheet.js';
19
22
  export { AdwAlertResponse } from './elements/adw-alert-dialog.js';
20
23
  export type { GtkPopoverAlign, GtkPopoverPosition, GtkPopoverRole } from './elements/gtk-popover.js';
21
24
  export type { AdwViewStackPageInfo } from './elements/adw-view-stack.js';
@@ -0,0 +1 @@
1
+ export { GioMenu as Menu, GioMenuItem as MenuItem } from '@gjsify/adwaita-core';
@@ -1,9 +1,14 @@
1
+ export { GtkAdjustment as Adjustment } from '@gjsify/adwaita-core';
2
+ export { GtkActionBar as ActionBar } from '../elements/gtk-action-bar.js';
3
+ export { GtkBox as Box } from '../elements/gtk-box.js';
1
4
  export { GtkButton as Button } from '../elements/gtk-button.js';
2
5
  export { GtkCheckButton as CheckButton } from '../elements/checks.js';
3
6
  export { GtkDropDown as DropDown } from '../elements/gtk-drop-down.js';
4
7
  export { GtkEntry as Entry } from '../elements/gtk-entry.js';
5
8
  export { GtkImage as Image } from '../elements/gtk-image.js';
9
+ export { GtkLabel as Label } from '../elements/gtk-label.js';
6
10
  export { GtkMenuButton as MenuButton } from '../elements/gtk-menu-button.js';
7
11
  export { GtkPopover as Popover } from '../elements/gtk-popover.js';
8
12
  export { GtkProgressBar as ProgressBar } from '../elements/gtk-progress-bar.js';
13
+ export { GtkStringList as StringList } from '@gjsify/adwaita-core';
9
14
  export { GtkSwitch as Switch } from '../elements/gtk-switch.js';
@@ -0,0 +1,64 @@
1
+ import type { SharedTreeNode } from '@gjsify/adwaita-core/conformance';
2
+ /** One authored placement, kept so {@link mountSharedTree} can hold the renderer to it. */
3
+ interface PlacedChild {
4
+ parent: HTMLElement;
5
+ child: HTMLElement;
6
+ slot: string;
7
+ }
8
+ /** One node that authored `extensions`, kept so {@link mountSharedTree} can hold it too. */
9
+ interface ExtendedNode {
10
+ el: HTMLElement;
11
+ node: SharedTreeNode;
12
+ }
13
+ /** What one build collects for the checks that can only run once the tree is connected. */
14
+ interface BuildRecord {
15
+ placed: PlacedChild[];
16
+ extended: ExtendedNode[];
17
+ }
18
+ /**
19
+ * A `SharedTreeNode`, realised as a DETACHED element tree: a tag, its authored properties as
20
+ * attributes, its style classes as classes, its extensions (ADR 0072) as the markup the element
21
+ * reads, its placement as `slot=`, its children, in that order — recursive and total,
22
+ * no tag list, no per-block case. A boolean authored property is the ATTRIBUTE'S PRESENCE
23
+ * (`toggleAttribute`), which is what every element in the corpus reads
24
+ * (`hasAttribute('revealed')`, `hasAttribute('expanded')`); spelling `"true"` would set a
25
+ * present attribute for `false` as well.
26
+ *
27
+ * EXCEPT AN AUTHORED `false` ON A PROPERTY THE ELEMENT DECLARES. Absence cannot say `false`
28
+ * where the GTK default is TRUE — `AdwNavigationPage:can-pop`, `GtkActionBar:revealed` —
29
+ * because those elements read an absent attribute as that default, so `can-pop: false`
30
+ * reached the page as `can-pop` unset and the page stayed poppable. The element's own
31
+ * property setter knows its attribute convention, so an authored `false` is written
32
+ * through it when the element (already upgraded: `createElement` of a defined tag
33
+ * constructs it) declares one; everything else keeps the presence rule. "Declares" means a
34
+ * member it can WRITE ({@link isWritable}): a getter-only accessor of the same name — the
35
+ * split button's and the menu button's read-only `active` — would throw a bare `TypeError`
36
+ * out of the assignment, so such a property falls back to the presence rule too.
37
+ *
38
+ * THE SLOT IS WRITTEN AS THE ATTRIBUTE THIS RENDERER ALREADY ROUTES ON, not translated:
39
+ * `src/slotted-children.ts` reads `slot=` off every light-DOM child and keeps the routing
40
+ * live. This builder read `tag`, `props` and `children` and dropped `slot` silently until a
41
+ * real `.blp` authored one — the `[top]` header bar landed in `adw-toolbar-view-content` and
42
+ * the window title was then discarded by `<adw-header-bar>`'s own build, at exit 0.
43
+ *
44
+ * NOT YET LIVE — see the file header. Nothing here has run `connectedCallback` until
45
+ * something connects it: {@link mountSharedTree} for the common case, or a caller's own
46
+ * container. A DETACHED build therefore cannot check a slot either: an element that has not
47
+ * upgraded has declared no slots yet, so the refusal below belongs to the mount.
48
+ */
49
+ export declare function buildSharedTree(node: SharedTreeNode, record?: BuildRecord): HTMLElement;
50
+ /** A tree {@link mountSharedTree} built and connected. */
51
+ export interface MountedSharedTree {
52
+ /** The authored root — connected, so every custom element under it has upgraded and run. */
53
+ root: HTMLElement;
54
+ /** Disconnects and discards the mount point. */
55
+ unmount: () => void;
56
+ }
57
+ /**
58
+ * {@link buildSharedTree}, attached under a fresh host `<div>` in `document.body` so the tree
59
+ * — and every custom element in it — is REAL rather than merely constructed. This is the
60
+ * instantiation half a caller reading the corpus's elements normally wants; a bare
61
+ * `buildSharedTree` is for a caller that already has somewhere of its own to attach it.
62
+ */
63
+ export declare function mountSharedTree(node: SharedTreeNode): MountedSharedTree;
64
+ export {};
@@ -1,25 +1,6 @@
1
- import { type StreamParser, type StringStream } from '@codemirror/language';
1
+ import { type StreamParser } from '@codemirror/language';
2
2
  import { type Extension } from '@codemirror/state';
3
3
  import { type Tag } from '@lezer/highlight';
4
- /** The 56 official NMOS 6502 mnemonics (uppercased for case-insensitive match). */
5
- export declare const OPCODES: ReadonlySet<string>;
6
- /** The registers that appear as bare operands (`ASL A`, `LDA $00,X`). */
7
- export declare const REGISTERS: ReadonlySet<string>;
8
- /** Assembler pseudo-ops. `define`/`dcb` are the easy6502 dialect; the rest are
9
- * common cross-assembler directives (with the leading dot handled separately). */
10
- export declare const DIRECTIVE_WORDS: ReadonlySet<string>;
11
- /**
12
- * Classify an identifier-shaped token. Pure + side-effect-free so it is unit
13
- * testable without a CodeMirror stream. `atLineStart` decides whether an
14
- * unknown word is a label DEFINITION (column 0) or a symbol REFERENCE.
15
- */
16
- export declare function classifyWord(word: string, atLineStart: boolean): string;
17
- /**
18
- * Tokenize one token from the stream. Exported for unit tests (feed it a
19
- * `StringStream`). Returns a token-class name (see file header) or `null` for
20
- * whitespace/unclassified punctuation.
21
- */
22
- export declare function token6502(stream: StringStream): string | null;
23
4
  /** Maps this mode's token-class names to @lezer/highlight tags. */
24
5
  export declare const asm6502TokenTable: Record<string, Tag>;
25
6
  /** The StreamParser powering the 6502 mode. */
@@ -1,4 +1,5 @@
1
1
  export { AdwSourceView } from './adw-source-view.js';
2
- export { asm6502, asm6502Parser, asm6502TokenTable, classifyWord, token6502, OPCODES, REGISTERS, DIRECTIVE_WORDS, } from './asm6502.js';
2
+ export { asm6502, asm6502Parser, asm6502TokenTable } from './asm6502.js';
3
3
  export { adwaitaEditorTheme, adwaitaHighlightStyle, ensureSourceViewStyleInjected, SOURCE_VIEW_CSS, SOURCE_VIEW_STYLE_ID, } from './theme.js';
4
- export { formatHexAddress, formatLineNumber, stripWhitespace, HEX_ADDRESS_STRIDE } from './hex.js';
4
+ export { ADW_SOURCE_6502_DIRECTIVES as DIRECTIVE_WORDS, ADW_SOURCE_6502_OPCODES as OPCODES, ADW_SOURCE_6502_REGISTERS as REGISTERS, ADW_SOURCE_HEX_STRIDE as HEX_ADDRESS_STRIDE, classifyAsm6502Word as classifyWord, formatHexAddress, formatLineNumber, stripSourceWhitespace as stripWhitespace, tokenizeAsm6502 as token6502, } from '@gjsify/adwaita-core';
5
+ export type { AdwSourceTokenClass, AdwSourceTokenStream } from '@gjsify/adwaita-core';
@@ -6,7 +6,7 @@ export declare const adwaitaHighlightStyle: HighlightStyle;
6
6
  /** Element id of the injected stylesheet (idempotency guard). */
7
7
  export declare const SOURCE_VIEW_STYLE_ID = "adw-source-view-style";
8
8
  /** The chrome stylesheet: container, copy button, LTR pin, syntax palette. */
9
- export declare const SOURCE_VIEW_CSS = "\n.adw-source-view {\n --adw-src-comment: #5e5c64;\n --adw-src-keyword: #1c71d8;\n --adw-src-number: #c64600;\n --adw-src-string: #26a269;\n --adw-src-label: #813d9c;\n --adw-src-register: #007e8a;\n --adw-src-directive: #a51d2d;\n --adw-src-operator: rgba(0, 0, 6, 0.55);\n --adw-src-selection: color-mix(in srgb, var(--accent-bg-color, #3584e4) 26%, transparent);\n --adw-src-gutter-bg: var(--view-bg-color, #ffffff);\n --adw-src-gutter-fg: rgba(0, 0, 6, 0.35);\n --adw-src-active-line: color-mix(in srgb, var(--view-fg-color, #00000a) 4%, transparent);\n\n /* Source code is inherently LTR \u2014 pin the whole widget so the gutter,\n scrollbar and copy button never mirror under an RTL page. */\n direction: ltr;\n position: relative;\n display: block;\n box-sizing: border-box;\n overflow: hidden;\n border-radius: var(--card-radius, 12px);\n background-color: var(--view-bg-color, #ffffff);\n color: var(--view-fg-color, rgba(0, 0, 6, 0.8));\n}\n\n.adw-source-view .cm-editor {\n border-radius: inherit;\n max-height: 100%;\n}\n\n.adw-source-view.adw-source-view--fill,\n.adw-source-view.adw-source-view--fill .cm-editor {\n height: 100%;\n}\n\n.adw-source-view .cm-editor.cm-focused {\n outline: none;\n}\n\n.adw-source-view__copy {\n position: absolute;\n top: 6px;\n right: 6px;\n z-index: 2;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 30px;\n padding: 0;\n border: none;\n border-radius: var(--button-radius, 9px);\n background-color: color-mix(in srgb, var(--view-bg-color, #ffffff) 82%, transparent);\n color: var(--view-fg-color, rgba(0, 0, 6, 0.75));\n opacity: 0.72;\n cursor: pointer;\n transition: opacity 0.15s ease, background-color 0.15s ease;\n -webkit-backdrop-filter: blur(6px);\n backdrop-filter: blur(6px);\n}\n\n.adw-source-view__copy:hover {\n opacity: 1;\n background-color: var(--button-hover-color, rgba(0, 0, 6, 0.13));\n}\n\n.adw-source-view__copy:active {\n background-color: var(--button-active-color, rgba(0, 0, 6, 0.19));\n}\n\n.adw-source-view__copy:focus-visible {\n opacity: 1;\n outline: 2px solid var(--accent-color, #1c71d8);\n outline-offset: 1px;\n}\n\n.adw-source-view__copy[hidden] {\n display: none;\n}\n\n.adw-source-view__copy svg {\n width: 16px;\n height: 16px;\n display: block;\n}\n\n.adw-source-view__copy .adw-icon {\n width: 16px;\n height: 16px;\n background-color: currentColor;\n -webkit-mask-repeat: no-repeat;\n mask-repeat: no-repeat;\n -webkit-mask-position: center;\n mask-position: center;\n}\n\n@media (prefers-color-scheme: dark) {\n :root:not(.theme-light) .adw-source-view {\n --adw-src-comment: #9a9996;\n --adw-src-keyword: #78aeed;\n --adw-src-number: #ffa348;\n --adw-src-string: #8ff0a4;\n --adw-src-label: #dc8add;\n --adw-src-register: #33d1c9;\n --adw-src-directive: #f66151;\n --adw-src-operator: rgba(255, 255, 255, 0.55);\n --adw-src-gutter-fg: rgba(255, 255, 255, 0.35);\n --adw-src-active-line: color-mix(in srgb, #ffffff 6%, transparent);\n }\n}\n\n:root.theme-dark .adw-source-view {\n --adw-src-comment: #9a9996;\n --adw-src-keyword: #78aeed;\n --adw-src-number: #ffa348;\n --adw-src-string: #8ff0a4;\n --adw-src-label: #dc8add;\n --adw-src-register: #33d1c9;\n --adw-src-directive: #f66151;\n --adw-src-operator: rgba(255, 255, 255, 0.55);\n --adw-src-gutter-fg: rgba(255, 255, 255, 0.35);\n --adw-src-active-line: color-mix(in srgb, #ffffff 6%, transparent);\n}\n";
9
+ export declare const SOURCE_VIEW_CSS: string;
10
10
  /**
11
11
  * Inject the chrome stylesheet once (browser-only, idempotent). Matches the
12
12
  * self-injection pattern of `@gjsify/adwaita-web`'s main entry, so importing
@@ -0,0 +1,4 @@
1
+ import type { AdwComboOption } from '@gjsify/adwaita-core';
2
+ import type { AdwSlotConsume } from './slotted-children.js';
3
+ /** The `model` slot, handing the authored list to `adopt`. */
4
+ export declare function stringListSlot(adopt: (model: AdwComboOption[]) => void): AdwSlotConsume;