@gjsify/adwaita-nativescript 0.30.0 → 0.32.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 (146) hide show
  1. package/lib/esm/index.js +1 -1
  2. package/lib/esm/widgets/adw-action-row.js +1 -1
  3. package/lib/esm/widgets/adw-avatar.js +1 -1
  4. package/lib/esm/widgets/adw-banner.js +1 -1
  5. package/lib/esm/widgets/adw-bottom-sheet.js +1 -1
  6. package/lib/esm/widgets/adw-button-content.js +1 -1
  7. package/lib/esm/widgets/adw-button-row.js +1 -1
  8. package/lib/esm/widgets/adw-carousel.js +1 -1
  9. package/lib/esm/widgets/adw-clamp.js +1 -1
  10. package/lib/esm/widgets/adw-combo-row.js +1 -1
  11. package/lib/esm/widgets/adw-data-grid.js +1 -0
  12. package/lib/esm/widgets/adw-drop-down.js +1 -0
  13. package/lib/esm/widgets/adw-entry-row.js +1 -1
  14. package/lib/esm/widgets/adw-entry.js +1 -0
  15. package/lib/esm/widgets/adw-expander-row.js +1 -1
  16. package/lib/esm/widgets/adw-header-bar.js +1 -1
  17. package/lib/esm/widgets/adw-inline-view-switcher.js +1 -1
  18. package/lib/esm/widgets/adw-navigation-split-view.js +1 -1
  19. package/lib/esm/widgets/adw-navigation-view.js +1 -1
  20. package/lib/esm/widgets/adw-overlay-split-view.js +1 -1
  21. package/lib/esm/widgets/adw-password-entry-row.js +1 -1
  22. package/lib/esm/widgets/adw-preferences-dialog.js +1 -1
  23. package/lib/esm/widgets/adw-preferences-group.js +1 -1
  24. package/lib/esm/widgets/adw-preferences-page.js +1 -1
  25. package/lib/esm/widgets/adw-sidebar.js +1 -1
  26. package/lib/esm/widgets/adw-spin-row.js +1 -1
  27. package/lib/esm/widgets/adw-spinner.js +1 -1
  28. package/lib/esm/widgets/adw-split-button.js +1 -1
  29. package/lib/esm/widgets/adw-status-page.js +1 -1
  30. package/lib/esm/widgets/adw-switch-row.js +1 -1
  31. package/lib/esm/widgets/adw-tab-view.js +1 -1
  32. package/lib/esm/widgets/adw-toolbar-view.js +1 -1
  33. package/lib/esm/widgets/adw-view-stack.js +1 -1
  34. package/lib/esm/widgets/adw-view-switcher-bar.js +1 -1
  35. package/lib/esm/widgets/adw-window-title.js +1 -1
  36. package/lib/esm/widgets/adw-wrap-box.js +1 -1
  37. package/lib/esm/widgets/avatar-color.js +1 -0
  38. package/lib/esm/widgets/bottom-sheet-state.js +1 -0
  39. package/lib/esm/widgets/button-content.js +1 -0
  40. package/lib/esm/widgets/carousel-state.js +1 -0
  41. package/lib/esm/widgets/chrome.js +1 -0
  42. package/lib/esm/widgets/data-grid-model.js +1 -0
  43. package/lib/esm/widgets/entry-row-view.js +1 -0
  44. package/lib/esm/widgets/icon-path.js +2 -2
  45. package/lib/esm/widgets/icons.ios.js +1 -0
  46. package/lib/esm/widgets/index.js +1 -1
  47. package/lib/esm/widgets/navigation-stack.js +1 -0
  48. package/lib/esm/widgets/preferences-group-state.js +1 -0
  49. package/lib/esm/widgets/preferences-search.js +1 -0
  50. package/lib/esm/widgets/row-state.js +1 -0
  51. package/lib/esm/widgets/sidebar-model.js +1 -0
  52. package/lib/esm/widgets/split-button.js +1 -0
  53. package/lib/esm/widgets/split-view-base.js +1 -1
  54. package/lib/esm/widgets/split-view-state.js +1 -0
  55. package/lib/esm/widgets/split-view-width.js +1 -0
  56. package/lib/esm/widgets/status-page-content.js +1 -0
  57. package/lib/esm/widgets/svg-path.js +2 -0
  58. package/lib/esm/widgets/tab-view-state.js +1 -0
  59. package/lib/esm/widgets/view-stack-state.js +1 -0
  60. package/lib/esm/widgets/view-switcher-base.js +1 -1
  61. package/lib/esm/widgets/view-switcher-model.js +1 -0
  62. package/lib/esm/widgets/wrap-box-layout.js +1 -0
  63. package/lib/types/banner.spec.d.ts +2 -0
  64. package/lib/types/bottom-sheet.spec.d.ts +2 -0
  65. package/lib/types/button-content.spec.d.ts +2 -0
  66. package/lib/types/carousel.spec.d.ts +1 -0
  67. package/lib/types/chrome.spec.d.ts +2 -0
  68. package/lib/types/data-grid.spec.d.ts +2 -0
  69. package/lib/types/drop-down.spec.d.ts +2 -0
  70. package/lib/types/entry-rows.spec.d.ts +2 -0
  71. package/lib/types/entry.spec.d.ts +2 -0
  72. package/lib/types/index.d.ts +2 -2
  73. package/lib/types/navigation-view.spec.d.ts +2 -0
  74. package/lib/types/preferences.spec.d.ts +2 -0
  75. package/lib/types/row-state.spec.d.ts +2 -0
  76. package/lib/types/sidebar.spec.d.ts +1 -0
  77. package/lib/types/split-button.spec.d.ts +1 -0
  78. package/lib/types/split-view-state.spec.d.ts +2 -0
  79. package/lib/types/split-view-width.spec.d.ts +2 -0
  80. package/lib/types/status-page.spec.d.ts +2 -0
  81. package/lib/types/svg-path.spec.d.ts +2 -0
  82. package/lib/types/tab-view.spec.d.ts +2 -0
  83. package/lib/types/view-stack.spec.d.ts +2 -0
  84. package/lib/types/view-switcher.spec.d.ts +1 -0
  85. package/lib/types/widgets/adw-action-row.d.ts +63 -7
  86. package/lib/types/widgets/adw-avatar.d.ts +2 -7
  87. package/lib/types/widgets/adw-banner.d.ts +26 -7
  88. package/lib/types/widgets/adw-bottom-sheet.d.ts +29 -11
  89. package/lib/types/widgets/adw-button-content.d.ts +41 -6
  90. package/lib/types/widgets/adw-button-row.d.ts +31 -9
  91. package/lib/types/widgets/adw-carousel.d.ts +70 -15
  92. package/lib/types/widgets/adw-clamp.d.ts +21 -4
  93. package/lib/types/widgets/adw-data-grid.d.ts +73 -0
  94. package/lib/types/widgets/adw-drop-down.d.ts +45 -0
  95. package/lib/types/widgets/adw-entry-row.d.ts +98 -2
  96. package/lib/types/widgets/adw-entry.d.ts +43 -0
  97. package/lib/types/widgets/adw-expander-row.d.ts +3 -0
  98. package/lib/types/widgets/adw-header-bar.d.ts +11 -2
  99. package/lib/types/widgets/adw-inline-view-switcher.d.ts +26 -0
  100. package/lib/types/widgets/adw-navigation-split-view.d.ts +2 -1
  101. package/lib/types/widgets/adw-navigation-view.d.ts +71 -16
  102. package/lib/types/widgets/adw-overlay-split-view.d.ts +29 -2
  103. package/lib/types/widgets/adw-password-entry-row.d.ts +33 -3
  104. package/lib/types/widgets/adw-preferences-dialog.d.ts +18 -0
  105. package/lib/types/widgets/adw-preferences-group.d.ts +56 -8
  106. package/lib/types/widgets/adw-preferences-page.d.ts +32 -1
  107. package/lib/types/widgets/adw-sidebar.d.ts +49 -7
  108. package/lib/types/widgets/adw-spinner.d.ts +8 -3
  109. package/lib/types/widgets/adw-split-button.d.ts +48 -13
  110. package/lib/types/widgets/adw-status-page.d.ts +5 -10
  111. package/lib/types/widgets/adw-switch-row.d.ts +21 -1
  112. package/lib/types/widgets/adw-tab-view.d.ts +129 -15
  113. package/lib/types/widgets/adw-toolbar-view.d.ts +39 -0
  114. package/lib/types/widgets/adw-view-stack.d.ts +30 -27
  115. package/lib/types/widgets/adw-view-switcher-bar.d.ts +22 -10
  116. package/lib/types/widgets/adw-window-title.d.ts +12 -8
  117. package/lib/types/widgets/adw-wrap-box.d.ts +21 -4
  118. package/lib/types/widgets/avatar-color.d.ts +14 -0
  119. package/lib/types/widgets/bottom-sheet-state.d.ts +73 -0
  120. package/lib/types/widgets/button-content.d.ts +43 -0
  121. package/lib/types/widgets/carousel-state.d.ts +85 -0
  122. package/lib/types/widgets/chrome.d.ts +159 -0
  123. package/lib/types/widgets/data-grid-model.d.ts +104 -0
  124. package/lib/types/widgets/entry-row-view.d.ts +88 -0
  125. package/lib/types/widgets/icon-path.d.ts +20 -0
  126. package/lib/types/widgets/icons.ios.d.ts +13 -0
  127. package/lib/types/widgets/index.d.ts +20 -5
  128. package/lib/types/widgets/navigation-stack.d.ts +153 -0
  129. package/lib/types/widgets/preferences-group-state.d.ts +52 -0
  130. package/lib/types/widgets/preferences-search.d.ts +68 -0
  131. package/lib/types/widgets/row-state.d.ts +71 -0
  132. package/lib/types/widgets/sidebar-model.d.ts +18 -0
  133. package/lib/types/widgets/split-button.d.ts +55 -0
  134. package/lib/types/widgets/split-view-base.d.ts +55 -12
  135. package/lib/types/widgets/split-view-state.d.ts +196 -0
  136. package/lib/types/widgets/split-view-width.d.ts +76 -0
  137. package/lib/types/widgets/status-page-content.d.ts +23 -0
  138. package/lib/types/widgets/svg-path.d.ts +28 -0
  139. package/lib/types/widgets/tab-view-state.d.ts +74 -0
  140. package/lib/types/widgets/view-stack-state.d.ts +35 -0
  141. package/lib/types/widgets/view-switcher-base.d.ts +61 -32
  142. package/lib/types/widgets/view-switcher-model.d.ts +114 -0
  143. package/lib/types/widgets/wrap-box-layout.d.ts +43 -0
  144. package/lib/types/wrap-box.spec.d.ts +2 -0
  145. package/package.json +7 -7
  146. package/src/theme/adwaita.css +393 -8
