@gjsify/adwaita-react-native 0.44.0 → 0.46.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 +415 -10
  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 +143 -10
package/README.md CHANGED
@@ -17,10 +17,24 @@ approximation.
17
17
 
18
18
  ## What this is, honestly
19
19
 
20
- **A walking skeleton, not a widget set.** Two widgets — `AdwBin` and `AdwClamp` —
21
- carrying the whole vertical: both platform halves, the resolution mechanism, the
22
- manifest declaration, a gate, suites on both sides, and a photograph of the GTK half.
23
- The remaining widgets are repetition against a boundary that has been measured.
20
+ **Not a widget set yet.** The table below is the whole of it, and every row carries the
21
+ whole vertical — both platform halves, the resolution mechanism, the `exports` entry, a
22
+ gate, and a suite on each side that reads the REAL tree. `AdwBin` and `AdwClamp` came
23
+ first and proved that shape; the groups since are where it starts earning its keep, and
24
+ the content-and-feedback widgets are the clearest case — each has a DERIVATION as its
25
+ shared half (an initials hash, a palette index, a queue policy, a ring geometry), so the
26
+ two implementations are held to the same number rather than to the same shape. The
27
+ boxed-list rows carry that argument across a whole preferences page. What is not here is
28
+ everything else libadwaita has: navigation, dialogs, the view switchers, the lists.
29
+
30
+ **Nothing here re-implements a rule that already has an owner.** Every derivation the
31
+ rows share — `string_is_not_empty` on both labels, `Adw.EntryRow`'s `update_empty` truth
32
+ table and its apply latch, character-counted truncation, the switch row's two routes into
33
+ one transition, the expander's disclosure — comes from
34
+ [`@gjsify/adwaita-core`](../../web/adwaita-core), which is the same call
35
+ `@gjsify/adwaita-web` and `@gjsify/adwaita-nativescript` make. The GTK half calls none of
36
+ it: the C original is right there, and the core's value on that path is as the oracle the
37
+ React Native half is measured against.
24
38
 
25
39
  **The promise is the Adwaita design language on React Native, not "your app runs".**
26
40
  Unlike [`@gjsify/react-native`](../react-native) — the opposite direction, which was
@@ -46,13 +60,82 @@ a GTK-only consumer does not need it installed.
46
60
 
47
61
  | widget | props | notes |
48
62
  |---|---|---|
63
+ | `AdwActionRow` | `title`, `subtitle`, `activatable` (false), `onActivated`, `children` | The fundamental boxed-list row. `children` are the SUFFIX |
64
+ | `AdwAvatar` | `size` (**required**), `text`, `showInitials`, `iconName` | Initials and palette entry from one port of `extract_initials_from_text` + `set_class_color`. `size` is required because libadwaita's default is the `-1` "ask the stylesheet" sentinel and neither renderer here has one |
65
+ | `AdwBanner` | `title`, `buttonLabel`, `revealed`, `useMarkup`, `buttonStyle`, `onButtonClicked` | An omitted `useMarkup` is FALSE on both halves — the value the widget reads back, not the TRUE its `GParamSpec` declares |
49
66
  | `AdwBin` | `children` | One child, no layout of its own |
67
+ | `AdwButtonContent` | `iconName`, `label`, `useUnderline`, `canShrink` | Four derivations from the core, including the 6px gap that is `border-spacing` and not `GtkBox:spacing` |
68
+ | `AdwButtonRow` | `title`, `onActivated` | A row that behaves like a button — always activatable, and holds no children at all |
50
69
  | `AdwClamp` | `children`, `maximumSize` (600), `tighteningThreshold` (400) | Constrain a child's width and centre it, on libadwaita's easing curve |
70
+ | `AdwComboRow` | `title`, `subtitle`, `model`, `selected`, `useSubtitle`, `onNotifySelected` | Pick one item of a list. `model` keeps libadwaita's NAME and takes `@gjsify/adwaita-core`'s option vocabulary instead of a `Gio.ListModel` — the GTK half builds the real `Gtk.StringList`. One item or none is not a choice: no chevron, and the row is not activatable. `useSubtitle` MOVES the value into the subtitle rather than adding a second copy of it |
71
+ | `AdwEntryRow` | `title`, `text`, `maxLength` (0), `editable` (true), `showApplyButton` (false), `onNotifyText`, `onApply`, `onEntryActivated` | The row IS the entry. `max-length` counts CHARACTERS |
72
+ | `AdwExpanderRow` | `title`, `subtitle`, `expanded` (false), `onNotifyExpanded`, `children` | `children` are the DISCLOSED rows. The header toggles, the disclosure does not |
73
+ | `AdwHeaderBar` | `start`, `titleWidget`, `title`, `subtitle`, `end` | The three slots as PROPS, in draw order. No window controls: a phone has none |
74
+ | `AdwNavigationPage` | `children`, `title`, `tag`, `canPop` (true) | One page of a navigation view, or one pane of a navigation split view. A widget on GTK because `adw_navigation_view_add` takes one; three properties and no drawing of its own |
75
+ | `AdwNavigationSplitView` | `children` (the content), `sidebar`, `sidebarTag`, `contentTag`, `sidebarTitle`, `contentTitle`, `collapsed`, `showContent`, `sidebarPosition`, plus the four sizing props | Sidebar beside content; a navigation stack when collapsed. Both panes are wrapped in an `Adw.NavigationPage` on GTK, because the two slots take nothing else |
76
+ | `AdwNavigationView` | `children` (the pages, first is the root), `animateTransitions` (true), `popOnEscape` (true), `ref` (`push`, `pop`, `popToTag`, `replaceWithTags`, `visiblePageTag`, `canGoBack`, `backButtonTooltip`) | A page stack. Pushed BY TAG through the ref, never by prop — `Adw.NavigationView:visible-page` is read-only |
77
+ | `AdwOverlaySplitView` | `children` (the content), `sidebar`, `collapsed`, `showSidebar` (true), `pinSidebar`, `sidebarPosition`, `enableShowGesture` (true), `enableHideGesture` (true), `onNotifyShowSidebar`, plus the four sizing props | Sidebar that slides OVER the content when collapsed. Collapsing hides an unpinned sidebar itself, which is what `onNotifyShowSidebar` reports |
78
+ | `AdwPasswordEntryRow` | `title`, `text`, `maxLength`, `editable`, `showApplyButton`, `onNotifyText`, `onApply`, `onEntryActivated` | `Adw.EntryRow`'s surface exactly — the subclass declares no property of its own. `maxLength` counts CHARACTERS through the core, never `TextInput.maxLength`'s UTF-16 units |
79
+ | `AdwPreferencesGroup` | `children` (the rows), `title`, `description` | A titled card. Five visibility answers from one `derivePreferencesGroupHeader` call; the card hides itself at zero rows while its header stays |
80
+ | `AdwPreferencesPage` | `children` (the groups), `title`, `iconName`, `name`, `description`, `descriptionCentered`, `useUnderline` | Four of the five properties are identity a view switcher reads, drawn by neither half — as in libadwaita. Only `description` is painted |
81
+ | `AdwSpinRow` | `title`, `subtitle`, `value`, `lower`, `upper`, `stepIncrement`, `digits`, `onNotifyValue` | The range is `Gtk.Adjustment`'s three own property names rather than a fourth private spelling. Every mutation clamps, including a bound that moves under the value |
82
+ | `AdwSpinner` | `widthRequest`, `heightRequest` | The BOX and the RING are two numbers: an unbounded box around a ring capped at 64 |
83
+ | `AdwStatusPage` | `children`, `iconName`, `title`, `description` | A centred empty state. The icon draws on GTK only |
84
+ | `AdwSwitchRow` | `title`, `subtitle`, `active` (false), `onNotifyActive` | Controlled. The whole row toggles, not only the handle |
85
+ | `AdwToastOverlay` | `children`, `ref` (`addToast`, `dismissAll`) | One toast at a time. A toast is PUSHED through the ref, never declared as a prop — `add_toast` is a call |
86
+ | `AdwToolbarView` | `children` (the content), `topBar`, `bottomBar`, `topBarStyle` (`flat`), `bottomBarStyle` (`flat`), `extendContentToTopEdge` (false), `extendContentToBottomEdge` (false) | Content framed by bars. The two styles reach the real widget on GTK and draw nothing on a phone |
87
+ | `AdwViewStack` | `pages` (`name`, `title`, `iconName`, `visible`, `badgeNumber`, `needsAttention`, `useUnderline`, `child`), `visibleChildName`, `onNotifyVisibleChild` | Named pages, one visible. A page is a PROP OBJECT because `Adw.ViewStackPage` is a GObject and not a widget |
88
+ | `AdwViewSwitcher` | `AdwViewStack`'s props plus `policy` (`narrow`) | A button row over the stack. It BUNDLES the stack libadwaita keeps separate, as both other renderers do — on GTK it still builds a real `Adw.ViewStack` and binds it to `Adw.ViewSwitcher:stack` |
89
+ | `AdwWindowTitle` | `title`, `subtitle` | Two labels; an EMPTY one takes no space, a blank one does |
90
+ | `AdwWrapBox` | `children` plus libadwaita's fourteen: `childSpacing`/`childSpacingUnit`, `lineSpacing`/`lineSpacingUnit`, `align`, `justify`, `justifyLastLine`, `lineHomogeneous`, `naturalLineLength`/`naturalLineLengthUnit`, `packDirection`, `wrapReverse`, `wrapPolicy`, `orientation` | Children flow onto new lines. The line DECISION is `@gjsify/adwaita-core`'s, the line BREAKING is Yoga's |
51
91
 
