@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
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
@@ -30,10 +44,8 @@ the same numbers.
30
44
 
31
45
  ## Install
32
46
 
33
- Not on npm yet: this is a new name, and the first publish plus its Trusted Publisher
34
- bootstrap is a maintainer action deliberately not attempted from CI or a feature branch
35
- ([the procedure](../../../docs/publishing.md)). Until then it is consumable from a
36
- workspace checkout.
47
+ Published since `0.44.0`, and on the release train from there
48
+ ([the first-publish procedure, for the next new name](../../../docs/publishing.md)).
37
49
 
38
50
  ```sh
39
51
  npm install @gjsify/adwaita-react-native
@@ -46,13 +58,82 @@ a GTK-only consumer does not need it installed.
46
58
 
47
59
  | widget | props | notes |
48
60
  |---|---|---|
61
+ | `AdwActionRow` | `title`, `subtitle`, `activatable` (false), `onActivated`, `children` | The fundamental boxed-list row. `children` are the SUFFIX |
62
+ | `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 |
63
+ | `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
64
  | `AdwBin` | `children` | One child, no layout of its own |
65
+ | `AdwButtonContent` | `iconName`, `label`, `useUnderline`, `canShrink` | Four derivations from the core, including the 6px gap that is `border-spacing` and not `GtkBox:spacing` |
66
+ | `AdwButtonRow` | `title`, `onActivated` | A row that behaves like a button — always activatable, and holds no children at all |
50
67
  | `AdwClamp` | `children`, `maximumSize` (600), `tighteningThreshold` (400) | Constrain a child's width and centre it, on libadwaita's easing curve |
68
+ | `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 |
69
+ | `AdwEntryRow` | `title`, `text`, `maxLength` (0), `editable` (true), `showApplyButton` (false), `onNotifyText`, `onApply`, `onEntryActivated` | The row IS the entry. `max-length` counts CHARACTERS |
70
+ | `AdwExpanderRow` | `title`, `subtitle`, `expanded` (false), `onNotifyExpanded`, `children` | `children` are the DISCLOSED rows. The header toggles, the disclosure does not |
71
+ | `AdwHeaderBar` | `start`, `titleWidget`, `title`, `subtitle`, `end` | The three slots as PROPS, in draw order. No window controls: a phone has none |
72
+ | `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 |
73
+ | `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 |
74
+ | `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 |
75
+ | `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 |
76
+ | `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 |
77
+ | `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 |
78
+ | `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 |
79
+ | `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 |
80
+ | `AdwSpinner` | `widthRequest`, `heightRequest` | The BOX and the RING are two numbers: an unbounded box around a ring capped at 64 |
81
+ | `AdwStatusPage` | `children`, `iconName`, `title`, `description` | A centred empty state. The icon draws on GTK only |
82
+ | `AdwSwitchRow` | `title`, `subtitle`, `active` (false), `onNotifyActive` | Controlled. The whole row toggles, not only the handle |
83
+ | `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 |
84
+ | `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 |
85
+ | `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 |
86
+ | `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` |
87
+ | `AdwWindowTitle` | `title`, `subtitle` | Two labels; an EMPTY one takes no space, a blank one does |
88
+ | `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
89
 
52
90
  Props are libadwaita's own names, camelCased — `maximumSize` is `AdwClamp:maximum-size`,
53
91
  not a React Native `maxWidth` — so the property you look up in libadwaita's documentation
54
92
  is the property you write. Defaults are libadwaita's.
55
93
 
