@gjsify/adwaita-react-native 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 (201) hide show
  1. package/README.md +417 -14
  2. package/lib/esm/index.gtk.js +1 -1
  3. package/lib/esm/index.js +1 -1
  4. package/lib/esm/index.native.js +1 -1
  5. package/lib/esm/row-shell.native.js +1 -0
  6. package/lib/esm/testing/react-native.js +1 -1
  7. package/lib/esm/widgets/action-row.gtk.js +1 -0
  8. package/lib/esm/widgets/action-row.js +1 -0
  9. package/lib/esm/widgets/action-row.native.js +1 -0
  10. package/lib/esm/widgets/avatar.gtk.js +1 -0
  11. package/lib/esm/widgets/avatar.js +1 -0
  12. package/lib/esm/widgets/avatar.native.js +1 -0
  13. package/lib/esm/widgets/banner.gtk.js +1 -0
  14. package/lib/esm/widgets/banner.js +1 -0
  15. package/lib/esm/widgets/banner.native.js +1 -0
  16. package/lib/esm/widgets/button-content.gtk.js +1 -0
  17. package/lib/esm/widgets/button-content.js +1 -0
  18. package/lib/esm/widgets/button-content.native.js +1 -0
  19. package/lib/esm/widgets/button-row.gtk.js +1 -0
  20. package/lib/esm/widgets/button-row.js +1 -0
  21. package/lib/esm/widgets/button-row.native.js +1 -0
  22. package/lib/esm/widgets/clamp.native.js +1 -1
  23. package/lib/esm/widgets/combo-row.gtk.js +1 -0
  24. package/lib/esm/widgets/combo-row.js +1 -0
  25. package/lib/esm/widgets/combo-row.native.js +1 -0
  26. package/lib/esm/widgets/entry-row.gtk.js +1 -0
  27. package/lib/esm/widgets/entry-row.js +1 -0
  28. package/lib/esm/widgets/entry-row.native.js +1 -0
  29. package/lib/esm/widgets/expander-row.gtk.js +1 -0
  30. package/lib/esm/widgets/expander-row.js +1 -0
  31. package/lib/esm/widgets/expander-row.native.js +1 -0
  32. package/lib/esm/widgets/header-bar.gtk.js +1 -0
  33. package/lib/esm/widgets/header-bar.js +1 -0
  34. package/lib/esm/widgets/header-bar.native.js +1 -0
  35. package/lib/esm/widgets/navigation-page.gtk.js +1 -0
  36. package/lib/esm/widgets/navigation-page.js +1 -0
  37. package/lib/esm/widgets/navigation-page.native.js +1 -0
  38. package/lib/esm/widgets/navigation-split-view.gtk.js +1 -0
  39. package/lib/esm/widgets/navigation-split-view.js +1 -0
  40. package/lib/esm/widgets/navigation-split-view.native.js +1 -0
  41. package/lib/esm/widgets/navigation-view.gtk.js +1 -0
  42. package/lib/esm/widgets/navigation-view.js +1 -0
  43. package/lib/esm/widgets/navigation-view.native.js +1 -0
  44. package/lib/esm/widgets/overlay-split-view.gtk.js +1 -0
  45. package/lib/esm/widgets/overlay-split-view.js +1 -0
  46. package/lib/esm/widgets/overlay-split-view.native.js +1 -0
  47. package/lib/esm/widgets/password-entry-row.gtk.js +1 -0
  48. package/lib/esm/widgets/password-entry-row.js +1 -0
  49. package/lib/esm/widgets/password-entry-row.native.js +1 -0
  50. package/lib/esm/widgets/preferences-group.gtk.js +1 -0
  51. package/lib/esm/widgets/preferences-group.js +1 -0
  52. package/lib/esm/widgets/preferences-group.native.js +1 -0
  53. package/lib/esm/widgets/preferences-page.gtk.js +1 -0
  54. package/lib/esm/widgets/preferences-page.js +1 -0
  55. package/lib/esm/widgets/preferences-page.native.js +1 -0
  56. package/lib/esm/widgets/spin-row.gtk.js +1 -0
  57. package/lib/esm/widgets/spin-row.js +1 -0
  58. package/lib/esm/widgets/spin-row.native.js +1 -0
  59. package/lib/esm/widgets/spinner.gtk.js +1 -0
  60. package/lib/esm/widgets/spinner.js +1 -0
  61. package/lib/esm/widgets/spinner.native.js +1 -0
  62. package/lib/esm/widgets/status-page.gtk.js +1 -0
  63. package/lib/esm/widgets/status-page.js +1 -0
  64. package/lib/esm/widgets/status-page.native.js +1 -0
  65. package/lib/esm/widgets/switch-row.gtk.js +1 -0
  66. package/lib/esm/widgets/switch-row.js +1 -0
  67. package/lib/esm/widgets/switch-row.native.js +1 -0
  68. package/lib/esm/widgets/toast-overlay.gtk.js +1 -0
  69. package/lib/esm/widgets/toast-overlay.js +1 -0
  70. package/lib/esm/widgets/toast-overlay.native.js +1 -0
  71. package/lib/esm/widgets/toolbar-view.gtk.js +1 -0
  72. package/lib/esm/widgets/toolbar-view.js +1 -0
  73. package/lib/esm/widgets/toolbar-view.native.js +1 -0
  74. package/lib/esm/widgets/view-stack.gtk.js +1 -0
  75. package/lib/esm/widgets/view-stack.js +1 -0
  76. package/lib/esm/widgets/view-stack.native.js +1 -0
  77. package/lib/esm/widgets/view-switcher.gtk.js +1 -0
  78. package/lib/esm/widgets/view-switcher.js +1 -0
  79. package/lib/esm/widgets/view-switcher.native.js +1 -0
  80. package/lib/esm/widgets/window-title.gtk.js +1 -0
  81. package/lib/esm/widgets/window-title.js +1 -0
  82. package/lib/esm/widgets/window-title.native.js +1 -0
  83. package/lib/esm/widgets/wrap-box.gtk.js +1 -0
  84. package/lib/esm/widgets/wrap-box.js +1 -0
  85. package/lib/esm/widgets/wrap-box.native.js +1 -0
  86. package/lib/types/index.d.ts +85 -1
  87. package/lib/types/index.gtk.d.ts +85 -1
  88. package/lib/types/index.native.d.ts +85 -1
  89. package/lib/types/parity.spec.d.ts +131 -1
  90. package/lib/types/props.d.ts +858 -2
  91. package/lib/types/row-shell.native.d.ts +25 -0
  92. package/lib/types/testing/gtk.spec.d.ts +73 -0
  93. package/lib/types/testing/react-native.d.ts +56 -1
  94. package/lib/types/testing/react-native.spec.d.ts +24 -2
  95. package/lib/types/testing/render.spec.d.ts +49 -0
  96. package/lib/types/widgets/action-row.d.ts +14 -0
  97. package/lib/types/widgets/action-row.gtk.d.ts +5 -0
  98. package/lib/types/widgets/action-row.native.d.ts +5 -0
  99. package/lib/types/widgets/avatar.d.ts +13 -0
  100. package/lib/types/widgets/avatar.gtk.d.ts +5 -0
  101. package/lib/types/widgets/avatar.native.d.ts +5 -0
  102. package/lib/types/widgets/avatar.native.spec.d.ts +3 -0
  103. package/lib/types/widgets/banner.d.ts +13 -0
  104. package/lib/types/widgets/banner.gtk.d.ts +5 -0
  105. package/lib/types/widgets/banner.native.d.ts +5 -0
  106. package/lib/types/widgets/banner.native.spec.d.ts +3 -0
  107. package/lib/types/widgets/button-content.d.ts +14 -0
  108. package/lib/types/widgets/button-content.gtk.d.ts +5 -0
  109. package/lib/types/widgets/button-content.native.d.ts +5 -0
  110. package/lib/types/widgets/button-content.native.spec.d.ts +3 -0
  111. package/lib/types/widgets/button-row.d.ts +13 -0
  112. package/lib/types/widgets/button-row.gtk.d.ts +5 -0
  113. package/lib/types/widgets/button-row.native.d.ts +5 -0
  114. package/lib/types/widgets/combo-row.d.ts +13 -0
  115. package/lib/types/widgets/combo-row.gtk.d.ts +15 -0
  116. package/lib/types/widgets/combo-row.native.d.ts +5 -0
  117. package/lib/types/widgets/content.gtk.spec.d.ts +3 -0
  118. package/lib/types/widgets/entry-row.d.ts +14 -0
  119. package/lib/types/widgets/entry-row.gtk.d.ts +5 -0
  120. package/lib/types/widgets/entry-row.native.d.ts +5 -0
  121. package/lib/types/widgets/expander-row.d.ts +19 -0
  122. package/lib/types/widgets/expander-row.gtk.d.ts +5 -0
  123. package/lib/types/widgets/expander-row.native.d.ts +5 -0
  124. package/lib/types/widgets/header-bar.d.ts +30 -0
  125. package/lib/types/widgets/header-bar.gtk.d.ts +5 -0
  126. package/lib/types/widgets/header-bar.gtk.spec.d.ts +3 -0
  127. package/lib/types/widgets/header-bar.native.d.ts +5 -0
  128. package/lib/types/widgets/header-bar.native.spec.d.ts +3 -0
  129. package/lib/types/widgets/navigation-page.d.ts +12 -0
  130. package/lib/types/widgets/navigation-page.gtk.d.ts +5 -0
  131. package/lib/types/widgets/navigation-page.native.d.ts +5 -0
  132. package/lib/types/widgets/navigation-page.native.spec.d.ts +3 -0
  133. package/lib/types/widgets/navigation-split-view.d.ts +15 -0
  134. package/lib/types/widgets/navigation-split-view.gtk.d.ts +5 -0
  135. package/lib/types/widgets/navigation-split-view.native.d.ts +10 -0
  136. package/lib/types/widgets/navigation-split-view.native.spec.d.ts +3 -0
  137. package/lib/types/widgets/navigation-view.d.ts +16 -0
  138. package/lib/types/widgets/navigation-view.gtk.d.ts +5 -0
  139. package/lib/types/widgets/navigation-view.native.d.ts +5 -0
  140. package/lib/types/widgets/navigation-view.native.spec.d.ts +3 -0
  141. package/lib/types/widgets/navigation.gtk.spec.d.ts +3 -0
  142. package/lib/types/widgets/overlay-split-view.d.ts +13 -0
  143. package/lib/types/widgets/overlay-split-view.gtk.d.ts +5 -0
  144. package/lib/types/widgets/overlay-split-view.native.d.ts +5 -0
  145. package/lib/types/widgets/overlay-split-view.native.spec.d.ts +3 -0
  146. package/lib/types/widgets/password-entry-row.d.ts +13 -0
  147. package/lib/types/widgets/password-entry-row.gtk.d.ts +5 -0
  148. package/lib/types/widgets/password-entry-row.native.d.ts +5 -0
  149. package/lib/types/widgets/preferences-group.d.ts +13 -0
  150. package/lib/types/widgets/preferences-group.gtk.d.ts +5 -0
  151. package/lib/types/widgets/preferences-group.native.d.ts +5 -0
  152. package/lib/types/widgets/preferences-page.d.ts +14 -0
  153. package/lib/types/widgets/preferences-page.gtk.d.ts +5 -0
  154. package/lib/types/widgets/preferences-page.native.d.ts +5 -0
  155. package/lib/types/widgets/preferences.gtk.spec.d.ts +3 -0
  156. package/lib/types/widgets/preferences.native.spec.d.ts +3 -0
  157. package/lib/types/widgets/rows.gtk.spec.d.ts +3 -0
  158. package/lib/types/widgets/rows.native.spec.d.ts +3 -0
  159. package/lib/types/widgets/spin-row.d.ts +13 -0
  160. package/lib/types/widgets/spin-row.gtk.d.ts +20 -0
  161. package/lib/types/widgets/spin-row.native.d.ts +5 -0
  162. package/lib/types/widgets/spinner.d.ts +17 -0
  163. package/lib/types/widgets/spinner.gtk.d.ts +5 -0
  164. package/lib/types/widgets/spinner.native.d.ts +5 -0
  165. package/lib/types/widgets/spinner.native.spec.d.ts +3 -0
  166. package/lib/types/widgets/status-page.d.ts +15 -0
  167. package/lib/types/widgets/status-page.gtk.d.ts +5 -0
  168. package/lib/types/widgets/status-page.gtk.spec.d.ts +3 -0
  169. package/lib/types/widgets/status-page.native.d.ts +5 -0
  170. package/lib/types/widgets/status-page.native.spec.d.ts +3 -0
  171. package/lib/types/widgets/switch-row.d.ts +14 -0
  172. package/lib/types/widgets/switch-row.gtk.d.ts +5 -0
  173. package/lib/types/widgets/switch-row.native.d.ts +5 -0
  174. package/lib/types/widgets/toast-overlay.d.ts +18 -0
  175. package/lib/types/widgets/toast-overlay.gtk.d.ts +23 -0
  176. package/lib/types/widgets/toast-overlay.native.d.ts +5 -0
  177. package/lib/types/widgets/toast-overlay.native.spec.d.ts +3 -0
  178. package/lib/types/widgets/toolbar-view.d.ts +23 -0
  179. package/lib/types/widgets/toolbar-view.gtk.d.ts +5 -0
  180. package/lib/types/widgets/toolbar-view.gtk.spec.d.ts +3 -0
  181. package/lib/types/widgets/toolbar-view.native.d.ts +5 -0
  182. package/lib/types/widgets/toolbar-view.native.spec.d.ts +3 -0
  183. package/lib/types/widgets/view-stack.d.ts +13 -0
  184. package/lib/types/widgets/view-stack.gtk.d.ts +52 -0
  185. package/lib/types/widgets/view-stack.native.d.ts +20 -0
  186. package/lib/types/widgets/view-stack.native.spec.d.ts +3 -0
  187. package/lib/types/widgets/view-switcher.d.ts +13 -0
  188. package/lib/types/widgets/view-switcher.gtk.d.ts +5 -0
  189. package/lib/types/widgets/view-switcher.native.d.ts +5 -0
  190. package/lib/types/widgets/view-switcher.native.spec.d.ts +3 -0
  191. package/lib/types/widgets/window-title.d.ts +14 -0
  192. package/lib/types/widgets/window-title.gtk.d.ts +5 -0
  193. package/lib/types/widgets/window-title.gtk.spec.d.ts +3 -0
  194. package/lib/types/widgets/window-title.native.d.ts +5 -0
  195. package/lib/types/widgets/window-title.native.spec.d.ts +3 -0
  196. package/lib/types/widgets/wrap-box.d.ts +22 -0
  197. package/lib/types/widgets/wrap-box.gtk.d.ts +5 -0
  198. package/lib/types/widgets/wrap-box.gtk.spec.d.ts +3 -0
  199. package/lib/types/widgets/wrap-box.native.d.ts +5 -0
  200. package/lib/types/widgets/wrap-box.native.spec.d.ts +3 -0
  201. package/package.json +139 -9