52
92
  Props are libadwaita's own names, camelCased — `maximumSize` is `AdwClamp:maximum-size`,
53
93
  not a React Native `maxWidth` — so the property you look up in libadwaita's documentation
54
94
  is the property you write. Defaults are libadwaita's.
55
95
 
96
+ A signal is named the way [`@gjsify/gtk-host`](../gtk-host)'s generated surface names it
97
+ (`onActivated` for `::activated`, `onNotifyActive` for `notify::active`), because the GTK
98
+ half hands the prop straight to the host and a second spelling here would be a translation
99
+ table nothing checks.
100
+
101
+ **A slot is a prop, never a `slot`-carrying child.** `AdwHeaderBar`'s three ends and
102
+ `AdwToolbarView`'s two bars are props because gtk-host routes a child by a `slot` prop on
103
+ the CHILD, and a prop of a React component is an arbitrary `ReactNode` with nothing to
104
+ write it on — `cloneElement` sets a prop on a COMPOSITE component, which forwards
105
+ nothing, so the slot would be silently dropped for exactly the children this package
106
+ ships. Each slot therefore gets one container widget on GTK, which is also what
107
+ libadwaita puts there itself.
108
+
109
+ **A property this package does not carry is ABSENT, never present and ignored** — the
110
+ omissions are listed under [Named divergences](#named-divergences). Two rules decide who
111
+ owns a value: `AdwSwitchRow:active` is strictly CONTROLLED (React Native's own contract for
112
+ `Switch`, and what a GTK consumer gets from the host's echo guard), while
113
+ `AdwEntryRow:text` and `AdwExpanderRow:expanded` are owned by the ROW — the prop seeds
114
+ them and overwrites them when it CHANGES, and a keystroke or a tap the consumer does not
115
+ echo back still stands. That is GObject's contract rather than React's, and both halves
116
+ follow it for the same mechanical reason: `@gjsify/gtk-host` patches a property only when
117
+ the prop changes, and `@gjsify/adwaita-core`'s state machines are the buffer on the other
118
+ side.
119
+
120
+ **Neither half styles text.** Bold-and-dim is `@gjsify/adwaita-web`'s stylesheet and
121
+ `@gjsify/adwaita-nativescript`'s theme CSS; this package has no theme layer to read
122
+ `@gjsify/adwaita-core`'s tokens through, so what the React Native half carries is layout
123
+ and visibility. Inventing a styling seam is a decision this slice does not make.
124
+
125
+ ### `AdwExpanderRow` needs a curated placement, and this package added it
126
+
127
+ `Adw.ExpanderRow` was in `@gjsify/gtk-host`'s GENERATED table, which knows the tag and no
128
+ placement rule, so every child of an `<adw-expander-row>` was an `uncurated-placement`
129
+ refusal. The policy is now curated in `gtk-host/src/descriptors/adw.ts` — `add_row` as the
130
+ default slot, `add_prefix`/`add_suffix` by name — and it needed one thing the `slotted`
131
+ policy did not have: `add_row` hands the child to an inner `Gtk.ListBox`, and
132
+ `gtk_list_box_remove` does NOT unwrap the implicit `GtkListBoxRow` that box makes for a
133
+ non-row child, so the child leaks on unmount behind one `Gtk-WARNING`. Measured on GTK
134
+ 4.22.4, and caught by the host's own "every slotted descriptor survives a round trip
135
+ through every slot" mechanism before this shipped. So `slotted` now takes the same
136
+ per-slot `wrapSlots` that `indexed` already declared for `GtkListBox`, and the host makes
137
+ the row itself. Any widget can go in a disclosure.
138
+
56
139
  ## How the two halves are selected
57
140
 
58
141
  Through the package's `exports` map and the `react-native` condition:
@@ -100,8 +183,24 @@ nothing:
100
183
  | the `.native` half type-checks against **real** React Native | the `react-native` package's own types, never a subset |
101
184
  | GTK: the widget is the real `Adw.*`, and it **renders** | the live GTK tree plus a GSK rasterisation, because GTK's failure mode is an empty window at exit 0 |
102
185
  | React Native: which primitives, which props, which nesting | React's own reconciler over `react-test-renderer` |
186
+ | GTK: where the children actually END UP, not that they exist | numbers read off the live tree. Three 100-point children at `childSpacing` 20 in a 1000-point frame sit at x=0, 120 and 240, and `align={1}` moves a two-child line to x=780 and 900; a toolbar view's content starts at `topBarHeight` and is `height − topBarHeight − bottomBarHeight` tall, and extending the top edge moves it to y=0 while the bar KEEPS its height |
187
+ | GTK: a slot is the slot it was written into | the style class libadwaita puts on the box it packs into — `start`/`end` on the header bar, `top-bar`/`bottom-bar` on the toolbar view. `pack_start`, `pack_end`, `add_top_bar` and `add_bottom_bar` are all WRITE-ONLY, so an assertion that the child is merely present passes with the child in the wrong slot |
103
188
  | both halves agree on the number | two frames, one of them ON the easing curve: 1000 points at `maximumSize` 400 gives width 400 at offset 300, and 700 points at the default 600/400 gives **575 at offset 62**, where a `min()` would give 600 |
104
189
  | both halves answer the same for a property value GObject cannot store | `normalizeClampSize` from `@gjsify/adwaita-core`, run by **both** halves — the same call `@gjsify/adwaita-web` and `@gjsify/adwaita-nativescript` make. `400.7` &rarr; 400, `NaN` &rarr; the default 600, `-5` &rarr; the range floor 0, asserted on both sides |
190
+ | both halves pick the same avatar colour, from the same bytes | libadwaita PUBLISHES its answer: `set_class_color` stamps `color{n}` on the avatar's internal gizmo. GTK reads `color11` off the live tree for "Ada Lovelace" and `color6` for "Grace Hopper"; React Native paints `#8c75d9` and `#eba831`, the same two entries flattened. Two names, because one agreeing proves only that both landed in a bucket once — the derivation is `g_str_hash` over UTF-8 BYTES, and a renderer hashing UTF-16 code units agrees for plenty of ASCII names |
191
+ | both halves show ONE toast for two adds | measured on libadwaita 1.9.3 as a single `AdwToastWidget` carrying the first title, and asserted of `@gjsify/adwaita-core`'s `AdwToastQueue` on the other side. Neither half runs the other's queue |
192
+ | the millisecond&rarr;second conversion cannot turn a brief toast into a permanent one | `Adw.Toast:timeout` counts whole seconds and reads back 5 on a default toast; `DEFAULT_TOAST_TIMEOUT` counts 5000 ms. The conversion is `ceil`, asserted against libadwaita's own default rather than against itself — `Math.round(400 / 1000)` is 0, which is "until dismissed" |
193
+ | the spinner's box and its ring are held on the half where each is a node | GTK measures the BOX (`[16, 16]` unrequested, 200 requested, no upper bound); React Native asserts the RING, which on GTK is an `AdwSpinnerPaintable` and not a widget at all — 64 points with an 8-point stroke inside a 200-point box |
194
+ | the rows share libadwaita's derivations rather than re-deriving them | the React Native half runs `@gjsify/adwaita-core` and the GTK half reads the answer back off the real widget: `activatable` false on `Adw.ActionRow` and `BUTTON_ROW_ACTIVATABLE` true on `Adw.ButtonRow`, the `notify` gate that stays SILENT for a set to the value already held on both the switch row and the expander, and `max-length` keeping `'🔒é'` — 2 characters, 3 UTF-16 units — where `TextInput.maxLength` would cut the pair in half |
195
+ | `AdwExpanderRow`: the disclosure is an ALLOCATION, not a flag | the live GTK tree, with animations off: the disclosed row is unmapped at 0×0 and still PARENTED while collapsed, and 596 wide below the header once revealed, with the expander's height equal to its header list plus its revealer to the point (109 = 55 + 54 on libadwaita 1.9.3) |
196
+ | `AdwExpanderRow`: an unechoed toggle survives the next render, on both halves | a second render with the prop unchanged, asserted on each side — the GTK one against the real widget through `@gjsify/gtk-host`'s patch-on-change, the React Native one through `ExpanderState` |
197
+
198
+ **Not proven: the row THEME.** What the rows lay out is structure — `flexDirection: 'row'`
199
+ is what makes a row a row — and what they do not carry is padding, the type scale, the
200
+ dim-label colour and the row separator. `@gjsify/adwaita-core`'s `/tokens` subpath states
201
+ outright that projecting its CSS custom properties onto a React Native style scale is a
202
+ mapping decision of its own, and this slice does not make it. The rows are correct and
203
+ unstyled.
105
204
 
106
205
  **Not proven: Yoga, and the device.** A `width` in a style object is an instruction to a
107
206
  layout engine that no test here runs. The React Native half is type-checked and
@@ -113,6 +212,96 @@ and until then it is a gap, not a formality.
113
212
  These are places where the two halves cannot be made identical, written down rather
114
213
  than smoothed over.
115
214
 
215
+ - **`AdwPreferencesPage` is not a scroller on React Native.** `Adw.PreferencesPage` wraps
216
+ its groups in a `GtkScrolledWindow`; this half emits the column and a consumer wraps it.
217
+ Not a shortcut: `testing/react-native.ts` may only double a React Native component that
218
+ IS a host element with its props forwarded, and `ScrollView` is a COMPOSITE that renders
219
+ `RCTScrollView` around a second content `View` and moves `contentContainerStyle` onto it.
220
+ A double of it would be a nesting real React Native never emits, and every assertion
221
+ written against it would be about the double — the measured reason `spinner.native.tsx`
222
+ refuses `ActivityIndicator`. The same wrapper carries the page's CLAMP:
223
+ `adw-preferences-page.ui` puts an `AdwClamp` inside the scrolled window, so a wide window
224
+ centres the groups at the clamp width while this half stretches them. `AdwClamp` is in
225
+ this package, so a consumer that wants both wraps with both.
226
+ - **`AdwPreferencesGroup` has no `header-suffix` and no `separate-rows`.** The first is a
227
+ placement question, not a naming one: `header-suffix` holds a WIDGET, so a React surface
228
+ has to spell it as a slot, and the group's curated descriptor in `@gjsify/gtk-host` is
229
+ `ordered` — `add`/`remove`, `remove-all` to reorder, because `Adw.PreferencesGroup.insert`
230
+ does not exist on libadwaita 1.x — which has no slots at all. Adding one changes a
231
+ placement policy other conformance vectors already assert, with its own measurement. The
232
+ second is pure card styling, and this package's React Native half draws no theme.
233
+ - **`AdwPreferencesGroup`'s `single-line` header state is derived and not drawn.** It is a
234
+ stylesheet number — `min-height: 34px` against `margin-bottom: 6px` — and there is no
235
+ theme layer here to spend it in. It is computed because it comes out of the same core call
236
+ as the four states that ARE drawn.
237
+ - **A pure-markup group title is hidden on GTK and shown on React Native.**
238
+ `adw-preferences-group.ui` sets `use-markup` on both header labels, and libadwaita's
239
+ visibility test reads the DISPLAYED text — so `<b></b>` is an empty label there. This half
240
+ paints the string verbatim and passes `useMarkup: false`, which is the case
241
+ `derivePreferencesGroupHeader` documents that value for, and which both sibling renderers
242
+ pass as well.
243
+ - **`AdwComboRow` has no popover on React Native.** `Adw.ComboRow` opens a `GtkPopover` over
244
+ a `GtkListView`; a row with no overlay layer cannot. The press advances to the next option
245
+ and wraps, which still runs the real `ComboState.select` guard — bounds and
246
+ no-op-on-same — so the arithmetic underneath is the shipped one and only the gesture is
247
+ this half's own.
248
+ - **`AdwComboRow`'s `useSubtitle` publishes the value at once on React Native and on the
249
+ next selection change on GTK.** What both halves DO agree on is that the value is drawn in
250
+ one place: `adw-combo-row.ui` binds the inline value view's `visible` to `use-subtitle`
251
+ with `sync-create|invert-boolean`, and this half hides its trailing label the same way.
252
+ What they cannot agree on is WHEN the subtitle picks the value up.
253
+ `adw_combo_row_set_use_subtitle` calls `selection_changed`, while the subtitle is written
254
+ by `selection_item_changed` — a different function, reached only from
255
+ `notify::selected-item` and `set_model` — so an authored subtitle survives switching
256
+ `use-subtitle` on and is replaced by the next selection change. Measured on libadwaita
257
+ 1.9.3 and asserted on both halves. Reproducing the lag here would mean carrying a
258
+ libadwaita ordering artefact into a renderer that has no reason for it.
259
+ - **`AdwSpinRow`'s range is spelled `lower`/`upper`/`stepIncrement`, where the two sibling
260
+ Adwaita renderers spell it `min`/`max`/`step`.** Those are
261
+ `adw_spin_row_new_with_range`'s PARAMETER names; these are `Gtk.Adjustment`'s own GObject
262
+ property names for the same three values, and this package's rule is that a caller writes
263
+ the property they would look up in libadwaita's documentation. The arithmetic is still
264
+ shared — both halves map onto `@gjsify/adwaita-core`'s `SpinState`, which uses the short
265
+ names internally.
266
+ - **`AdwSpinRow`'s decimal separator is the process locale's on GTK and always `.` on React
267
+ Native.** `gtk_spin_button_update` formats the displayed value through the C library's
268
+ locale — measured on gjs 1.88.1 under a de_DE locale, a `digits={2}` row of 3.14159 reads
269
+ `3,14` — while `Number.prototype.toFixed` is specified never to localise and gives `3.14`
270
+ on every machine there is. The two halves therefore agree on the DIGIT COUNT and differ by
271
+ one character. Both suites assert the digits; neither builds its expectation from the
272
+ locale, because a test that did would be measuring the machine it runs on.
273
+ - **A range that moves past itself notifies twice more on React Native than on GTK.** The
274
+ GTK half builds one new `Gtk.Adjustment` from `lower`, `upper` and `stepIncrement`
275
+ together, so moving 0…100/50 to 200…300/250 is a single step. The React Native half
276
+ applies each property in its own effect — one per setter, because each has its own guard
277
+ in the C — so it passes through an inverted range: `setMin(200)` runs while the maximum is
278
+ still 100, and `SpinState`'s clamp answers the maximum. `onNotifyValue` therefore reports
279
+ `100, 200, 250` where GTK reports the end state. The settled value is the same on both,
280
+ React batches the renders, and the stream is asserted so that changing it is a decision.
281
+ - **`AdwSpinRow` carries no `climb-rate`, `snap-to-ticks`, `numeric`, `update-policy` or
282
+ `wrap`.** Each needs an editable text entry or a key-repeat timer the React Native half
283
+ does not have, so carrying them would mean a property GTK honours and the phone ignores.
284
+ Neither sibling renderer has them either.
285
+ - **`AdwPasswordEntryRow`'s caps-lock indicator is present and can never show.**
286
+ `indicatorVisible` is `editing && show_indicator`, and `show_indicator` is pushed from
287
+ `!revealed && capsLockOn` — but React Native exposes no keyboard modifier state, and this
288
+ surface carries no prop libadwaita does not have, so nothing can set it. The node stays in
289
+ the tree, hidden, and a test asserts that: "no caps-lock warning" and "no caps-lock
290
+ support" must not be the same picture. `@gjsify/adwaita-nativescript` hit the same wall
291
+ and answered it with a host seam, which is a surface this package does not have.
292
+ - **`AdwPasswordEntryRow` publishes no `revealed`, where both sibling renderers do.**
293
+ `Adw.PasswordEntryRow` declares no property of its own — its generated prop interface is
294
+ empty over `AdwEntryRowProps` — and the peek state is private to the widget. A `revealed`
295
+ prop would be the one place this surface invents a name; the button owns it on both halves.
296
+ - **The glyphs on the three rows are this half's own.** The chevron, the two steppers, the
297
+ apply check, the caps-lock arrow and the peek pair all stand in for icon-theme names the
298
+ core carries as data (`pan-down-symbolic`, `value-increase-symbolic`,
299
+ `adw-entry-apply-symbolic`, `caps-lock-symbolic`, `view-reveal-symbolic`). They are NOT
300
+ what `@gjsify/adwaita-web` draws — that renderer masks a generated CSS class from the same
301
+ names and draws no text at all — so they are named here as a divergence rather than as a
302
+ shared fallback. The accessible NAMES beside them do come from the core, so
303
+ "Show Password"/"Hide Password"/"Apply"/"Caps Lock is on" are one string in one place
304
+ across three renderers.
116
305
  - **`AdwClamp` ignores the child's intrinsic minimum on React Native.** libadwaita's
117
306
  clamp is a two-pass measure-then-allocate, and a child minimum wider than the clamp
118
307
  RAISES all three thresholds — which is how such a child still gets its minimum
@@ -124,13 +313,229 @@ than smoothed over.
124
313
  and inventing a styling seam is a decision this slice does not make.
125
314
  - **One unclamped frame.** Before the first `onLayout` there is no available width, so
126
315
  the child renders full-width for one frame.
127
- - **A second child is kept on React Native and dropped on GTK, silently.** `Adw.Bin` and
128
- `Adw.Clamp` are one-child widgets, and gtk-host's `single` child policy fills that slot
129
- with `set_child`, so a second child EVICTS the first — with no throw, no host error and
130
- no GLib message. A `View` has no such limit and renders both. Both behaviours are pinned
131
- by a test on each side, so neither can move alone. Refusing more than one child on both
132
- halves would close it and is a surface decision this slice does not make.
316
+ - **A second child is kept on React Native and dropped on GTK, silently.** `Adw.Bin`,
317
+ `Adw.Clamp`, `Adw.StatusPage:child` and `Adw.ToolbarView:content` are one-child slots,
318
+ and gtk-host's `single` child policy fills them with `set_child`, so a second child
319
+ EVICTS the first — with no throw, no host error and no GLib message. A `View` has no
320
+ such limit and renders both. Both behaviours are pinned by a test on each side, so
321
+ neither can move alone. Refusing more than one child on both halves would close it and
322
+ is a surface decision this slice does not make.
323
+ - **`AdwHeaderBar` resolves an unauthored title on GTK and leaves it blank on a phone.**
324
+ Authoring neither `title` nor `subtitle` installs no title widget at all, so
325
+ libadwaita's `update_title` (adw-header-bar.c:475) walks navigation page → dialog →
326
+ window → application name and puts what it finds in the centre; a phone has none of
327
+ those to walk. Both sides are asserted — the GTK suite reads the window's own title
328
+ back out of the bar, the React Native suite reads two collapsed labels.
329
+ - **`AdwHeaderBar` has a `title`/`subtitle` that `Adw.HeaderBar` does not.** The real
330
+ widget has no `title` property; its derived centre is a plain `gtk_label_new (NULL)`
331
+ with no subtitle at all, and an app that wants one sets an `AdwWindowTitle` as its
332
+ title widget. A declarative surface wants the attribute, so authoring either installs
333
+ an `AdwWindowTitle` centre. This is the same divergence `@gjsify/adwaita-web` and
334
+ `@gjsify/adwaita-nativescript` carry, recorded as `HeaderBarRenderState.derivedSubtitle`
335
+ in `@gjsify/adwaita-core`.
336
+ - **Neither renderer here resolves an icon theme, so `iconName` is accepted and not
337
+ drawn.** `icon-name` names an entry in an ICON THEME and React Native has none — no
338
+ `Image` source a GNOME symbolic name resolves to, and no renderer for the SVG
339
+ `@gjsify/adwaita-nativescript` substituted instead. Drawing the name as text would put
340
+ the literal `folder-symbolic` on screen. So `AdwStatusPage` shows no icon, `AdwAvatar`'s
341
+ icon mode is a coloured circle with the initials hidden where GTK draws
342
+ `adw-avatar-default-symbolic`, and `AdwButtonContent`'s icon slot sits in the row with
343
+ libadwaita's own `hexpand` and holds no glyph. The props are carried so a GTK consumer's
344
+ props stay portable, and the ABSENCE of an icon node is asserted in each case, so the
345
+ day one appears it is a decision and not a drift.
346
+ - **`AdwToolbarView` does not run libadwaita's allocation on React Native, and cannot.**
347
+ `adw_toolbar_view_size_allocate` is two chained CLAMPs over the bars' MINIMUM and
348
+ NATURAL heights — ported as `toolbarViewAllocate` and held to vectors — and React
349
+ Native hands a component an already-laid-out size and never a child's intrinsic
350
+ minimum. Feeding the measurement in as both `min` and `nat` would turn each CLAMP into
351
+ the identity and dress a pass-through up as libadwaita's arithmetic. The consequence is
352
+ one-directional: a STRETCHY bar keeps its natural height where libadwaita would shrink
353
+ it toward its minimum to protect the content.
354
+ - **`AdwToolbarView`'s four style classes have nowhere to land on a phone.** `raised`,
355
+ `border`, `undershoot-top` and `undershoot-bottom` are what `topBarStyle` and
356
+ `bottomBarStyle` derive; React Native has no class system to stamp them into. Both
357
+ props are carried and reach no style, which is asserted on the React Native side and
358
+ measured against libadwaita's own `update_undershoots` on the GTK side.
359
+ - **`AdwWrapBox`'s `naturalLineLength` is a MAX SIZE on React Native.** libadwaita caps
360
+ the box's NATURAL size REQUEST and leaves a larger allocation free to happen; neither
361
+ CSS nor Yoga has a property that caps only the intrinsic contribution, so this half
362
+ writes `maxWidth`/`maxHeight`. `@gjsify/adwaita-web` records the same deliberate
363
+ deviation. Limiting line length inside a popover — the intended use — behaves the same
364
+ either way.
365
+ - **`AdwWrapBox` wraps every child in a `View` of its own.** `flex-grow` and `flex-shrink`
366
+ belong to the CHILD, and this component does not own its children's styles:
367
+ NativeScript sets them as attached properties and the browser publishes a custom
368
+ property its stylesheet reads, and neither seam exists here. The wrapper is therefore
369
+ visible in the tree and is asserted rather than left as an implementation detail.
370
+ - **`AdwWrapBox`'s `align` is snapped to three positions on both non-GTK renderers.** C
371
+ offsets the whole line block by `roundf (length_delta * align)` — a continuum — and
372
+ flexbox has `flex-start`, `center` and `flex-end`. The snap is the renderers'
373
+ approximation and not libadwaita's rule, which is why it lives in
374
+ `@gjsify/adwaita-core`'s `wrapBoxFlexStyle` rather than in a conformance vector. The
375
+ GTK half runs none of it: `Adw.WrapBox` is `adw-wrap-layout.c` itself, and the suite
376
+ reads the continuum back off the live tree.
377
+ - **`AdwAvatar`'s font size is the CAP, not a measurement.** `update_font_size` scales
378
+ the label's measured aspect ratio against `avatarMaxFontSize(size)`; React Native
379
+ reports a text box only through `onLayout`, i.e. after layout — the same missing
380
+ measure pass that makes `AdwClamp` pass `childMin: 0`. Using the cap alone stays inside
381
+ libadwaita's bound. The NativeScript port's `size * 0.4` heuristic is deliberately not
382
+ copied: it is not monotonic in `size` and exceeds the cap above ~54 points.
383
+ - **`AdwButtonContent` cannot stamp `image-text-button`.** `adw_button_content_root` puts
384
+ the class on the nearest `GtkButton` ancestor, and this package ships no button for it
385
+ to find. `buttonContentStyleTargetIndex` holds the retarget rule for a renderer that has
386
+ a tree to walk; when a button lands here, that is the call to make.
387
+ - **`AdwSpinner` draws the track and not the arc.** `AdwSpinnerPaintable`'s segment
388
+ extends, overlaps, contracts and idles on an ease-in-out-sine while the whole figure
389
+ turns, and drawing it needs a path renderer that is not a dependency of this package.
390
+ What is drawn is the circle underneath — `ADW_SPINNER_TRACK_OPACITY` of the current
391
+ colour, exactly what the browser renderer paints under its arc. The `_spinner.scss`
392
+ substitute (a fixed 90-degree `border-top-color` chase at 0.8s) is a different animation
393
+ with a different period, so copying it would put a wrong number where there is an absent
394
+ one. **The suite asserts the track's opacity and nothing about motion** — there is no
395
+ animation assertion here, because there is no animation to assert.
396
+ - **`Adw.Toast:timeout` is lossy in the other direction.** GObject stores whole seconds,
397
+ so 1500 ms is 2 s on GTK and stays 1500 ms on React Native.
398
+ - **A toast's action button has no callback.** `Adw.Toast` expresses its action as
399
+ `action-name`, a `GAction` this package has no surface for, so pressing the button does
400
+ what both other renderers do: dismiss the current toast, which advances the queue.
401
+ - **`dismissAll`'s REMOVAL is asserted only on React Native.**
402
+ `adw_toast_overlay_dismiss_all` animates the strip out over real time, and pumping the
403
+ main context for ~1.6s leaves the `AdwToastWidget` in place — measured. GTK asserts that
404
+ the call lands and costs no diagnostic; the removal is asserted where the queue is ours.
405
+ - **`AdwBanner` reduces markup to its plain text.** React Native has no inline-markup
406
+ layer, and painting `<b>Metered</b>` literally is further from what GTK draws than
407
+ painting `Metered` is. Unparseable markup keeps the raw string, which is Pango's own
408
+ fallback.
409
+ - **A press assertion proves the widget ASKS for the press, never that a tap arrives.**
410
+ The `react-native` double forwards `onPress` verbatim; the real runtime wires it through
411
+ the press responder. Same class of gap as Yoga, one layer up.
133
412
  - **`Adw.ClampScrollable` has no counterpart and will not get one.** It binds its four
134
413
  scroll properties onto its child, which is a GTK adoption concern; on React Native
135
414
  scrolling belongs to the `ScrollView`, not to the clamp. This is an asymmetry, not a
136
415
  missing widget.
416
+ - **No icons anywhere on the React Native half.** `AdwActionRow:icon-name`,
417
+ `AdwButtonRow:start-icon-name`/`:end-icon-name` and `Adw.EntryRow`'s edit and indicator
418
+ icons all name an entry in a GTK ICON THEME, and this package ships no icon renderer for
419
+ React Native. The PROPS are therefore absent from the surface rather than accepted on one
420
+ half and dropped on the other. Two affordances that are the widget's own rather than a
421
+ caller's prop do get a stand-in CHARACTER — the entry row's apply button (`✓`) and the
422
+ expander's chevron (`▾`/`▴`) — because without them those two widgets give a user no
423
+ signal that they do anything. Neither is what `@gjsify/adwaita-web` draws: that renderer
424
+ masks a generated `.adw-icon--<name>` CSS class and shows no text at all.
425
+ - **`add_prefix` has no counterpart.** `Adw.ActionRow` and `Adw.ExpanderRow` both have a
426
+ prefix slot, reachable on the GTK half by writing `slot="prefix"` on a child. React
427
+ Native has no slot mechanism, and giving the surface a `prefix` PROP taking a node would
428
+ be a second child channel that only one half implements, so the surface offers `children`
429
+ only — the suffix on the action row, the disclosure on the expander.
430
+ - **`AdwExpanderRow` carries no `enable-expansion` and no `show-enable-switch`.** The
431
+ enable switch is a SECOND control inside the row with its own veto over the disclosure,
432
+ and the rule tying the two flags together lives in no shared place:
433
+ `@gjsify/adwaita-core`'s `ExpanderState` — what all three renderers compose — models the
434
+ disclosure alone. Adding it here would create a fourth private copy of a rule three
435
+ renderers need; lifting it into the core first is what would close this, and this slice
436
+ does not do it.
437
+ - **A disclosed child must be a real row on GTK, and can be anything on React Native.**
438
+ `adw_expander_row_add_row` hands the widget to an inner `Gtk.ListBox`, which wraps a
439
+ non-row child in an implicit `GtkListBoxRow` that `remove` then cannot find — measured on
440
+ libadwaita 1.9.3, a `Gtk.Label` disclosed child leaks on unmount behind a single
441
+ `Gtk-WARNING`, an `Adw.ActionRow` round-trips cleanly. The curated descriptor carries the
442
+ measurement. A React Native `View` has no such rule.
443
+ - **`AdwEntryRow`'s empty↔filled cross-fade is a hard swap.** libadwaita animates between
444
+ the placeholder and the floating title over its own duration; the React Native half
445
+ switches at the two endpoints, the same compromise `@gjsify/adwaita-nativescript` makes,
446
+ because a cross-fade needs an animation seam this slice does not add.
447
+ - **`AdwSwitchRow` is strictly controlled and `Adw.SwitchRow` is not.** React Native's own
448
+ contract for `Switch` is that the component renders the `value` prop whatever the user
449
+ does, so a toggle the consumer declines to echo back is not kept here — where GTK keeps
450
+ it. The other two stateful rows go the GTK way (see [Widgets](#widgets)); this one goes
451
+ React Native's, because a `Switch` that disagrees with its `value` prop is a bug on that
452
+ platform.
453
+ - **The navigation view animates on GTK and swaps instantly on React Native, and there
454
+ is no automatic back button.** `animateTransitions` reaches the real
455
+ `Adw.NavigationView` and reaches `NavigationViewState` on the other half, where nothing
456
+ spends it — this package has no animation layer, which is the same position
457
+ `@gjsify/adwaita-nativescript` records ("kept for API parity"). `popOnEscape` is inert
458
+ for the plainer reason that a phone has no Escape key. And where the browser renderer
459
+ finds an `<adw-header-bar>` inside the visible page and injects a back button into it,
460
+ neither NativeScript nor this package can identify a header bar inside an opaque child:
461
+ `canGoBack()` and `backButtonTooltip()` on the handle are libadwaita's own two
462
+ derivations, and the caller wires its own button to them.
463
+ - **An untitled `Adw.NavigationPage` is a GTK warning and nothing at all on React
464
+ Native.** Measured on libadwaita 1.9.3: a page with no title prints `AdwNavigationPage
465
+ 0x… is missing a title. To hide a header bar title, consider using
466
+ AdwHeaderBar:show-title instead.` The React Native half has no counterpart, so the
467
+ `'Back'` tooltip fallback — which needs an empty title — is asserted on that half only,
468
+ against the constant both halves import from `@gjsify/adwaita-core`.
469
+ - **Neither split view has a content minimum to protect on React Native.** libadwaita
470
+ caps the sidebar with the content pane's own minimum width and reports
471
+ `sidebar_min + content_min` as the view's own minimum; React Native hands a component an
472
+ already-laid-out size and never a child's intrinsic minimum, so `contentMin` and
473
+ `sidebarChildMin` go in as 0. The consequences are one-directional and both measured:
474
+ the sidebar can take its full share of a view too narrow for both panes, and the view
475
+ cannot refuse to be narrower than its contents the way GTK does (the GTK suite asserts
476
+ that refusal at 380 against `measureSplitViewHorizontal`; the React Native suite cannot
477
+ ask). Same class as `AdwClamp`'s `childMin`.
478
+ - **The two sidebar-width rules can only be told apart one at a time on GTK.**
479
+ `resolveNavigationSidebarWidth` caps the sidebar's MAX BOUND by `width - content_min`
480
+ and `resolveOverlaySidebarWidth` caps the RESULT, which the core's own vectors separate
481
+ at 300 points (180 versus 100). The NAVIGATION half of that pair is unreachable through
482
+ a window: `measure_uncollapsed` makes `sidebar_min + content_min` its minimum, GTK never
483
+ allocates below a minimum, and from there upwards `width - content_min` never falls under
484
+ `sidebar_min`, so the bound cap never inverts. The OVERLAY half is reachable, because its
485
+ minimum is `(int) (sidebar_min * show_progress) + content_min` — a hidden sidebar takes
486
+ that term out — and the GTK suite reads its 100 off the live tree. So the two answers are
487
+ never asserted side by side here; the disagreement itself is held by
488
+ `@gjsify/adwaita-core`'s vectors, and this package asserts the navigation minimum and the
489
+ overlay cap separately.
490
+ - **The overlay's reveal is instant on React Native.** libadwaita animates with a spring
491
+ `(1, 0.5, 500)`; `@gjsify/adwaita-web` approximates it from `requestAnimationFrame` and
492
+ `@gjsify/adwaita-nativescript` from `View.animate()`. React Native's own answer is
493
+ `Animated`, a COMPOSITE surface the test double may not stand in for, so the core's
494
+ `INSTANT_SPLIT_VIEW_ANIMATOR` default stands and `enableShowGesture` /
495
+ `enableHideGesture` are carried and inert. `show-progress` still runs through the core,
496
+ so the continuum is expressible the day an animator is plugged in.
497
+ - **The React Native split views resolve `start`/`end` against `ltr` only.**
498
+ `isSidebarAtVisualStart` takes a reading direction, GTK resolves it from the widget, and
499
+ React Native's lives on `I18nManager` — not a host component, so not something
500
+ `testing/react-native.ts` may double. The core call still takes the parameter; closing
501
+ this is one argument.
502
+ - **`sidebar-position: end` is invisible on a COLLAPSED React Native split view.**
503
+ `resolveNavigationStack` builds the stack the other way round for `end` — the content is
504
+ the root page and the sidebar is pushed on top of it — but the LAST entry, which is the
505
+ pane on screen, is the same for both positions at every value of `show-content`. What
506
+ differs is the push/pop DIRECTION, which a renderer spends on a slide and this one has
507
+ none of. The position IS asserted where it is observable: the docked draw order.
508
+ - **`sidebarTitle` and `contentTitle` reach a real page on GTK and nothing on a phone.**
509
+ They are `Adw.NavigationPage:title` of the wrap `AdwNavigationSplitView` puts around each
510
+ pane, which libadwaita uses for the header of a collapsed view. The React Native half has
511
+ no header bar to put a title in, so it carries them and draws neither — the same shape as
512
+ `iconName`.
513
+ - **`onNotifySelected` and `onNotifyValue` do not carry a PROGRAMMATIC change on GTK.** A
514
+ user pick reaches both halves. A change the caller made through `selected` / `value`
515
+ reaches the React Native half only: gtk-host suppresses a `notify::` raised inside its own
516
+ property write, and writing the prop IS that write — for the spin row through the
517
+ `adjustment` object it re-sets rather than through a `value` property. Measured on
518
+ libadwaita 1.9.3: a re-render from `selected={0}` to `selected={2}` moves the widget and
519
+ calls nothing, while `row.selected = 1` from outside React calls it. Same rule as
520
+ `onNotifyVisibleChild` below, and benign for the ordinary controlled pattern — the
521
+ consumer made the change and already knows — but it is not "every change".
522
+ - **`onNotifyVisibleChild` does not carry the same set of changes on both halves.** A
523
+ press on the switcher reaches both. A change the CALLER made through
524
+ `visibleChildName` reaches the React Native half only — it re-applies the prop through
525
+ `selectName` and reports what the stack settled on, while gtk-host drops the notify
526
+ raised inside its own property write, which is the same rule `onNotifyExpanded` already
527
+ records. The mount AUTO-PICK reaches neither: libadwaita notifies it from inside
528
+ `adw_view_stack_add_titled`, before React has committed the `ref` the settled name
529
+ would be read off (measured — the GTK half used to report `''` there, a name no page
530
+ carries), and on the other half the core's auto-pick lands before the subscription
531
+ exists. Both halves are asserted at the two ends of that.
532
+ - **`AdwViewSwitcher` bundles the stack libadwaita keeps separate.** `Adw.ViewSwitcher:stack`
533
+ points at an `Adw.ViewStack` elsewhere in the tree, and a React prop cannot hold a widget
534
+ that does not exist yet on the half where widgets exist at all. Both other renderers made
535
+ the same call. On GTK nothing is simulated: the component builds a real `Adw.ViewStack`
536
+ and writes it into that property, which the GTK suite asserts by identity.
537
+ - **The switcher's buttons carry no icon.** Same icon-theme rule as above, with one extra
538
+ consequence worth naming: a page with an icon and NO title still gets a button, because
539
+ `isViewSwitcherButtonVisible` tests both — and on React Native that button's label is
540
+ empty. The button's ORIENTATION is still applied, since it is what arranges the label
541
+ and the badge.
@@ -1 +1 @@
1
- import{AdwBin as e}from"./widgets/bin.gtk.js";import{AdwClamp as t}from"./widgets/clamp.gtk.js";export{e as AdwBin,t as AdwClamp};
1
+ import{AdwActionRow as e}from"./widgets/action-row.gtk.js";import{AdwAvatar as t}from"./widgets/avatar.gtk.js";import{AdwBanner as n}from"./widgets/banner.gtk.js";import{AdwBin as r}from"./widgets/bin.gtk.js";import{AdwButtonContent as i}from"./widgets/button-content.gtk.js";import{AdwButtonRow as a}from"./widgets/button-row.gtk.js";import{AdwClamp as o}from"./widgets/clamp.gtk.js";import{AdwComboRow as s}from"./widgets/combo-row.gtk.js";import{AdwEntryRow as c}from"./widgets/entry-row.gtk.js";import{AdwExpanderRow as l}from"./widgets/expander-row.gtk.js";import{AdwHeaderBar as u}from"./widgets/header-bar.gtk.js";import{AdwNavigationPage as d}from"./widgets/navigation-page.gtk.js";import{AdwNavigationSplitView as f}from"./widgets/navigation-split-view.gtk.js";import{AdwNavigationView as p}from"./widgets/navigation-view.gtk.js";import{AdwOverlaySplitView as m}from"./widgets/overlay-split-view.gtk.js";import{AdwPasswordEntryRow as h}from"./widgets/password-entry-row.gtk.js";import{AdwPreferencesGroup as g}from"./widgets/preferences-group.gtk.js";import{AdwPreferencesPage as _}from"./widgets/preferences-page.gtk.js";import{AdwSpinRow as v}from"./widgets/spin-row.gtk.js";import{AdwSpinner as y}from"./widgets/spinner.gtk.js";import{AdwStatusPage as b}from"./widgets/status-page.gtk.js";import{AdwSwitchRow as x}from"./widgets/switch-row.gtk.js";import{AdwToastOverlay as S}from"./widgets/toast-overlay.gtk.js";import{AdwToolbarView as C}from"./widgets/toolbar-view.gtk.js";import{AdwViewStack as w}from"./widgets/view-stack.gtk.js";import{AdwViewSwitcher as T}from"./widgets/view-switcher.gtk.js";import{AdwWindowTitle as E}from"./widgets/window-title.gtk.js";import{AdwWrapBox as D}from"./widgets/wrap-box.gtk.js";const O={ActionRow:e,Avatar:t,Banner:n,Bin:r,ButtonContent:i,ButtonRow:a,Clamp:o,ComboRow:s,EntryRow:c,ExpanderRow:l,HeaderBar:u,NavigationPage:d,NavigationSplitView:f,NavigationView:p,OverlaySplitView:m,PasswordEntryRow:h,PreferencesGroup:g,PreferencesPage:_,SpinRow:v,Spinner:y,StatusPage:b,SwitchRow:x,ToastOverlay:S,ToolbarView:C,ViewStack:w,ViewSwitcher:T,WindowTitle:E,WrapBox:D};export{O as Adw,e as AdwActionRow,t as AdwAvatar,n as AdwBanner,r as AdwBin,i as AdwButtonContent,a as AdwButtonRow,o as AdwClamp,s as AdwComboRow,c as AdwEntryRow,l as AdwExpanderRow,u as AdwHeaderBar,d as AdwNavigationPage,f as AdwNavigationSplitView,p as AdwNavigationView,m as AdwOverlaySplitView,h as AdwPasswordEntryRow,g as AdwPreferencesGroup,_ as AdwPreferencesPage,v as AdwSpinRow,y as AdwSpinner,b as AdwStatusPage,x as AdwSwitchRow,S as AdwToastOverlay,C as AdwToolbarView,w as AdwViewStack,T as AdwViewSwitcher,E as AdwWindowTitle,D as AdwWrapBox};
package/lib/esm/index.js CHANGED
@@ -1 +1 @@
1
- import{AdwBin as e}from"./widgets/bin.js";import{AdwClamp as t}from"./widgets/clamp.js";export{e as AdwBin,t as AdwClamp};
1
+ import{AdwActionRow as e}from"./widgets/action-row.js";import{AdwAvatar as t}from"./widgets/avatar.js";import{AdwBanner as n}from"./widgets/banner.js";import{AdwBin as r}from"./widgets/bin.js";import{AdwButtonContent as i}from"./widgets/button-content.js";import{AdwButtonRow as a}from"./widgets/button-row.js";import{AdwClamp as o}from"./widgets/clamp.js";import{AdwComboRow as s}from"./widgets/combo-row.js";import{AdwEntryRow as c}from"./widgets/entry-row.js";import{AdwExpanderRow as l}from"./widgets/expander-row.js";import{AdwHeaderBar as u}from"./widgets/header-bar.js";import{AdwNavigationPage as d}from"./widgets/navigation-page.js";import{AdwNavigationSplitView as f}from"./widgets/navigation-split-view.js";import{AdwNavigationView as p}from"./widgets/navigation-view.js";import{AdwOverlaySplitView as m}from"./widgets/overlay-split-view.js";import{AdwPasswordEntryRow as h}from"./widgets/password-entry-row.js";import{AdwPreferencesGroup as g}from"./widgets/preferences-group.js";import{AdwPreferencesPage as _}from"./widgets/preferences-page.js";import{AdwSpinRow as v}from"./widgets/spin-row.js";import{AdwSpinner as y}from"./widgets/spinner.js";import{AdwStatusPage as b}from"./widgets/status-page.js";import{AdwSwitchRow as x}from"./widgets/switch-row.js";import{AdwToastOverlay as S}from"./widgets/toast-overlay.js";import{AdwToolbarView as C}from"./widgets/toolbar-view.js";import{AdwViewStack as w}from"./widgets/view-stack.js";import{AdwViewSwitcher as T}from"./widgets/view-switcher.js";import{AdwWindowTitle as E}from"./widgets/window-title.js";import{AdwWrapBox as D}from"./widgets/wrap-box.js";const O={ActionRow:e,Avatar:t,Banner:n,Bin:r,ButtonContent:i,ButtonRow:a,Clamp:o,ComboRow:s,EntryRow:c,ExpanderRow:l,HeaderBar:u,NavigationPage:d,NavigationSplitView:f,NavigationView:p,OverlaySplitView:m,PasswordEntryRow:h,PreferencesGroup:g,PreferencesPage:_,SpinRow:v,Spinner:y,StatusPage:b,SwitchRow:x,ToastOverlay:S,ToolbarView:C,ViewStack:w,ViewSwitcher:T,WindowTitle:E,WrapBox:D};export{O as Adw,e as AdwActionRow,t as AdwAvatar,n as AdwBanner,r as AdwBin,i as AdwButtonContent,a as AdwButtonRow,o as AdwClamp,s as AdwComboRow,c as AdwEntryRow,l as AdwExpanderRow,u as AdwHeaderBar,d as AdwNavigationPage,f as AdwNavigationSplitView,p as AdwNavigationView,m as AdwOverlaySplitView,h as AdwPasswordEntryRow,g as AdwPreferencesGroup,_ as AdwPreferencesPage,v as AdwSpinRow,y as AdwSpinner,b as AdwStatusPage,x as AdwSwitchRow,S as AdwToastOverlay,C as AdwToolbarView,w as AdwViewStack,T as AdwViewSwitcher,E as AdwWindowTitle,D as AdwWrapBox};
@@ -1 +1 @@
1
- import{AdwBin as e}from"./widgets/bin.native.js";import{AdwClamp as t}from"./widgets/clamp.native.js";export{e as AdwBin,t as AdwClamp};
1
+ import{AdwActionRow as e}from"./widgets/action-row.native.js";import{AdwAvatar as t}from"./widgets/avatar.native.js";import{AdwBanner as n}from"./widgets/banner.native.js";import{AdwBin as r}from"./widgets/bin.native.js";import{AdwButtonContent as i}from"./widgets/button-content.native.js";import{AdwButtonRow as a}from"./widgets/button-row.native.js";import{AdwClamp as o}from"./widgets/clamp.native.js";import{AdwComboRow as s}from"./widgets/combo-row.native.js";import{AdwEntryRow as c}from"./widgets/entry-row.native.js";import{AdwExpanderRow as l}from"./widgets/expander-row.native.js";import{AdwWindowTitle as u}from"./widgets/window-title.native.js";import{AdwHeaderBar as d}from"./widgets/header-bar.native.js";import{AdwNavigationPage as f}from"./widgets/navigation-page.native.js";import{AdwNavigationSplitView as p}from"./widgets/navigation-split-view.native.js";import{AdwNavigationView as m}from"./widgets/navigation-view.native.js";import{AdwOverlaySplitView as h}from"./widgets/overlay-split-view.native.js";import{AdwPasswordEntryRow as g}from"./widgets/password-entry-row.native.js";import{AdwPreferencesGroup as _}from"./widgets/preferences-group.native.js";import{AdwPreferencesPage as v}from"./widgets/preferences-page.native.js";import{AdwSpinRow as y}from"./widgets/spin-row.native.js";import{AdwSpinner as b}from"./widgets/spinner.native.js";import{AdwStatusPage as x}from"./widgets/status-page.native.js";import{AdwSwitchRow as S}from"./widgets/switch-row.native.js";import{AdwToastOverlay as C}from"./widgets/toast-overlay.native.js";import{AdwToolbarView as w}from"./widgets/toolbar-view.native.js";import{AdwViewStack as T}from"./widgets/view-stack.native.js";import{AdwViewSwitcher as E}from"./widgets/view-switcher.native.js";import{AdwWrapBox as D}from"./widgets/wrap-box.native.js";const O={ActionRow:e,Avatar:t,Banner:n,Bin:r,ButtonContent:i,ButtonRow:a,Clamp:o,ComboRow:s,EntryRow:c,ExpanderRow:l,HeaderBar:d,NavigationPage:f,NavigationSplitView:p,NavigationView:m,OverlaySplitView:h,PasswordEntryRow:g,PreferencesGroup:_,PreferencesPage:v,SpinRow:y,Spinner:b,StatusPage:x,SwitchRow:S,ToastOverlay:C,ToolbarView:w,ViewStack:T,ViewSwitcher:E,WindowTitle:u,WrapBox:D};export{O as Adw,e as AdwActionRow,t as AdwAvatar,n as AdwBanner,r as AdwBin,i as AdwButtonContent,a as AdwButtonRow,o as AdwClamp,s as AdwComboRow,c as AdwEntryRow,l as AdwExpanderRow,d as AdwHeaderBar,f as AdwNavigationPage,p as AdwNavigationSplitView,m as AdwNavigationView,h as AdwOverlaySplitView,g as AdwPasswordEntryRow,_ as AdwPreferencesGroup,v as AdwPreferencesPage,y as AdwSpinRow,b as AdwSpinner,x as AdwStatusPage,S as AdwSwitchRow,C as AdwToastOverlay,w as AdwToolbarView,T as AdwViewStack,E as AdwViewSwitcher,u as AdwWindowTitle,D as AdwWrapBox};
@@ -0,0 +1 @@
1
+ import"./_virtual/_rolldown/runtime.js";import{deriveRowLabels as e}from"@gjsify/adwaita-core";import{Text as t,View as n}from"react-native";import{jsx as r,jsxs as i}from"react/jsx-runtime";const a={flexDirection:`row`,alignItems:`center`},o={flexDirection:`column`,flexGrow:1,flexShrink:1},s={display:`none`};function AdwRowLabels({title:a,subtitle:c}){let l=e({title:a,subtitle:c});return i(n,{style:o,children:[r(t,{style:l.titleVisible?void 0:s,children:l.title}),r(t,{style:l.subtitleVisible?void 0:s,children:l.subtitle})]})}export{s as ADW_ROW_HIDDEN_STYLE,a as ADW_ROW_STYLE,o as ADW_ROW_TEXT_COLUMN_STYLE,AdwRowLabels};
@@ -1 +1 @@
1
- import"../_virtual/_rolldown/runtime.js";import{createElement as e}from"react";const t=`RCTView`,View=n=>e(t,n);export{t as RCT_VIEW,View};
1
+ import"../_virtual/_rolldown/runtime.js";import{createElement as e}from"react";const t=`RCTView`,n=`RCTText`,r=`RCTSwitch`,i=`RCTSinglelineTextInputView`,View=n=>e(t,n),Text=t=>e(n,t),Pressable=n=>e(t,n),Switch=t=>e(r,t),refuseTextInputState=e=>{throw Error(`@gjsify/adwaita-react-native: TextInput.State.${e}() is not in the test double. It is React Native's module-scoped focus registry, which needs a running host; a widget that has started to call it needs a real device or a different oracle, not a stub answer this suite invented.`)},a=Object.assign(t=>e(i,t),{State:{currentlyFocusedInput:()=>refuseTextInputState(`currentlyFocusedInput`),currentlyFocusedField:()=>refuseTextInputState(`currentlyFocusedField`),focusTextInput:()=>refuseTextInputState(`focusTextInput`),blurTextInput:()=>refuseTextInputState(`blurTextInput`)}});export{Pressable,r as RCT_SWITCH,n as RCT_TEXT,i as RCT_TEXT_INPUT,t as RCT_VIEW,Switch,Text,a as TextInput,View};
@@ -0,0 +1 @@
1
+ import"../_virtual/_rolldown/runtime.js";import{jsx as e}from"@gjsify/gtk-host/react/jsx-runtime";function AdwActionRow({title:t,subtitle:n,activatable:r,onActivated:i,children:a}){return e(`adw-action-row`,{title:t,subtitle:n,activatable:r,onActivated:i,children:a})}export{AdwActionRow};
@@ -0,0 +1 @@
1
+ import"../_virtual/_rolldown/runtime.js";import{refuseBaseModule as e}from"../refuse.js";function AdwActionRow(t){return e(`AdwActionRow`)}export{AdwActionRow};
@@ -0,0 +1 @@
1
+ import"../_virtual/_rolldown/runtime.js";import{ADW_ROW_STYLE as e,AdwRowLabels as t}from"../row-shell.native.js";import{Pressable as n}from"react-native";import{jsx as r,jsxs as i}from"react/jsx-runtime";function AdwActionRow({title:a,subtitle:o,activatable:s,onActivated:c,children:l}){return i(n,{style:e,disabled:s!==!0,onPress:c,children:[r(t,{title:a,subtitle:o}),l]})}export{AdwActionRow};
@@ -0,0 +1 @@
1
+ import"../_virtual/_rolldown/runtime.js";import{jsx as e}from"@gjsify/gtk-host/react/jsx-runtime";function AdwAvatar({size:t,text:n,showInitials:r,iconName:i}){return e(`adw-avatar`,{size:t,text:n,"show-initials":r,"icon-name":i})}export{AdwAvatar};
@@ -0,0 +1 @@
1
+ import"../_virtual/_rolldown/runtime.js";import{refuseBaseModule as e}from"../refuse.js";function AdwAvatar(t){return e(`AdwAvatar`)}export{AdwAvatar};
@@ -0,0 +1 @@
1
+ import"../_virtual/_rolldown/runtime.js";import{avatarColor as e,avatarInitials as t,avatarMaxFontSize as n,avatarMode as r,flattenAvatarGradient as i}from"@gjsify/adwaita-core";import{Text as a,View as o}from"react-native";import{jsx as s}from"react/jsx-runtime";function AdwAvatar({size:c,text:l,showInitials:u}){let d=l??``,f=e(d),p=r({hasCustomImage:!1,showInitials:u??!1,text:d});return s(o,{style:{width:c,height:c,borderRadius:c/2,backgroundColor:i(f),alignItems:`center`,justifyContent:`center`},children:s(a,{style:{color:f.fg,fontSize:n(c),display:p===`initials`?`flex`:`none`},children:t(d)})})}export{AdwAvatar};
@@ -0,0 +1 @@
1
+ import"../_virtual/_rolldown/runtime.js";import{jsx as e}from"@gjsify/gtk-host/react/jsx-runtime";function AdwBanner({title:t,buttonLabel:n,revealed:r,useMarkup:i,buttonStyle:a,onButtonClicked:o}){return e(`adw-banner`,{title:t,"button-label":n,revealed:r,"use-markup":i,"button-style":a,onButtonClicked:o})}export{AdwBanner};
@@ -0,0 +1 @@
1
+ import"../_virtual/_rolldown/runtime.js";import{refuseBaseModule as e}from"../refuse.js";function AdwBanner(t){return e(`AdwBanner`)}export{AdwBanner};
@@ -0,0 +1 @@
1
+ import"../_virtual/_rolldown/runtime.js";import{ADW_ACCENT_FG_COLOR as e,adwaitaAccent as t,adwaitaAccentBgColor as n,bannerButtonStyleClasses as r,bannerButtonText as i,bannerButtonVisible as a,onAdwaitaAccentChanged as o,parseBannerButtonStyle as s,stripMarkup as c}from"@gjsify/adwaita-core";import{useSyncExternalStore as l}from"react";import{Text as u,View as d}from"react-native";import{jsx as f,jsxs as p}from"react/jsx-runtime";const onAdwaitaAccentChangedStore=e=>o(e);function AdwBanner({title:o,buttonLabel:m,revealed:h,useMarkup:g,buttonStyle:_,onButtonClicked:v}){let y=l(onAdwaitaAccentChangedStore,t,t),b=o??``,x=m??``,S=r(s(_)).includes(`suggested-action`);return p(d,{style:{display:h??!1?`flex`:`none`,flexDirection:`row`,alignItems:`center`},children:[f(u,{style:{flexGrow:1},children:g??!1?c(b)??b:b}),f(u,{accessibilityRole:`button`,onPress:v,style:{display:a(x)?`flex`:`none`,backgroundColor:S?n(y):void 0,color:S?e:void 0},children:i(x)})]})}export{AdwBanner};
@@ -0,0 +1 @@
1
+ import"../_virtual/_rolldown/runtime.js";import{jsx as e}from"@gjsify/gtk-host/react/jsx-runtime";function AdwButtonContent({iconName:t,label:n,useUnderline:r,canShrink:i}){return e(`adw-button-content`,{"icon-name":t,label:n,"use-underline":r,"can-shrink":i})}export{AdwButtonContent};
@@ -0,0 +1 @@
1
+ import"../_virtual/_rolldown/runtime.js";import{refuseBaseModule as e}from"../refuse.js";function AdwButtonContent(t){return e(`AdwButtonContent`)}export{AdwButtonContent};
@@ -0,0 +1 @@
1
+ import"../_virtual/_rolldown/runtime.js";import{BUTTON_CONTENT_BOX_SPACING as e,buttonContentEllipsize as t,buttonContentIconExpands as n,buttonContentLabelText as r,buttonContentLabelVisible as i}from"@gjsify/adwaita-core";import{Text as a,View as o}from"react-native";import{jsx as s,jsxs as c}from"react/jsx-runtime";function AdwButtonContent({label:l,useUnderline:u,canShrink:d}){let f=l??``;return c(o,{style:{flexDirection:`row`,alignItems:`center`,columnGap:e},children:[s(o,{style:{flexGrow:+!!n(f)}}),s(a,{numberOfLines:+(t(d??!1)===`end`),ellipsizeMode:`tail`,style:{display:i(f)?`flex`:`none`},children:r(f,u??!1)})]})}export{AdwButtonContent};
@@ -0,0 +1 @@
1
+ import"../_virtual/_rolldown/runtime.js";import{jsx as e}from"@gjsify/gtk-host/react/jsx-runtime";function AdwButtonRow({title:t,onActivated:n}){return e(`adw-button-row`,{title:t,onActivated:n})}export{AdwButtonRow};
@@ -0,0 +1 @@
1
+ import"../_virtual/_rolldown/runtime.js";import{refuseBaseModule as e}from"../refuse.js";function AdwButtonRow(t){return e(`AdwButtonRow`)}export{AdwButtonRow};
@@ -0,0 +1 @@
1
+ import"../_virtual/_rolldown/runtime.js";import{ADW_ROW_HIDDEN_STYLE as e,ADW_ROW_STYLE as t}from"../row-shell.native.js";import{ButtonRowState as n}from"@gjsify/adwaita-core";import{Pressable as r,Text as i}from"react-native";import{jsx as a}from"react/jsx-runtime";const o={...t,justifyContent:`center`},buttonRowState=e=>{let t=new n;return t.setTitle(e),t.state};function AdwButtonRow({title:t,onActivated:n}){let s=buttonRowState(t);return a(r,{style:o,disabled:!s.activatable,onPress:n,children:a(i,{style:s.titleVisible?void 0:e,children:s.title})})}export{AdwButtonRow};
@@ -1 +1 @@
1
- import"../_virtual/_rolldown/runtime.js";import{ADW_CLAMP_DEFAULTS as e,clampAllocate as t,normalizeClampSize as n}from"@gjsify/adwaita-core";import{View as r}from"react-native";import{jsx as i}from"react/jsx-runtime";import{useCallback as a,useState as o}from"react";function AdwClamp({children:s,maximumSize:c,tighteningThreshold:l}){let[u,d]=o(null),f=a(e=>{d(e.nativeEvent.layout.width)},[]),p=u===null?null:t(u,{maximumSize:n(c,e.maximumSize),tighteningThreshold:n(l,e.tighteningThreshold),childMin:0,childNat:0});return i(r,{onLayout:f,style:{alignSelf:`stretch`},children:i(r,{style:p===null?void 0:{width:p.childSize,marginStart:p.offset},children:s})})}export{AdwClamp};
1
+ import"../_virtual/_rolldown/runtime.js";import{ADW_CLAMP_DEFAULTS as e,clampAllocate as t,normalizeClampSize as n}from"@gjsify/adwaita-core";import{useCallback as r,useState as i}from"react";import{View as a}from"react-native";import{jsx as o}from"react/jsx-runtime";function AdwClamp({children:s,maximumSize:c,tighteningThreshold:l}){let[u,d]=i(null),f=r(e=>{d(e.nativeEvent.layout.width)},[]),p=u===null?null:t(u,{maximumSize:n(c,e.maximumSize),tighteningThreshold:n(l,e.tighteningThreshold),childMin:0,childNat:0});return o(a,{onLayout:f,style:{alignSelf:`stretch`},children:o(a,{style:p===null?void 0:{width:p.childSize,marginStart:p.offset},children:s})})}export{AdwClamp};
@@ -0,0 +1 @@
1
+ import"../_virtual/_rolldown/runtime.js";import{jsx as e}from"@gjsify/gtk-host/react/jsx-runtime";import{ADW_COMBO_NO_SELECTION as t,normalizeComboOptions as n}from"@gjsify/adwaita-core";import r from"gi://Gtk?version=4.0";import{useCallback as i,useMemo as a,useRef as o}from"react";const s=4294967295,comboSelectedIndex=e=>e===4294967295?t:e;function AdwComboRow({title:t,subtitle:s,model:c,selected:l,useSubtitle:u,onNotifySelected:d}){let f=o(null),p=n(c).map(e=>e.label),m=a(()=>new r.StringList({strings:p}),[p.join(``)]),h=i(()=>{let e=f.current;e!==null&&d?.(comboSelectedIndex(e.selected))},[d]);return e(`adw-combo-row`,{ref:f,title:t,subtitle:s,model:m,selected:l,"use-subtitle":u,onNotifySelected:d===void 0?void 0:h})}export{AdwComboRow,s as GTK_INVALID_LIST_POSITION,comboSelectedIndex};
@@ -0,0 +1 @@
1
+ import"../_virtual/_rolldown/runtime.js";import{refuseBaseModule as e}from"../refuse.js";function AdwComboRow(t){return e(`AdwComboRow`)}export{AdwComboRow};