@@ -1,20 +1,134 @@
1
- import type { StackLayout } from '@nativescript/core';
2
- import { AdwViewSwitcherBase, type AdwViewPage } from './view-switcher-base.js';
3
- export declare class AdwTabView extends AdwViewSwitcherBase {
4
- /** The per-tab close buttons, parallel to {@link AdwViewSwitcherBase._buttons}. */
5
- private readonly _closeButtons;
1
+ import { GridLayout, type EventData, type View } from '@nativescript/core';
2
+ import type { AdwTabPageSpec, TabViewPagesChange } from '@gjsify/adwaita-core';
3
+ import { type AdwTabPage, type TabViewNotifyPayload } from './tab-view-state.js';
4
+ import type { AdwViewPage } from './view-switcher-base.js';
5
+ export type { AdwTabPage };
6
+ /** Event name emitted when the selected page changes. Mirrors `notify::selected-page`. */
7
+ export declare const NOTIFY_SELECTED_PAGE = "notify::selected-page";
8
+ /** Event name emitted for every page-list change (attach / detach / reorder / pin / update). */
9
+ export declare const PAGES_CHANGED = "pages-changed";
10
+ /** Event name emitted for every close ATTEMPT, before the verdict is applied. */
11
+ export declare const CLOSE_PAGE = "close-page";
12
+ /** Payload of {@link NOTIFY_SELECTED_PAGE}. */
13
+ export interface NotifySelectedPageEventData extends EventData, TabViewNotifyPayload {
14
+ }
15
+ /** Payload of {@link PAGES_CHANGED} — the core's page-list change, verbatim. */
16
+ export interface PagesChangedEventData extends EventData, TabViewPagesChange {
17
+ }
18
+ /** Payload of {@link CLOSE_PAGE}. */
19
+ export interface ClosePageEventData extends EventData {
20
+ /** The page being asked about. */
21
+ id: string;
22
+ /** Its index while it is still in the view. */
23
+ index: number;
24
+ }
25
+ export declare class AdwTabView extends GridLayout {
26
+ private readonly _state;
27
+ private readonly _bar;
28
+ private readonly _contentArea;
29
+ /** Tab chips keyed by page id — the bar is edited in place, never rebuilt. */
30
+ private readonly _chips;
31
+ private _autohide;
32
+ private _defaultIcon;
33
+ private _generatedIds;
34
+ /**
35
+ * The `close-page` decision seam. Return `true` to confirm, `false` to deny,
36
+ * `'defer'` to hold the page until {@link closePageFinish} — which is how an
37
+ * app shows a "save before closing?" dialog. Unset takes libadwaita's own
38
+ * default, `!page.pinned` (adw-tab-view.c:1990-1991).
39
+ *
40
+ * A PROPERTY rather than an event return value because NS events cannot
41
+ * carry one; {@link CLOSE_PAGE} still fires for every attempt, so observing
42
+ * and deciding stay separable.
43
+ */
44
+ closeHandler: ((page: AdwTabPage) => boolean | 'defer') | null;
6
45
  constructor();
7
- protected get barClass(): string;
8
- protected get buttonClass(): string;
9
- /** Append a small ✕ close button to each tab (shown only when active). */
10
- protected _buildButtonExtras(button: StackLayout, _page: AdwViewPage, index: number): void;
11
- /** Reveal the close button only on the active tab (touch analogue of hover). */
12
- protected _applyButtonState(_button: StackLayout, index: number, active: boolean): void;
13
- /** Remove a tab + its page (no-op when only one tab remains). */
14
- private _closeTab;
15
- /** Rebuild from scratch — drop the stale per-tab close-button refs first. */
46
+ /** All pages in order. */
47
+ get pages(): readonly AdwTabPage[];
48
+ /** Number of pages. */
49
+ get nPages(): number;
50
+ /** Length of the pinned prefix. */
51
+ get nPinnedPages(): number;
52
+ /** Id of the selected page, `null` when the view is empty. */
53
+ get selectedId(): string | null;
54
+ /** Index of the selected page, `-1` when the view is empty — never 0 for an empty view. */
55
+ get selectedIndex(): number;
56
+ /** The selected page index. Setting it IGNORES a non-integer or out-of-range value. */
57
+ get selected(): number;
58
+ set selected(value: number);
59
+ isClosing(id: string): boolean;
60
+ setSelectedPage(id: string | null): boolean;
61
+ selectNthPage(n: number): boolean;
62
+ selectPreviousPage(): boolean;
63
+ selectNextPage(): boolean;
64
+ selectFirstPage(): boolean;
65
+ selectLastPage(): boolean;
66
+ /** The next page, WRAPPING to the first (Ctrl+Tab). */
67
+ cycleNextPage(): boolean;
68
+ /** The previous page, WRAPPING to the last (Ctrl+Shift+Tab). */
69
+ cyclePreviousPage(): boolean;
70
+ /** Add a page opened FROM `parentId`, deriving its position (Adw.TabView.add_page). */
71
+ addPage(spec: AdwTabPageSpec<View>, parentId?: string | null): number;
72
+ insertPage(spec: AdwTabPageSpec<View>, position: number): number;
73
+ prependPage(spec: AdwTabPageSpec<View>): number;
74
+ appendPage(spec: AdwTabPageSpec<View>): number;
75
+ insertPinnedPage(spec: AdwTabPageSpec<View>, position: number): number;
76
+ prependPinnedPage(spec: AdwTabPageSpec<View>): number;
77
+ appendPinnedPage(spec: AdwTabPageSpec<View>): number;
78
+ /** Pin or unpin a page, re-ordering it in the same step. Returns its new position. */
79
+ setPagePinned(id: string, pinned: boolean): number;
80
+ /** Request a close. Fires {@link CLOSE_PAGE}, then applies {@link closeHandler}'s verdict. */
81
+ closePage(id: string): boolean;
82
+ closePageFinish(id: string, confirm: boolean): boolean;
83
+ closeOtherPages(id: string): void;
84
+ closePagesBefore(id: string): void;
85
+ closePagesAfter(id: string): void;
86
+ /** Remove a page unconditionally, running the successor rule first. */
87
+ detachPage(id: string): AdwTabPage | null;
88
+ reorderPage(id: string, position: number): boolean;
89
+ reorderBackward(id: string): boolean;
90
+ reorderForward(id: string): boolean;
91
+ reorderFirst(id: string): boolean;
92
+ reorderLast(id: string): boolean;
93
+ setPageTitle(id: string, title: string | null): boolean;
94
+ setPageIcon(id: string, icon: string | null): boolean;
95
+ setPageLoading(id: string, loading: boolean): boolean;
96
+ setPageNeedsAttention(id: string, needsAttention: boolean): boolean;
97
+ /** Every precondition the model refused, as C would have warned about it. */
98
+ get diagnostics(): readonly string[];
99
+ /**
100
+ * Whether the tab bar hides itself when it has nothing to show
101
+ * (`Adw.TabBar:autohide`, adw-tab-bar.c:142-164). Defaults to `false` rather
102
+ * than to the platform's `DEFAULT_TAB_AUTOHIDE`, so a bar that was always
103
+ * visible before this lift stays visible unless asked otherwise.
104
+ */
105
+ get autohide(): boolean;
106
+ set autohide(value: boolean);
107
+ /** `Adw.TabView:default-icon` — what a PINNED page with no icon of its own shows. */
108
+ get defaultIcon(): string | null;
109
+ set defaultIcon(value: string | null);
110
+ /**
111
+ * Replace every page from a plain `{ title, content, icon? }` list.
112
+ *
113
+ * Kept because that was this widget's only API before the lift, when it
114
+ * derived from `AdwViewSwitcherBase` and rebuilt the whole bar on every
115
+ * change. It now goes through the model — each entry becomes an appended page
116
+ * with a generated id — so the incremental bar, the close protocol and the
117
+ * selection rules apply to it too.
118
+ */
16
119
  setViews(pages: AdwViewPage[]): void;
17
- /** The tab pages — an alias of the shared {@link AdwViewSwitcherBase.views}. */
120
+ /** The pages as a plain list — the shape {@link setViews} takes. */
121
+ get views(): AdwViewPage[];
122
+ set views(pages: AdwViewPage[]);
123
+ /** Alias of {@link views}, matching the widget's own vocabulary. */
18
124
  get tabs(): AdwViewPage[];
19
125
  set tabs(pages: AdwViewPage[]);
126
+ private _onPagesChange;
127
+ private _insertChip;
128
+ private _refreshChip;
129
+ /** Show only the selected page, mark its chip active, gate the close buttons. */
130
+ private _applySelection;
131
+ private _applyBarVisibility;
132
+ private _requestClose;
133
+ private _nextId;
20
134
  }
@@ -1,4 +1,5 @@
1
1
  import { GridLayout, StackLayout, View } from '@nativescript/core';
2
+ import { type AdwToolbarStyle } from './chrome.js';
2
3
  export declare class AdwToolbarView extends GridLayout {
3
4
  /** The top-bar slot (row 0) — stack of header bars / toolbars. */
4
5
  protected readonly _topBox: StackLayout;
@@ -6,6 +7,7 @@ export declare class AdwToolbarView extends GridLayout {
6
7
  protected readonly _bottomBox: StackLayout;
7
8
  /** The currently-installed content view (row 1), if any. */
8
9
  private _content;
10
+ private _props;
9
11
  constructor();
10
12
  /** Append a widget (e.g. an {@link AdwHeaderBar}) to the top-bar slot. */
11
13
  addTopBar(view: View): void;
@@ -19,4 +21,41 @@ export declare class AdwToolbarView extends GridLayout {
19
21
  get topBar(): StackLayout;
20
22
  /** The bottom-bar slot container. */
21
23
  get bottomBar(): StackLayout;
24
+ /** `Adw.ToolbarView:top-bar-style` — `flat` (default), `raised` or `raised-border`. */
25
+ get topBarStyle(): AdwToolbarStyle;
26
+ set topBarStyle(value: AdwToolbarStyle);
27
+ /** `Adw.ToolbarView:bottom-bar-style` — `flat` (default), `raised` or `raised-border`. */
28
+ get bottomBarStyle(): AdwToolbarStyle;
29
+ set bottomBarStyle(value: AdwToolbarStyle);
30
+ /** `Adw.ToolbarView:extend-content-to-top-edge` — draw the top bar OVER the content. */
31
+ get extendContentToTopEdge(): boolean;
32
+ set extendContentToTopEdge(value: boolean);
33
+ /** `Adw.ToolbarView:extend-content-to-bottom-edge` — draw the bottom bar OVER the content. */
34
+ get extendContentToBottomEdge(): boolean;
35
+ set extendContentToBottomEdge(value: boolean);
36
+ /**
37
+ * Put each bar box in its own row, or — when the content extends under it —
38
+ * in the CONTENT row pinned to that edge, which is how an NS `GridLayout`
39
+ * spells "the content spans the full height and the bar overlays it".
40
+ */
41
+ private _applyBarPlacement;
42
+ /**
43
+ * Re-append the bar boxes so they sit ON TOP of the content.
44
+ *
45
+ * NativeScript paints siblings in add order, and an extended bar shares a
46
+ * grid cell with the content — which is added later, so without this the
47
+ * content would cover the very bar it is supposed to scroll under. A no-op
48
+ * while neither edge is extended, since the boxes then have their own rows.
49
+ */
50
+ private _restackBars;
51
+ /**
52
+ * Re-derive the four libadwaita style classes from the current state.
53
+ *
54
+ * Composed against the CURRENT class names rather than the base ones, so a
55
+ * class a consumer appended survives (the storybook appends
56
+ * `sb-sidebar-pane` to one of these). Each assignment is guarded on a real
57
+ * change: this runs from `layoutChanged`, and re-styling a view can schedule
58
+ * another layout pass.
59
+ */
60
+ private _syncClasses;
22
61
  }
@@ -1,46 +1,49 @@
1
1
  import { GridLayout, View, type EventData } from '@nativescript/core';
2
+ import { type AdwViewStackPage, type ViewStackNotifyPayload } from './view-stack-state.js';
3
+ export type { AdwViewStackPage };
2
4
  /** Event name emitted when the visible child changes. Mirrors GObject `notify::visible-child`. */
3
5
  export declare const NOTIFY_VISIBLE_CHILD = "notify::visible-child";
4
- /** Payload of the {@link NOTIFY_VISIBLE_CHILD} event. */
5
- export interface NotifyVisibleChildEventData extends EventData {
6
- /** The newly-visible page's index. */
7
- index: number;
8
- /** The newly-visible page's name. */
9
- name: string;
10
- /** The newly-visible page's title. */
11
- title: string;
12
- }
13
- /** One page registered with an {@link AdwViewStack}. */
14
- export interface AdwViewStackPage {
15
- /** Stable identifier used by `visibleChildName` / switcher binding. */
16
- name: string;
17
- /** Human-facing title shown in a bound switcher button. */
18
- title: string;
19
- /** Optional Adwaita symbolic SVG shown in a bound switcher button. */
20
- icon?: string;
21
- /** The page content view, shown when this page is selected. */
22
- content: View;
6
+ /**
7
+ * Payload of the {@link NOTIFY_VISIBLE_CHILD} event. `index` is `-1` and
8
+ * `name`/`title` are `''` when nothing is selected — the state an empty stack, a
9
+ * fully-hidden stack and a removed visible page all land in.
10
+ */
11
+ export interface NotifyVisibleChildEventData extends EventData, ViewStackNotifyPayload {
23
12
  }
24
13
  export declare class AdwViewStack extends GridLayout {
25
- private readonly _pages;
26
- private _visibleIndex;
14
+ private readonly _state;
27
15
  constructor();
28
16
  /**
29
- * Register a page. The FIRST page added becomes visible automatically so the
30
- * stack is never empty, matching `Adw.ViewStack`. Returns the page handle.
17
+ * Register a page. It becomes visible when nothing is selected yet — and,
18
+ * unlike before, that auto-pick NOTIFIES, so a bound switcher highlights the
19
+ * initial page without a manual `refresh()` (`add_page`,
20
+ * adw-view-stack.c:1149-1151 → the notify at :1038-1039). Returns the page handle.
31
21
  */
32
22
  add(content: View, name: string, title?: string, icon?: string): AdwViewStackPage;
33
23
  /** Convenience alias matching `Adw.ViewStack.add_titled`. */
34
24
  addTitled(content: View, name: string, title: string): AdwViewStackPage;
25
+ /**
26
+ * Remove the first page named `name` and detach its content view. Returns
27
+ * whether anything was removed. When the removed page was the visible one the
28
+ * stack ends up showing NOTHING and emits no event — `stack_remove` clears
29
+ * `visible_child` without re-picking (adw-view-stack.c:1202-1203).
30
+ */
31
+ removePage(name: string): boolean;
32
+ /**
33
+ * Show or hide a page (`AdwViewStackPage:visible`). Returns whether the
34
+ * SELECTION moved: hiding the visible page falls back to the next visible one
35
+ * and making a page visible while nothing is selected selects it
36
+ * (`update_child_visible`, adw-view-stack.c:1061-1082).
37
+ */
38
+ setPageVisible(name: string, visible: boolean): boolean;
35
39
  /** All registered pages, in add order (a bound switcher reads this). */
36
40
  get pages(): readonly AdwViewStackPage[];
37
- /** The visible page index. Swaps the visible page + emits `notify::visible-child`. */
41
+ /** The visible page index, `-1` when nothing is selected. Swaps the visible page + emits. */
38
42
  get visibleChildIndex(): number;
39
43
  set visibleChildIndex(value: number);
40
- /** The visible page name (`Adw.ViewStack.visible-child-name`). */
44
+ /** The visible page name (`Adw.ViewStack.visible-child-name`), `''` for none. */
41
45
  get visibleChildName(): string;
42
- set visibleChildName(name: string);
46
+ set visibleChildName(name: string | null | undefined);
43
47
  /** The visible page content view, or `null`. */
44
48
  get visibleChild(): View | null;
45
- private _apply;
46
49
  }
@@ -3,11 +3,10 @@ import { AdwViewStack } from './adw-view-stack.js';
3
3
  export declare class AdwViewSwitcherBar extends GridLayout {
4
4
  /** The horizontal (homogeneous) row of buttons. */
5
5
  private readonly _bar;
6
- /** The tappable button containers, one per stack page, in page order. */
7
- private readonly _buttons;
6
+ private _nodes;
8
7
  private _stack;
9
8
  private _stackListener;
10
- private _revealed;
9
+ private readonly _barState;
11
10
  constructor();
12
11
  /** Bind to an {@link AdwViewStack}: build buttons from its pages + two-way sync. */
13
12
  setStack(stack: AdwViewStack | null): void;
@@ -15,15 +14,28 @@ export declare class AdwViewSwitcherBar extends GridLayout {
15
14
  get stack(): AdwViewStack | null;
16
15
  set stack(value: AdwViewStack | null);
17
16
  /**
18
- * Whether the bar is shown (`Adw.ViewSwitcherBar.reveal`). An adaptive layout
19
- * sets this `true` on narrow screens and `false` on wide ones (where a header-bar
20
- * `AdwViewSwitcher` takes over).
17
+ * Whether the layout asked for the bar — `Adw.ViewSwitcherBar:reveal`. An
18
+ * adaptive layout sets it `true` on narrow screens and `false` on wide ones,
19
+ * where a header-bar `AdwViewSwitcher` takes over.
20
+ */
21
+ get reveal(): boolean;
22
+ set reveal(value: boolean);
23
+ /**
24
+ * Whether the bar is actually shown. READ-ONLY: a one-page stack keeps it
25
+ * collapsed however loudly the layout asks (adw-view-switcher-bar.c:125).
26
+ * Write {@link reveal} to make the request.
21
27
  */
22
28
  get revealed(): boolean;
23
- set revealed(value: boolean);
24
- /** Rebuild the button row from the bound stack's pages (call after late page adds). */
29
+ /**
30
+ * Rebuild the button row from the bound stack's pages — needed after pages
31
+ * were added without changing the stack's selection. libadwaita rebuilds on
32
+ * the pages model's `items-changed` (adw-view-switcher.c:258-263), which the
33
+ * NS stack has no counterpart for.
34
+ */
25
35
  refresh(): void;
36
+ private _bindStack;
37
+ private _unbindStack;
26
38
  private _rebuild;
27
- /** Mark the button for the stack's visible page active (accent label via CSS). */
28
- private _syncActive;
39
+ private _buildButton;
40
+ private _applyRevealed;
29
41
  }
@@ -1,19 +1,23 @@
1
1
  import { Label, StackLayout } from '@nativescript/core';
2
+ /** Event name emitted when {@link AdwWindowTitle.title} changes. */
3
+ export declare const NOTIFY_TITLE = "notify::title";
4
+ /** Event name emitted when {@link AdwWindowTitle.subtitle} changes. */
5
+ export declare const NOTIFY_SUBTITLE = "notify::subtitle";
2
6
  export declare class AdwWindowTitle extends StackLayout {
3
7
  /** The bold title label. */
4
8
  protected readonly _titleLabel: Label;
5
- /** The dim subtitle label (created lazily — only in the tree when set). */
9
+ /** The dim subtitle label. */
6
10
  protected readonly _subtitleLabel: Label;
7
- private _hasSubtitle;
11
+ /** The headless title/subtitle pair + change detection (ADR 0004). */
12
+ private readonly _state;
8
13
  constructor();
9
- /** The window title (bold, top line). */
14
+ /** The window title (bold, top line). Empty collapses its label. */
10
15
  get title(): string;
11
16
  set title(value: string);
12
- /**
13
- * The subtitle (dim second line). Setting a non-empty value adds the subtitle
14
- * label; setting empty removes it — so an empty subtitle leaves no blank gap,
15
- * matching `Adw.WindowTitle`.
16
- */
17
+ /** The subtitle (dim second line). Empty collapses its label. */
17
18
  get subtitle(): string;
18
19
  set subtitle(value: string);
20
+ /** Push the derived text + visibility onto the two `Label`s. */
21
+ private _apply;
22
+ private _notify;
19
23
  }
@@ -3,15 +3,32 @@ export declare class AdwWrapBox extends WrapLayout {
3
3
  private _childSpacing;
4
4
  private _lineSpacing;
5
5
  constructor();
6
- /** Append a child; applies the uniform child/line spacing as a margin. */
6
+ /** Append a child. */
7
7
  add(view: View): void;
8
8
  /** Remove a previously-added child. */
9
9
  remove(view: View): void;
10
- private _applySpacing;
11
- /** Horizontal gap between items in a line, in DIPs. */
10
+ /**
11
+ * Every path a child can enter by — `add()`, a direct `addChild()`, and XML
12
+ * inflation via `_addChildFromBuilder` — ends here, which is why the spacing
13
+ * is applied here and not in `add()`. It used to be applied in `add()` only,
14
+ * so a child declared in markup got no spacing at all; C routes GtkBuildable's
15
+ * `add_child` through the same append for the same reason.
16
+ */
17
+ addChild(view: View): void;
18
+ /** Horizontal gap between items in a line, in DIPs. Defaults to 0, as in C. */
12
19
  get childSpacing(): number;
13
20
  set childSpacing(value: number);
14
- /** Vertical gap between wrapped lines, in DIPs. */
21
+ /** Vertical gap between wrapped lines, in DIPs. Defaults to 0, as in C. */
15
22
  get lineSpacing(): number;
16
23
  set lineSpacing(value: number);
24
+ /**
25
+ * Re-apply the spacing to every child already in the tree.
26
+ *
27
+ * The spacing used to be baked in at add time, so `box.childSpacing = 12`
28
+ * after the children were added did nothing; `adw_wrap_box_set_child_spacing`
29
+ * hands the new value to the layout manager, which re-runs the allocation for
30
+ * children that are already there.
31
+ */
32
+ private _applySpacingToChildren;
33
+ private _applySpacing;
17
34
  }
@@ -0,0 +1,14 @@
1
+ import { avatarInitials } from '@gjsify/adwaita-core';
2
+ export { avatarInitials };
3
+ /** A flat avatar fill plus the light initials colour that goes on top of it. */
4
+ export interface NsAvatarColor {
5
+ /** The gradient collapsed to a single `#rrggbb` background. */
6
+ fill: string;
7
+ /** The palette's light `fg`, for the initials label. */
8
+ fg: string;
9
+ }
10
+ /**
11
+ * The fill + initials colour `Adw.Avatar` would paint for `text`, flattened for
12
+ * the NativeScript CSS subset.
13
+ */
14
+ export declare function avatarColor(text: string): NsAvatarColor;
@@ -0,0 +1,73 @@
1
+ import type { EventData, View } from '@nativescript/core';
2
+ import { BottomSheetPresentation } from '@gjsify/adwaita-core';
3
+ import type { BottomSheetCloseOutcome, BottomSheetCloseSource } from '@gjsify/adwaita-core';
4
+ /** Event name emitted when the sheet's open state changes. Mirrors GObject `notify::open`. */
5
+ export declare const NOTIFY_OPEN = "notify::open";
6
+ /**
7
+ * Event name emitted when a dismissal is refused. Mirrors the
8
+ * `AdwBottomSheet::close-attempt` signal (adw-bottom-sheet.c:1010-1026).
9
+ */
10
+ export declare const CLOSE_ATTEMPT = "close-attempt";
11
+ /**
12
+ * Event name emitted when the `sheet.close` action is used on an ALREADY-closed
13
+ * sheet, so the host can forward it to an enclosing sheet/dialog — the NS
14
+ * equivalent of `gtk_widget_activate_action (parent, "sheet.close")`
15
+ * (adw-bottom-sheet.c:382-385).
16
+ */
17
+ export declare const SHEET_CLOSE = "sheet.close";
18
+ /** Payload of the `notify::open` event. */
19
+ export interface NotifyOpenEventData extends EventData {
20
+ /** Whether the sheet is now open. */
21
+ open: boolean;
22
+ }
23
+ /** The two `View.visibility` values the sheet panel ever takes. */
24
+ export type NsSheetVisibility = 'visible' | 'collapse';
25
+ /** The open/can-close model an `AdwBottomSheet` delegates to. */
26
+ export declare function createBottomSheetPresentation(): BottomSheetPresentation;
27
+ /**
28
+ * The `visibility` the sheet panel must carry for the current open state. NS has
29
+ * no transform transition in its CSS subset, so the reveal is instant — the
30
+ * spring animation and its intermediate `progress` are not modelled here.
31
+ */
32
+ export declare function sheetVisibility(open: boolean): NsSheetVisibility;
33
+ /** Push {@link sheetVisibility} onto the real panel view. */
34
+ export declare function applySheetVisibility(panel: View, open: boolean): void;
35
+ /**
36
+ * Which event a gate verdict makes the widget emit, or `null` when it emits
37
+ * nothing.
38
+ *
39
+ * `'close'` is absent on purpose: the state applies it, and the resulting
40
+ * `notify::open` IS the notification. `'ignored'` is the genuinely silent one —
41
+ * a locked sheet swallowing a swipe, or a tap on the decorative drag handle.
42
+ */
43
+ export declare function bottomSheetCloseEvent(outcome: BottomSheetCloseOutcome): string | null;
44
+ /** What a dismissal request produced: the verdict plus the event to emit, if any. */
45
+ export interface BottomSheetCloseResult {
46
+ /** The gate's verdict, already applied to the state. */
47
+ outcome: BottomSheetCloseOutcome;
48
+ /** Event name for `notify()`, or `null` when the gate is silent. */
49
+ eventName: string | null;
50
+ }
51
+ /**
52
+ * The whole of `AdwBottomSheet.requestClose` except the `notify()` call.
53
+ *
54
+ * It lives HERE rather than inside the `extends GridLayout` module so the spec
55
+ * can drive the real path: a spec that re-assembled `state.requestClose()` and
56
+ * `bottomSheetCloseEvent()` itself would be transcribing the code under test and
57
+ * could not detect the drift it exists to catch.
58
+ */
59
+ export declare function requestBottomSheetClose(state: BottomSheetPresentation, source: BottomSheetCloseSource): BottomSheetCloseResult;
60
+ /**
61
+ * Add a marker class to a view's `className` exactly once.
62
+ *
63
+ * libadwaita never writes to the child's own style classes — the marker lives on
64
+ * the internal bin (`adw_bottom_sheet_set_content`, adw-bottom-sheet.c:1497-1510).
65
+ * This port does write it, and used to do so with a bare string concat, so
66
+ * `setContent(v)` twice left `'adw-bottom-sheet-content adw-bottom-sheet-content'`.
67
+ */
68
+ export declare function addMarkerClass(className: string | null | undefined, marker: string): string;
69
+ /**
70
+ * Drop a marker class again — a view replaced by another must not keep the
71
+ * marker of the slot it no longer occupies.
72
+ */
73
+ export declare function removeMarkerClass(className: string | null | undefined, marker: string): string;
@@ -0,0 +1,43 @@
1
+ import { BUTTON_CONTENT_STYLE_CLASS, buttonContentEllipsize, buttonContentLabelText, buttonContentLabelVisible } from '@gjsify/adwaita-core';
2
+ import type { ButtonContentEllipsize } from '@gjsify/adwaita-core';
3
+ export { BUTTON_CONTENT_STYLE_CLASS, buttonContentEllipsize, buttonContentLabelText, buttonContentLabelVisible };
4
+ export type { ButtonContentEllipsize };
5
+ /** The class the content carries while `can-shrink` is set, for the theme to key off. */
6
+ export declare const BUTTON_CONTENT_CAN_SHRINK_CLASS = "can-shrink";
7
+ /**
8
+ * The SVG the icon view is given: the app's, or the `image-missing` asset for an
9
+ * empty slot.
10
+ *
11
+ * That fallback is `gtk_image_set_from_icon_name (icon, "image-missing")`
12
+ * (adw-button-content.c:355-356), applied by `init` too while `icon_name` is
13
+ * still `""` (:284, :294). The widget NEVER hides the image — only the label
14
+ * (:300, :398) — so this port keeps the icon view parented at all times and
15
+ * swaps its source, which is the same shape as the C. The doc comments at :228
16
+ * and :343 claim the icon is hidden instead; the code disagrees with them and
17
+ * this follows the code (see the conformance vector's `rule`).
18
+ */
19
+ export declare function buttonContentIconSvg(svg: string): string;
20
+ /** Whether the icon shown is the empty-slot fallback rather than an app asset. */
21
+ export declare function buttonContentIconIsFallback(svg: string): boolean;
22
+ /**
23
+ * The parent button's `className` with `image-text-button` added — the root-time
24
+ * half of `adw_button_content_root` (:115).
25
+ *
26
+ * Adds rather than rewrites, so the `adw-button suggested-action pill` a caller
27
+ * composed survives; and it is idempotent, so a re-parent cannot double the
28
+ * token.
29
+ */
30
+ export declare function buttonContentRootedParentClassName(current: string): string;
31
+ /**
32
+ * The parent button's `className` with `image-text-button` removed — the unroot
33
+ * half (:126).
34
+ *
35
+ * The C removes it on unroot rather than leaving it behind, so a button that
36
+ * loses its content goes back to plain-button padding. A port that only ever
37
+ * added the class would leave the 9px on a button that is now text-only.
38
+ */
39
+ export declare function buttonContentUnrootedParentClassName(current: string): string;
40
+ /** The label view's `visibility` — NS's spelling of `gtk_widget_set_visible` (:398). */
41
+ export declare function buttonContentLabelVisibility(label: string): 'visible' | 'collapse';
42
+ /** The content's own `className` for a `can-shrink` value, other tokens untouched. */
43
+ export declare function buttonContentClassName(current: string, canShrink: boolean): string;
@@ -0,0 +1,85 @@
1
+ import type { Label } from '@nativescript/core';
2
+ import { CarouselState } from '@gjsify/adwaita-core';
3
+ import type { CarouselScrollRequest, CarouselStateChange } from '@gjsify/adwaita-core';
4
+ /**
5
+ * Default page width (DIPs) used for offset math until the consumer sets
6
+ * `pageWidth`. libadwaita MEASURES its pages (adw-carousel.c:739-765); NS gives
7
+ * a widget no size before its first layout pass, so a plausible phone-width
8
+ * default keeps the offsets sane until the consumer supplies the real one.
9
+ */
10
+ export declare const DEFAULT_CAROUSEL_PAGE_WIDTH = 320;
11
+ /** Construction seams an `AdwCarousel` hands to its state machine. */
12
+ export interface NsCarouselStateOptions {
13
+ /** Clock for the wheel lockout — injected so a spec can step past it. */
14
+ now?: () => number;
15
+ /** Invoked for every accepted scroll; the widget turns it into a `scrollToHorizontalOffset`. */
16
+ onScrollTo?: (request: CarouselScrollRequest) => void;
17
+ }
18
+ /**
19
+ * The state machine an `AdwCarousel` delegates to.
20
+ *
21
+ * `animateScroll` is FALSE: the `ScrollView` animates the pixels, but it reports
22
+ * nothing until it has, and on an untested platform it may report nothing at
23
+ * all. Keeping the model authoritative means a `scrollToPage` is correct the
24
+ * instant it is called, which is also what the port did before the lift —
25
+ * {@link CarouselScrollSync} is what keeps the two from fighting.
26
+ */
27
+ export declare function createCarouselState(options?: NsCarouselStateOptions): CarouselState;
28
+ /** A page width that can be divided by — anything else falls back to the default. */
29
+ export declare function normalizeCarouselPageWidth(value: number): number;
30
+ /** The horizontal scroll offset in DIPs for a position — `distance * position` (adw-carousel.c:797-801). */
31
+ export declare function carouselScrollOffset(position: number, distance: number): number;
32
+ /** The inverse: the position a `ScrollView` at `offset` is showing. */
33
+ export declare function carouselPositionAtOffset(offset: number, distance: number): number;
34
+ /**
35
+ * Keeps the model in step with a `ScrollView` that animates its own scrolls.
36
+ *
37
+ * Without this the two fight: the widget moves the model the moment
38
+ * `scrollToPage` is called, then the animation replays every intermediate offset
39
+ * back at it, so the dots would run backwards to where the scroll STARTED and
40
+ * crawl forward again, emitting a second `page-changed` on arrival.
41
+ *
42
+ * So a programmatic scroll declares its destination with {@link expect}, and
43
+ * every offset before that destination is ignored. A scroll nobody declared is a
44
+ * user swipe and drives the model directly — which is how a free flick gets a
45
+ * fractional position at all, something the port had no way to observe.
46
+ */
47
+ export declare class CarouselScrollSync {
48
+ /** Position a programmatic scroll is animating towards, `null` while idle. */
49
+ private _expected;
50
+ /** Declare where a programmatic scroll is heading; its intermediate offsets are then ignored. */
51
+ expect(position: number): void;
52
+ /**
53
+ * Feed one `ScrollView` scroll event. Returns whether the model was updated
54
+ * — `false` while a programmatic scroll is still in flight.
55
+ */
56
+ apply(state: CarouselState, position: number, epsilon?: number): boolean;
57
+ }
58
+ /** The class string each dot `Label` must carry, in page order. */
59
+ export declare function carouselDotClasses(state: CarouselState): string[];
60
+ /**
61
+ * Push {@link carouselDotClasses} onto the real dot labels.
62
+ *
63
+ * The selected dot comes from `get_page_at_position` (adw-carousel.c:222-239),
64
+ * not from `Math.round`, so a carousel resting half-way between two pages marks
65
+ * the LOWER one — and, unlike the integer compare this replaces, it marks
66
+ * something at all while a swipe is in progress.
67
+ */
68
+ export declare function applyCarouselDots(state: CarouselState, dots: readonly Label[]): void;
69
+ /** The data half of the `notify::position` event (minus NS's `eventName`/`object`). */
70
+ export interface CarouselNotifyPayload {
71
+ /** The clamped fractional scroll position. */
72
+ position: number;
73
+ /** The number of pages. */
74
+ nPages: number;
75
+ /** The page the position settles on, `-1` when the carousel is empty. */
76
+ page: number;
77
+ /** `true` for a user navigation (swipe, dot tap, keynav). */
78
+ interactive: boolean;
79
+ }
80
+ /**
81
+ * Project a core change onto the event payload. Kept as a function rather than
82
+ * spreading the change so the internal `reason` discriminator — which names a C
83
+ * notification site, not an NS event — never leaks into consumer code.
84
+ */
85
+ export declare function carouselNotifyPayload(change: CarouselStateChange): CarouselNotifyPayload;