@@ -1,5 +1,16 @@
1
- import type { ReactNode } from 'react';
2
- /** What every widget in this package accepts. */
1
+ import type { AdwBannerButtonStyle, AdwComboOptionInput, AdwLengthUnit, AdwPackType, AdwToast, AdwToolbarStyle, AdwViewSwitcherPolicy, AdwWrapBoxJustify, AdwWrapBoxOrientation, AdwWrapBoxPackDirection, AdwWrapPolicy } from '@gjsify/adwaita-core';
2
+ import type { ReactNode, Ref } from 'react';
3
+ /**
4
+ * What a widget that HOLDS a child accepts.
5
+ *
6
+ * Not every widget does. `Adw.WindowTitle` is two labels and no child slot; `Adw.Avatar`,
7
+ * `Adw.Banner`, `Adw.Spinner` and `Adw.ButtonContent` are leaves; `Adw.ButtonRow` has no
8
+ * child API in libadwaita at all, and `Adw.SwitchRow` and `Adw.EntryRow` fill their one
9
+ * slot themselves. Their prop types deliberately do NOT extend this, so a child written
10
+ * into one is a TYPE error rather than a node `@gjsify/gtk-host` refuses at runtime on one
11
+ * half while React Native renders it on the other. A `children` a widget would have to
12
+ * drop is a hole in the surface, not a convenience.
13
+ */
3
14
  export interface AdwWidgetProps {
4
15
  children?: ReactNode;
5
16
  }
@@ -17,3 +28,848 @@ export interface AdwClampProps extends AdwWidgetProps {
17
28
  /** `tightening-threshold` — where the eased tightening starts. Default 400. */
18
29
  tighteningThreshold?: number;
19
30
  }