94
+ A signal is named the way [`@gjsify/gtk-host`](../gtk-host)'s generated surface names it
95
+ (`onActivated` for `::activated`, `onNotifyActive` for `notify::active`), because the GTK
96
+ half hands the prop straight to the host and a second spelling here would be a translation
97
+ table nothing checks.
98
+
99
+ **A slot is a prop, never a `slot`-carrying child.** `AdwHeaderBar`'s three ends and
100
+ `AdwToolbarView`'s two bars are props because gtk-host routes a child by a `slot` prop on
101
+ the CHILD, and a prop of a React component is an arbitrary `ReactNode` with nothing to
102
+ write it on — `cloneElement` sets a prop on a COMPOSITE component, which forwards
103
+ nothing, so the slot would be silently dropped for exactly the children this package
104
+ ships. Each slot therefore gets one container widget on GTK, which is also what
105
+ libadwaita puts there itself.
106
+
107
+ **A property this package does not carry is ABSENT, never present and ignored** — the
108
+ omissions are listed under [Named divergences](#named-divergences). Two rules decide who
109
+ owns a value: `AdwSwitchRow:active` is strictly CONTROLLED (React Native's own contract for
110
+ `Switch`, and what a GTK consumer gets from the host's echo guard), while
111
+ `AdwEntryRow:text` and `AdwExpanderRow:expanded` are owned by the ROW — the prop seeds
112
+ them and overwrites them when it CHANGES, and a keystroke or a tap the consumer does not
113
+ echo back still stands. That is GObject's contract rather than React's, and both halves
114
+ follow it for the same mechanical reason: `@gjsify/gtk-host` patches a property only when
115
+ the prop changes, and `@gjsify/adwaita-core`'s state machines are the buffer on the other
116
+ side.
117
+
118
+ **Neither half styles text.** Bold-and-dim is `@gjsify/adwaita-web`'s stylesheet and
119
+ `@gjsify/adwaita-nativescript`'s theme CSS; this package has no theme layer to read
120
+ `@gjsify/adwaita-core`'s tokens through, so what the React Native half carries is layout
121
+ and visibility. Inventing a styling seam is a decision this slice does not make.
122
+
123
+ ### `AdwExpanderRow` needs a curated placement, and this package added it
124
+
125
+ `Adw.ExpanderRow` was in `@gjsify/gtk-host`'s GENERATED table, which knows the tag and no
126
+ placement rule, so every child of an `<adw-expander-row>` was an `uncurated-placement`
127
+ refusal. The policy is now curated in `gtk-host/src/descriptors/adw.ts` — `add_row` as the
128
+ default slot, `add_prefix`/`add_suffix` by name — and it needed one thing the `slotted`
129
+ policy did not have: `add_row` hands the child to an inner `Gtk.ListBox`, and
130
+ `gtk_list_box_remove` does NOT unwrap the implicit `GtkListBoxRow` that box makes for a
131
+ non-row child, so the child leaks on unmount behind one `Gtk-WARNING`. Measured on GTK
132
+ 4.22.4, and caught by the host's own "every slotted descriptor survives a round trip
133
+ through every slot" mechanism before this shipped. So `slotted` now takes the same
134
+ per-slot `wrapSlots` that `indexed` already declared for `GtkListBox`, and the host makes
135
+ the row itself. Any widget can go in a disclosure.
136
+
56
137
  ## How the two halves are selected
57
138
 
58
139
  Through the package's `exports` map and the `react-native` condition:
@@ -100,8 +181,24 @@ nothing:
100
181
  | the `.native` half type-checks against **real** React Native | the `react-native` package's own types, never a subset |
101
182
  | 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
183
  | React Native: which primitives, which props, which nesting | React's own reconciler over `react-test-renderer` |
184
+ | 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 |
185
+ | 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
186
  | 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
187
  | 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 |
188
+ | 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 |
189
+ | 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 |
190
+ | 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" |
191
+ | 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 |
192
+ | 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 |
193
+ | `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) |
194
+ | `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` |
195
+
196
+ **Not proven: the row THEME.** What the rows lay out is structure — `flexDirection: 'row'`
197
+ is what makes a row a row — and what they do not carry is padding, the type scale, the
198
+ dim-label colour and the row separator. `@gjsify/adwaita-core`'s `/tokens` subpath states
199
+ outright that projecting its CSS custom properties onto a React Native style scale is a
200
+ mapping decision of its own, and this slice does not make it. The rows are correct and
201
+ unstyled.
105
202
 
106
203
  **Not proven: Yoga, and the device.** A `width` in a style object is an instruction to a
107
204
  layout engine that no test here runs. The React Native half is type-checked and
@@ -113,6 +210,96 @@ and until then it is a gap, not a formality.
113
210
  These are places where the two halves cannot be made identical, written down rather
114
211
  than smoothed over.
115
212
 
213
+ - **`AdwPreferencesPage` is not a scroller on React Native.** `Adw.PreferencesPage` wraps
214
+ its groups in a `GtkScrolledWindow`; this half emits the column and a consumer wraps it.
215
+ Not a shortcut: `testing/react-native.ts` may only double a React Native component that
216
+ IS a host element with its props forwarded, and `ScrollView` is a COMPOSITE that renders
217
+ `RCTScrollView` around a second content `View` and moves `contentContainerStyle` onto it.
218
+ A double of it would be a nesting real React Native never emits, and every assertion
219
+ written against it would be about the double — the measured reason `spinner.native.tsx`
220
+ refuses `ActivityIndicator`. The same wrapper carries the page's CLAMP:
221
+ `adw-preferences-page.ui` puts an `AdwClamp` inside the scrolled window, so a wide window
222
+ centres the groups at the clamp width while this half stretches them. `AdwClamp` is in
223
+ this package, so a consumer that wants both wraps with both.
224
+ - **`AdwPreferencesGroup` has no `header-suffix` and no `separate-rows`.** The first is a
225
+ placement question, not a naming one: `header-suffix` holds a WIDGET, so a React surface
226
+ has to spell it as a slot, and the group's curated descriptor in `@gjsify/gtk-host` is
227
+ `ordered` — `add`/`remove`, `remove-all` to reorder, because `Adw.PreferencesGroup.insert`
228
+ does not exist on libadwaita 1.x — which has no slots at all. Adding one changes a
229
+ placement policy other conformance vectors already assert, with its own measurement. The
230
+ second is pure card styling, and this package's React Native half draws no theme.
231
+ - **`AdwPreferencesGroup`'s `single-line` header state is derived and not drawn.** It is a
232
+ stylesheet number — `min-height: 34px` against `margin-bottom: 6px` — and there is no
233
+ theme layer here to spend it in. It is computed because it comes out of the same core call
234
+ as the four states that ARE drawn.
235
+ - **A pure-markup group title is hidden on GTK and shown on React Native.**
236
+ `adw-preferences-group.ui` sets `use-markup` on both header labels, and libadwaita's
237
+ visibility test reads the DISPLAYED text — so `<b></b>` is an empty label there. This half
238
+ paints the string verbatim and passes `useMarkup: false`, which is the case
239
+ `derivePreferencesGroupHeader` documents that value for, and which both sibling renderers
240
+ pass as well.
241
+ - **`AdwComboRow` has no popover on React Native.** `Adw.ComboRow` opens a `GtkPopover` over
242
+ a `GtkListView`; a row with no overlay layer cannot. The press advances to the next option
243
+ and wraps, which still runs the real `ComboState.select` guard — bounds and
244
+ no-op-on-same — so the arithmetic underneath is the shipped one and only the gesture is
245
+ this half's own.
246
+ - **`AdwComboRow`'s `useSubtitle` publishes the value at once on React Native and on the
247
+ next selection change on GTK.** What both halves DO agree on is that the value is drawn in
248
+ one place: `adw-combo-row.ui` binds the inline value view's `visible` to `use-subtitle`
249
+ with `sync-create|invert-boolean`, and this half hides its trailing label the same way.
250
+ What they cannot agree on is WHEN the subtitle picks the value up.
251
+ `adw_combo_row_set_use_subtitle` calls `selection_changed`, while the subtitle is written
252
+ by `selection_item_changed` — a different function, reached only from
253
+ `notify::selected-item` and `set_model` — so an authored subtitle survives switching
254
+ `use-subtitle` on and is replaced by the next selection change. Measured on libadwaita
255
+ 1.9.3 and asserted on both halves. Reproducing the lag here would mean carrying a
256
+ libadwaita ordering artefact into a renderer that has no reason for it.
257
+ - **`AdwSpinRow`'s range is spelled `lower`/`upper`/`stepIncrement`, where the two sibling
258
+ Adwaita renderers spell it `min`/`max`/`step`.** Those are
259
+ `adw_spin_row_new_with_range`'s PARAMETER names; these are `Gtk.Adjustment`'s own GObject
260
+ property names for the same three values, and this package's rule is that a caller writes
261
+ the property they would look up in libadwaita's documentation. The arithmetic is still
262
+ shared — both halves map onto `@gjsify/adwaita-core`'s `SpinState`, which uses the short
263
+ names internally.
264
+ - **`AdwSpinRow`'s decimal separator is the process locale's on GTK and always `.` on React
265
+ Native.** `gtk_spin_button_update` formats the displayed value through the C library's
266
+ locale — measured on gjs 1.88.1 under a de_DE locale, a `digits={2}` row of 3.14159 reads
267
+ `3,14` — while `Number.prototype.toFixed` is specified never to localise and gives `3.14`
268
+ on every machine there is. The two halves therefore agree on the DIGIT COUNT and differ by
269
+ one character. Both suites assert the digits; neither builds its expectation from the
270
+ locale, because a test that did would be measuring the machine it runs on.
271
+ - **A range that moves past itself notifies twice more on React Native than on GTK.** The
272
+ GTK half builds one new `Gtk.Adjustment` from `lower`, `upper` and `stepIncrement`
273
+ together, so moving 0…100/50 to 200…300/250 is a single step. The React Native half
274
+ applies each property in its own effect — one per setter, because each has its own guard
275
+ in the C — so it passes through an inverted range: `setMin(200)` runs while the maximum is
276
+ still 100, and `SpinState`'s clamp answers the maximum. `onNotifyValue` therefore reports
277
+ `100, 200, 250` where GTK reports the end state. The settled value is the same on both,
278
+ React batches the renders, and the stream is asserted so that changing it is a decision.
279
+ - **`AdwSpinRow` carries no `climb-rate`, `snap-to-ticks`, `numeric`, `update-policy` or
280
+ `wrap`.** Each needs an editable text entry or a key-repeat timer the React Native half
281
+ does not have, so carrying them would mean a property GTK honours and the phone ignores.
282
+ Neither sibling renderer has them either.
283
+ - **`AdwPasswordEntryRow`'s caps-lock indicator is present and can never show.**
284
+ `indicatorVisible` is `editing && show_indicator`, and `show_indicator` is pushed from
285
+ `!revealed && capsLockOn` — but React Native exposes no keyboard modifier state, and this
286
+ surface carries no prop libadwaita does not have, so nothing can set it. The node stays in
287
+ the tree, hidden, and a test asserts that: "no caps-lock warning" and "no caps-lock
288
+ support" must not be the same picture. `@gjsify/adwaita-nativescript` hit the same wall
289
+ and answered it with a host seam, which is a surface this package does not have.
290
+ - **`AdwPasswordEntryRow` publishes no `revealed`, where both sibling renderers do.**
291
+ `Adw.PasswordEntryRow` declares no property of its own — its generated prop interface is
292
+ empty over `AdwEntryRowProps` — and the peek state is private to the widget. A `revealed`
293
+ prop would be the one place this surface invents a name; the button owns it on both halves.
294
+ - **The glyphs on the three rows are this half's own.** The chevron, the two steppers, the
295
+ apply check, the caps-lock arrow and the peek pair all stand in for icon-theme names the
296
+ core carries as data (`pan-down-symbolic`, `value-increase-symbolic`,
297
+ `adw-entry-apply-symbolic`, `caps-lock-symbolic`, `view-reveal-symbolic`). They are NOT
298
+ what `@gjsify/adwaita-web` draws — that renderer masks a generated CSS class from the same
299
+ names and draws no text at all — so they are named here as a divergence rather than as a
300
+ shared fallback. The accessible NAMES beside them do come from the core, so
301
+ "Show Password"/"Hide Password"/"Apply"/"Caps Lock is on" are one string in one place
302
+ across three renderers.
116
303
  - **`AdwClamp` ignores the child's intrinsic minimum on React Native.** libadwaita's
117
304
  clamp is a two-pass measure-then-allocate, and a child minimum wider than the clamp
118
305
  RAISES all three thresholds — which is how such a child still gets its minimum
@@ -124,13 +311,229 @@ than smoothed over.
124
311
  and inventing a styling seam is a decision this slice does not make.
125
312
  - **One unclamped frame.** Before the first `onLayout` there is no available width, so
126
313
  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.
314
+ - **A second child is kept on React Native and dropped on GTK, silently.** `Adw.Bin`,
315
+ `Adw.Clamp`, `Adw.StatusPage:child` and `Adw.ToolbarView:content` are one-child slots,
316
+ and gtk-host's `single` child policy fills them with `set_child`, so a second child
317
+ EVICTS the first — with no throw, no host error and no GLib message. A `View` has no
318
+ such limit and renders both. Both behaviours are pinned by a test on each side, so
319
+ neither can move alone. Refusing more than one child on both halves would close it and
320
+ is a surface decision this slice does not make.
321
+ - **`AdwHeaderBar` resolves an unauthored title on GTK and leaves it blank on a phone.**
322
+ Authoring neither `title` nor `subtitle` installs no title widget at all, so
323
+ libadwaita's `update_title` (adw-header-bar.c:475) walks navigation page → dialog →
324
+ window → application name and puts what it finds in the centre; a phone has none of
325
+ those to walk. Both sides are asserted — the GTK suite reads the window's own title
326
+ back out of the bar, the React Native suite reads two collapsed labels.
327
+ - **`AdwHeaderBar` has a `title`/`subtitle` that `Adw.HeaderBar` does not.** The real
328
+ widget has no `title` property; its derived centre is a plain `gtk_label_new (NULL)`
329
+ with no subtitle at all, and an app that wants one sets an `AdwWindowTitle` as its
330
+ title widget. A declarative surface wants the attribute, so authoring either installs
331
+ an `AdwWindowTitle` centre. This is the same divergence `@gjsify/adwaita-web` and
332
+ `@gjsify/adwaita-nativescript` carry, recorded as `HeaderBarRenderState.derivedSubtitle`
333
+ in `@gjsify/adwaita-core`.
334
+ - **Neither renderer here resolves an icon theme, so `iconName` is accepted and not
335
+ drawn.** `icon-name` names an entry in an ICON THEME and React Native has none — no
336
+ `Image` source a GNOME symbolic name resolves to, and no renderer for the SVG
337
+ `@gjsify/adwaita-nativescript` substituted instead. Drawing the name as text would put
338
+ the literal `folder-symbolic` on screen. So `AdwStatusPage` shows no icon, `AdwAvatar`'s
339
+ icon mode is a coloured circle with the initials hidden where GTK draws
340
+ `adw-avatar-default-symbolic`, and `AdwButtonContent`'s icon slot sits in the row with
341
+ libadwaita's own `hexpand` and holds no glyph. The props are carried so a GTK consumer's
342
+ props stay portable, and the ABSENCE of an icon node is asserted in each case, so the
343
+ day one appears it is a decision and not a drift.
344
+ - **`AdwToolbarView` does not run libadwaita's allocation on React Native, and cannot.**
345
+ `adw_toolbar_view_size_allocate` is two chained CLAMPs over the bars' MINIMUM and
346
+ NATURAL heights — ported as `toolbarViewAllocate` and held to vectors — and React
347
+ Native hands a component an already-laid-out size and never a child's intrinsic
348
+ minimum. Feeding the measurement in as both `min` and `nat` would turn each CLAMP into
349
+ the identity and dress a pass-through up as libadwaita's arithmetic. The consequence is
350
+ one-directional: a STRETCHY bar keeps its natural height where libadwaita would shrink
351
+ it toward its minimum to protect the content.
352
+ - **`AdwToolbarView`'s four style classes have nowhere to land on a phone.** `raised`,
353
+ `border`, `undershoot-top` and `undershoot-bottom` are what `topBarStyle` and
354
+ `bottomBarStyle` derive; React Native has no class system to stamp them into. Both
355
+ props are carried and reach no style, which is asserted on the React Native side and
356
+ measured against libadwaita's own `update_undershoots` on the GTK side.
357
+ - **`AdwWrapBox`'s `naturalLineLength` is a MAX SIZE on React Native.** libadwaita caps
358
+ the box's NATURAL size REQUEST and leaves a larger allocation free to happen; neither
359
+ CSS nor Yoga has a property that caps only the intrinsic contribution, so this half
360
+ writes `maxWidth`/`maxHeight`. `@gjsify/adwaita-web` records the same deliberate
361
+ deviation. Limiting line length inside a popover — the intended use — behaves the same
362
+ either way.
363
+ - **`AdwWrapBox` wraps every child in a `View` of its own.** `flex-grow` and `flex-shrink`
364
+ belong to the CHILD, and this component does not own its children's styles:
365
+ NativeScript sets them as attached properties and the browser publishes a custom
366
+ property its stylesheet reads, and neither seam exists here. The wrapper is therefore
367
+ visible in the tree and is asserted rather than left as an implementation detail.
368
+ - **`AdwWrapBox`'s `align` is snapped to three positions on both non-GTK renderers.** C
369
+ offsets the whole line block by `roundf (length_delta * align)` — a continuum — and
370
+ flexbox has `flex-start`, `center` and `flex-end`. The snap is the renderers'
371
+ approximation and not libadwaita's rule, which is why it lives in
372
+ `@gjsify/adwaita-core`'s `wrapBoxFlexStyle` rather than in a conformance vector. The
373
+ GTK half runs none of it: `Adw.WrapBox` is `adw-wrap-layout.c` itself, and the suite
374
+ reads the continuum back off the live tree.
375
+ - **`AdwAvatar`'s font size is the CAP, not a measurement.** `update_font_size` scales
376
+ the label's measured aspect ratio against `avatarMaxFontSize(size)`; React Native
377
+ reports a text box only through `onLayout`, i.e. after layout — the same missing
378
+ measure pass that makes `AdwClamp` pass `childMin: 0`. Using the cap alone stays inside
379
+ libadwaita's bound. The NativeScript port's `size * 0.4` heuristic is deliberately not
380
+ copied: it is not monotonic in `size` and exceeds the cap above ~54 points.
381
+ - **`AdwButtonContent` cannot stamp `image-text-button`.** `adw_button_content_root` puts
382
+ the class on the nearest `GtkButton` ancestor, and this package ships no button for it
383
+ to find. `buttonContentStyleTargetIndex` holds the retarget rule for a renderer that has
384
+ a tree to walk; when a button lands here, that is the call to make.
385
+ - **`AdwSpinner` draws the track and not the arc.** `AdwSpinnerPaintable`'s segment
386
+ extends, overlaps, contracts and idles on an ease-in-out-sine while the whole figure
387
+ turns, and drawing it needs a path renderer that is not a dependency of this package.
388
+ What is drawn is the circle underneath — `ADW_SPINNER_TRACK_OPACITY` of the current
389
+ colour, exactly what the browser renderer paints under its arc. The `_spinner.scss`
390
+ substitute (a fixed 90-degree `border-top-color` chase at 0.8s) is a different animation
391
+ with a different period, so copying it would put a wrong number where there is an absent
392
+ one. **The suite asserts the track's opacity and nothing about motion** — there is no
393
+ animation assertion here, because there is no animation to assert.
394
+ - **`Adw.Toast:timeout` is lossy in the other direction.** GObject stores whole seconds,
395
+ so 1500 ms is 2 s on GTK and stays 1500 ms on React Native.
396
+ - **A toast's action button has no callback.** `Adw.Toast` expresses its action as
397
+ `action-name`, a `GAction` this package has no surface for, so pressing the button does
398
+ what both other renderers do: dismiss the current toast, which advances the queue.
399
+ - **`dismissAll`'s REMOVAL is asserted only on React Native.**
400
+ `adw_toast_overlay_dismiss_all` animates the strip out over real time, and pumping the
401
+ main context for ~1.6s leaves the `AdwToastWidget` in place — measured. GTK asserts that
402
+ the call lands and costs no diagnostic; the removal is asserted where the queue is ours.
403
+ - **`AdwBanner` reduces markup to its plain text.** React Native has no inline-markup
404
+ layer, and painting `<b>Metered</b>` literally is further from what GTK draws than
405
+ painting `Metered` is. Unparseable markup keeps the raw string, which is Pango's own
406
+ fallback.
407
+ - **A press assertion proves the widget ASKS for the press, never that a tap arrives.**
408
+ The `react-native` double forwards `onPress` verbatim; the real runtime wires it through
409
+ the press responder. Same class of gap as Yoga, one layer up.
133
410
  - **`Adw.ClampScrollable` has no counterpart and will not get one.** It binds its four
134
411
  scroll properties onto its child, which is a GTK adoption concern; on React Native
135
412
  scrolling belongs to the `ScrollView`, not to the clamp. This is an asymmetry, not a
136
413
  missing widget.
414
+ - **No icons anywhere on the React Native half.** `AdwActionRow:icon-name`,
415
+ `AdwButtonRow:start-icon-name`/`:end-icon-name` and `Adw.EntryRow`'s edit and indicator
416
+ icons all name an entry in a GTK ICON THEME, and this package ships no icon renderer for
417
+ React Native. The PROPS are therefore absent from the surface rather than accepted on one
418
+ half and dropped on the other. Two affordances that are the widget's own rather than a
419
+ caller's prop do get a stand-in CHARACTER — the entry row's apply button (`✓`) and the
420
+ expander's chevron (`▾`/`▴`) — because without them those two widgets give a user no
421
+ signal that they do anything. Neither is what `@gjsify/adwaita-web` draws: that renderer
422
+ masks a generated `.adw-icon--<name>` CSS class and shows no text at all.
423
+ - **`add_prefix` has no counterpart.** `Adw.ActionRow` and `Adw.ExpanderRow` both have a
424
+ prefix slot, reachable on the GTK half by writing `slot="prefix"` on a child. React
425
+ Native has no slot mechanism, and giving the surface a `prefix` PROP taking a node would
426
+ be a second child channel that only one half implements, so the surface offers `children`
427
+ only — the suffix on the action row, the disclosure on the expander.
428
+ - **`AdwExpanderRow` carries no `enable-expansion` and no `show-enable-switch`.** The
429
+ enable switch is a SECOND control inside the row with its own veto over the disclosure,
430
+ and the rule tying the two flags together lives in no shared place:
431
+ `@gjsify/adwaita-core`'s `ExpanderState` — what all three renderers compose — models the
432
+ disclosure alone. Adding it here would create a fourth private copy of a rule three
433
+ renderers need; lifting it into the core first is what would close this, and this slice
434
+ does not do it.
435
+ - **A disclosed child must be a real row on GTK, and can be anything on React Native.**
436
+ `adw_expander_row_add_row` hands the widget to an inner `Gtk.ListBox`, which wraps a
437
+ non-row child in an implicit `GtkListBoxRow` that `remove` then cannot find — measured on
438
+ libadwaita 1.9.3, a `Gtk.Label` disclosed child leaks on unmount behind a single
439
+ `Gtk-WARNING`, an `Adw.ActionRow` round-trips cleanly. The curated descriptor carries the
440
+ measurement. A React Native `View` has no such rule.
441
+ - **`AdwEntryRow`'s empty↔filled cross-fade is a hard swap.** libadwaita animates between
442
+ the placeholder and the floating title over its own duration; the React Native half
443
+ switches at the two endpoints, the same compromise `@gjsify/adwaita-nativescript` makes,
444
+ because a cross-fade needs an animation seam this slice does not add.
445
+ - **`AdwSwitchRow` is strictly controlled and `Adw.SwitchRow` is not.** React Native's own
446
+ contract for `Switch` is that the component renders the `value` prop whatever the user
447
+ does, so a toggle the consumer declines to echo back is not kept here — where GTK keeps
448
+ it. The other two stateful rows go the GTK way (see [Widgets](#widgets)); this one goes
449
+ React Native's, because a `Switch` that disagrees with its `value` prop is a bug on that
450
+ platform.
451
+ - **The navigation view animates on GTK and swaps instantly on React Native, and there
452
+ is no automatic back button.** `animateTransitions` reaches the real
453
+ `Adw.NavigationView` and reaches `NavigationViewState` on the other half, where nothing
454
+ spends it — this package has no animation layer, which is the same position
455
+ `@gjsify/adwaita-nativescript` records ("kept for API parity"). `popOnEscape` is inert
456
+ for the plainer reason that a phone has no Escape key. And where the browser renderer
457
+ finds an `<adw-header-bar>` inside the visible page and injects a back button into it,
458
+ neither NativeScript nor this package can identify a header bar inside an opaque child:
459
+ `canGoBack()` and `backButtonTooltip()` on the handle are libadwaita's own two
460
+ derivations, and the caller wires its own button to them.
461
+ - **An untitled `Adw.NavigationPage` is a GTK warning and nothing at all on React
462
+ Native.** Measured on libadwaita 1.9.3: a page with no title prints `AdwNavigationPage
463
+ 0x… is missing a title. To hide a header bar title, consider using
464
+ AdwHeaderBar:show-title instead.` The React Native half has no counterpart, so the
465
+ `'Back'` tooltip fallback — which needs an empty title — is asserted on that half only,
466
+ against the constant both halves import from `@gjsify/adwaita-core`.
467
+ - **Neither split view has a content minimum to protect on React Native.** libadwaita
468
+ caps the sidebar with the content pane's own minimum width and reports
469
+ `sidebar_min + content_min` as the view's own minimum; React Native hands a component an
470
+ already-laid-out size and never a child's intrinsic minimum, so `contentMin` and
471
+ `sidebarChildMin` go in as 0. The consequences are one-directional and both measured:
472
+ the sidebar can take its full share of a view too narrow for both panes, and the view
473
+ cannot refuse to be narrower than its contents the way GTK does (the GTK suite asserts
474
+ that refusal at 380 against `measureSplitViewHorizontal`; the React Native suite cannot
475
+ ask). Same class as `AdwClamp`'s `childMin`.
476
+ - **The two sidebar-width rules can only be told apart one at a time on GTK.**
477
+ `resolveNavigationSidebarWidth` caps the sidebar's MAX BOUND by `width - content_min`
478
+ and `resolveOverlaySidebarWidth` caps the RESULT, which the core's own vectors separate
479
+ at 300 points (180 versus 100). The NAVIGATION half of that pair is unreachable through
480
+ a window: `measure_uncollapsed` makes `sidebar_min + content_min` its minimum, GTK never
481
+ allocates below a minimum, and from there upwards `width - content_min` never falls under
482
+ `sidebar_min`, so the bound cap never inverts. The OVERLAY half is reachable, because its
483
+ minimum is `(int) (sidebar_min * show_progress) + content_min` — a hidden sidebar takes
484
+ that term out — and the GTK suite reads its 100 off the live tree. So the two answers are
485
+ never asserted side by side here; the disagreement itself is held by
486
+ `@gjsify/adwaita-core`'s vectors, and this package asserts the navigation minimum and the
487
+ overlay cap separately.
488
+ - **The overlay's reveal is instant on React Native.** libadwaita animates with a spring
489
+ `(1, 0.5, 500)`; `@gjsify/adwaita-web` approximates it from `requestAnimationFrame` and
490
+ `@gjsify/adwaita-nativescript` from `View.animate()`. React Native's own answer is
491
+ `Animated`, a COMPOSITE surface the test double may not stand in for, so the core's
492
+ `INSTANT_SPLIT_VIEW_ANIMATOR` default stands and `enableShowGesture` /
493
+ `enableHideGesture` are carried and inert. `show-progress` still runs through the core,
494
+ so the continuum is expressible the day an animator is plugged in.
495
+ - **The React Native split views resolve `start`/`end` against `ltr` only.**
496
+ `isSidebarAtVisualStart` takes a reading direction, GTK resolves it from the widget, and
497
+ React Native's lives on `I18nManager` — not a host component, so not something
498
+ `testing/react-native.ts` may double. The core call still takes the parameter; closing
499
+ this is one argument.
500
+ - **`sidebar-position: end` is invisible on a COLLAPSED React Native split view.**
501
+ `resolveNavigationStack` builds the stack the other way round for `end` — the content is
502
+ the root page and the sidebar is pushed on top of it — but the LAST entry, which is the
503
+ pane on screen, is the same for both positions at every value of `show-content`. What
504
+ differs is the push/pop DIRECTION, which a renderer spends on a slide and this one has
505
+ none of. The position IS asserted where it is observable: the docked draw order.
506
+ - **`sidebarTitle` and `contentTitle` reach a real page on GTK and nothing on a phone.**
507
+ They are `Adw.NavigationPage:title` of the wrap `AdwNavigationSplitView` puts around each
508
+ pane, which libadwaita uses for the header of a collapsed view. The React Native half has
509
+ no header bar to put a title in, so it carries them and draws neither — the same shape as
510
+ `iconName`.
511
+ - **`onNotifySelected` and `onNotifyValue` do not carry a PROGRAMMATIC change on GTK.** A
512
+ user pick reaches both halves. A change the caller made through `selected` / `value`
513
+ reaches the React Native half only: gtk-host suppresses a `notify::` raised inside its own
514
+ property write, and writing the prop IS that write — for the spin row through the
515
+ `adjustment` object it re-sets rather than through a `value` property. Measured on
516
+ libadwaita 1.9.3: a re-render from `selected={0}` to `selected={2}` moves the widget and
517
+ calls nothing, while `row.selected = 1` from outside React calls it. Same rule as
518
+ `onNotifyVisibleChild` below, and benign for the ordinary controlled pattern — the
519
+ consumer made the change and already knows — but it is not "every change".
520
+ - **`onNotifyVisibleChild` does not carry the same set of changes on both halves.** A
521
+ press on the switcher reaches both. A change the CALLER made through
522
+ `visibleChildName` reaches the React Native half only — it re-applies the prop through
523
+ `selectName` and reports what the stack settled on, while gtk-host drops the notify
524
+ raised inside its own property write, which is the same rule `onNotifyExpanded` already
525
+ records. The mount AUTO-PICK reaches neither: libadwaita notifies it from inside
526
+ `adw_view_stack_add_titled`, before React has committed the `ref` the settled name
527
+ would be read off (measured — the GTK half used to report `''` there, a name no page
528
+ carries), and on the other half the core's auto-pick lands before the subscription
529
+ exists. Both halves are asserted at the two ends of that.
530
+ - **`AdwViewSwitcher` bundles the stack libadwaita keeps separate.** `Adw.ViewSwitcher:stack`
531
+ points at an `Adw.ViewStack` elsewhere in the tree, and a React prop cannot hold a widget
532
+ that does not exist yet on the half where widgets exist at all. Both other renderers made
533
+ the same call. On GTK nothing is simulated: the component builds a real `Adw.ViewStack`
534
+ and writes it into that property, which the GTK suite asserts by identity.
535
+ - **The switcher's buttons carry no icon.** Same icon-theme rule as above, with one extra
536
+ consequence worth naming: a page with an icon and NO title still gets a button, because
537
+ `isViewSwitcherButtonVisible` tests both — and on React Native that button's label is
538
+ empty. The button's ORIENTATION is still applied, since it is what arranges the label
539
+ 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};