31
+ /**
32
+ * `Adw.HeaderBar` — the start / centre / end bar at the top of a window.
33
+ *
34
+ * THE THREE SLOTS ARE PROPS, NOT CHILDREN, and the names are the GTK host's own slot
35
+ * names (`start`, `end`, `title` — `packages/framework/gtk-host/src/descriptors/adw.ts`),
36
+ * which are `adw_header_bar_pack_start` / `_pack_end` / `:title-widget`. A bare child
37
+ * would have to pick one of them, and `Adw.HeaderBar`'s buildable default picking `start`
38
+ * is a GTK detail no React caller should have to know.
39
+ *
40
+ * PACK ORDER DOES NOT ARISE HERE, and that is the one place this surface is SIMPLER than
41
+ * the imperative API rather than different from it. `adw_header_bar_pack_end` PREPENDS
42
+ * (adw-header-bar.c:1106), so `packEnd(menu); packEnd(search)` draws `search | menu`;
43
+ * `HeaderBarState` in `@gjsify/adwaita-core` stores the end slot in DRAW order for
44
+ * exactly that reason. A prop is already draw order — `end={<><Search /><Menu /></>}` is
45
+ * what it looks like — so there is no order to reverse and no rule to get backwards.
46
+ */
47
+ export interface AdwHeaderBarProps {
48
+ /**
49
+ * `title-widget` — a custom centre.
50
+ *
51
+ * Either/or with {@link title}/{@link subtitle}, as `adw_header_bar_set_title_widget`
52
+ * is with the derived label it empties out of the centre bin (:1201).
53
+ */
54
+ titleWidget?: ReactNode;
55
+ /**
56
+ * The centre's title.
57
+ *
58
+ * A DIVERGENCE FROM LIBADWAITA, and the same one both other renderers carry:
59
+ * `Adw.HeaderBar` has NO `title` property at all. Its derived centre is a plain
60
+ * `gtk_label_new (NULL)` (`construct_title_label`, adw-header-bar.c:512) over a title
61
+ * RESOLVED from the navigation page, then the dialog, then the window, then the
62
+ * application name (`update_title`, :475) — and an app that wants a subtitle sets an
63
+ * `AdwWindowTitle` as its title widget. A declarative surface wants the attribute, so
64
+ * authoring one installs an {@link AdwWindowTitleProps} centre; it is recorded as
65
+ * `HeaderBarRenderState.derivedSubtitle` in `@gjsify/adwaita-core`.
66
+ */
67
+ title?: string;
68
+ /** The centre's subtitle. Same divergence as {@link title}. */
69
+ subtitle?: string;
70
+ /** `pack_start` — the leading slot, in draw order. */
71
+ start?: ReactNode;
72
+ /** `pack_end` — the trailing slot, in draw order. */
73
+ end?: ReactNode;
74
+ }
75
+ /** `Adw.StatusPage` — a centred empty state: icon, title, description and one child. */
76
+ export interface AdwStatusPageProps extends AdwWidgetProps {
77
+ /**
78
+ * `icon-name` — the symbolic icon above the title.
79
+ *
80
+ * CARRIED ON BOTH HALVES AND DRAWN ONLY ON GTK. An icon NAME needs an icon theme to
81
+ * resolve it, and React Native has none — the same wall `@gjsify/adwaita-nativescript`
82
+ * hit, which took an SVG string instead. The README names it; `status-page.native.spec.tsx`
83
+ * pins that the tree has no icon node, so the day one appears is a decision and not a
84
+ * drift.
85
+ */
86
+ iconName?: string;
87
+ /** `title` — the bold line. An empty title takes no space (`string_is_not_empty`). */
88
+ title?: string;
89
+ /** `description` — the dim line below it. Empty takes no space. */
90
+ description?: string;
91
+ }
92
+ /**
93
+ * `Adw.ToolbarView` — a content area framed by top and/or bottom bars.
94
+ *
95
+ * `children` IS THE CONTENT, i.e. `Adw.ToolbarView:content`: the buildable default child
96
+ * on GTK, the unnamed slot in `@gjsify/adwaita-web` and the fallback slot in
97
+ * `@gjsify/adwaita-nativescript`. The two bar slots are props under the names all three
98
+ * renderers already give their bar containers.
99
+ */
100
+ export interface AdwToolbarViewProps extends AdwWidgetProps {
101
+ /** `adw_toolbar_view_add_top_bar` — what sits above the content. */
102
+ topBar?: ReactNode;
103
+ /** `adw_toolbar_view_add_bottom_bar` — what sits below it. */
104
+ bottomBar?: ReactNode;
105
+ /** `top-bar-style`. Default `flat`. */
106
+ topBarStyle?: AdwToolbarStyle;
107
+ /** `bottom-bar-style`. Default `flat`. */
108
+ bottomBarStyle?: AdwToolbarStyle;
109
+ /** `extend-content-to-top-edge` — the content runs UNDER the top bar. Default false. */
110
+ extendContentToTopEdge?: boolean;
111
+ /** `extend-content-to-bottom-edge`. Default false. */
112
+ extendContentToBottomEdge?: boolean;
113
+ }
114
+ /** `Adw.WindowTitle` — a title over a subtitle, for the centre of a header bar. */
115
+ export interface AdwWindowTitleProps {
116
+ /** `title`. The label is HIDDEN when this is empty, not merely blank. */
117
+ title?: string;
118
+ /** `subtitle`. Hidden when empty, by the same rule. */
119
+ subtitle?: string;
120
+ }
121
+ /**
122
+ * `Adw.WrapBox` — a box whose children flow onto new lines when they run out of room.
123
+ *
124
+ * All fourteen properties, each under libadwaita's own name. The three length properties
125
+ * come in pairs with their unit, which is why `childSpacing` and `childSpacingUnit` are
126
+ * two props and not one string: they are two GObject properties, and they are resolved
127
+ * against the unit SEPARATELY, so the two spacings can legitimately disagree about it.
128
+ */
129
+ export interface AdwWrapBoxProps extends AdwWidgetProps {
130
+ /** `child-spacing` — the gap between children on one line, in {@link childSpacingUnit}. Default 0. */
131
+ childSpacing?: number;
132
+ /** `child-spacing-unit`. Default `px` — NOT the split views' `sp`. */
133
+ childSpacingUnit?: AdwLengthUnit;
134
+ /** `line-spacing` — the gap between lines, in {@link lineSpacingUnit}. Default 0. */
135
+ lineSpacing?: number;
136
+ /** `line-spacing-unit`. Default `px`. */
137
+ lineSpacingUnit?: AdwLengthUnit;
138
+ /** `align` — where the children sit ALONG the line: 0 start, 0.5 middle, 1 end. Default 0. */
139
+ align?: number;
140
+ /** `justify` — whether and how a COMPLETE line is stretched. Default `none`. */
141
+ justify?: AdwWrapBoxJustify;
142
+ /** `justify-last-line` — whether the FINAL line is stretched too. Default false. */
143
+ justifyLastLine?: boolean;
144
+ /** `line-homogeneous` — whether every line takes the same space. Default false. */
145
+ lineHomogeneous?: boolean;
146
+ /** `natural-line-length`, in {@link naturalLineLengthUnit}. `-1` (the default) is UNSET. */
147
+ naturalLineLength?: number;
148
+ /** `natural-line-length-unit`. Default `px`. */
149
+ naturalLineLengthUnit?: AdwLengthUnit;
150
+ /** `pack-direction` — which end of a line children are packed from. Default `start-to-end`. */
151
+ packDirection?: AdwWrapBoxPackDirection;
152
+ /** `wrap-reverse` — whether lines wrap upwards. Default false. */
153
+ wrapReverse?: boolean;
154
+ /** `wrap-policy` — whether an overflowing line squeezes its children. Default `natural`. */
155
+ wrapPolicy?: AdwWrapPolicy;
156
+ /** `orientation` — the axis children are packed along. Default `horizontal`. */
157
+ orientation?: AdwWrapBoxOrientation;
158
+ }
159
+ /**
160
+ * `Adw.Avatar` — a round avatar showing initials derived from a name, or a
161
+ * fallback icon.
162
+ *
163
+ * `size` IS REQUIRED, and that is the one place this file departs from "libadwaita's
164
+ * defaults are the defaults". `AdwAvatar:size`'s GParamSpec default is the `-1`
165
+ * sentinel meaning "take the size from the stylesheet", and a renderer with no
166
+ * stylesheet cannot honour a stylesheet value. Measured against libadwaita 1.9.3, that
167
+ * path is degenerate on GTK too: a default-constructed avatar measures 20 wide and 18
168
+ * tall — not even square — and raises one `Pango-CRITICAL` from `update_font_size`,
169
+ * because the font cap for a negative size is negative. Reproducing that is not a goal
170
+ * and inventing a number behind the caller's back is how the two halves come to
171
+ * disagree, so the caller says.
172
+ *
173
+ * `custom-image` IS ABSENT. It is a `GdkPaintable` on GTK and an image source on React
174
+ * Native — two types with no shared spelling, and this file may import neither. The
175
+ * consequence is that `avatarMode` here only ever answers `'initials'` or `'icon'`.
176
+ */
177
+ export interface AdwAvatarProps {
178
+ /** `size` — the diameter. Required; see above. */
179
+ size: number;
180
+ /** `text` — the name the initials AND the colour are derived from. */
181
+ text?: string;
182
+ /** `show-initials` — initials instead of the fallback icon. Default false. */
183
+ showInitials?: boolean;
184
+ /** `icon-name` — the fallback icon. Default libadwaita's `adw-avatar-default-symbolic`. */
185
+ iconName?: string;
186
+ }
187
+ /**
188
+ * `Adw.Banner` — a full-width strip carrying one in-context message and an optional
189
+ * action button.
190
+ *
191
+ * ON `useMarkup`'s DEFAULT, which is measured and not the one written down.
192
+ * `AdwBanner:use-markup`'s GParamSpec declares TRUE (adw-banner.c:422-425) and
193
+ * `@gjsify/adwaita-core`'s `ADW_BANNER_DEFAULTS` records that — but a freshly
194
+ * constructed `Adw.Banner` READS BACK FALSE, measured on libadwaita 1.9.3.
195
+ * `adw_banner_get_use_markup` delegates to `gtk_label_get_use_markup (self->title)`,
196
+ * `adw-banner.ui` never sets `use-markup` on that label, and a pspec default is only
197
+ * applied to properties construction actually writes. So the declared default is never
198
+ * reached. Both halves here answer FALSE for an omitted value, because that is what the
199
+ * widget on the other side of the surface answers.
200
+ */
201
+ export interface AdwBannerProps {
202
+ /** `title` — the message. Pango markup when {@link useMarkup}. */
203
+ title?: string;
204
+ /** `button-label` — empty means no button. Its `_` is always a mnemonic marker. */
205
+ buttonLabel?: string;
206
+ /** `revealed` — whether the strip is on screen. Default false. */
207
+ revealed?: boolean;
208
+ /** `use-markup` — whether {@link title} is Pango markup. Default false; see above. */
209
+ useMarkup?: boolean;
210
+ /** `button-style` — grey (`'default'`) or `.suggested-action`. */
211
+ buttonStyle?: AdwBannerButtonStyle;
212
+ /** `button-clicked` — the action button was pressed. */
213
+ onButtonClicked?: () => void;
214
+ }
215
+ /**
216
+ * `Adw.Spinner` — a busy indicator.
217
+ *
218
+ * THE PROPERTIES ARE `GtkWidget`'s, BECAUSE `Adw.Spinner` HAS NONE OF ITS OWN. Its
219
+ * whole `GParamSpec` set is inherited: `adw_spinner_measure` reports `MIN_SIZE` as both
220
+ * the minimum AND the natural size, so the widget never grows on its own and the only
221
+ * way to make one bigger is to ask for a size. Measured on libadwaita 1.9.3: a fresh
222
+ * spinner measures `[16, 16]` and one with `width-request` 200 measures `[200, 200]`.
223
+ * A `size` prop would therefore be a renderer-ism of exactly the kind `maximumSize`
224
+ * exists to avoid — the two other Adwaita renderers each invented one.
225
+ *
226
+ * The BOX and the RING are different numbers, and only the box is a property: the ring
227
+ * is `spinnerGeometry`'s, capped at 64 and centred on the box, so a 200-point request
228
+ * occupies 200 points of layout around a 64-point ring.
229
+ */
230
+ export interface AdwSpinnerProps {
231
+ /** `width-request` — the box width. Unset (or `-1`) is libadwaita's natural 16. */
232
+ widthRequest?: number;
233
+ /** `height-request` — the box height. Unset (or `-1`) is libadwaita's natural 16. */
234
+ heightRequest?: number;
235
+ }
236
+ /** `Adw.ButtonContent` — an icon paired with a label, for the inside of a button. */
237
+ export interface AdwButtonContentProps {
238
+ /** `icon-name` — an icon-theme name. Empty draws `image-missing`, it does not hide the icon. */
239
+ iconName?: string;
240
+ /** `label` — empty hides the label node. */
241
+ label?: string;
242
+ /** `use-underline` — whether `_` marks a mnemonic in {@link label}. Default false. */
243
+ useUnderline?: boolean;
244
+ /** `can-shrink` — whether the label ellipsizes rather than widening the button. Default false. */
245
+ canShrink?: boolean;
246
+ }
247
+ /**
248
+ * What a caller does to an {@link AdwToastOverlayProps} through its `ref`.
249
+ *
250
+ * A TOAST IS PUSHED, NEVER DECLARED, and that is libadwaita's shape rather than a
251
+ * React convenience: `adw_toast_overlay_add_toast` is a call, the overlay owns the
252
+ * queue, and nothing about "which toast is on screen" is a property a caller writes.
253
+ * Modelling it as a `toasts={[…]}` array would put the ordering in the caller's hands
254
+ * on one half and in libadwaita's on the other.
255
+ *
256
+ * `dismissAll` and not `dismiss`: `adw_toast_overlay_dismiss_all` is the only dismissal
257
+ * the OVERLAY has. Dismissing just the current toast is `adw_toast_dismiss`, a method on
258
+ * the toast, so an overlay-level `dismiss()` would be a name libadwaita does not have —
259
+ * and `AdwToastQueue.clear()` is the same operation on the other half.
260
+ */
261
+ export interface AdwToastOverlayHandle {
262
+ /** `add_toast` — show it now if the slot is free, otherwise queue it FIFO. */
263
+ addToast(toast: AdwToast): void;
264
+ /** `dismiss_all` — dismiss the visible toast and discard everything behind it. */
265
+ dismissAll(): void;
266
+ }
267
+ /** `Adw.ToastOverlay` — wraps content and shows one transient toast at a time over it. */
268
+ export interface AdwToastOverlayProps extends AdwWidgetProps {
269
+ /** The imperative surface — see {@link AdwToastOverlayHandle}. */
270
+ ref?: Ref<AdwToastOverlayHandle>;
271
+ }
272
+ /**
273
+ /**
274
+ * The two labels every boxed-list row draws — `AdwPreferencesRow:title` and
275
+ * `AdwActionRow:subtitle`.
276
+ *
277
+ * Their VISIBILITY is a derivation and not a prop: libadwaita binds `string_is_not_empty`
278
+ * onto both labels, so an empty title hides its label instead of leaving a blank line.
279
+ * `@gjsify/adwaita-core`'s `deriveRowLabels` is that rule, and the React Native half runs
280
+ * it — the GTK half gets it from the real widget.
281
+ */
282
+ export interface AdwRowProps {
283
+ /** `title` — the row's first line. */
284
+ title?: string;
285
+ /** `subtitle` — the dim second line. */
286
+ subtitle?: string;
287
+ }
288
+ /**
289
+ * `Adw.ActionRow` — the fundamental boxed-list row: two labels and a trailing slot.
290
+ *
291
+ * CHILDREN ARE THE SUFFIX, which is `@gjsify/gtk-host`'s curated default slot for this
292
+ * widget (`add_suffix`) and therefore not a choice made here. `add_prefix` is reachable on
293
+ * GTK by writing `slot="prefix"` on the child and has no counterpart on the React Native
294
+ * half, so this surface does not offer it — see the README.
295
+ */
296
+ export interface AdwActionRowProps extends AdwRowProps, AdwWidgetProps {
297
+ /**
298
+ * `GtkListBoxRow:activatable` — whether a click activates the row.
299
+ *
300
+ * `Adw.ActionRow`'s own template sets it FALSE, so an omitted prop is a row that does
301
+ * not react to a click, on both halves.
302
+ */
303
+ activatable?: boolean;
304
+ /** `AdwActionRow::activated`. */
305
+ onActivated?: () => void;
306
+ }
307
+ /**
308
+ * `Adw.ButtonRow` — a boxed-list row that behaves like a button.
309
+ *
310
+ * NO `activatable`: the upstream template hardcodes `activatable=True` and the class
311
+ * documentation says "AdwButtonRow is always activatable", so there is no opt-out to
312
+ * model. `@gjsify/adwaita-core` exports that fact as `BUTTON_ROW_ACTIVATABLE` and the
313
+ * React Native half reads it rather than writing `true`.
314
+ */
315
+ export interface AdwButtonRowProps {
316
+ /** `title` — the centred label. */
317
+ title?: string;
318
+ /** `AdwButtonRow::activated`. */
319
+ onActivated?: () => void;
320
+ }
321
+ /**
322
+ * `Adw.SwitchRow` — a row whose trailing control is a switch.
323
+ *
324
+ * CONTROLLED, on both halves: `active` is the value the row shows and `onNotifyActive` is
325
+ * the only way it changes. That is React Native's own contract for `Switch` ("a controlled
326
+ * component that requires an `onValueChange` callback that updates the `value` prop"), and
327
+ * it is also what a GTK consumer gets from `@gjsify/gtk-host`, whose echo guard drops the
328
+ * `notify::active` raised by the host's own property write.
329
+ */
330
+ export interface AdwSwitchRowProps extends AdwRowProps {
331
+ /** `Adw.SwitchRow:active` — whether the switch is on. Default `false`. */
332
+ active?: boolean;
333
+ /**
334
+ * `notify::active`, with the new value.
335
+ *
336
+ * libadwaita has exactly ONE notify path for this property and it cannot see where the
337
+ * change came from, so a drag on the handle and a click on the title arrive here
338
+ * identically — the row is the control, not just the slider.
339
+ */
340
+ onNotifyActive?: (active: boolean) => void;
341
+ }
342
+ /**
343
+ * `Adw.EntryRow` — a boxed-list row that is itself a text entry.
344
+ *
345
+ * THE ROW OWNS ITS TEXT, which is GObject's contract and not React's: `text` seeds the
346
+ * entry and overwrites it whenever the prop CHANGES, and a keystroke that the consumer
347
+ * does not echo back still stands. Both halves behave that way for the same reason — on
348
+ * GTK because `@gjsify/gtk-host` patches a property only when it changes, on React Native
349
+ * because `@gjsify/adwaita-core`'s `EntryRowState` is the buffer.
350
+ */
351
+ export interface AdwEntryRowProps {
352
+ /** `title` — the floating label, and the placeholder while the row is empty. */
353
+ title?: string;
354
+ /** `GtkEditable:text` — the entry contents. */
355
+ text?: string;
356
+ /**
357
+ * `Adw.EntryRow:max-length` — maximum number of CHARACTERS, `0` (the default) meaning
358
+ * unlimited. Code points, never UTF-16 units: `@gjsify/adwaita-core`'s `clampEntryText`
359
+ * is what counts them on the React Native half, because `TextInput`'s own `maxLength`
360
+ * counts units and cuts a surrogate pair in half.
361
+ */
362
+ maxLength?: number;
363
+ /** `GtkEditable:editable` — whether the entry accepts edits. Default `true`. */
364
+ editable?: boolean;
365
+ /** `Adw.EntryRow:show-apply-button` — typing reveals an apply button. Default `false`. */
366
+ showApplyButton?: boolean;
367
+ /** `notify::text`, with the new contents. */
368
+ onNotifyText?: (text: string) => void;
369
+ /** `AdwEntryRow::apply` — the apply button, or Enter while it shows. */
370
+ onApply?: () => void;
371
+ /** `AdwEntryRow::entry-activated` — Enter when there is nothing to apply. */
372
+ onEntryActivated?: () => void;
373
+ }
374
+ /**
375
+ * `Adw.ExpanderRow` — a boxed-list row that discloses further rows beneath itself.
376
+ *
377
+ * CHILDREN ARE THE DISCLOSED ROWS, which is `@gjsify/gtk-host`'s curated default slot
378
+ * for this widget (`add_row`) and therefore not a choice made here. `add_prefix` and
379
+ * `add_suffix` are reachable on GTK by writing `slot="prefix"` / `slot="suffix"` on a
380
+ * child and have no counterpart on the React Native half, so this surface does not offer
381
+ * them — see the README.
382
+ *
383
+ * THE ROW OWNS ITS DISCLOSURE, the way `Adw.EntryRow` owns its text and for the same
384
+ * mechanical reason: `expanded` seeds the row and overwrites it whenever the PROP
385
+ * changes, and a tap the consumer does not echo back still stands. On GTK because the
386
+ * real widget toggles itself and `@gjsify/gtk-host` patches a property only when the prop
387
+ * changes; on React Native because `@gjsify/adwaita-core`'s `ExpanderState` is the
388
+ * buffer.
389
+ */
390
+ export interface AdwExpanderRowProps extends AdwRowProps, AdwWidgetProps {
391
+ /** `Adw.ExpanderRow:expanded` — whether the disclosure is revealed. Default `false`. */
392
+ expanded?: boolean;
393
+ /**
394
+ * `notify::expanded`, with the new flag.
395
+ *
396
+ * A change the CONSUMER made does not come back through here — on GTK because
397
+ * `@gjsify/gtk-host` drops the notify raised inside its own property write, on React
398
+ * Native because the prop-sync path does not call it. Both halves therefore report a
399
+ * disclosure the USER made and nothing else.
400
+ */
401
+ onNotifyExpanded?: (expanded: boolean) => void;
402
+ }
403
+ /**
404
+ * `Adw.PreferencesPage` — a scrolling page of {@link AdwPreferencesGroupProps}.
405
+ *
406
+ * FOUR OF THE FIVE PROPERTIES ARE IDENTITY, NOT PAINT, and that is libadwaita's design
407
+ * rather than a thin port: `adw_preferences_dialog_add` binds `title`, `name`, `icon-name`
408
+ * and `use-underline` onto the view-stack page it wraps the page in, and
409
+ * `create_search_row_subtitle` reads the title back when a second page is visible. The page
410
+ * itself draws none of them — a view switcher and the search results do. Both sibling
411
+ * renderers carry them for the same reason and paint them just as little.
412
+ *
413
+ * `description` IS the exception: it is drawn at the top of the page, above the first
414
+ * group, and both halves draw it.
415
+ *
416
+ * `banner` IS ABSENT. `AdwPreferencesPage:banner` takes an `Adw.Banner` INSTANCE — a
417
+ * GObject, not a description of one — and this file may import neither `gi://Adw` nor a
418
+ * React Native module. Same wall, and the same answer, as `AdwAvatarProps`' `custom-image`.
419
+ */
420
+ export interface AdwPreferencesPageProps extends AdwWidgetProps {
421
+ /** `title` — shown by a view switcher and by search results, never by the page. */
422
+ title?: string;
423
+ /** `icon-name` — the symbolic a view switcher shows. Carried on both halves, drawn on neither. */
424
+ iconName?: string;
425
+ /** `name` — the view-stack child name. NOT `GtkWidget:name`, which the page shadows. */
426
+ name?: string;
427
+ /**
428
+ * `description` — the line above the first group. Empty takes no space.
429
+ *
430
+ * ON THE RAW STRING, unlike {@link AdwPreferencesGroupProps}' two labels.
431
+ * `adw_preferences_page_set_description` tests `description && *description` while
432
+ * `update_title_visibility` reads the label's DISPLAYED text, so a pure-markup page
433
+ * description is visible on GTK where a pure-markup group title is not. Both halves
434
+ * therefore agree here, and the group's divergence must not be copied onto this one.
435
+ */
436
+ description?: string;
437
+ /** `description-centered` — whether {@link description} is centred. Default false. */
438
+ descriptionCentered?: boolean;
439
+ /** `use-underline` — whether `_` marks a mnemonic in {@link title}. Default false. */
440
+ useUnderline?: boolean;
441
+ }
442
+ /**
443
+ * `Adw.PreferencesGroup` — a titled card of rows.
444
+ *
445
+ * THE FIVE VISIBILITY ANSWERS COME FROM `derivePreferencesGroupHeader`, on the React Native
446
+ * half, and from libadwaita on the GTK one. They are not `title !== ''`: `header-visible` is
447
+ * a three-way OR, `single-line` is load-bearing for the stylesheet's `min-height: 34px`, and
448
+ * `listbox-visible` reads the RAW child count — `update_listbox_visibility` counts
449
+ * `gtk_widget_observe_children`, not the title-filtered model `get_rows` builds, so a row
450
+ * with an empty title still keeps the card painted.
451
+ *
452
+ * `header-suffix` IS ABSENT, and it is a placement question rather than a naming one.
453
+ * `AdwPreferencesGroup:header-suffix` holds a WIDGET, so a React surface has to spell it as
454
+ * a slot — and the group's curated descriptor in `@gjsify/gtk-host` is `ordered`
455
+ * (`add`/`remove`, `remove-all` to reorder), which has no slots at all. Adding one means
456
+ * changing a placement policy other conformance vectors already assert, with its own
457
+ * measurement; it is not something a widget lands on the way past. The README names it.
458
+ *
459
+ * `separate-rows` IS ABSENT for the opposite reason: it is pure card styling, and this
460
+ * package's React Native half draws no theme (see `row-shell.native.tsx`), so the GTK half
461
+ * would honour it and the phone half could only ignore it.
462
+ */
463
+ export interface AdwPreferencesGroupProps extends AdwWidgetProps {
464
+ /** `title` — the card's heading. Hidden when empty, not merely blank. */
465
+ title?: string;
466
+ /** `description` — the dim line under it. Hidden when empty, and it forces a two-line header. */
467
+ description?: string;
468
+ }
469
+ /**
470
+ * `Adw.ComboRow` — a row that picks one item out of a list.
471
+ *
472
+ * The two labels are {@link AdwRowProps}', which every boxed-list row shares — including
473
+ * their derived visibility, which is not `title !== ''`.
474
+ *
475
+ * `model` IS THE LIBADWAITA NAME AND NOT THE LIBADWAITA TYPE, which is the one liberty this
476
+ * surface takes and the reason it can exist at all. `AdwComboRow:model` is a
477
+ * `Gio.ListModel`; a props file that may import neither `gi://Gio` nor `react-native` cannot
478
+ * name that type, and the gallery refuses the widget outright for exactly this
479
+ * (`adwaita-gallery-trees.mjs`: "its items are a Gio.ListModel; a row without them teaches
480
+ * the wrong thing"). What both halves CAN share is `@gjsify/adwaita-core`'s
481
+ * `AdwComboOptionInput` — the option vocabulary `<adw-combo-row>` and
482
+ * `@gjsify/adwaita-nativescript` already accept — so the property keeps libadwaita's name
483
+ * and takes the shared description of a model. The GTK half turns it into the real
484
+ * `Gtk.StringList` it has to be; the React Native half feeds it to `ComboState`.
485
+ *
486
+ * `onNotifySelected` REPORTS A USER PICK ON BOTH HALVES AND A PROGRAMMATIC ONE ON ONE, which
487
+ * is a NAMED DIVERGENCE and not the agreement this paragraph used to claim. `ComboState` tags
488
+ * its changes `interactive` and the React Native half deliberately does not gate on it, so a
489
+ * `selected` the consumer authored comes back there. The GTK half cannot: gtk-host suppresses
490
+ * a `notify::` raised inside its OWN property write (`inHostWrite()` in its `signals.ts`), and
491
+ * writing the `selected` prop IS that write. MEASURED on libadwaita 1.9.3 — a re-render from
492
+ * `selected={0}` to `selected={2}` moves the widget and calls NOTHING, while `row.selected = 1`
493
+ * from outside React calls it. Benign for the ordinary controlled pattern, where the consumer
494
+ * made the change and already knows; not benign as a claim, because "fires on every change"
495
+ * sends a reader looking for a callback that never arrives. Same rule, same reason and the
496
+ * same README entry as `onNotifyVisibleChild`. A consumer that wants user picks only compares
497
+ * against the value it authored.
498
+ *
499
+ * `expression`, `factory`, `list-factory`, `header-factory`, `enable-search` and
500
+ * `search-match-mode` are all absent, and all for the `model` reason one step further: each
501
+ * is a `Gtk.*` instance. Neither sibling renderer has them either.
502
+ */
503
+ export interface AdwComboRowProps extends AdwRowProps {
504
+ /** `model` — the selectable items. See above on the type. */
505
+ model?: readonly AdwComboOptionInput[];
506
+ /** `selected` — the position of the selected item. Default 0. */
507
+ selected?: number;
508
+ /**
509
+ * `use-subtitle` — whether the selected item's label REPLACES {@link subtitle}. Default false.
510
+ *
511
+ * REPLACES, not "appears twice": `adw-combo-row.ui` binds the inline value view's `visible`
512
+ * to this property with `sync-create|invert-boolean`, so the value is drawn in the subtitle
513
+ * OR in the trailing slot and never in both. Both halves are held to that.
514
+ *
515
+ * WHEN the subtitle picks the value up is a NAMED DIVERGENCE, in the README: this surface
516
+ * publishes it at once, libadwaita on the next selection change. Measured — the setter calls
517
+ * `selection_changed`, and the subtitle is written by `selection_item_changed`.
518
+ */
519
+ useSubtitle?: boolean;
520
+ /** `notify::selected` — the selected position moved. */
521
+ onNotifySelected?: (selected: number) => void;
522
+ }
523
+ /**
524
+ * `Adw.SpinRow` — a row holding a number with a stepper.
525
+ *
526
+ * The two labels are {@link AdwRowProps}', as on every other boxed-list row here.
527
+ *
528
+ * THE RANGE IS THREE SCALARS AND libadwaita SPELLS IT AS ONE OBJECT. `AdwSpinRow:adjustment`
529
+ * is a `Gtk.Adjustment` — a GObject that is not a widget, which is what the gallery refuses
530
+ * the widget for — so the same rule as {@link AdwComboRowProps}' `model` applies: this file
531
+ * cannot name the type, and the three values it carries are named here instead. The names
532
+ * are the ADJUSTMENT's own GObject property names — `Gtk.Adjustment:lower`, `:upper`,
533
+ * `:step-increment` — rather than a fourth private spelling.
534
+ *
535
+ * THAT IS A DECLARED DIVERGENCE FROM THE TWO SIBLING RENDERERS, which flatten the same three
536
+ * onto `min`/`max`/`step`. Those are `adw_spin_row_new_with_range`'s PARAMETER names, not
537
+ * property names, and `props.ts`' rule is that a caller writes the property they would look
538
+ * up in libadwaita's documentation. `@gjsify/adwaita-core`'s `SpinState` calls them
539
+ * `min`/`max`/`step` internally; both halves here map onto that, so the arithmetic is still
540
+ * shared and only the spelling at the surface differs.
541
+ *
542
+ * `digits` IS A ROW PROPERTY AND NOT AN ADJUSTMENT ONE — `AdwSpinRow:digits`, the number of
543
+ * decimal places DISPLAYED. It is carried because it is the only one of the row's own
544
+ * properties both halves can honour: the core has no `digits`, so the React Native half
545
+ * formats with it directly and the GTK half hands it to the real widget.
546
+ *
547
+ * `climb-rate`, `snap-to-ticks`, `numeric`, `update-policy` and `wrap` are absent: each
548
+ * needs an editable text entry or a key-repeat timer that the React Native half does not
549
+ * have, so carrying them would mean a property GTK honours and the phone ignores. Neither
550
+ * sibling renderer has them either.
551
+ */
552
+ export interface AdwSpinRowProps extends AdwRowProps {
553
+ /** `value` — the current number, clamped into {@link lower}…{@link upper}. Default 0. */
554
+ value?: number;
555
+ /** `Gtk.Adjustment:lower` — the smallest value the stepper reaches. Default 0. */
556
+ lower?: number;
557
+ /** `Gtk.Adjustment:upper` — the largest. Default 100, which is `SpinState`'s own. */
558
+ upper?: number;
559
+ /** `Gtk.Adjustment:step-increment` — one stepper press. Default 1. */
560
+ stepIncrement?: number;
561
+ /** `digits` — decimal places DISPLAYED. Default 0. */
562
+ digits?: number;
563
+ /**
564
+ * `notify::value` — the value moved.
565
+ *
566
+ * Same divergence and the same measurement as {@link AdwComboRowProps.onNotifySelected},
567
+ * reached by a different route: this row writes no `value` property, it re-sets the
568
+ * memoised `adjustment`, and `notify::value` is raised from inside THAT host write.
569
+ */
570
+ onNotifyValue?: (value: number) => void;
571
+ }
572
+ /**
573
+ * `Adw.PasswordEntryRow` — an entry row whose contents are masked, with a peek button.
574
+ *
575
+ * IT DECLARES NO PROPERTIES OF ITS OWN, and that is measured rather than assumed:
576
+ * `AdwPasswordEntryRowProps` in `@gjsify/gtk-host`'s generated table is an EMPTY interface
577
+ * over `AdwEntryRowProps`. Everything the subclass adds is behaviour — the mask, the peek
578
+ * toggle installed through `add_suffix`, and the caps-lock indicator driven through the
579
+ * private `adw_entry_row_set_show_indicator` hook. So this surface is `Adw.EntryRow`'s, and
580
+ * `@gjsify/adwaita-core`'s `PasswordEntryRowState` composes an `EntryRowState` for the same
581
+ * reason the C subclasses rather than copies.
582
+ *
583
+ * WHICH IS WHY IT EXTENDS RATHER THAN RESTATES {@link AdwEntryRowProps}. The two carried the
584
+ * same eight members written out twice, and a second copy of a prop surface is the shape that
585
+ * drifts silently: a member added to the entry row would simply not reach this one, and
586
+ * `parity.spec.ts` compares each widget against its OWN base, so nothing would notice.
587
+ *
588
+ * `revealed` IS THEREFORE NOT A PROP, although both sibling renderers publish one. It is not
589
+ * a libadwaita property, the peek state is private to the widget, and a prop would be the
590
+ * one place this file invents a name. The button owns it on both halves.
591
+ *
592
+ * `activates-default`, `enable-emoji-completion`, `input-hints`, `input-purpose` and
593
+ * `attributes` are absent — the last two by type, the first by there being no default widget
594
+ * on a phone. Neither sibling renderer has them.
595
+ */
596
+ export interface AdwPasswordEntryRowProps extends AdwEntryRowProps {
597
+ }
598
+ /**
599
+ * `Adw.NavigationPage` — one page of an {@link AdwNavigationViewProps}.
600
+ *
601
+ * IT IS A WIDGET IN ITS OWN RIGHT ON GTK AND THAT IS WHY IT IS ONE HERE.
602
+ * `adw_navigation_view_add` takes an `AdwNavigationPage`, not a `GtkWidget`, and so do
603
+ * `adw_navigation_split_view_set_sidebar` / `_set_content` — a `Gtk.Box` handed to any
604
+ * of them is a rejected child. `@gjsify/adwaita-web` exposes it as its own element
605
+ * (`<adw-navigation-page>`) for the same reason; `@gjsify/adwaita-nativescript` does
606
+ * not, because a NativeScript `View` cannot carry the tag and it keeps the tag of
607
+ * record in the core instead.
608
+ */
609
+ export interface AdwNavigationPageProps extends AdwWidgetProps {
610
+ /**
611
+ * `title` — this page's title, and the NEXT page's back-button tooltip. Default `''`.
612
+ *
613
+ * OPTIONAL IN THE TYPE AND EXPECTED IN PRACTICE, measured on libadwaita 1.9.3: a page
614
+ * with no title prints `AdwNavigationPage 0x… is missing a title. To hide a header bar
615
+ * title, consider using AdwHeaderBar:show-title instead.` — a real GTK diagnostic that
616
+ * the React Native half has no counterpart for, and one the GTK suite's
617
+ * `installDiagnosticsGate` fails on. It is not `g_return_if_fail`, so the widget still
618
+ * works; it is the difference between an omitted title and a deliberate one.
619
+ */
620
+ title?: string;
621
+ /**
622
+ * `tag` — the page's identity, unique within one view.
623
+ *
624
+ * `''` is a LEGAL tag and not "untagged": the C tag table is a plain `g_str_hash`
625
+ * table and only a NULL tag is skipped (`add_page`). An omitted prop is the NULL.
626
+ */
627
+ tag?: string;
628
+ /**
629
+ * `can-pop` — whether a shortcut or the back button may leave this page. Default true.
630
+ *
631
+ * It does NOT gate {@link AdwNavigationViewHandle.pop}, which is libadwaita's own
632
+ * split: `adw_navigation_view_pop` ignores it and only `pop_shortcut_cb` and
633
+ * `AdwBackButton` consult it.
634
+ */
635
+ canPop?: boolean;
636
+ }
637
+ /**
638
+ * What a caller does to an {@link AdwNavigationViewProps} through its `ref`.
639
+ *
640
+ * A PAGE IS PUSHED BY TAG, NEVER BY HANDLE, and that is the one place this surface is
641
+ * narrower than libadwaita's. `adw_navigation_view_push` takes an `AdwNavigationPage`
642
+ * and `pop_to_page` likewise; a page handle is an `Adw.NavigationPage` on GTK and a
643
+ * React element on React Native — two types with no shared spelling, the same wall
644
+ * `custom-image` hits on {@link AdwAvatarProps}. The tag overloads are strings on both
645
+ * halves, and a tag is what makes a page addressable at all, so those are the surface.
646
+ *
647
+ * `visiblePageTag`, `canGoBack` and `backButtonTooltip` are METHODS rather than
648
+ * properties because they are reads of live widget state: `Adw.NavigationView` answers
649
+ * them from its own stack, the React Native half from `NavigationViewState`, and a
650
+ * value snapshotted into an object at `useImperativeHandle` time would be stale by the
651
+ * first push.
652
+ */
653
+ export interface AdwNavigationViewHandle {
654
+ /**
655
+ * `push_by_tag` — push the page carrying `tag`.
656
+ *
657
+ * Returns nothing, because `adw_navigation_view_push_by_tag` returns `void`: an
658
+ * unknown tag is a `g_critical`, not a `false`.
659
+ */
660
+ push(tag: string): void;
661
+ /** `pop` — pop the visible page. `false` when it was the root. */
662
+ pop(): boolean;
663
+ /** `pop_to_tag` — pop until the page carrying `tag` is visible. */
664
+ popToTag(tag: string): boolean;
665
+ /** `replace_with_tags` — replace the whole stack. The last tag becomes visible. */
666
+ replaceWithTags(tags: readonly string[]): void;
667
+ /** `visible-page`'s tag, or `null` — for an untagged page too. */
668
+ visiblePageTag(): string | null;
669
+ /** `AdwBackButton`'s visibility rule: a previous page exists AND the visible page `can-pop`. */
670
+ canGoBack(): boolean;
671
+ /** That button's tooltip — the revealed page's title, or `'Back'`. `null` when there is no button. */
672
+ backButtonTooltip(): string | null;
673
+ }
674
+ /**
675
+ * `Adw.NavigationView` — a stack of pages, one visible at a time.
676
+ *
677
+ * `children` ARE THE STATICALLY-ADDED PAGES, in `adw_navigation_view_add` order, and
678
+ * the first one is the root: `add_page` auto-pushes whenever the stack is EMPTY, so a
679
+ * declared page 0 becomes visible without anyone pushing it. Both other renderers
680
+ * snapshot their declared children exactly this way.
681
+ *
682
+ * Every mutation after that is a CALL through {@link AdwNavigationViewHandle}, not a
683
+ * prop, and that is libadwaita's shape rather than a React convenience:
684
+ * `Adw.NavigationView:visible-page` is READ-ONLY, and `push`/`pop` are methods. A
685
+ * `visiblePageTag={…}` prop would put the stack in the caller's hands on one half and
686
+ * in libadwaita's on the other.
687
+ */
688
+ export interface AdwNavigationViewProps extends AdwWidgetProps {
689
+ /**
690
+ * `animate-transitions` — whether a push or a pop slides. Default true.
691
+ *
692
+ * CARRIED ON BOTH HALVES AND ANIMATED ONLY ON GTK, which is the same shape
693
+ * `@gjsify/adwaita-nativescript` records ("kept for API parity"): this package has
694
+ * no animation layer, so the swap is instant on React Native either way. The value
695
+ * still reaches `NavigationViewState`, whose `finishTransition()` seam is what a
696
+ * renderer with no animation settles immediately.
697
+ */
698
+ animateTransitions?: boolean;
699
+ /**
700
+ * `pop-on-escape` — whether Escape pops the visible page. Default true.
701
+ *
702
+ * Carried and inert on React Native, where there is no Escape key: the core's
703
+ * `popFromEscape()` is what it gates, and nothing on a phone calls it.
704
+ */
705
+ popOnEscape?: boolean;
706
+ /** The imperative surface — see {@link AdwNavigationViewHandle}. */
707
+ ref?: Ref<AdwNavigationViewHandle>;
708
+ }
709
+ /**
710
+ * The four sizing properties both split views share, under libadwaita's own names.
711
+ *
712
+ * They come as a QUARTET and not a single width because that is what the widgets are:
713
+ * a FRACTION of the view, clamped between a minimum and a maximum, with the two bounds
714
+ * written in a scale-aware unit. `@gjsify/adwaita-core` resolves them —
715
+ * `resolveSidebarBounds` then `resolveNavigationSidebarWidth` /
716
+ * `resolveOverlaySidebarWidth`, which answer the SAME input differently and both
717
+ * halves of this package run.
718
+ */
719
+ export interface AdwSidebarWidthProps {
720
+ /** `min-sidebar-width`, in {@link sidebarWidthUnit}. Default 180. */
721
+ minSidebarWidth?: number;
722
+ /** `max-sidebar-width`, in {@link sidebarWidthUnit}. Default 280. Raised to the minimum when below it. */
723
+ maxSidebarWidth?: number;
724
+ /** `sidebar-width-fraction` — the share of the view the sidebar asks for. Default 0.25. */
725
+ sidebarWidthFraction?: number;
726
+ /** `sidebar-width-unit`. Default `sp`, which is a pixel passthrough at 96 dpi. */
727
+ sidebarWidthUnit?: AdwLengthUnit;
728
+ }
729
+ /**
730
+ * `Adw.NavigationSplitView` — a sidebar beside content, which becomes a navigation
731
+ * stack when collapsed.
732
+ *
733
+ * `children` IS THE CONTENT PANE and {@link sidebar} is a prop, the same split
734
+ * {@link AdwToolbarViewProps} makes and for the same reason — gtk-host routes a child
735
+ * by a `slot` prop on the CHILD, which a `ReactNode` handed in as a prop has nothing
736
+ * to carry.
737
+ *
738
+ * BOTH PANES ARE WRAPPED IN AN `Adw.NavigationPage` ON GTK, and that is not a
739
+ * convenience: `adw_navigation_split_view_set_sidebar` takes an `AdwNavigationPage`,
740
+ * so an unwrapped `Gtk.Box` is a rejected child. Hence the four `sidebar*` /
741
+ * `content*` page properties below — the tag pair is what
742
+ * `@gjsify/adwaita-nativescript` calls `sidebarTag`/`contentTag` for exactly this
743
+ * reason ("a `View` is not an `Adw.NavigationPage`"), and `@gjsify/adwaita-web` reads
744
+ * the same `tag` off its slotted pane.
745
+ */
746
+ export interface AdwNavigationSplitViewProps extends AdwWidgetProps, AdwSidebarWidthProps {
747
+ /** `sidebar` — the sidebar pane's content. */
748
+ sidebar?: ReactNode;
749
+ /** The sidebar page's `Adw.NavigationPage:tag`. Colliding with {@link contentTag} is refused. */
750
+ sidebarTag?: string;
751
+ /** The content page's `Adw.NavigationPage:tag`. */
752
+ contentTag?: string;
753
+ /** The sidebar page's `Adw.NavigationPage:title`. */
754
+ sidebarTitle?: string;
755
+ /** The content page's `Adw.NavigationPage:title`. */
756
+ contentTitle?: string;
757
+ /** `collapsed` — one pane at a time. Default false. */
758
+ collapsed?: boolean;
759
+ /**
760
+ * `show-content` — which pane a COLLAPSED view shows. Default false (the sidebar).
761
+ *
762
+ * It is not the whole answer, which is the widget's entire point: a LONE child
763
+ * stays visible whatever this says, and with `sidebar-position: end` the CONTENT is
764
+ * the root page. That ordering table is `resolveNavigationStack` in the core, and
765
+ * both halves read `visiblePane` out of it rather than this flag.
766
+ */
767
+ showContent?: boolean;
768
+ /** `sidebar-position` — which side the sidebar is packed on. Default `start`. */
769
+ sidebarPosition?: AdwPackType;
770
+ }
771
+ /**
772
+ * `Adw.OverlaySplitView` — a sidebar beside content, which slides OVER it when
773
+ * collapsed instead of replacing it.
774
+ *
775
+ * Its panes are plain `GtkWidget`s, so unlike {@link AdwNavigationSplitViewProps}
776
+ * nothing is wrapped and there are no page properties.
777
+ */
778
+ export interface AdwOverlaySplitViewProps extends AdwWidgetProps, AdwSidebarWidthProps {
779
+ /** `sidebar` — the sidebar pane's content. `children` is the content pane. */
780
+ sidebar?: ReactNode;
781
+ /** `collapsed` — the sidebar overlays rather than docks. Default false. */
782
+ collapsed?: boolean;
783
+ /**
784
+ * `show-sidebar` — whether the sidebar is revealed. Default TRUE.
785
+ *
786
+ * IT IS NOT PURELY A CALLER'S VALUE, and that is why {@link onNotifyShowSidebar}
787
+ * exists: unless {@link pinSidebar} is set, collapsing HIDES the sidebar and
788
+ * uncollapsing SHOWS it (`adw_overlay_split_view_set_collapsed`). Both halves
789
+ * report that back rather than silently disagreeing with the prop.
790
+ */
791
+ showSidebar?: boolean;
792
+ /** `pin-sidebar` — collapsing leaves {@link showSidebar} alone. Default false. */
793
+ pinSidebar?: boolean;
794
+ /** `sidebar-position`. Default `start`. */
795
+ sidebarPosition?: AdwPackType;
796
+ /** `enable-show-gesture` — edge-swipe to open. Default true. */
797
+ enableShowGesture?: boolean;
798
+ /** `enable-hide-gesture` — swipe to close. Default true. */
799
+ enableHideGesture?: boolean;
800
+ /** `notify::show-sidebar` — the value the widget settled on, the caller's or its own. */
801
+ onNotifyShowSidebar?: (showSidebar: boolean) => void;
802
+ }
803
+ /**
804
+ * One page of an {@link AdwViewStackProps}.
805
+ *
806
+ * IT IS A PROP OBJECT AND NOT A WIDGET, because `Adw.ViewStackPage` is not one: it is
807
+ * a GObject the stack hands back from `adw_view_stack_get_page (child)`, so it can be
808
+ * neither a JSX child nor a `slot`. Both other renderers reach the same shape from the
809
+ * other direction — `@gjsify/adwaita-web` consumes its `<adw-view-stack-page>`
810
+ * children into descriptors at connect, `@gjsify/adwaita-nativescript` takes
811
+ * `add(content, name, title, icon)` — and `@gjsify/adwaita-core`'s
812
+ * `AdwViewStackPageSpec` is the record both already build.
813
+ */
814
+ export interface AdwViewStackPageProps {
815
+ /** `name` — the page's identity, and what `visible-child-name` selects. */
816
+ name: string;
817
+ /** `title` — falls back to {@link name} when absent, which is the core's own deviation from C. */
818
+ title?: string;
819
+ /** `icon-name` — carried on both halves, drawn only on GTK (no icon theme on a phone). */
820
+ iconName?: string;
821
+ /** `visible` — whether the page participates in selection at all. Default true. */
822
+ visible?: boolean;
823
+ /** `badge-number` — 0 is no badge; above 999 the label is `999+`. Default 0. */
824
+ badgeNumber?: number;
825
+ /** `needs-attention` — the bare dot, with or without a badge. Default false. */
826
+ needsAttention?: boolean;
827
+ /** `use-underline` — whether `_` marks a mnemonic in {@link title}. Default false. */
828
+ useUnderline?: boolean;
829
+ /** The page body. */
830
+ child?: ReactNode;
831
+ }
832
+ /**
833
+ * `Adw.ViewStack` — named pages, one visible at a time.
834
+ *
835
+ * `visibleChildName` is AUTHORED, not owned: an absent one leaves the stack on its own
836
+ * auto-pick (`adw_view_stack_add` selects the first VISIBLE page and notifies), and an
837
+ * unknown name is REFUSED rather than clamped — `adw_view_stack_set_visible_child_name`
838
+ * warns and leaves the selection alone. Both rules are `ViewStackState`'s, which is
839
+ * what `@gjsify/adwaita-web` and `@gjsify/adwaita-nativescript` run too.
840
+ */
841
+ export interface AdwViewStackProps {
842
+ /** The pages, in `add` order. */
843
+ pages?: readonly AdwViewStackPageProps[];
844
+ /** `visible-child-name` — which page to show. */
845
+ visibleChildName?: string;
846
+ /**
847
+ * `notify::visible-child` — the name the stack settled on.
848
+ *
849
+ * WHAT REACHES IT IS NOT THE SAME SET ON THE TWO HALVES, measured. A press on the
850
+ * switcher reaches both. A change the CALLER made through {@link visibleChildName}
851
+ * reaches the React Native half only, because gtk-host drops the notify raised
852
+ * inside its own property write — the rule {@link AdwExpanderRowProps.onNotifyExpanded}
853
+ * records. And the mount AUTO-PICK reaches neither: libadwaita notifies it from
854
+ * inside `adw_view_stack_add_titled`, before React has committed the `ref` the name
855
+ * would be read off, and the core's own auto-pick lands before the subscription
856
+ * exists. The README carries the table.
857
+ */
858
+ onNotifyVisibleChild?: (name: string) => void;
859
+ }
860
+ /**
861
+ * `Adw.ViewSwitcher` — a row of buttons over an {@link AdwViewStackProps}.
862
+ *
863
+ * IT BUNDLES THE STACK LIBADWAITA KEEPS SEPARATE, and so do both other renderers.
864
+ * `Adw.ViewSwitcher:stack` is a WIDGET-valued property — the switcher points at an
865
+ * `Adw.ViewStack` somewhere else in the tree — and a React prop cannot hold a widget
866
+ * that does not exist yet on the half where widgets exist at all. So the switcher owns
867
+ * its pages here, exactly as `<adw-view-switcher>` and NativeScript's
868
+ * `AdwViewSwitcherBase` do; on GTK it still builds a real `Adw.ViewStack` and hands it
869
+ * to a real `Adw.ViewSwitcher` through that property, so nothing about the widget is
870
+ * simulated.
871
+ */
872
+ export interface AdwViewSwitcherProps extends AdwViewStackProps {
873
+ /** `policy` — `narrow` stacks icon over label, `wide` puts them side by side. Default `narrow`. */
874
+ policy?: AdwViewSwitcherPolicy;
875
+ }