react-native-gtkx 0.2.0-alpha.1 → 0.2.0-alpha.2

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 (144) hide show
  1. package/README.md +11 -2
  2. package/dist/adw/widgets.generated.d.ts +4 -4
  3. package/dist/adw/widgets.generated.js +51 -51
  4. package/dist/adw/widgets.generated.js.map +1 -1
  5. package/dist/animated/create-animated.d.ts +2 -0
  6. package/dist/animated/create-animated.js +2 -0
  7. package/dist/animated/create-animated.js.map +1 -1
  8. package/dist/animated/index.d.ts +2 -0
  9. package/dist/animated/index.js +1 -0
  10. package/dist/animated/index.js.map +1 -1
  11. package/dist/animated/value-xy.d.ts +41 -0
  12. package/dist/animated/value-xy.js +90 -0
  13. package/dist/animated/value-xy.js.map +1 -0
  14. package/dist/animated/value.d.ts +9 -0
  15. package/dist/animated/value.js +30 -2
  16. package/dist/animated/value.js.map +1 -1
  17. package/dist/common/icon.d.ts +23 -0
  18. package/dist/common/icon.js +14 -0
  19. package/dist/common/icon.js.map +1 -0
  20. package/dist/common/index.d.ts +2 -0
  21. package/dist/common/index.js +2 -0
  22. package/dist/common/index.js.map +1 -1
  23. package/dist/common/list.d.ts +82 -0
  24. package/dist/common/list.js +166 -0
  25. package/dist/common/list.js.map +1 -0
  26. package/dist/common/widget.d.ts +1 -22
  27. package/dist/common/widget.js +75 -8
  28. package/dist/common/widget.js.map +1 -1
  29. package/dist/components/animated.d.ts +4 -2
  30. package/dist/components/animated.js +3 -1
  31. package/dist/components/animated.js.map +1 -1
  32. package/dist/components/app-registry.d.ts +26 -0
  33. package/dist/components/app-registry.js.map +1 -1
  34. package/dist/components/host-node.d.ts +7 -0
  35. package/dist/components/host-node.js +26 -1
  36. package/dist/components/host-node.js.map +1 -1
  37. package/dist/components/index.d.ts +6 -2
  38. package/dist/components/index.js +2 -1
  39. package/dist/components/index.js.map +1 -1
  40. package/dist/components/measure.d.ts +13 -0
  41. package/dist/components/measure.js +51 -0
  42. package/dist/components/measure.js.map +1 -0
  43. package/dist/components/modal.d.ts +1 -1
  44. package/dist/components/press-event.d.ts +28 -0
  45. package/dist/components/press-event.js +46 -0
  46. package/dist/components/press-event.js.map +1 -0
  47. package/dist/components/pressable.d.ts +2 -6
  48. package/dist/components/pressable.js +14 -8
  49. package/dist/components/pressable.js.map +1 -1
  50. package/dist/components/scroll-view.d.ts +4 -0
  51. package/dist/components/scroll-view.js +8 -2
  52. package/dist/components/scroll-view.js.map +1 -1
  53. package/dist/components/text-input.js +1 -1
  54. package/dist/components/text-input.js.map +1 -1
  55. package/dist/components/text.js +25 -1
  56. package/dist/components/text.js.map +1 -1
  57. package/dist/components/use-layout-child.js +17 -14
  58. package/dist/components/use-layout-child.js.map +1 -1
  59. package/dist/components/view.d.ts +9 -4
  60. package/dist/components/view.js +8 -2
  61. package/dist/components/view.js.map +1 -1
  62. package/dist/contracts.d.ts +19 -3
  63. package/dist/contracts.js.map +1 -1
  64. package/dist/gtk/index.d.ts +2 -1
  65. package/dist/gtk/index.js +8 -1
  66. package/dist/gtk/index.js.map +1 -1
  67. package/dist/gtk/widgets.generated.d.ts +14 -14
  68. package/dist/gtk/widgets.generated.js +101 -102
  69. package/dist/gtk/widgets.generated.js.map +1 -1
  70. package/dist/gtk/window-actions.d.ts +77 -0
  71. package/dist/gtk/window-actions.js +193 -0
  72. package/dist/gtk/window-actions.js.map +1 -0
  73. package/dist/gtkx/bridge/geometry.d.ts +15 -0
  74. package/dist/gtkx/bridge/geometry.js +38 -0
  75. package/dist/gtkx/bridge/geometry.js.map +1 -0
  76. package/dist/gtkx/bridge/index.d.ts +2 -0
  77. package/dist/gtkx/bridge/index.js +7 -2
  78. package/dist/gtkx/bridge/index.js.map +1 -1
  79. package/dist/gtkx/bridge/slot-portal.d.ts +12 -0
  80. package/dist/gtkx/bridge/slot-portal.js +17 -0
  81. package/dist/gtkx/bridge/slot-portal.js.map +1 -0
  82. package/dist/gtkx/bridge/svg-node.js +10 -54
  83. package/dist/gtkx/bridge/svg-node.js.map +1 -1
  84. package/dist/gtkx/bridge/use-signal.js +2 -2
  85. package/dist/gtkx/bridge/use-signal.js.map +1 -1
  86. package/dist/index.d.ts +2 -2
  87. package/dist/index.js +1 -1
  88. package/dist/index.js.map +1 -1
  89. package/dist/mcp/data/generated.d.ts +99 -77
  90. package/dist/mcp/data/generated.js +107 -76
  91. package/dist/mcp/data/generated.js.map +1 -1
  92. package/dist/mcp/server.js +1 -1
  93. package/dist/mcp/server.js.map +1 -1
  94. package/dist/navigation/sidebar.d.ts +31 -1
  95. package/dist/navigation/sidebar.js +12 -2
  96. package/dist/navigation/sidebar.js.map +1 -1
  97. package/dist/responder/system.d.ts +27 -0
  98. package/dist/responder/system.js +184 -0
  99. package/dist/responder/system.js.map +1 -0
  100. package/dist/responder/touch-history.d.ts +10 -0
  101. package/dist/responder/touch-history.js +78 -0
  102. package/dist/responder/touch-history.js.map +1 -0
  103. package/dist/responder/types.d.ts +63 -0
  104. package/dist/responder/types.js +29 -0
  105. package/dist/responder/types.js.map +1 -0
  106. package/dist/responder/use-responder.d.ts +12 -0
  107. package/dist/responder/use-responder.js +98 -0
  108. package/dist/responder/use-responder.js.map +1 -0
  109. package/dist/runner/host-dev.js +3 -1
  110. package/dist/runner/host-dev.js.map +1 -1
  111. package/dist/runner/host.js +5 -1
  112. package/dist/runner/host.js.map +1 -1
  113. package/dist/runner/index.js +1 -1
  114. package/dist/runner/index.js.map +1 -1
  115. package/dist/sea/gtkx-config-module.js +1 -1
  116. package/dist/sea/gtkx-config-module.js.map +1 -1
  117. package/dist/style/box-shadow.d.ts +7 -0
  118. package/dist/style/box-shadow.js +197 -0
  119. package/dist/style/box-shadow.js.map +1 -0
  120. package/dist/style/index.d.ts +2 -0
  121. package/dist/style/index.js +2 -0
  122. package/dist/style/index.js.map +1 -1
  123. package/dist/style/split-style.d.ts +5 -2
  124. package/dist/style/split-style.js +31 -3
  125. package/dist/style/split-style.js.map +1 -1
  126. package/dist/style/text-decoration.d.ts +15 -0
  127. package/dist/style/text-decoration.js +26 -0
  128. package/dist/style/text-decoration.js.map +1 -0
  129. package/dist/style/visual-css.js +37 -1
  130. package/dist/style/visual-css.js.map +1 -1
  131. package/dist/svg/gradient-geometry.js +2 -5
  132. package/dist/svg/gradient-geometry.js.map +1 -1
  133. package/dist/testing/index.js.map +1 -1
  134. package/dist/vendor/react-native/pan-responder.d.ts +102 -0
  135. package/dist/vendor/react-native/pan-responder.js +196 -0
  136. package/dist/vendor/react-native/pan-responder.js.map +1 -0
  137. package/dist/vendor/react-native/touch-history-math.d.ts +18 -0
  138. package/dist/vendor/react-native/touch-history-math.js +102 -0
  139. package/dist/vendor/react-native/touch-history-math.js.map +1 -0
  140. package/dist/vite/index.js +1 -1
  141. package/dist/vite/index.js.map +1 -1
  142. package/dist/vitest/index.d.ts +1 -1
  143. package/dist/vitest/index.js.map +1 -1
  144. package/package.json +9 -9
@@ -1 +1 @@
1
- {"version":3,"file":"generated.js","sourceRoot":"","sources":["../../../src/mcp/data/generated.ts"],"names":[],"mappings":"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","sourcesContent":["// GENERATED FILE — do not edit by hand.\n// Produced by scripts/generate-mcp-data.mjs from docs/api.md,\n// docs/platform-layer.md, docs/gtkx-rc2-notes.md, docs/getting-started.md,\n// docs/research/navigation-extensibility.md and\n// scripts/widget-surface/classification.json.\n//\n// Regenerate after touching any of those:\n// node scripts/generate-mcp-data.mjs\n// Check without writing (used in verification):\n// node scripts/generate-mcp-data.mjs --check\n\nexport type PortableRecord = {\n readonly name: string\n readonly subpath: \"react-native\"\n readonly gtkImplementation?: string\n readonly supported: string\n readonly differences: string\n}\n\nexport type CommonRecord = {\n readonly name: string\n readonly subpath: \"react-native-gtkx/common\"\n readonly summary: string\n}\n\nexport type WidgetRecord = {\n readonly name: string\n readonly subpath: \"react-native-gtkx/gtk\" | \"react-native-gtkx/adw\"\n readonly wrapped: boolean\n readonly reason?: string\n}\n\nexport type DocChunk = {\n readonly doc: string\n readonly heading: string\n readonly text: string\n}\n\nexport const PORTABLE_COMPONENTS = [\n {\n name: \"View\",\n subpath: \"react-native\",\n gtkImplementation: \"GtkBox (RnGtkxViewBox)\",\n supported:\n \"`style`, `onLayout`, `testID`, children, `pointerEvents` (auto/none/box-none/box-only — mapped onto GTK picking: can-target + a contains() vfunc override; also honored from `style.pointerEvents`, the prop wins)\",\n differences:\n \"nesting another pointerEvents inside a box-only view is not supported\",\n },\n {\n name: \"Text\",\n subpath: \"react-native\",\n gtkImplementation: \"GtkLabel (Pango)\",\n supported:\n \"wrap, `numberOfLines` (ellipsize END), `textAlign`, font styles, `onLayout`, `testID`\",\n differences:\n \"nested `Text` elements are concatenated without per-span styles; text is always ellipsizable (shrinkable in narrow windows)\",\n },\n {\n name: \"Image\",\n subpath: \"react-native\",\n gtkImplementation: \"GtkPicture\",\n supported:\n '`source={{uri}}`/string — local paths, file:// and **http(s)** (Node fetch → disk cache keyed by URL, in-flight de-duplication), `resizeMode` cover/contain/stretch/center, `onLoad`/`onError`; **`.svg` files load like any other image** — `Gdk.Texture.newFromFilename` rasterizes them via librsvg, no extra code needed (for building vector graphics from state instead of a file, see the \"Svg\" section below — a separate import, not part of this table)',\n differences:\n \"no synchronous size from remote images (style sets the size, as in RN); cache is not size-limited yet\",\n },\n {\n name: \"TextInput\",\n subpath: \"react-native\",\n gtkImplementation: \"GtkEntry / GtkTextView\",\n supported:\n \"controlled/uncontrolled (`value`/`defaultValue`), `onChangeText`, `onSubmitEditing`, `onFocus`/`onBlur`, `placeholder` (own dim overlay in multiline — GtkTextView has none), `secureTextEntry`, `editable`, `keyboardType`, `multiline`, `clearButtonMode` (GtkEntry's built-in clear icon; RN ships this on iOS only) (real GtkTextView: word wrap, internal scroll, Enter inserts a newline and never fires onSubmitEditing — RN semantics)\",\n differences: \"multiline needs a height in the style (as RN recommends)\",\n },\n {\n name: \"Pressable\",\n subpath: \"react-native\",\n gtkImplementation: \"GtkFixed + GestureClick/Motion\",\n supported:\n \"`onPress(In/Out)`, `onLongPress` (`delayLongPress`), `onHoverIn/Out`, `disabled`, function-form `style`/`children` receiving `{pressed, hovered}`\",\n differences: \"—\",\n },\n {\n name: \"TouchableOpacity\",\n subpath: \"react-native\",\n gtkImplementation: \"on top of Pressable\",\n supported: \"`activeOpacity`\",\n differences: \"—\",\n },\n {\n name: \"ScrollView\",\n subpath: \"react-native\",\n gtkImplementation: \"GtkScrolledWindow\",\n supported:\n \"vertical/`horizontal`, `contentContainerStyle`, `onScroll`, `onContentSizeChange`, `stickyHeaderIndices` (RN model: the REAL child is translated and painted on top — no duplicate), ref: `scrollTo`/`scrollToEnd` (`ScrollViewHandle`)\",\n differences: \"`animated` in scrollTo is ignored\",\n },\n {\n name: \"FlatList\",\n subpath: \"react-native\",\n gtkImplementation: \"windowed core on ScrollView\",\n supported:\n \"virtualization (`estimatedItemSize` or `getItemLayout`, **`windowSize`/`initialNumToRender` — the primary scroll-performance knobs**, `maxToRenderPerBatch`/`updateCellsBatchingPeriod`), `data`/`renderItem`/`keyExtractor`/`extraData`, `ItemSeparatorComponent`, `ListHeader/Footer/EmptyComponent`, `onEndReached(-Threshold)`, `onViewableItemsChanged`/`viewabilityConfig` (`ViewToken`), `inverted` (RN chat semantics: opens at `data[0]`, stays pinned on prepend), `refreshing`/`onRefresh`, `horizontal`, `stickyHeaderIndices`, ref: `scrollToIndex`/`scrollToItem`/`scrollToOffset` + ScrollView methods (`FlatListHandle`)\",\n differences:\n \"1000 rows mount windowed in ~120 ms (v1 full mount was 879 ms); `windowSize` defaults to **11**, not RN's 5 — desktop has no mobile memory pressure and a wider window means fewer mount+reflow bursts per scrolled pixel (measured: −21% churn, late frames 10/s → 7.7/s); rows beyond the visible ones are mounted `maxToRenderPerBatch` (10) at a time every `updateCellsBatchingPeriod` (50) ms, so a flick or a long `scrollToOffset` fills its window over several frames instead of stalling one; no pull gesture — `onRefresh` must be app-triggered; an inverted list shorter than its viewport anchors to the top, not the bottom\",\n },\n {\n name: \"SectionList\",\n subpath: \"react-native\",\n gtkImplementation: \"on top of FlatList\",\n supported:\n \"`sections`, `renderSectionHeader`, sticky section headers by default (`stickySectionHeadersEnabled`)\",\n differences:\n \"viewability props are not exposed (section-aware ViewTokens pending)\",\n },\n {\n name: \"Switch\",\n subpath: \"react-native\",\n gtkImplementation: \"GtkSwitch\",\n supported: \"`value`/`onValueChange`, `disabled`\",\n differences: \"sized by the GTK theme, not iOS metrics\",\n },\n {\n name: \"ActivityIndicator\",\n subpath: \"react-native\",\n gtkImplementation: \"GtkSpinner\",\n supported: \"`animating`, `size` (small/large/number)\",\n differences: \"no `color` yet\",\n },\n {\n name: \"Modal\",\n subpath: \"react-native\",\n gtkImplementation: \"modal GtkWindow (portal)\",\n supported:\n \"`visible`, `onRequestClose` (Escape/close button), `title`, `width`/`height`; independently resizable with relayout\",\n differences:\n \"desktop semantics: a separate window, not an overlay; `transparent`/`animationType` are no-ops\",\n },\n {\n name: \"Animated.View\",\n subpath: \"react-native\",\n gtkImplementation: \"direct widget calls\",\n supported:\n \"`opacity` and the whole `transform` array — `translateX/Y`, `scale`, `scaleX`, `scaleY`, `rotate`/`rotateZ` — driven by Animated nodes, bypassing React (an angle comes from `interpolate` with a `deg`/`rad` outputRange)\",\n differences:\n \"`rotateX`/`rotateY`/`perspective` (3D), `skewX`/`skewY` and `matrix` are not supported, and the transform origin is always the view's centre (no `transformOrigin`)\",\n },\n {\n name: \"SafeAreaView\",\n subpath: \"react-native\",\n gtkImplementation: \"= View\",\n supported: \"—\",\n differences: \"no notches on desktop\",\n },\n {\n name: \"StatusBar\",\n subpath: \"react-native\",\n gtkImplementation: \"null\",\n supported: \"—\",\n differences: \"no status bar\",\n },\n {\n name: \"Root\",\n subpath: \"react-native\",\n gtkImplementation: \"internal root\",\n supported: \"`width`/`height`\",\n differences: \"extension: required by the test harness\",\n },\n {\n name: \"NestedRoot\",\n subpath: \"react-native\",\n gtkImplementation: \"internal root\",\n supported: \"—\",\n differences:\n \"extension: a Yoga root inside any GTK container slot (navigation pages, custom containers); the slot allocation is the viewport\",\n },\n {\n name: \"IntrinsicRoot\",\n subpath: \"react-native\",\n gtkImplementation: \"internal root\",\n supported: \"—\",\n differences:\n \"extension: a content-sized Yoga root for chrome slots (HeaderBar start/end) — reports its content size to GTK\",\n },\n] as const satisfies readonly PortableRecord[]\n\nexport const PORTABLE_APIS = [\n {\n name: \"StyleSheet\",\n subpath: \"react-native\",\n supported:\n \"`create`, `flatten`, `compose`, `absoluteFill(Object)`, `hairlineWidth`\",\n differences: \"—\",\n },\n {\n name: \"PlatformColor\",\n subpath: \"react-native\",\n supported:\n 'Adwaita variables: `PlatformColor(\"accent-bg-color\")` → `var(--...)`, `@named`',\n differences: \"names are Adwaita, not iOS/Android\",\n },\n {\n name: \"AppRegistry\",\n subpath: \"react-native\",\n supported:\n \"`registerComponent`, `runApplication(appKey, {title,width,height,initialProps,chrome,applicationActions,actionAccels,windowActions,windowControllers,breakpoints})`, `getAppKeys`\",\n differences:\n 'desktop window parameters; `chrome: \"content\"` uses an AdwApplicationWindow with no window titlebar — the app\\'s HeaderBars (navigation) become the chrome. `applicationActions`/`actionAccels` reach the underlying `GtkApplication` (`app.*` actions — what a `Gio.Notification` action button targets); `windowActions`/`windowControllers` reach the window (`win.*` actions, a window-scoped `GtkShortcutController`); `breakpoints` reaches `AdwApplicationWindow`\\'s own prop and only does anything under `chrome: \"content\"` (a dev warning fires otherwise)',\n },\n {\n name: \"Platform\",\n subpath: \"react-native\",\n supported:\n '`OS: \"linux\"`, `Version` (GTK), `select` (linux → native → default), `isTV`, `isTesting`',\n differences: \"—\",\n },\n {\n name: \"Dimensions\",\n subpath: \"react-native\",\n supported: '`get(\"window\"/\"screen\")`, `addEventListener(\"change\")`',\n differences: \"main window only (transient windows are ignored)\",\n },\n {\n name: \"useWindowDimensions\",\n subpath: \"react-native\",\n supported: \"reactive main-window dimensions\",\n differences: \"—\",\n },\n {\n name: \"Appearance\",\n subpath: \"react-native\",\n supported:\n \"`getColorScheme`, `setColorScheme` (AdwStyleManager), `addChangeListener`\",\n differences: \"—\",\n },\n {\n name: \"useColorScheme\",\n subpath: \"react-native\",\n supported: \"reactive theme\",\n differences: \"—\",\n },\n {\n name: \"AppState\",\n subpath: \"react-native\",\n supported: \"`currentState` active/background, `addEventListener`\",\n differences: \"driven by the window's `is-active`\",\n },\n {\n name: \"Alert\",\n subpath: \"react-native\",\n supported: \"`alert(title, message, buttons, options)` → Adw.AlertDialog\",\n differences: \"`cancel`/`destructive`/`isPreferred` styles\",\n },\n {\n name: \"Linking\",\n subpath: \"react-native\",\n supported:\n '`openURL`, `canOpenURL` (http/https/mailto/file), `getInitialURL` (null), `addEventListener(\"url\")`',\n differences:\n 'system launcher; no deep-link delivery on desktop yet — \"url\" subscriptions never fire',\n },\n {\n name: \"InteractionManager\",\n subpath: \"react-native\",\n supported:\n \"`runAfterInteractions(task?)` (cancellable, then-able), `createInteractionHandle`/`clearInteractionHandle`, `addListener`\",\n differences:\n \"navigation transitions register interactions, so screen work deferred with `runAfterInteractions` waits for the push/pop slide\",\n },\n {\n name: \"DevSettings\",\n subpath: \"react-native\",\n supported:\n \"`addMenuItem(title, handler)` (entries in the Dev Menu — Ctrl+Shift+D in `run-linux --dev`, the react-native-windows shortcut), `reload(reason?)`\",\n differences: \"silent no-ops in release builds, like RN\",\n },\n {\n name: \"I18nManager\",\n subpath: \"react-native\",\n supported:\n \"`isRTL` (live: GTK's read of the locale text direction), `doLeftAndRightSwapInRTL`, `getConstants`\",\n differences:\n \"`allowRTL`/`forceRTL`/`swapLeftAndRightInRTL` are accepted no-ops (mobile persistence has no desktop store)\",\n },\n {\n name: \"BackHandler\",\n subpath: \"react-native\",\n supported: '`addEventListener(\"hardwareBackPress\")`, `exitApp`',\n differences:\n \"no hardware back key on desktop — subscriptions are honored but nothing fires them yet\",\n },\n {\n name: \"Animated\",\n subpath: \"react-native\",\n supported:\n \"`Value`, `timing`, `spring`, `sequence`, `parallel`, `delay`, `loop`, `interpolate` (numbers and deg/rad strings, clamp/extend/identity)\",\n differences:\n \"`useNativeDriver` is ignored (with a warning); the direct path is native-speed anyway\",\n },\n {\n name: \"Easing\",\n subpath: \"react-native\",\n supported: \"linear/ease/quad/cubic/in/out/inOut/bezier\",\n differences: \"—\",\n },\n {\n name: \"version\",\n subpath: \"react-native\",\n supported: \"package version\",\n differences: \"extension\",\n },\n] as const satisfies readonly PortableRecord[]\n\nexport const COMMON_PRIMITIVES = [\n {\n name: \"NavigationStack\",\n subpath: \"react-native-gtkx/common\",\n summary: \"`Adw.NavigationView` driven by a `stack` array of tags\",\n },\n {\n name: \"NavigationStackPage\",\n subpath: \"react-native-gtkx/common\",\n summary: \"one page of that stack, identified by `tag`\",\n },\n {\n name: \"SlotContent\",\n subpath: \"react-native-gtkx/common\",\n summary:\n \"Sizing: fills the slot. Use for: a page body, a pane, a dialog body.\",\n },\n {\n name: \"IntrinsicContent\",\n subpath: \"react-native-gtkx/common\",\n summary:\n \"Sizing: sized by its own Yoga layout. Use for: an AdwHeaderBar slot, a toolbar area, a list row.\",\n },\n] as const satisfies readonly CommonRecord[]\n\nexport const GTK_WIDGETS = [\n { name: \"GtkActionBar\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n {\n name: \"GtkAppChooserButton\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: true,\n },\n {\n name: \"GtkAppChooserWidget\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: true,\n },\n { name: \"GtkAspectFrame\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkBox\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkButton\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkCalendar\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkCellView\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkCenterBox\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkCheckButton\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkColorButton\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n {\n name: \"GtkColorChooserWidget\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: true,\n },\n {\n name: \"GtkColorDialogButton\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: true,\n },\n { name: \"GtkColumnView\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkComboBox\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkComboBoxText\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkDragIcon\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkDrawingArea\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkDropDown\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkEditableLabel\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkEmojiChooser\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkEntry\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkExpander\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n {\n name: \"GtkFileChooserWidget\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: true,\n },\n { name: \"GtkFixed\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkFlowBox\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkFontButton\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n {\n name: \"GtkFontChooserWidget\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: true,\n },\n {\n name: \"GtkFontDialogButton\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: true,\n },\n { name: \"GtkFrame\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkGLArea\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n {\n name: \"GtkGraphicsOffload\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: true,\n },\n { name: \"GtkGrid\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkGridView\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkHeaderBar\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkIconView\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkImage\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkInfoBar\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkInscription\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkLabel\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkLevelBar\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkLinkButton\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkListBox\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkListView\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkLockButton\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkMediaControls\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkMenuButton\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkNotebook\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkOverlay\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkPaned\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkPasswordEntry\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkPicture\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkPopover\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkPopoverBin\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkPopoverMenu\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n {\n name: \"GtkPopoverMenuBar\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: true,\n },\n { name: \"GtkProgressBar\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkRange\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkRevealer\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkScale\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkScaleButton\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkScrollbar\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n {\n name: \"GtkScrolledWindow\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: true,\n },\n { name: \"GtkSearchBar\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkSearchEntry\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkSeparator\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkShortcutLabel\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n {\n name: \"GtkShortcutsGroup\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: true,\n },\n {\n name: \"GtkShortcutsSection\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: true,\n },\n {\n name: \"GtkShortcutsShortcut\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: true,\n },\n { name: \"GtkSpinButton\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkSpinner\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkStack\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkStackSidebar\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkStackSwitcher\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkStatusbar\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkSwitch\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkText\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkTextView\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkToggleButton\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkTreeExpander\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkTreeView\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkVideo\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkViewport\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkVolumeButton\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n {\n name: \"GtkWindowControls\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: true,\n },\n { name: \"GtkWindowHandle\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n {\n name: \"GtkAboutDialog\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: false,\n reason: \"toplevel (derives Gtk.Window)\",\n },\n {\n name: \"GtkAppChooserDialog\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: false,\n reason: \"toplevel (derives Gtk.Window)\",\n },\n {\n name: \"GtkApplicationWindow\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: false,\n reason: \"toplevel (derives Gtk.Window)\",\n },\n {\n name: \"GtkAssistant\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: false,\n reason: \"toplevel (derives Gtk.Window)\",\n },\n {\n name: \"GtkColorChooserDialog\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: false,\n reason: \"toplevel (derives Gtk.Window)\",\n },\n {\n name: \"GtkDialog\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: false,\n reason: \"toplevel (derives Gtk.Window)\",\n },\n {\n name: \"GtkFileChooserDialog\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: false,\n reason: \"toplevel (derives Gtk.Window)\",\n },\n {\n name: \"GtkFlowBoxChild\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: false,\n reason: \"child-only (derives Gtk.FlowBoxChild)\",\n },\n {\n name: \"GtkFontChooserDialog\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: false,\n reason: \"toplevel (derives Gtk.Window)\",\n },\n {\n name: \"GtkListBoxRow\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: false,\n reason: \"child-only (derives Gtk.ListBoxRow)\",\n },\n {\n name: \"GtkMessageDialog\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: false,\n reason: \"toplevel (derives Gtk.Window)\",\n },\n {\n name: \"GtkPageSetupUnixDialog\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: false,\n reason: \"toplevel (derives Gtk.Window)\",\n },\n {\n name: \"GtkPrintUnixDialog\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: false,\n reason: \"toplevel (derives Gtk.Window)\",\n },\n {\n name: \"GtkShortcutsWindow\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: false,\n reason: \"toplevel (derives Gtk.Window)\",\n },\n {\n name: \"GtkWindow\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: false,\n reason: \"toplevel (derives Gtk.Window)\",\n },\n] as const satisfies readonly WidgetRecord[]\n\nexport const ADW_WIDGETS = [\n { name: \"AdwAboutDialog\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwAlertDialog\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwAvatar\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwBanner\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwBin\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwBottomSheet\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwBreakpointBin\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwButtonContent\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwCarousel\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n {\n name: \"AdwCarouselIndicatorDots\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: true,\n },\n {\n name: \"AdwCarouselIndicatorLines\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: true,\n },\n { name: \"AdwClamp\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n {\n name: \"AdwClampScrollable\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: true,\n },\n { name: \"AdwDialog\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwFlap\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwHeaderBar\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n {\n name: \"AdwInlineViewSwitcher\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: true,\n },\n { name: \"AdwLayoutSlot\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwLeaflet\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n {\n name: \"AdwMultiLayoutView\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: true,\n },\n {\n name: \"AdwNavigationSplitView\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: true,\n },\n {\n name: \"AdwNavigationView\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: true,\n },\n {\n name: \"AdwOverlaySplitView\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: true,\n },\n {\n name: \"AdwPreferencesDialog\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: true,\n },\n {\n name: \"AdwPreferencesGroup\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: true,\n },\n { name: \"AdwShortcutLabel\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n {\n name: \"AdwShortcutsDialog\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: true,\n },\n { name: \"AdwSidebar\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwSpinner\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwSplitButton\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwSqueezer\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwStatusPage\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwTabBar\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwTabButton\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwTabOverview\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwTabView\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwToastOverlay\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwToggleGroup\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwToolbarView\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwViewStack\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwViewSwitcher\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n {\n name: \"AdwViewSwitcherBar\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: true,\n },\n {\n name: \"AdwViewSwitcherSidebar\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: true,\n },\n {\n name: \"AdwViewSwitcherTitle\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: true,\n },\n { name: \"AdwWindowTitle\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwWrapBox\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n {\n name: \"AdwAboutWindow\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"toplevel (derives Gtk.Window)\",\n },\n {\n name: \"AdwActionRow\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"child-only (derives Gtk.ListBoxRow)\",\n },\n {\n name: \"AdwApplicationWindow\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"toplevel (derives Gtk.Window)\",\n },\n {\n name: \"AdwButtonRow\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"child-only (derives Gtk.ListBoxRow)\",\n },\n {\n name: \"AdwComboRow\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"child-only (derives Gtk.ListBoxRow)\",\n },\n {\n name: \"AdwEntryRow\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"child-only (derives Gtk.ListBoxRow)\",\n },\n {\n name: \"AdwExpanderRow\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"child-only (derives Gtk.ListBoxRow)\",\n },\n {\n name: \"AdwMessageDialog\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"toplevel (derives Gtk.Window)\",\n },\n {\n name: \"AdwNavigationPage\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"child-only (denylist — see scripts/widget-surface/classify.ts)\",\n },\n {\n name: \"AdwPasswordEntryRow\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"child-only (derives Gtk.ListBoxRow)\",\n },\n {\n name: \"AdwPreferencesPage\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"child-only (denylist — see scripts/widget-surface/classify.ts)\",\n },\n {\n name: \"AdwPreferencesRow\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"child-only (derives Gtk.ListBoxRow)\",\n },\n {\n name: \"AdwPreferencesWindow\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"toplevel (derives Gtk.Window)\",\n },\n {\n name: \"AdwSpinRow\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"child-only (derives Gtk.ListBoxRow)\",\n },\n {\n name: \"AdwSwitchRow\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"child-only (derives Gtk.ListBoxRow)\",\n },\n {\n name: \"AdwWindow\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"toplevel (derives Gtk.Window)\",\n },\n] as const satisfies readonly WidgetRecord[]\n\nexport const DOC_CHUNKS = [\n {\n doc: \"docs/api.md\",\n heading: \"Components\",\n text: \"| Export | GTK implementation | Supported | Differences from RN |\\n| ------------------- | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\\n| `View` | GtkBox (RnGtkxViewBox) | `style`, `onLayout`, `testID`, children, `pointerEvents` (auto/none/box-none/box-only — mapped onto GTK picking: can-target + a contains() vfunc override; also honored from `style.pointerEvents`, the prop wins) | nesting another pointerEvents inside a box-only view is not supported |\\n| `Text` | GtkLabel (Pango) | wrap, `numberOfLines` (ellipsize END), `textAlign`, font styles, `onLayout`, `testID` | nested `Text` elements are concatenated without per-span styles; text is always ellipsizable (shrinkable in narrow windows) |\\n| `Image` | GtkPicture | `source={{uri}}`/string — local paths, file:// and **http(s)** (Node fetch → disk cache keyed by URL, in-flight de-duplication), `resizeMode` cover/contain/stretch/center, `onLoad`/`onError`; **`.svg` files load like any other image** — `Gdk.Texture.newFromFilename` rasterizes them via librsvg, no extra code needed (for building vector graphics from state instead of a file, see the \\\"Svg\\\" section below — a separate import, not part of this table) | no synchronous size from remote images (style sets the size, as in RN); cache is not size-limited yet |\\n| `TextInput` | GtkEntry / GtkTextView | controlled/uncontrolled (`value`/`defaultValue`), `onChangeText`, `onSubmitEditing`, `onFocus`/`onBlur`, `placeholder` (own dim overlay in multiline — GtkTextView has none), `secureTextEntry`, `editable`, `keyboardType`, `multiline`, `clearButtonMode` (GtkEntry's built-in clear icon; RN ships this on iOS only) (real GtkTextView: word wrap, internal scroll, Enter inserts a newline and never fires onSubmitEditing — RN semantics) | multiline needs a height in the style (as RN recommends) |\\n| `Pressable` | GtkFixed + GestureClick/Motion | `onPress(In/Out)`, `onLongPress` (`delayLongPress`), `onHoverIn/Out`, `disabled`, function-form `style`/`children` receiving `{pressed, hovered}` | — |\\n| `TouchableOpacity` | on top of Pressable | `activeOpacity` | — |\\n| `ScrollView` | GtkScrolledWindow | vertical/`horizontal`, `contentContainerStyle`, `onScroll`, `onContentSizeChange`, `stickyHeaderIndices` (RN model: the REAL child is translated and painted on top — no duplicate), ref: `scrollTo`/`scrollToEnd` (`ScrollViewHandle`) | `animated` in scrollTo is ignored |\\n| `FlatList` | windowed core on ScrollView | virtualization (`estimatedItemSize` or `getItemLayout`, **`windowSize`/`initialNumToRender` — the primary scroll-performance knobs**, `maxToRenderPerBatch`/`updateCellsBatchingPeriod`), `data`/`renderItem`/`keyExtractor`/`extraData`, `ItemSeparatorComponent`, `ListHeader/Footer/EmptyComponent`, `onEndReached(-Threshold)`, `onViewableItemsChanged`/`viewabilityConfig` (`ViewToken`), `inverted` (RN chat semantics: opens at `data[0]`, stays pinned on prepend), `refreshing`/`onRefresh`, `horizontal`, `stickyHeaderIndices`, ref: `scrollToIndex`/`scrollToItem`/`scrollToOffset` + ScrollView methods (`FlatListHandle`) | 1000 rows mount windowed in ~120 ms (v1 full mount was 879 ms); `windowSize` defaults to **11**, not RN's 5 — desktop has no mobile memory pressure and a wider window means fewer mount+reflow bursts per scrolled pixel (measured: −21% churn, late frames 10/s → 7.7/s); rows beyond the visible ones are mounted `maxToRenderPerBatch` (10) at a time every `updateCellsBatchingPeriod` (50) ms, so a flick or a long `scrollToOffset` fills its window over several frames instead of stalling one; no pull gesture — `onRefresh` must be app-triggered; an inverted list shorter than its viewport anchors to the top, not the bottom |\\n| `SectionList` | on top of FlatList | `sections`, `renderSectionHeader`, sticky section headers by default (`stickySectionHeadersEnabled`) | viewability props are not exposed (section-aware ViewTokens pending) |\\n| `Switch` | GtkSwitch | `value`/`onValueChange`, `disabled` | sized by the GTK theme, not iOS metrics |\\n| `ActivityIndicator` | GtkSpinner | `animating`, `size` (small/large/number) | no `color` yet |\\n| `Modal` | modal GtkWindow (portal) | `visible`, `onRequestClose` (Escape/close button), `title`, `width`/`height`; independently resizable with relayout | desktop semantics: a separate window, not an overlay; `transparent`/`animationType` are no-ops |\\n| `Animated.View` | direct widget calls | `opacity` and the whole `transform` array — `translateX/Y`, `scale`, `scaleX`, `scaleY`, `rotate`/`rotateZ` — driven by Animated nodes, bypassing React (an angle comes from `interpolate` with a `deg`/`rad` outputRange) | `rotateX`/`rotateY`/`perspective` (3D), `skewX`/`skewY` and `matrix` are not supported, and the transform origin is always the view's centre (no `transformOrigin`) |\\n| `SafeAreaView` | = View | — | no notches on desktop |\\n| `StatusBar` | null | — | no status bar |\\n| `Root` | internal root | `width`/`height` | extension: required by the test harness |\\n| `NestedRoot` | internal root | — | extension: a Yoga root inside any GTK container slot (navigation pages, custom containers); the slot allocation is the viewport |\\n| `IntrinsicRoot` | internal root | — | extension: a content-sized Yoga root for chrome slots (HeaderBar start/end) — reports its content size to GTK |\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"API modules\",\n text: '| Export | Supported | Differences |\\n| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\\n| `StyleSheet` | `create`, `flatten`, `compose`, `absoluteFill(Object)`, `hairlineWidth` | — |\\n| `PlatformColor` | Adwaita variables: `PlatformColor(\"accent-bg-color\")` → `var(--...)`, `@named` | names are Adwaita, not iOS/Android |\\n| `AppRegistry` | `registerComponent`, `runApplication(appKey, {title,width,height,initialProps,chrome,applicationActions,actionAccels,windowActions,windowControllers,breakpoints})`, `getAppKeys` | desktop window parameters; `chrome: \"content\"` uses an AdwApplicationWindow with no window titlebar — the app\\'s HeaderBars (navigation) become the chrome. `applicationActions`/`actionAccels` reach the underlying `GtkApplication` (`app.*` actions — what a `Gio.Notification` action button targets); `windowActions`/`windowControllers` reach the window (`win.*` actions, a window-scoped `GtkShortcutController`); `breakpoints` reaches `AdwApplicationWindow`\\'s own prop and only does anything under `chrome: \"content\"` (a dev warning fires otherwise) |\\n| `Platform` | `OS: \"linux\"`, `Version` (GTK), `select` (linux → native → default), `isTV`, `isTesting` | — |\\n| `Dimensions` | `get(\"window\"/\"screen\")`, `addEventListener(\"change\")` | main window only (transient windows are ignored) |\\n| `useWindowDimensions` | reactive main-window dimensions | — |\\n| `Appearance` | `getColorScheme`, `setColorScheme` (AdwStyleManager), `addChangeListener` | — |\\n| `useColorScheme` | reactive theme | — |\\n| `AppState` | `currentState` active/background, `addEventListener` | driven by the window\\'s `is-active` |\\n| `Alert` | `alert(title, message, buttons, options)` → Adw.AlertDialog | `cancel`/`destructive`/`isPreferred` styles |\\n| `Linking` | `openURL`, `canOpenURL` (http/https/mailto/file), `getInitialURL` (null), `addEventListener(\"url\")` | system launcher; no deep-link delivery on desktop yet — \"url\" subscriptions never fire |\\n| `InteractionManager` | `runAfterInteractions(task?)` (cancellable, then-able), `createInteractionHandle`/`clearInteractionHandle`, `addListener` | navigation transitions register interactions, so screen work deferred with `runAfterInteractions` waits for the push/pop slide |\\n| `DevSettings` | `addMenuItem(title, handler)` (entries in the Dev Menu — Ctrl+Shift+D in `run-linux --dev`, the react-native-windows shortcut), `reload(reason?)` | silent no-ops in release builds, like RN |\\n| `I18nManager` | `isRTL` (live: GTK\\'s read of the locale text direction), `doLeftAndRightSwapInRTL`, `getConstants` | `allowRTL`/`forceRTL`/`swapLeftAndRightInRTL` are accepted no-ops (mobile persistence has no desktop store) |\\n| `BackHandler` | `addEventListener(\"hardwareBackPress\")`, `exitApp` | no hardware back key on desktop — subscriptions are honored but nothing fires them yet |\\n| `Animated` | `Value`, `timing`, `spring`, `sequence`, `parallel`, `delay`, `loop`, `interpolate` (numbers and deg/rad strings, clamp/extend/identity) | `useNativeDriver` is ignored (with a warning); the direct path is native-speed anyway |\\n| `Easing` | linear/ease/quad/cubic/in/out/inOut/bezier | — |\\n| `version` | package version | extension |\\n\\nStyles (which keys go where and what is unsupported) — [style system table](../packages/react-native-gtkx/src/style/README.md).',\n },\n {\n doc: \"docs/api.md\",\n heading: \"Key differences from React Native (summary)\",\n text: \"1. **Desktop, not mobile**: `Modal` is a real window; `runApplication` accepts a title and dimensions; gestures are mouse-driven (hover works, no touch gestures);\\n2. **Node.js runtime**: all of npm/Node is available (fs, sqlite, napi) — \\\"native modules\\\" are written as regular Node modules; RN libraries with iOS/Android code do not work;\\n3. **Layout is exactly RN's**: every container runs a custom GtkLayoutManager that obeys only the Yoga engine — GTK widget minimums never leak into the layout, windows shrink freely, and `Dimensions.get(\\\"window\\\")` reports the app viewport (the window's content area under the headerbar, like RN's app window);\\n4. **Text**: the ellipsis is opt-in via `numberOfLines`, exactly like RN; plain text wraps naturally and an unbreakable word wider than its box clips to it (text leaves clip; containers keep paint-overflow);\\n5. **transform** is paint-only, like RN: `translateX/Y`, `scale`, `scaleX`, `scaleY` and `rotate`/`rotateZ` apply to any component's style (not just `Animated.View`), the array composes left to right as in RN and CSS, and the origin is the view's centre. A transformed child honestly draws past its container over siblings (later siblings stay on top, RN's default z-order) without moving any ancestor, and GTK routes input through the transform, so a rotated view is clickable in its rotated shape. Rotation and scale reach the widget as the `GskTransform` of its allocation (`docs/research/transforms.md`); 3D (`rotateX`/`rotateY`/`perspective`), `skewX`/`skewY`, `matrix` and `transformOrigin` are not supported;\\n6. **Animations never auto-stop**: the desktop \\\"reduce animations\\\" hint is not applied automatically (GTK-side animations are kept on to match `Animated`, which runs on its own timers) — honoring reduced motion stays an app-level opt-in, as in RN;\\n7. **Lists are windowed like RN's**: FlatList/SectionList mount only the rows around the viewport (prefix-sum offsets, `estimatedItemSize` refined by real measurements or exact `getItemLayout`); sticky headers translate the REAL widget (no duplicate) and `inverted` follows the RN chat contract — `contentOffset` counts from the end where `data[0]` renders. The one RefreshControl compromise: desktop has no pull gesture, so `refreshing`/`onRefresh` are API-compatible but the trigger is app chrome (a button/shortcut);\\n8. The package ships compiled (`dist/`: ESM + `.d.ts` alongside, sources embedded in the maps); consumers — Metro (`react-native-gtkx/metro` preset) and vite (preset) — both consume the built output. Requires Node ≥ 24 (the gtkx runtime floor; the run-linux host also relies on `module.registerHooks`).\\n9. **Pre-commit hooks regenerate derived data**: editing this file (or the other generator inputs) and forgetting to run `scripts/generate-mcp-data.mjs` no longer fails CI — the pre-commit hook regenerates `packages/react-native-gtkx/src/mcp/data/generated.ts` and stages it for you.\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"Navigation (`react-native-gtkx/navigation`)\",\n text: 'A [react-navigation](https://reactnavigation.org) stack navigator backed by\\n`Adw.NavigationView` — native Adwaita page transitions, the HeaderBar back\\nbutton and back gestures stay in sync with react-navigation state (the\\nreact-native-windows / native-stack model). Requires the optional peer\\n`@react-navigation/native` (v8).\\n\\n`@react-navigation/native@8` itself peers on `react-native: \"*\"` (unlike\\n`@react-navigation/core@8`, which has no react-native peer at all). If your\\napp has no `react-native` package anywhere in its tree — a vite+gtkx app\\nwith no Metro side, exactly what `examples/gallery` demonstrates —\\n`npm install` will print an unmet-peer-dependency warning for it. This is\\nharmless: react-native-gtkx never imports anything from the `react-native`\\npackage, so nothing actually needs it at runtime; the warning is npm being\\nstrict about a peer range upstream declared loosely (`\"*\"` — any version\\nsatisfies it, npm just wants the package present at all).\\n\\n```tsx\\nimport { NavigationContainer } from \"@react-navigation/native\"\\nimport { createStackNavigator } from \"react-native-gtkx/navigation\"\\n\\n// Run the app with chrome: \"content\" — the navigator\\'s HeaderBars ARE the\\n// window chrome (the default system chrome would add a second titlebar):\\n// AppRegistry.runApplication(name, { ..., chrome: \"content\" })\\n\\nconst Stack = createStackNavigator()\\n\\nconst App = () => (\\n <NavigationContainer>\\n <Stack.Navigator>\\n <Stack.Screen\\n name=\"Home\"\\n component={HomeScreen}\\n />\\n <Stack.Screen\\n name=\"Details\"\\n component={DetailsScreen}\\n options={{ title: \"Details page\" }}\\n />\\n </Stack.Navigator>\\n </NavigationContainer>\\n)\\n```\\n\\n- Screen `options`: `title` (HeaderBar title, defaults to the route name),\\n `headerShown` (default true).\\n- `createSidebarNavigator` — the desktop drawer equivalent on\\n `Adw.NavigationSplitView`: a persistent native sidebar (`AdwActionRow`\\n per screen, in a GtkListBox with Adwaita `navigation-sidebar` styling)\\n selects between parallel screens (TabRouter semantics). Navigator prop\\n `sidebarTitle`; screen `options`: `title`, `icon` (Adwaita symbolic icon\\n name for the row\\'s prefix), `color` (a CSS color for a colored-dot\\n prefix instead of `icon` — the two are mutually exclusive per row,\\n `color` wins if both are set), `count` (a badge suffix, hidden when 0 or\\n unset). Run the app with `chrome: \"content\"` so the split view\\'s\\n HeaderBars are the window chrome (`examples/gallery` is built on it).\\n Navigator prop `headerButtons` packs declarative native buttons into the\\n content HeaderBar end (`{id, icon, tooltip, onPress}`, `icon` is an\\n Adwaita symbolic name) — the gallery\\'s color-scheme toggle uses it.\\n Navigator prop `collapseWidth` (sp): below this width the split view\\n collapses to the sidebar or the content pane alone, through a native\\n `Adw.Breakpoint` wrapping the view in an `AdwBreakpointBin` — NOT a\\n `useWindowDimensions` conditional (see docs/platform-layer.md, \"Two ways\\n to react to size\"); the property flip happens inside GTK\\'s own\\n allocation pass, costing no React render for the resize itself. Unset by\\n default — no `AdwBreakpointBin` is mounted at all, so existing consumers\\n see no behavior change. Any route becoming active while collapsed\\n reveals content (`AdwNavigationSplitView.showContent`, a plain native\\n property write, not React state) — a row click OR a programmatic\\n `navigate()`/`jumpTo()`; the native back button that then appears\\n reverses it. Re-selecting the same, already-active row after that also\\n reveals content again — GTK\\'s `row-selected` does not refire for a\\n re-click with no selection change, so this is driven by `row-activated`\\n (fires on every click) in addition. The reverse direction — the split\\n view\\'s own back button, Escape or back gesture hiding content again — is\\n observed too: it fires a `sidebarShown` event\\n (`navigation.addListener(\"sidebarShown\", …)`) on the currently active\\n route, the same event-map protocol `createStackNavigator`\\'s\\n `transitionStart`/`transitionEnd` use. Nothing in react-navigation state\\n changes when this fires — TabRouter has no \"closed\" concept, the same\\n route stays focused, only the pane did — so it exists purely for an app\\n that wants to react (`examples/tasks-nav`\\'s `ContentScreen` resets its\\n own in-screen \"open task\" state on it). Never fired for content being\\n revealed (that direction is already an ordinary state change) or when\\n `collapseWidth` is unset. Resizing back above `collapseWidth` and then\\n back below it again does NOT reset `showContent` or the selection —\\n confirmed empirically, not assumed — both simply persist across the\\n round trip, the same size-class behavior a mobile master-detail app\\n relies on; see docs/research/navigation-extensibility.md for the\\n evidence.\\n- Sidebar navigator props `minWidth` / `minHeight` (px, default 360×294 —\\n GNOME\\'s own adaptive floor): the narrowest size this navigator\\'s UI\\n supports, applied to the `AdwBreakpointBin` that `collapseWidth` mounts.\\n Ignored when `collapseWidth` is unset, since no bin exists then. Adwaita\\n cannot measure a breakpoint bin — what it contains changes with the\\n breakpoints — so the bin reports a minimum of ZERO and warns that\\n `width-request`/`height-request` must be set. Under `chrome: \"content\"`\\n the bin is the window\\'s own child, so that zero IS the window\\'s floor:\\n the window resizes straight past what the pane inside can draw, and\\n Adwaita clips the pane instead of adapting it (\"AdwNavigationSplitView\\n exceeds AdwBreakpointBin width: requested 469 px, 360 px available\" in\\n the journal, felt as a list running off the right edge with its trailing\\n controls cut away). An app whose content HeaderBar needs more than the\\n default must raise it — measure the pane rather than guessing: a\\n segmented control as `headerTitle` costs ~110px on its own and, unlike a\\n title label, cannot ellipsize. `examples/tasks-nav` passes `480` for\\n exactly that reason; the value stays below its `collapseWidth`, so the\\n collapsed layout is still fully reachable.\\n- Sidebar screen options `headerLeft` / `headerRight` / `headerTitle`:\\n `() => ReactNode` — the content HeaderBar\\'s own start/end/title, per\\n screen, on top of the one navigator-wide default. This is what lets one\\n screen\\'s header change shape with ITS OWN selection (a filter toggle\\n group for a list, a back button plus star/trash for an open item):\\n call `navigation.setOptions({ headerLeft, headerRight, headerTitle })`\\n from inside the screen, in an effect keyed on whatever local state\\n decides its shape — no stack involved, and no new navigator API beyond\\n the options themselves (`useNavigationBuilder` already re-resolves\\n descriptor options on every `setOptions` call). `headerTitle` replaces\\n the HeaderBar\\'s title widget outright (unset, the page\\'s own title\\n shows automatically, as before). A screen\\'s own `headerButtons`\\n (`HeaderButton[]`, same shape as the navigator prop) replaces the\\n navigator-level default entirely for that screen. **Caveat, found\\n while testing this**: `setOptions` MERGES into the previously resolved\\n options rather than replacing them — a call that omits `headerRight`\\n does not clear a `headerRight` a PREVIOUS call set, it leaves it in\\n place. A screen that flips between shapes must give every one of these\\n four keys an explicit value (`undefined` counts as a real overwrite; an\\n absent key does not) on every call, not just the ones currently in use.\\n- Sidebar navigator prop `sidebarContent`:\\n `(props: SidebarContentProps) => ReactNode` — replaces the ENTIRE sidebar\\n pane\\'s body, for a sidebar that needs sections, a search field, a footer,\\n or anything a flat list of rows cannot express. The sidebar\\'s children\\n stop being \"one row per screen\": you draw what you like, and navigation\\n is just the `jumpTo` you were handed. `SidebarContentProps` carries\\n `routes` (key, name, resolved options, title, `focused`), `focusedIndex`\\n and `jumpTo(name)` — use those rather than dispatching yourself, so\\n selection cannot drift from navigation state. The pane\\'s AdwHeaderBar and\\n `sidebarTitle` still belong to the navigator: this is the body under it,\\n not the chrome. Mounted as React Native content (a layout root filling\\n the pane); a sidebar built from GTK widgets wraps its own tree in\\n `WidgetContent`, the same escape hatch `contentLayout: \"widget\"` is for a\\n screen body. Reach for `sidebarRow` first if you only want a different\\n ROW — it keeps the navigator\\'s list and everything attached to it.\\n- Sidebar screen option `sidebarRow`: `() => ReactNode` — draw the row\\n yourself instead of letting `title`/`icon`/`color`/`count` compose one.\\n Those four are a convenience, not the ceiling: they build an\\n `AdwActionRow`, which brings Adwaita\\'s own row metrics with it, so an app\\n wanting a different shape, density or height had nothing to reach for.\\n Return anything a `GtkListBoxRow` can hold — React Native content, GTK\\n widgets, a differently-configured Adwaita row. The navigator keeps owning\\n row BEHAVIOUR (selection, click → `jumpTo`, staying in step with\\n navigation state, the collapsed reveal), so a custom row cannot drift out\\n of sync with the router; only what is drawn changes. A screen that passes\\n none of `icon`/`color`/`count` gets a compact `GtkListBoxRow` + label\\n automatically — `AdwActionRow`\\'s height is right when there IS a prefix\\n and a count to lay out and pure cost when there is not.\\n- Sidebar screen option `contentLayout`: `\"react-native\"` (default) or\\n `\"widget\"` — what the screen\\'s body IS. The default mounts it in a Yoga\\n layout root that fills the pane, so `<View style={{ flex: 1 }}>` behaves\\n the way it does anywhere else. `\"widget\"` packs the body into the page\\n directly, with no layout root in between, for a screen whose body is a\\n GTK widget tree (a `GtkScrolledWindow` around an `AdwClamp` around a\\n `.boxed-list` `GtkListBox`, say): GTK\\'s own sizing — `vexpand`, a list\\'s\\n natural height — then applies normally. **Under the default a widget tree\\n collapses instead**, and quietly: every widget becomes a single Yoga LEAF\\n measured for its own natural size, so a container renders its first child,\\n drops the rest, and reports the ~1px it can shrink to, with no error\\n anywhere. `examples/tasks-nav` is built this way. Mixing is per screen,\\n not per subtree — a `\"widget\"` screen that wants React Native content\\n somewhere inside it wraps that part in `SlotContent` itself.\\n- Stack screen options `headerLeft` / `headerRight`: `() => ReactNode` —\\n real RN content in the HeaderBar (inputs included), hosted by an\\n intrinsic-size root; `headerButtons` render after `headerRight`\\n (hn-app\\'s header search filter is the demo).\\n- Stack screen option `gestureEnabled: false` disables the native back\\n button, Escape and the back gesture for that screen (the page\\'s\\n Adwaita `can-pop`); a programmatic `goBack` still pops. `usePreventRemove`\\n works through the same mechanism — a prevented route reports\\n `can-pop: false`, so no native pop can race react-navigation state; the\\n route pops once the app lifts the guard (e.g. after its own\\n confirmation dialog).\\n- Stack screen option `animation` maps onto `Adw.NavigationView`\\'s\\n `animate-transitions` — GTK has exactly one transition style, not a\\n choice of styles like iOS/Android, so the option collapses to a\\n boolean: `\"none\"` turns transitions off, any other value (including\\n native-stack\\'s own style names, e.g. `\"slide_from_bottom\"`, `\"fade\"`)\\n turns them on, with the standard Adwaita transition rather than the\\n one asked for. Requesting a specific type still animates — it is not\\n silently treated as `\"none\"` — and warns once in development.\\n `animate-transitions` is a property of the whole view, not a per-page\\n one, so there is no per-screen granularity to offer: the value used is\\n read from whichever screen is currently on top of the visible stack,\\n recomputed on every navigation. Setting it once via `screenOptions`\\n (the same value for every screen) is the reliable way to use this —\\n the per-screen case only matters if different screens genuinely\\n disagree, and even then only the active one\\'s value is observed.\\n Interactive swipe-back gestures always animate regardless of this\\n setting — Adwaita\\'s own behavior, not overridable here.\\n- The factories are typed: `createStackNavigator<ParamList>()` gives\\n typed `Screen` configs and `StackScreenProps<ParamList, Route>` for\\n screen components (`SidebarScreenProps` likewise).\\n- The stack navigator emits `transitionStart` / `transitionEnd` on a\\n screen\\'s `navigation` object, matching `@react-navigation/stack` and\\n `@react-navigation/native-stack` exactly: `{ data: { closing: boolean } }`,\\n `closing: false` for the screen being pushed in, `closing: true` for the\\n screen being popped out. A screen that stays mounted without actually\\n entering or leaving (e.g. the screen underneath a push) gets neither\\n event, same as upstream. Two things worth knowing before relying on\\n timing:\\n - **`transitionEnd` is tied to `AdwNavigationPage`\\'s own `shown`/`hidden`\\n signals** — contrary to an earlier version of this page, Adwaita DOES\\n expose a transition-finished signal (four of them, in fact: `showing`,\\n `shown`, `hiding`, `hidden`, all per-page). `transitionEnd` on the\\n entering screen fires on that screen\\'s `shown`; on the leaving screen\\n it fires on `hidden`. `transitionDuration` (default 400 ms) is a\\n fallback only, used when a page\\'s own signal never arrives — a\\n signal-less environment, or a page skipped entirely by a multi-hop\\n pop (popping past an intermediate screen never fires anything on it,\\n since it was never the one actually on screen during the transition).\\n When transitions are not animated, the real signals still fire —\\n immediately — so `transitionEnd` is not delayed by the fallback\\n window either.\\n - **Native pops do not fire these events at all today.** A user-driven\\n pop (the Adwaita back button, Escape, the back gesture) is handled by\\n the widget itself before this package\\'s code is told about it, so\\n there is nothing to hook a `transitionStart` into. Only\\n programmatic navigation (`navigate`, `goBack`, `dispatch`, …) fires\\n `transitionStart`/`transitionEnd`.\\n- The sidebar navigator emits `sidebarShown` (`{ data: undefined }`) on a\\n screen\\'s `navigation` object — the collapsed-mode counterpart of a native\\n pop, and the one case where a native, user-driven interaction (the split\\n view\\'s own back button, Escape, the back gesture) DOES get an event: the\\n widget-level property that changes (`showContent`) has no\\n react-navigation state behind it at all, so there is no state change for\\n an app to observe any other way. Fired on the active route only when\\n `showContent` goes from shown back to hidden, and only while\\n `collapseWidth` is set; never fired for content being revealed (that\\n already shows up as an ordinary focused-route change).\\n- The rest of the react-navigation surface — `useNavigation`, `useRoute`,\\n `useFocusEffect`, `useIsFocused`, `useNavigationContainerRef`,\\n `CommonActions`, `StackActions`, `usePreventRemove`, `NavigationContainer`\\n and everything else — comes from `@react-navigation/native` directly, not\\n from this package. **Breaking change**: earlier versions re-exported a\\n subset of these names from `react-native-gtkx/navigation`; the re-export\\n was removed because it was never complete (anything beyond the subset\\n still required importing from `@react-navigation/native`, so it was one\\n more place to look rather than a convenience). This package\\'s navigation\\n entry point now exports exactly its own surface: `createStackNavigator`,\\n `createSidebarNavigator`, and the option/prop types around them.\\n- Each screen mounts its own layout root inside the page: the page\\'s\\n content allocation is that screen\\'s viewport.\\n- Differences from `@react-navigation/native-stack`: `headerRight`/custom\\n header widgets are not supported yet; deep-link \"url\" events never fire\\n on desktop (see `Linking`).',\n },\n {\n doc: \"docs/api.md\",\n heading: \"Svg\",\n text: 'Vector graphics built from state, modeled on\\n[react-native-svg](https://github.com/software-mansion/react-native-svg) (the\\nde-facto standard RN mirrors) rather than invented from scratch — portable\\ncode costs nothing to bring over. Drawing goes through `Gsk.Path`/\\n`Gtk.Snapshot` on a single custom widget (`RnGtkxSvgNode`, `registerClass` +\\nan overridden `snapshot()` vfunc — the same mechanism `RnGtkxLayout` and\\n`RnGtkxViewBox` already use), not a rasterized image: for that, `Image`\\nalready loads `.svg` files today (see the `Image` row above).\\n\\n**Not part of the main `react-native-gtkx` export surface** — unlike every\\ncomponent in the table above, `Svg` and everything below are exported only\\nfrom `react-native-gtkx/svg`, in the shape of the `react-native-svg` package\\nitself. `react-native-svg` is a separate package on every other platform (RN\\nhas no built-in `Svg`), so this project mirrors that split instead of adding\\n`Svg` to the main entry, which would make code written against it fail to\\ncompile anywhere else. See \"`react-native-svg` compatibility\" below for the\\nexact import and how the alias resolves it.\\n\\n```tsx\\nimport Svg, { Circle, G, Path, Rect } from \"react-native-svg\"\\n\\nconst Icon = () => (\\n <Svg\\n width={24}\\n height={24}\\n viewBox=\"0 0 24 24\"\\n >\\n <Circle\\n cx={12}\\n cy={12}\\n r={10}\\n fill=\"#1c71d8\"\\n />\\n <Path\\n d=\"M8 12 l3 3 l5 -6\"\\n stroke=\"white\"\\n strokeWidth={2}\\n fill=\"none\"\\n />\\n </Svg>\\n)\\n```\\n\\n- **`Svg`**: `width`/`height` (or `style`) size it — a Yoga leaf like\\n `Image`, sized entirely by style/flex, never by measuring the widget\\n (nothing here is intrinsic-sized). `viewBox=\"minX minY width height\"` and\\n `preserveAspectRatio` (`xMin/xMid/xMax` × `YMin/YMid/YMax`, `meet`/`slice`,\\n `none`; default `xMidYMid meet`) reshape the internal coordinate system\\n exactly like real SVG — Yoga never sees them. Content always clips to the\\n allocated bounds (no `overflow: visible` opt-out).\\n- **`Path`**: `d` is handed straight to `Gsk.Path.parse()`, which understands\\n SVG path syntax natively — there is no path parser of our own.\\n- **`Rect`** (`x`/`y`/`width`/`height`/`rx`/`ry`), **`Circle`**\\n (`cx`/`cy`/`r`), **`Ellipse`** (`cx`/`cy`/`rx`/`ry`), **`Line`**\\n (`x1`/`y1`/`x2`/`y2`, stroke-only — no `fill` prop at all, not even\\n ignored), **`Polygon`**/**`Polyline`** (`points`, `\"x,y x,y …\"` or\\n space-separated, closed/open respectively): each is a small geometry\\n helper away from the same `d` syntax, so every shape ends up drawn through\\n that one `Gsk.Path.parse()` call.\\n- Every shape accepts `fill`/`stroke` (a static CSS color — hex/`rgb()`/\\n `hsl()`/named/`transparent`/`none`, or `\"url(#id)\"` referencing a\\n gradient; default `fill=\"black\"`, `stroke=\"none\"`, matching SVG),\\n `fillRule` (`nonzero` | `evenodd`), `fillOpacity`/`strokeOpacity`/\\n `opacity`, `strokeWidth`, `strokeLinecap`/`strokeLinejoin`,\\n `strokeDasharray`, `strokeDashoffset`.\\n- **`G`** groups children under an `opacity` and/or a `transform` string —\\n `translate()`/`scale()`/`rotate()`/`rotate(a,cx,cy)`/`matrix()`, the plain\\n SVG transform-list syntax (`matrix()` maps directly onto\\n `Gsk.Transform.matrix2d()`); `skewX`/`skewY` and the structured\\n `transform={[{translateX:...}]}` array form `Animated.View` accepts are\\n not supported here.\\n- **Gradients**: `<Defs>` holds `<LinearGradient id x1 y1 x2 y2>` /\\n `<RadialGradient id cx cy r>` (fractions 0–1 by default —\\n `gradientUnits=\"objectBoundingBox\"`, mapped against the shape\\'s own\\n `Gsk.Path.getBounds()`; `gradientUnits=\"userSpaceOnUse\"` uses the\\n coordinates as-is instead), each with `<Stop offset stopColor\\nstopOpacity>` children (`offset` accepts `0.5` or `\"50%\"`). `Defs` must be\\n a direct child of `Svg` (nested `Defs` are not scanned). No\\n `gradientTransform`, no `spreadMethod` beyond the default pad behavior.\\n **Known limitation**: constructing a `Gsk.ColorStop` currently crashes in\\n gtkx-rc2\\'s native addon — verified through three independent construction\\n paths (the generated constructor, its property setters, and a bypass that\\n skips `ColorStop` entirely), all failing in the same compiled native code,\\n so this is not fixable from application code. A gradient reference\\n degrades to painting nothing for that fill/stroke (the same safe path as\\n an unresolvable `url(#id)`) rather than crashing the app; the coordinate\\n math itself is unaffected and unit-tested\\n (`packages/react-native-gtkx/tests/unit/svg/gradient-geometry.test.ts`) —\\n gradients will render as soon as this is fixed upstream, with no changes\\n needed on either side.\\n- **Animated**: the numeric props above (shape geometry, `opacity`,\\n `strokeWidth`, `strokeDashoffset`) accept an `Animated.Value`/\\n interpolation in place of a number. A tick mutates the widget\\'s paint\\n state directly and calls `queueDraw()` — the same bypass-React pattern\\n `Animated.View` uses for `transform` (`setStoredTransform` +\\n `queueAllocate`), just on its own invalidation channel since none of this\\n touches Yoga. `G`\\'s `transform` string and `d`/`points` are not\\n Animated-aware (they are strings, not numbers).\\n- Not in scope: `<Text>`/`<TSpan>` on a path, `<Mask>`, `<ClipPath>`, SVG\\n filters, `<Use>`/`<Symbol>`/`<Pattern>`, and rasterizing arbitrary SVG\\n strings at runtime (`SvgXml` — `Image` already covers SVG **files**). None\\n of these have a real consumer yet; `Path`/`Rect`/`Circle`/`Ellipse`/\\n `Line`/`Polygon`/`Polyline`/`G` cover icons, charts and indicators, the\\n overwhelming majority of real usage.',\n },\n {\n doc: \"docs/api.md\",\n heading: \"`react-native-svg` compatibility (`react-native-gtkx/svg`)\",\n text: '`react-native-gtkx/svg` re-exports the same set in `react-native-svg`\\'s\\nshape (`Svg` as both the default and a named export). The `react-native-gtkx/\\nmetro` and `react-native-gtkx/vite` presets alias the bare `react-native-svg`\\npackage name to it automatically, the same way they alias `react-native`\\nitself — so portable code that imports from `react-native-svg` runs\\nunmodified:\\n\\n```tsx\\nimport Svg, { Circle, Path } from \"react-native-svg\"\\n```\\n\\nApps using neither preset can point their own bundler alias at\\n`react-native-gtkx/svg` by hand. `react-native-svg` itself is never a\\ndependency of this package and does not need to be installed — the alias\\nworks whether or not the real package is present.',\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"Why you would reach for it\",\n text: \"- A GTK capability that React Native has no concept of: a real\\n `Adw.NavigationView` stack, a `GtkListBox` row, a native `GtkEntry`.\\n- Your own router, or no router: drive navigation from `useState`, a reducer,\\n a URL, a state machine.\\n- A property we did not think to surface in the navigator's options. Every\\n widget below is re-exported straight from the gtkx bindings, so the full\\n GObject property and signal surface is yours — including properties added\\n to gtkx after this page was written.\",\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"Declarative primitives\",\n text: \"These are the two components we wrap, because a raw `Adw.NavigationView` is\\nimperative (`push`, `pop`, `pop_to_tag`) and React is not.\\n\\n| Export | What it is |\\n| --------------------- | ------------------------------------------------------ |\\n| `NavigationStack` | `Adw.NavigationView` driven by a `stack` array of tags |\\n| `NavigationStackPage` | one page of that stack, identified by `tag` |\\n\\nThey **inherit every prop of the underlying widget** and only add to it, so\\nanything you could set on `Adw.NavigationPage` you can set on\\n`NavigationStackPage`.\",\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"React Native content inside GTK slots\",\n text: \"| Export | Sizing | Use for |\\n| ------------------ | ---------------------------- | ------------------------------------------------ |\\n| `SlotContent` | fills the slot | a page body, a pane, a dialog body |\\n| `IntrinsicContent` | sized by its own Yoga layout | an AdwHeaderBar slot, a toolbar area, a list row |\",\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"GTK widgets, driven by React Native\",\n text: 'Every `GtkWidget` subclass gtkx binds — 87 of them at last count, from\\n`GtkBox` and `GtkButton` to `GtkColumnView` and `GtkEmojiChooser`. The list is\\ngenerated, not hand-picked: `scripts/generate-widget-surface.ts` classifies\\ngtkx\\'s full binding by real GObject inheritance (see\\n`scripts/widget-surface/classification.json` for the exact list gtkx binds\\ntoday) and `src/gtk/widgets.generated.ts` is the committed result. Re-run the\\ngenerator after a gtkx upgrade to pick up new widgets — it diffs against its\\nown previous output and prints what changed.\\n\\nThey keep **every prop gtkx binds** and gain `style` and `onLayout`. Position\\nand appearance both come from the style prop, exactly like anywhere else in\\nReact Native:\\n\\n```tsx\\n<View style={{ flexDirection: \"row\", gap: 8, alignItems: \"center\" }}>\\n <GtkEntry\\n style={{ flex: 1 }}\\n placeholderText=\"Filter\"\\n />\\n <GtkButton\\n style={{ width: 72, backgroundColor: \"#3584e4\", borderRadius: 6 }}\\n label=\"Go\"\\n />\\n</View>\\n```\\n\\nThe entry flexes, the button takes its width and its colour. The layout half\\nof the style drives Yoga; the visual half becomes a GTK CSS class **on the\\nwidget itself**, so the button really is blue, not a blue box behind a button.\\nSet no size and the widget\\'s own natural size wins.\\n\\n**Outside React Native layout they step aside.** The same `GtkButton` dropped\\ninto a `AdwHeaderBar`\\'s `start` or a `AdwToolbarView`\\'s `topBar` — where there is no\\nYoga tree to join — renders as the bare widget. One symbol, both worlds, no\\nflag to remember.',\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"Unwrapped by necessity\",\n text: \"Two families of widget are exported **raw** instead of wrapped, because a\\nwrapper box around them would be invalid GTK rather than a convenience:\\n\\n- **toplevels** — `GtkWindow` and everything that derives it: every\\n `Gtk*Dialog`, `GtkApplicationWindow`, `GtkAssistant`, `GtkShortcutsWindow`,\\n and their Adwaita counterparts (`AdwWindow`, `AdwApplicationWindow`,\\n `AdwAboutWindow`, `AdwMessageDialog`, `AdwPreferencesWindow`). A wrapper box\\n around a window is not a layout, it is two windows.\\n- **child-only widgets** — valid solely as the direct child of one specific\\n parent. `GtkListBoxRow` and `GtkFlowBoxChild` (plus everything that derives\\n them — every Adwaita preferences row, `AdwActionRow` included) are caught\\n mechanically, by real inheritance. `AdwNavigationPage` and\\n `AdwPreferencesPage` derive `Gtk.Widget` directly with no shared base to\\n catch them mechanically, so they are a two-entry, doc-verified denylist\\n instead — see `scripts/widget-surface/classify.ts` for the exact reasoning\\n behind each.\\n\\n`GtkGestureClick` is a third, simpler case: an event controller, not a\\nwidget at all, so it was never a candidate for wrapping in the first place.\\n\\nNothing here is unreachable — every raw export above is still exported,\\nby name, from `react-native-gtkx/gtk` or `/adw`, exactly as gtkx binds it.\",\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"Auxiliary objects, not widgets at all\",\n text: 'A further set of real JSX elements gtkx provides are not `Gtk.Widget` or\\n`Adw.Widget` subclasses either, so `scripts/generate-widget-surface.ts`\\nnever sees them at all — same reason `GtkGestureClick` above is hand-kept\\nrather than generated, just a wider set: actions and menus (`GSimpleAction`,\\n`GMenu`), a responsive breakpoint (`AdwBreakpoint`), one option of an\\n`AdwToggleGroup` (`AdwToggle` — a segmented-control entry, not a widget of\\nits own) and the two leaf elements an `AdwShortcutsDialog` is built from\\n(`AdwShortcutsSection`, `AdwShortcutsItem`), a text buffer and an\\nadjustment — the model objects `GtkTextView`/spin- and scale-style widgets\\nbind to (`GtkTextBuffer`, `GtkAdjustment`), keyboard shortcuts\\n(`GtkShortcut`, `GtkShortcutController`), and the two drag-and-drop\\ncontrollers (`GtkDragSource`, `GtkDropTarget`). All of them are exported, by\\nname, from `react-native-gtkx/gtk` or `/adw`, next to `GtkApplication` and\\n`GtkGestureClick`.\\n\\n```tsx\\n<GtkApplicationWindow\\n actions={\\n <GSimpleAction\\n name=\"new\"\\n onActivate={onNew}\\n />\\n }\\n breakpoints={\\n <AdwBreakpoint\\n condition={Adw.BreakpointCondition.parse(\"max-width: 500sp\")}\\n onApply={() => setCollapsed(true)}\\n onUnapply={() => setCollapsed(false)}\\n />\\n }\\n/>\\n```\\n\\n**One caveat found while building `examples/tasks-app`, worth knowing before\\nyou rely on it in a test:** `AdwBreakpoint`\\'s `onApply`/`onUnapply` never\\nfired in the `@gtkx/vitest` headless-sway gtk test project, even with a\\ngenuine `swaymsg` resize past the condition\\'s threshold (see\\n`packages/react-native-gtkx/tests/gtk/bridge/auxiliary-elements.gtk.test.tsx`)\\n— but it works exactly as documented in a real GNOME session (verified with\\na throwaway app launched via `node scripts/vm.ts app`). Treat it as untestable\\nunder headless sway today, not as broken.',\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"The window and application AppRegistry built\",\n text: '`useParentWindow` (the `Gtk.Window` ancestor), `useApplication` (the\\n`Adw.Application` — `.sendNotification(id, notification)` is the common\\nreason to reach it) and `quit` (the same function `AppRegistry` wires to a\\nwindow\\'s own close button) are re-exported from `react-native-gtkx/gtk`.\\nNone of these give you the window or application object ITSELF to build —\\n`AppRegistry.runApplication` already did that — they let already-mounted\\ncode reach back into it, the same way `useBindSetting` needs a `Gtk.Window`\\nto bind a `defaultWidth` property on:\\n\\n```tsx\\nconst window = useParentWindow()\\nuseBindSetting({\\n schema,\\n key: \"window-width\",\\n object: window,\\n property: \"defaultWidth\",\\n})\\n```',\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"GSettings\",\n text: '`useSetting` and `useBindSetting` come straight from `@gtkx/react`, re-\\nexported from `react-native-gtkx/gtk` next to the `Gio` namespace they read\\nand write through:\\n\\n```tsx\\nconst [value, setValue] = useSetting(schema, \"color-scheme\")\\nuseBindSetting({\\n schema,\\n key: \"window-width\",\\n object: windowRef,\\n property: \"defaultWidth\",\\n})\\n```\\n\\nTurning a `.gschema.xml` file into the `SettingsSchema` object these hooks\\nexpect (`{ id, path, keys }`) is a build-time concern, not something this\\nsubpath does — `#data/your-schema.gschema.xml` resolves for free on the\\n`gtkx dev`/`gtkx build` toolchain (the `gtkx:settings` vite plugin ships\\ninside `@gtkx/cli` itself), the same way `examples/tasks-app` uses it. It is\\nnot wired into the Metro toolchain (`react-native run-linux`) at all — an\\napp on that path has to construct the `SettingsSchema` object by hand\\n(`{ id, path, keys: { \"key-name\": \"s\" } }`, matching the schema\\'s own type\\nstrings) or add its own build step.',\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"Adwaita structure\",\n text: 'Every `Adw.Widget` subclass gtkx binds — 46 wrapped the same way as the GTK\\nwidgets above, from `AdwAvatar` and `AdwCarousel` to `AdwToolbarView` and\\n`AdwViewSwitcher`. `AdwHeaderBar` and `AdwToolbarView` now take `style` too,\\nand still step aside into the bare widget in a slot that has no Yoga tree —\\n`AdwToolbarView`\\'s own `topBar` is exactly that kind of slot:\\n\\n```tsx\\n<View style={{ flex: 1 }}>\\n <AdwToolbarView\\n style={{ flex: 1 }}\\n topBar={<AdwHeaderBar showTitle={false} />}\\n >\\n <SlotContent>{/* … */}</SlotContent>\\n </AdwToolbarView>\\n</View>\\n```\\n\\n`AdwNavigationView` and `AdwNavigationSplitView` are wrapped the same way;\\n`NavigationStack` above is a declarative layer on top of the former, not a\\nreplacement for it — the raw widget is always one import away.\\n\\n`AdwApplicationWindow` (a toplevel) and `AdwNavigationPage` (valid only as a\\ndirect child of `AdwNavigationView`/`AdwNavigationSplitView`) are exported\\nraw — see \"Unwrapped by necessity\" above.',\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"Namespaces\",\n text: \"`Adw`, `Gdk`, `Gio`, `Gtk`, `Pango` — exported as values, because you need\\nboth the runtime enums and the types:\\n\\n```tsx\\n;<GtkScrolledWindow hscrollbarPolicy={Gtk.PolicyType.NEVER} />\\nconst viewRef = useRef<Adw.NavigationView | null>(null)\\n```\",\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"Navigation without a router\",\n text: 'The stack is an array of tags. Change the array, the widget animates.\\n\\n```tsx\\nimport { useState } from \"react\"\\nimport { Pressable, Text, View } from \"react-native\"\\nimport {\\n AdwHeaderBar,\\n AdwToolbarView,\\n NavigationStack,\\n NavigationStackPage,\\n SlotContent,\\n} from \"react-native-gtkx/gtk` and `react-native-gtkx/adw\"\\n\\nconst App = () => {\\n const [stack, setStack] = useState([\"home\"])\\n\\n return (\\n <NavigationStack\\n stack={stack}\\n // The Adwaita back button, Escape, the back gesture and the\\n // back-history menu all arrive here. Follow them in your own state.\\n onPopped={(tag) => setStack((s) => s.filter((entry) => entry !== tag))}\\n >\\n <NavigationStackPage\\n tag=\"home\"\\n title=\"Home\"\\n >\\n <AdwToolbarView topBar={<AdwHeaderBar />}>\\n <SlotContent>\\n <Pressable onPress={() => setStack((s) => [...s, \"detail\"])}>\\n <Text>Open detail</Text>\\n </Pressable>\\n </SlotContent>\\n </AdwToolbarView>\\n </NavigationStackPage>\\n\\n <NavigationStackPage\\n tag=\"detail\"\\n title=\"Detail\"\\n >\\n <AdwToolbarView topBar={<AdwHeaderBar />}>\\n <SlotContent>\\n <View />\\n </SlotContent>\\n </AdwToolbarView>\\n </NavigationStackPage>\\n </NavigationStack>\\n )\\n}\\n```\\n\\nA runnable version is `examples/adwaita-primitives` — three levels deep, with\\nReact Native content in the header bar and a raw `GtkButton` beside it.',\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"`NavigationStack` props\",\n text: \"Everything `Adw.NavigationView` has, plus:\\n\\n| Prop | Meaning |\\n| ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\\n| `stack` | ordered page tags, root first. This is the navigation state |\\n| `animateTransitions` | forwarded straight to `Adw.NavigationView`'s own property. Default true — GTK has one transition style, so this is only ever on/off |\\n| `onPopped(tag)` | the WIDGET popped by itself. Not called for pops you caused by changing `stack` |\\n| `onPageClosed(tag)` | a closing page finished animating out and left the tree |\\n| `onTransitionStart()` / `onTransitionEnd()` | a push/pop/replace began / finished, the latter driven by the transitioning page's own `shown`/`hidden` signal |\\n| `transitionDuration` | ms, default 400 — a fallback window for retention and the callbacks above, used only when a page's own transition signal never arrives; not a measurement of the real transition length |\\n| `ref` | the `Adw.NavigationView` itself, for anything not modelled here |\\n\\nPages not listed in `stack` are still accepted as children and simply are not\\nshown, so a router may hand over all of its screens at once.\\n\\n**Exit animations are handled for you.** When a tag leaves `stack`, the widget\\nstill animates the page out. `NavigationStack` keeps a snapshot of that page\\nuntil its `hidden` signal (with a timer fallback for two cases where that\\nsignal never arrives on its own: compositors that never emit it, and a page\\nskipped over entirely by a multi-hop pop — see `transitionDuration` above),\\nso you never have to keep rendering pages you already consider gone.\",\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"React Native content in native chrome\",\n text: 'An AdwHeaderBar slot wants a widget that knows its own size, which is what\\n`IntrinsicContent` provides:\\n\\n```tsx\\n<AdwHeaderBar\\n start={\\n <IntrinsicContent>\\n <Text>{stack.length} deep</Text>\\n </IntrinsicContent>\\n }\\n end={[\\n <GtkButton\\n key=\"home\"\\n iconName=\"go-home-symbolic\"\\n onClicked={reset}\\n />,\\n ]}\\n/>\\n```',\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"Two ways to react to size\",\n text: 'Two mechanisms answer two different questions, and neither is a replacement\\nfor the other:\\n\\n- **\"Render different content at different widths\"** — `useWindowDimensions`\\n (from `react-native`, portable, already exists). A resize triggers a React\\n render, your component reads the new width, you return different JSX.\\n This is the right and ONLY tool for anything that changes what is\\n rendered — swapping a filter bar for a compact one, hiding a column,\\n changing text.\\n- **\"Flip a widget property natively at a threshold, with no render at all\"**\\n — `AdwBreakpoint` + `AdwBreakpointBin`. `Adw.Breakpoint` is a condition\\n (a size/aspect-ratio threshold) plus a set of property setters: when the\\n condition starts holding, each setter writes its value onto its target\\n object\\'s property directly, through GObject, inside GTK\\'s own allocation\\n pass; when the condition stops holding, the setter puts the property back\\n to whatever it held before. **No React commit, no Yoga pass, no JS\\n callback runs for the flip itself** — a resize costs nothing beyond what\\n GTK\\'s layout was already doing.\\n\\n `Adw.Breakpoint` is not a widget — verified against the real binding,\\n `Adw.Breakpoint.prototype instanceof Gtk.Widget` is `false`; its\\n prototype chain bottoms out at plain `GObject.Object`. It draws nothing\\n and occupies no space, so it is exported raw (`AdwBreakpoint`, from\\n `react-native-gtkx/adw`), the same way `GtkGestureClick` is: running it\\n through `wrapReactNative` would hand it a Yoga node for something that\\n is not a rectangle, which is a layout bug, not a convenience.\\n `Adw.BreakpointBin` (`AdwBreakpointBin`) IS a real widget — a container\\n that scopes breakpoints to its own child subtree instead of a whole\\n window — and is wrapped normally, taking `style`/flex like anything else\\n here.\\n\\n A breakpoint\\'s setters may only target widgets INSIDE the\\n `AdwBreakpointBin` they are attached to, never the bin itself — so the\\n widget whose property you want to flip must be the bin\\'s child:\\n\\n ```tsx\\n import { Adw, AdwBreakpoint, AdwBreakpointBin } from \"react-native-gtkx/adw\"\\n\\n const splitViewRef = useRef<Adw.NavigationSplitView | null>(null)\\n const breakpointRef = useRef<Adw.Breakpoint | null>(null)\\n\\n useEffect(() => {\\n if (!splitViewRef.current || !breakpointRef.current) return\\n const collapsed = new GObject.Value()\\n collapsed.init(GObject.typeFromName(\"gboolean\"))\\n collapsed.setBoolean(true)\\n breakpointRef.current.addSetter(splitViewRef.current, \"collapsed\", collapsed)\\n }, [])\\n\\n <AdwBreakpointBin\\n breakpoints={\\n <AdwBreakpoint\\n ref={breakpointRef}\\n condition={Adw.BreakpointCondition.newLength(\\n Adw.BreakpointConditionLengthType.MAX_WIDTH,\\n 500,\\n Adw.LengthUnit.SP,\\n )}\\n />\\n }\\n >\\n <AdwNavigationSplitView ref={splitViewRef} …>…</AdwNavigationSplitView>\\n </AdwBreakpointBin>\\n ```\\n\\n `addSetter` wants a genuine, boxed `GObject.Value` — found empirically: a\\n bare JS `true` fails a `G_IS_VALUE` assertion on the native side, it does\\n not silently coerce. `createSidebarNavigator`\\'s own `collapseWidth` (see\\n below) is built on exactly this pair; reading `collapsed`/`showContent`\\n back (e.g. to decide whether a click should also reveal content) is a\\n plain native property read through the same ref, not React state — so\\n neither the flip nor a read of it costs a render.\\n\\nNo `useBreakpoint(condition) → boolean` hook exists, and none is planned:\\nit would return a flag to JS and trigger a re-render on every crossing,\\nwhich is precisely what `useWindowDimensions` already does — a second name\\nfor the first mechanism, with none of the second\\'s native-setter value.\\nIf what you want is \"my component\\'s JSX changes\", reach for\\n`useWindowDimensions`; only reach for `AdwBreakpoint` when the thing that\\nshould change is a widget property GTK itself owns, and you want that\\nchange to cost nothing.',\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"Mixing with react-navigation\",\n text: \"They compose, because the navigator is built on these primitives. Use\\n`react-native-gtkx/navigation` for the app's structure and drop to\\n`react-native-gtkx/gtk` and `react-native-gtkx/adw` where you need a widget the options do not cover —\\nfor example a raw `GtkButton` in `headerButtons`, or a `GtkListBox` inside a\\nscreen.\\n\\nKeeping portable code portable: put Linux-only UI behind a `.linux.tsx`\\nplatform extension, or behind `Platform.select({ linux: … })`. Options a\\nplatform does not understand are ignored, and in development the navigator\\nwarns with the screen and option name rather than swallowing them silently.\",\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"Wrapping a widget we do not export\",\n text: 'The generated surface above covers every current `Gtk.Widget`/`Adw.Widget`\\nsubclass gtkx binds, but \"current\" is doing work in that sentence: a gtkx\\nrelease can add a widget before this package\\'s generator has been re-run for\\nit, and non-widget GI classes (an event controller, a filter, an adjustment)\\nwere never candidates for the widget surface in the first place even though\\na handful of them are occasionally worth putting inside RN layout too.\\n`wrapReactNative` is how you reach either without waiting on us — it is\\ngeneric, so the widget\\'s own props keep their types:\\n\\n```tsx\\nimport { GtkPopover } from \"@gtkx/jsx/gtk\"\\nimport { wrapReactNative } from \"react-native-gtkx/gtk` and `react-native-gtkx/adw\"\\n\\nconst Popover = wrapReactNative(GtkPopover)\\n// <Popover style={{ width: 240 }} autohide … /> — `autohide` still typed\\n```\\n\\n(`GtkPopover` here is already part of the generated surface — this is the\\nsame mechanism `src/gtk/widgets.generated.ts` uses under the hood, just\\napplied by hand. It stays useful the day gtkx binds something this package\\nhas not regenerated for yet.)\\n\\nTwo lower-level forms exist for cases the wrapper does not fit:\\n\\n- `<Widget style={…}>` — wrap an element you already have in hand;\\n- `useWidgetLayout(ref, { style })` — attach layout to a widget whose ref you\\n own, with no wrapper component at all. Returns the GTK CSS class from the\\n style\\'s visual half, for you to pass to `cssClasses`.',\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"The escape hatch\",\n text: \"If something is missing, reach the widget directly:\\n\\n```tsx\\nconst viewRef = useRef<Adw.NavigationView | null>(null)\\n<NavigationStack ref={viewRef} stack={stack}>…</NavigationStack>\\n// viewRef.current is the real Adw.NavigationView\\n```\\n\\nThere is deliberately no wall here. A missing convenience should cost you one\\nline, not a fork.\",\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"Related\",\n text: \"- [API v1](api.md) — the portable React Native surface.\\n- [Navigation research](research/navigation-extensibility.md) — how the\\n adapter maps react-navigation onto these primitives.\\n- [What we need from gtkx](upstream-gtkx.md) — the upstream agenda.\",\n },\n {\n doc: \"docs/getting-started.md\",\n heading: \"Requirements\",\n text: \"- Linux (x64/arm64, glibc), GTK4 ≥ 4.20, libadwaita ≥ 1.8 (Ubuntu 26.04+, Fedora 43+);\\n- Node.js ≥ 24;\\n- dev packages: `sudo apt install libgtk-4-dev libadwaita-1-dev` (Ubuntu).\",\n },\n {\n doc: \"docs/getting-started.md\",\n heading: \"New project from the template\",\n text: \"```bash\\nnpx degit itsmepetrov/react-native-gtkx/template my-app && cd my-app\\nnpm install\\nnpm run dev # window with Fast Refresh (edits apply without a restart)\\nnpm run build && npm start # production bundle, runs with plain node\\n```\\n\\nMeasured in a clean Ubuntu 26.04 container: 63 seconds from install to a window on screen.\",\n },\n {\n doc: \"docs/getting-started.md\",\n heading: \"How it works\",\n text: '```\\nyour code (react-native API)\\n └─ vite preset: aliases react-native → react-native-gtkx, platform\\n extensions .linux.tsx → .native.tsx → base\\n └─ react-native-gtkx: Yoga (WASM) computes flexbox; styles are split into\\n layout (Yoga) and visual (GTK CSS); coordinates are applied to\\n real GTK widgets\\n └─ gtkx: React reconciler → GTK4 via FFI\\n```\\n\\nThe entry point is the same as in RN:\\n\\n```tsx\\nimport { AppRegistry, StyleSheet, Text, View } from \"react-native\"\\n\\nconst App = () => (\\n <View style={styles.screen}>\\n <Text style={styles.title}>Hello, GNOME!</Text>\\n </View>\\n)\\n\\nconst styles = StyleSheet.create({\\n screen: { flex: 1, alignItems: \"center\", justifyContent: \"center\" },\\n title: { fontSize: 24, fontWeight: \"700\" },\\n})\\n\\nAppRegistry.registerComponent(\"app\", () => App)\\nAppRegistry.runApplication(\"app\", { title: \"My App\", width: 800, height: 600 })\\n```\\n\\n`runApplication` accepts desktop parameters (`title`, `width`, `height`) — the only extension over the RN signature.',\n },\n {\n doc: \"docs/getting-started.md\",\n heading: \"Add Linux to an existing React Native app\",\n text: 'Linux is an [out-of-tree platform](https://reactnative.dev/docs/out-of-tree-platforms)\\n(the react-native-windows/macOS model): your app keeps its ios/ and\\nandroid/ folders, its Metro/Babel toolchain, and gains one more target.\\nFour steps:\\n\\n1. **Install the platform package:**\\n\\n ```bash\\n npm install react-native-gtkx\\n ```\\n\\n Its own `react-native.config.js` declares the `linux` platform and the\\n `run-linux` command — nothing to declare app-side.\\n\\n2. **Wrap your Metro config** (`metro.config.js`):\\n\\n ```js\\n const { getDefaultConfig } = require(\"@react-native/metro-config\")\\n const { withLinuxPlatform } = require(\"react-native-gtkx/metro\")\\n\\n module.exports = withLinuxPlatform(getDefaultConfig(__dirname))\\n ```\\n\\n The wrap adds the platform (`.linux.tsx` extensions,\\n `Platform.OS === \"linux\"`), redirects `react-native` imports to the\\n platform package, and keeps host-side modules (GTK bindings, react,\\n yoga) out of the bundle. Babel stays completely stock.\\n\\n3. **Add `gtkx.config.ts`** with the GTK application id:\\n\\n ```ts\\n import { defineConfig } from \"@gtkx/config\"\\n\\n export default defineConfig({\\n libraries: [\"Gtk-4.0\", \"Adw-1\"],\\n applicationId: \"com.example.myapp\",\\n })\\n ```\\n\\n4. **Start the app from the entry** — on desktop the entry launches the\\n app itself (the same pattern as react-native-web\\'s `index.web.js`):\\n\\n ```js\\n // index.js, after AppRegistry.registerComponent(...)\\n if (Platform.OS === \"linux\") {\\n AppRegistry.runApplication(appName, {\\n title: \"My App\",\\n width: 800,\\n height: 600,\\n })\\n }\\n ```\\n\\nRun it:\\n\\n```bash\\nnpx react-native run-linux # release bundle\\nnpx react-native run-linux --dev # Metro dev server + Fast Refresh\\n```\\n\\nThe command ensures the gtkx codegen store, bundles with Metro for\\n`--platform linux` and opens the window. With `--dev` it starts (or\\nreuses) the Metro dev server and edits apply to the live window with\\ncomponent state preserved; syntax errors print readably in the terminal\\nand the app recovers on the next successful build. **Ctrl+Shift+D** (the\\nreact-native-windows shortcut — the desktop stand-in for the shake\\ngesture) opens the Dev Menu: Reload plus any entries the app registers\\nvia `DevSettings.addMenuItem`. `examples/rn-app` is a complete cli-init\\napp with all three platforms wired this way.\\n\\n`run-linux` always runs what it builds — for a release build that stops\\nshort of opening a window (packaging, CI, handing a bundle to someone\\nelse\\'s machine), use `build-linux` instead; see\\n[Shipping an app](#shipping-an-app) below for what it produces and what\\nrunning it later needs.\\n\\nNotes for typed code: add an `env.d.ts` with\\n`import \"react-native-gtkx/types\"` — it augments the stock `react-native`\\ntypes so `Platform.select({ linux: ... })` typechecks, and `Pressable`\\'s\\nstate callback accepts `hovered` (declared optional — a component shared\\nwith ios/android gets `undefined` there, so write\\n`hovered && styles.hovered`). Future platform-specific props land in the\\nsame file. One thing augmentation\\ncannot teach is `Platform.OS === \"linux\"` (property types do not merge) —\\nuse `Platform.select` in typed code. Deep imports\\n(`react-native/Libraries/...`) are not supported — only the public\\n`react-native` surface.',\n },\n {\n doc: \"docs/getting-started.md\",\n heading: \"Navigation\",\n text: \"Multi-screen apps use the standard react-navigation API with a native\\nAdwaita stack navigator: install `@react-navigation/native` and import\\n`createStackNavigator` from `react-native-gtkx/navigation` — pages render\\nas `Adw.NavigationPage` with the HeaderBar back button wired to\\nreact-navigation state. See [docs/api.md](api.md#navigation-react-native-gtkxnavigation), and\\n[docs/research/navigation-extensibility.md](research/navigation-extensibility.md)\\nfor porting an existing react-navigation app (which options carry over,\\nwhich are silently ignored today, and what the desktop cannot mean).\",\n },\n {\n doc: \"docs/getting-started.md\",\n heading: \"Svg\",\n text: '`<Svg>`/`<Path>`/`<Circle>` and the rest of the vector-graphics API come from\\n`react-native-svg`, not from `react-native-gtkx` itself — matching every\\nother platform, where `react-native-svg` is a separate package too (RN has\\nno built-in `Svg`). See [docs/api.md](api.md#svg) for the component set and\\n[the compat-subpath section](api.md#react-native-svg-compatibility-react-native-gtkxsvg)\\nfor how both presets alias the bare `react-native-svg` import to it.\\n\\nThat alias is a bundler-level rewrite, so TypeScript still needs its own\\nanswer for the specifier `\"react-native-svg\"` — an unresolved import in the\\neditor even though the build works fine. Which fix applies depends on what\\nthe project targets:\\n\\n- **Also ships to iOS/Android/web**: install the real `react-native-svg` —\\n the app needs it on those platforms regardless. `react-native-svg` ships\\n its own `.d.ts` (no separate `@types` package exists or is needed), so\\n TypeScript resolves real, complete types for the specifier; the Linux\\n build never actually executes that package\\'s code — the preset rewrites\\n the import to `react-native-gtkx/svg` before it reaches Node. Nothing\\n react-native-gtkx-specific to configure.\\n- **Linux-only project** (the template, or an app with no mobile target):\\n add `react-native-svg` as a **devDependency purely for its types** —\\n `npm install -D react-native-svg`. This is the ordinary fix for a\\n bundler-alias setup once the aliased name has no real package installed —\\n the same shape as react-native-web\\'s own TypeScript guidance (install a\\n real, type-bearing package alongside the alias rather than fabricate\\n one). Side benefit: if this package\\'s compat surface ever drifts from\\n upstream `react-native-svg`\\'s props (see the \"Deliberate gaps\" note in\\n `packages/react-native-gtkx/src/svg-compat/index.ts`), the mismatch shows\\n up as a type error instead of compiling silently.\\n\\nWe deliberately did not ship an ambient `declare module \"react-native-svg\"`\\n— the trick `react-native-gtkx/types` uses to teach the stock `react-native`\\ntypes about the `linux` platform. That works there because it only\\n_augments_ an already-resolved module (interfaces merge). Here the module\\ndoes not resolve at all without one of the two installs above, so the shim\\nwould have to declare the whole module unconditionally to help — and a\\nproject that installs the real `react-native-svg` later (adding a mobile\\ntarget) would then carry two declarations of the same module, the shim and\\nthe real package\\'s own, colliding. Installing the real package, even only\\nas a devDependency, never has that problem: there is only ever one\\ndeclaration of `\"react-native-svg\"` in play.',\n },\n {\n doc: \"docs/getting-started.md\",\n heading: \"Metro or vite?\",\n text: \"- **Adding Linux to an existing RN app** (ios/android + Metro): the\\n section above — standard RN toolchain end to end,\\n `run-linux --dev` for Fast Refresh.\\n- **Linux-first project**: the template with the vite preset\\n (`react-native-gtkx/vite`; `gtkx dev` gives Fast Refresh, builds are\\n single-file bundles). Both paths consume the same published package.\",\n },\n {\n doc: \"docs/getting-started.md\",\n heading: \"Shipping an app\",\n text: \"The two paths get you from source to something installable differently,\\nbecause they take different positions on what stays out of the bundle.\\n\\n**vite path** (`gtkx build`): everything except the native GTK addon is\\ninlined into one file. `dist/bundle.js` + `dist/gtkx.node` (plus\\n`dist/gschemas.compiled` if the app declares a GSettings schema — the\\nbundle's own banner points `GSETTINGS_SCHEMA_DIR` at its own directory) is\\nthe whole runtime: copy those anywhere with Node ≥24, GTK4 ≥4.20 and\\nlibadwaita ≥1.8, and `node bundle.js` runs it. No `node_modules` involved.\\n\\n**Metro path** (`react-native build-linux`): the release counterpart to\\n`run-linux` that iOS, Android and react-native-windows already have and\\nthis platform did not until now — it bundles with Metro and stops, instead\\nof bundling and immediately running like `run-linux` does:\\n\\n```bash\\nnpx react-native build-linux # writes dist/main.jsbundle\\n```\\n\\nThis is **not** self-contained, unlike the vite path. Metro deliberately\\nkeeps `@gtkx/*`, `react` and `yoga-layout` out of the bundle — they have to\\nbe the exact instances the Node+GTK host loads, not a second copy Metro\\ninlines (see `packages/react-native-gtkx/src/metro/index.ts`,\\n`HOST_MODULE_EXTERNALS`, for why). So running `dist/main.jsbundle` needs,\\non top of Node ≥24/GTK4/libadwaita, a real `node_modules` with\\n`react-native-gtkx` installed and the app's `gtkx.config.ts` present at the\\nworking directory:\\n\\n```bash\\nnode node_modules/react-native-gtkx/dist/runner/host.js dist/main.jsbundle\\n```\\n\\n(run from the app root — the config loader reads `gtkx.config.ts` from the\\ncurrent directory, exactly like `run-linux` itself). Any ordinary\\n`npm install` of the app already has that `node_modules`; the difference\\nfrom the vite path only matters when packaging for a machine that never\\nran one — see `scripts/build-deb.ts`'s Metro branch, which builds that\\nclosure itself: a fresh, isolated install of the locally-packed\\n`react-native-gtkx` plus `gtkx codegen`, never a copy of a monorepo's own\\nhoisted `node_modules` (which would prove nothing about what a real install\\nneeds).\\n\\nThat is the **default** artifact, and it is the only one that carries the\\n`node_modules` caveat. `--standalone` below removes it entirely: the same\\nMetro build, emitted as one self-contained file that runs on a system Node\\nwith nothing installed beside it — the vite path's shape, on the Metro\\npath.\",\n },\n {\n doc: \"docs/getting-started.md\",\n heading: \"One file (Metro path)\",\n text: \"`build-linux` produces three artifacts. Which one you want is a question\\nabout the delivery channel, not about the build — they share the same\\nMetro step and differ only in how much of the runtime travels with the\\napp:\\n\\n| Flag | Artifact | Needs installed | Size (`hn-app`, linux-arm64) |\\n| -------------- | -------------------------- | ---------------------------------- | ---------------------------- |\\n| _(none)_ | `dist/main.jsbundle` | a `node_modules` tree **and** Node | 0.4 MB + the tree |\\n| `--standalone` | `dist/<name>.cjs` | Node only (`Depends: nodejs`) | 6.9 MB |\\n| `--sea` | `dist/<name>` (executable) | nothing at all | 104 MB (30 MB compressed) |\\n\\n```bash\\nnpx react-native build-linux --standalone # in the app root\\nnode ./dist/<your-package-name>.cjs # one script, system node\\n\\nnpx react-native build-linux --sea\\n./dist/<your-package-name> # one executable, nothing else\\n```\\n\\nBoth flags produce the jsbundle exactly as before, then one additional\\nfile next to it. `--sea-output <path>` overrides where it goes; the\\ndefault is `dist/<package name>` with any npm scope stripped (plus `.cjs`\\nfor `--standalone`).\\n\\n**Pick `--standalone` for anything installed through a package manager.**\\nIt is the same shape gtkx's own packaging produces and the same shape the\\nvite path already ships in its `.deb` — a bundle plus a `nodejs`\\ndependency — and it is the lightest of the three by any measure that\\ncounts: the plain jsbundle looks smaller only because its `node_modules`\\ntree is not weighed. **Pick `--sea` for \\\"download this one file and run\\nit\\\"**, where nothing can be assumed to be installed. They are not\\ncompeting implementations: `--sea` is `--standalone` with a copy of Node\\nwrapped around it, and that copy is the entire 97 MB between them.\\n\\nA tagged release of this repo publishes the `--sea` executable for\\n`hn-app`, `zstd`-compressed, alongside the `.deb`s (`zstd -d` it and run\\nit). The `.deb`s remain how you install these apps; the executable is\\nthere for the machine that has no Node to depend on.\\n\\nThat copy is stripped of its debug symbols as part of the build, which is\\nnot a micro-optimisation: the `node` binary NodeSource distributes for\\nUbuntu ships `with debug_info, not stripped` — 117 MB, 98 MB after\\n`strip --strip-all` — so 19 MB of every unstripped SEA is debug\\ninformation for Node's own C++, which nothing in a shipped app can use.\\nThe step is best-effort: a build machine without binutils gets a warning\\nand a larger executable, not a failed build. It also runs strictly before\\npostject, since `--strip-all` removes exactly the kind of non-allocated\\nsection the injected blob is. What remains after that is Node itself, and\\nit does not compress away either — but it does compress: 30 MB with\\n`zstd -19`, which is what a download actually costs.\\n\\nThe native addon (`@gtkx/native-*.node`, a real `dlopen`ed library) cannot\\nbe JavaScript, so both artifacts carry it as bytes — a SEA asset in the\\nexecutable, a base64 literal in the `.cjs` — and extract it to\\n`$XDG_CACHE_HOME/react-native-gtkx-sea` on first run, keyed by content\\nhash. That is what keeps \\\"one file\\\" honest in both cases.\\n\\nNothing extra to install to bundle it. That work is done by **rolldown**,\\nwhich is vite's own engine — vite 8 depends on it outright, `@gtkx/cli`\\ndepends on vite, and this package depends on `@gtkx/cli`, so it is already\\nin every install. (esbuild, which gtkx's tutorial uses for the same job,\\nwould have been the one genuinely new bundler in the tree: vite 8 lists it\\nas an _optional_ peer and does not install it.)\\n\\nOne thing `--sea` does need that a plain `build-linux` does not: **the\\ngtkx codegen store**, and therefore GTK development headers on the build\\nmachine. A plain `build-linux` deliberately needs neither — Metro\\nexternalizes every GTK module — but the SEA inlines `virtual:gtkx-config`,\\nwhich re-exports `@gtkx/jsx/metadata`, a codegen product. `build-linux\\n--sea` runs `gtkx codegen` itself; it just can't do so on a machine\\nwithout the headers.\\n\\n`postject` is fetched through `npx` at build time, so the first run needs\\nnetwork access.\\n\\nThis follows gtkx's own tutorial (`gtkx-org/gtkx examples/tutorial`:\\nbundle to CJS, `node --experimental-sea-config`, postject injects the blob\\ninto a copy of the `node` binary) for the SEA/postject mechanics.\\nIt diverges on the two hard parts specific to this project — full\\nreasoning, including everything found empirically while building it (not\\njust designed on paper), lives in\\n`packages/react-native-gtkx/src/sea/bundle.ts` and `native-shim.ts`; the\\nshort version:\\n\\n- **The native addon** (`@gtkx/native-<platform>-<libc>`, loaded through\\n dlopen) cannot be embedded as bundled code — a SEA is a V8 code cache\\n blob, dlopen needs a real file. The tutorial's own answer is to keep it\\n BESIDE the executable; that's two files, which is exactly what this\\n build exists to stop being. This build embeds it as a Node SEA \\\"asset\\\"\\n instead and extracts it to a per-user cache directory\\n (`$XDG_CACHE_HOME/react-native-gtkx-sea`, falling back to `os.tmpdir()`\\n for a read-only `$HOME`) on first run, keyed by a content hash so\\n repeat launches reuse the extracted file. Loading it back turned out to\\n need `process.dlopen()`, not `require()` — a SEA's main script can only\\n `require()` built-ins and embedded assets (confirmed empirically:\\n `require(anyAbsolutePath)` throws `ERR_UNKNOWN_BUILTIN_MODULE`) — and,\\n found only by actually running the result, an explicit\\n `nativeModule.exports.init()` call right after `dlopen()`: without it\\n the first GTK-driven callback into JS panics on the Rust side (\\\"the\\n Node environment was accessed from a thread it is not installed on\\\").\\n- **Metro's externals** (`HOST_MODULE_EXTERNALS`) are inlined by a\\n generated entry — a third host implementation alongside `host.ts` and\\n `host-dev.ts` — that `await import()`s every externalized name and\\n assembles `globalThis.__hostModules` before running the jsbundle text,\\n instead of the app needing a runtime `node_modules` to load them from.\\n `gtkx.config.ts` is resolved once, at bundle time (like the vite path\\n already does), not on every process start (like `host.ts` does) — a SEA\\n has no \\\"app root\\\" to read a config file from at runtime.\\n\\nSize, measured on the one platform this was built and proven on\\n(linux-arm64): **104 MB** for `hn-app`, 30 MB compressed. Stripped Node is\\n~98 MB of that — the bundled app code plus the embedded native addon is\\nunder 7 MB. Worth saying plainly: that is still a heavy download for what\\na Hacker News reader needs, and it will not shrink further while the\\nartifact carries a full Node binary. That is the trade `--sea` exists to\\nmake, and `--standalone` is the answer whenever it isn't worth it.\\n\\n**Proof, not just a build**: copied the executable alone (no `node_modules`,\\nno source tree) to an isolated directory on the VM, removed `/usr/bin/node`\\nfrom the system (confirmed `command -v node` found nothing), launched the\\nbinary under a headless Wayland compositor, and screenshotted a live,\\nworking \\\"Hacker News\\\" window with real fetched data — not a build log, not\\na run from the source tree.\\n\\n**vite path — not done here.** Investigated, and it does not generalize\\nthe same way: the vite bundle loads the native addon through\\n`createRequire(import.meta.url)(\\\"./gtkx.node\\\")` — a dynamically obtained\\n`require`, not a literal `require(...)` call — which a bundler does not\\nintercept the way it intercepts a static import (verified: the resolve\\nhook never fires for it in a real rebuild of `dist/bundle.js`). The vite\\nbundle also has its own top-level await, incompatible with the CJS format\\na Node SEA main script requires. Both are fixable in principle (a\\ntext-level rewrite of the compiled `require` call before re-bundling,\\nversion-coupled to `@gtkx/cli`'s vite plugin), but that is a different,\\nmore fragile technique than the Metro path's, and wasn't built or proven\\nhere. If a true single file is wanted for the vite path too, that rewrite\\nis where to start — not a repeat of this approach.\",\n },\n {\n doc: \"docs/getting-started.md\",\n heading: \"Examples in the repository\",\n text: \"- `examples/profile` — a static layout; the same source also builds with react-native-web (`examples/profile-web`);\\n- `examples/playground` — interactive: Pressable, TextInput, Switch, FlatList, Modal, Animated, responsive via flexWrap;\\n- `examples/gallery` — a gallery of the entire v1 surface;\\n- `examples/rn-app` — a cli-init React Native app with ios + android + linux;\\n- `examples/hn-app` — a Hacker News reader on the Metro path: live API data over Node fetch, state-based two-screen navigation, a lazily loaded comment tree.\",\n },\n {\n doc: \"docs/getting-started.md\",\n heading: \"Tests\",\n text: 'Unit logic is plain vitest — no special setup, runs anywhere. Component\\ntests render real GTK widgets under a headless Wayland compositor, and\\nreact-native-gtkx ships the whole recipe as two subpaths so a consumer app\\ndoes not have to rediscover it:\\n\\n- `react-native-gtkx/vitest` — `reactNativeGtkxTest()`, a ready Vitest\\n project config: the headless-compositor plugin, the `react-native` alias\\n and Metro-style platform extensions, an inline-deps default for RN\\n libraries that import `react-native` themselves (`@react-navigation`),\\n and the React act-environment setup;\\n- `react-native-gtkx/testing` — re-exports `@gtkx/testing`\\'s\\n render/screen/userEvent/fireEvent surface (already RN-shaped: `getByText`\\n finds a `Text`, `userEvent.click` walks up to a `Pressable`\\'s gesture\\n controller — no wrapper needed) plus `renderHookWithWindow`, for hooks\\n that read the active window (`useWindowDimensions` and similar) —\\n `renderHook` alone mounts into a windowless container.\\n\\nMinimal `vitest.config.ts`:\\n\\n```ts\\nimport { reactNativeGtkxTest } from \"react-native-gtkx/vitest\"\\nimport { defineConfig } from \"vitest/config\"\\n\\nexport default defineConfig(reactNativeGtkxTest())\\n```\\n\\nThe default test glob is `**/*.gtk.test.{ts,tsx}`; override `include` (and\\n`name`, `headless`, `platform`, `inlineDeps`, `setupFiles`,\\n`fileParallelism`) through `reactNativeGtkxTest`\\'s options. For a project\\nthat also has portable unit tests, use the result as one entry of\\n`test.projects` instead of the whole config — `vitest.config.ts` at this\\nrepo\\'s root is the reference (`process.platform === \"linux\"` guards the\\ngtk project so `npm test` still works on a non-Linux dev machine, running\\nonly the unit project there).\\n\\n```tsx\\nimport { Root } from \"react-native\"\\nimport { render, screen } from \"react-native-gtkx/testing\"\\nimport { expect, it } from \"vitest\"\\nimport { App } from \"../src/App\"\\n\\nit(\"renders the greeting\", async () => {\\n // react-native-gtkx components need a layout root — AppRegistry.runApplication()\\n // in the real app, <Root> in a test.\\n await render(\\n <Root\\n width={800}\\n height={600}\\n >\\n <App />\\n </Root>,\\n )\\n expect(screen.getByText(\"Hello, GNOME!\")).toBeTruthy()\\n})\\n```\\n\\nRequirements: a headless Wayland compositor and D-Bus on PATH — the same\\nsystem packages CI installs, `sway xwayland dbus` (Ubuntu:\\n`apt install sway xwayland dbus`). A missing compositor fails a test run\\nwith a readable error (`Cannot find the \"sway\" executable on PATH`) rather\\nthan hanging. `gtkx codegen` must already have generated the project\\'s\\n`@gtkx/gi` bindings before the first test run — a bare `vitest run` does\\nnot trigger codegen itself, unlike `gtkx dev`/`gtkx build`; the template\\'s\\nown `package.json` wires this as a `pretest` script.\\n\\n`packages/react-native-gtkx/tests/gtk/` is this repo\\'s own suite, built on\\nthe same `@gtkx/testing` surface directly (it tests source, not the\\npublished package) — a good place to see more query and `userEvent`\\npatterns in context. Query roles with `Gtk.AccessibleRole` enums (see\\ndocs/gtkx-rc2-notes.md for the live workarounds still baked into that\\nrecipe).',\n },\n {\n doc: \"docs/getting-started.md\",\n heading: \"MCP server for agents\",\n text: 'An agent working inside a project that depends on react-native-gtkx can\\nask the library about itself instead of guessing: `react-native-gtkx-mcp`\\nis a [Model Context Protocol](https://modelcontextprotocol.io) server that\\nships as a `bin` on this package. Register it in `.mcp.json` (Claude\\nCode, project-level) or the equivalent config of any MCP-compatible\\nclient:\\n\\n```json\\n{\\n \"mcpServers\": {\\n \"react-native-gtkx\": { \"command\": \"npx\", \"args\": [\"react-native-gtkx-mcp\"] }\\n }\\n}\\n```\\n\\nRunning it as `npx react-native-gtkx-mcp` from the project root resolves\\nthe locally installed `node_modules/.bin` entry — no separate install,\\nand it always answers for the exact react-native-gtkx version the\\nproject actually has.\\n\\nThree tools:\\n\\n- `rn_gtkx_list_surface` — browse the surface without knowing a name\\n first (portable components/APIs, gtk/adw widgets, common) with counts;\\n- `rn_gtkx_describe_component` — the one to reach for first: does a\\n component/widget exist, which subpath it is exported from, what GTK\\n widget backs it, what differs from React Native, whether a gtk/adw\\n widget is wrapped (takes `style`/`onLayout`) or raw;\\n- `rn_gtkx_search_docs` — free-text fallback for symptoms and known-issue\\n questions the other two cannot answer by name.\\n\\nIt works without GTK installed — plain Node, no `@gtkx/*` import\\nanywhere in it, reading only the package\\'s own bundled docs/manifest data.\\nThat matters in practice: the agent is often reading the project from a\\nMac, with no GTK toolchain around at all.',\n },\n {\n doc: \"docs/getting-started.md\",\n heading: \"Next steps\",\n text: \"- [docs/api.md](api.md) — the entire v1 surface and differences from RN;\\n- [CONTRIBUTING.md](../CONTRIBUTING.md) — developing the library itself (from macOS — via the UTM VM);\\n- [docs/gtkx-rc2-notes.md](gtkx-rc2-notes.md) — the gtkx rc.2 baseline: workarounds, what it fixed, quirks that stay.\",\n },\n {\n doc: \"docs/gtkx-rc2-notes.md\",\n heading: \"Live workarounds\",\n text: '| Name | What rc.2 does | Our workaround | Removal condition |\\n| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------- |\\n| `use-signal-stale-handler` | `useSignal` routes the handler through React\\'s `useEffectEvent`; `react-reconciler@0.33.0` only refreshes it in `commitBeforeMutationEffects` for `case 0` (FunctionComponent) — `case 11` (ForwardRef) and `case 15` (SimpleMemoComponent) fall through unrefreshed, so any `useEffectEvent` in a `memo`/`forwardRef` component is pinned to its mount closure forever (our `ScrollView` is a `forwardRef` with the `useSignal` calls inside it — confirmed upstream, gtkx-org/gtkx#467) — a fetch-fed FlatList empties itself on the first scroll | `gtkx/bridge/use-signal.ts` re-pins the latest handler (insertion effect) and hands gtkx a stable wrapper; the bridge exports that hook, not gtkx\\'s | A stable React 19.3 (React fixed the refresh on the 19.3 line; no stable gtkx 0.34.x yet) |\\n| `runtime-dedupe` | Two bundled copies of the gtkx runtime still double-init GLib and abort (`g_log_set_writer_func` called twice); nothing guards against it | `src/vite/index.ts` puts `resolve.dedupe` over `@gtkx/*` + `react` (+ `@react-navigation/*` for its context) into the preset every app inherits | Idempotent runtime init upstream, or an error that names the duplicate |\\n| `renderhook-no-window` | `renderHook` still mounts into a bare `Gtk.Box`, so window-dependent APIs have no toplevel to read | Hook tests create a window with `render()` first (`tests/gtk/apis/dimensions.test.tsx`); packaged for consumers as `renderHookWithWindow` (`react-native-gtkx/testing`) | `renderHook` mounts into the same harness window `render` uses |\\n| `graphene-rect-nested-boxed-props` | `new Graphene.Rect({ origin: new Graphene.Point(...), size: new Graphene.Size(...) })` hits the same native \"Expected an Object for Boxed field write type, got Object\" as the `gsk-colorstop-boxed-write` row below — a boxed struct\\'s constructor writing another boxed value into one of its own fields | `gtkx/bridge/svg-node.ts` builds the clip rect through `Graphene.Rect.alloc().init(x, y, w, h)` instead — a working escape hatch `Gsk.ColorStop` does not have | Upstream fixes boxed-struct fields that are themselves another boxed type |\\n| `gsk-colorstop-boxed-write` | Constructing a `Gsk.ColorStop` (an inline `{ float offset; GdkRGBA color; }` boxed struct) crashes in the native addon writing the `color` field — \"Expected an Object for Boxed field write type, got Object\". Verified through three independent paths (constructor props, the property setter, and skipping `ColorStop` for a plain `{offset, color}` object, which fails differently with \"No native handle associated with Object\" — the array marshaling genuinely needs a native-backed instance per element) | `gtkx/bridge/svg-node.ts`\\'s `makeColorStop` catches the throw and returns `null`; a gradient with zero constructible stops paints nothing for that fill/stroke instead of crashing (the same path as an unresolved `url(#missing)` reference) — SVG `<LinearGradient>`/`<RadialGradient>` ship with this degradation, not cut from the API | Upstream fixes boxed-struct fields that are themselves another boxed type (nested embed, not a pointer) |',\n },\n {\n doc: \"docs/gtkx-rc2-notes.md\",\n heading: \"Fixed in rc.2 (rc.1 history, one line each)\",\n text: \"- **`vitest-compositor`** — rc.1 defaulted the headless display to weston and\\n took sway through an option; rc.2's default IS sway, so `vitest.config.ts`\\n calls the plugin with no arguments.\\n- **`no-virtual-seat`** — rc.1 had no input seat under sway, so windows never\\n activated and `userEvent` was impossible; rc.2 starts a virtual seat for sway\\n (`needsVirtualSeat: true`), a rendered toplevel now reports `is-active: true`,\\n and coordinate-level input is on the table.\\n- **`fixed-layout-child`** — rc.1's declarative `<GtkFixedLayoutChild>` created\\n a detached object (Gtk-CRITICAL, positions never applied); moot for us since\\n containers moved to our own `RnGtkxLayout` manager and GtkFixed left the\\n codebase entirely.\\n- **`controllers-as-children`** — rc.1 silently ignored controllers passed as\\n JSX; rc.2 has a `controllers` slot on `GtkWidget`. Pressable and TextInput\\n still attach theirs imperatively on purpose (wired once per widget, handlers\\n read from a ref) — a choice now, not a workaround.\",\n },\n {\n doc: \"docs/gtkx-rc2-notes.md\",\n heading: \"New in the rc.2 era\",\n text: \"Two regressions/gaps first seen on rc.2, both with reproductions and both\\nwritten up for upstream in [docs/upstream-gtkx.md](upstream-gtkx.md):\\n\\n- **The `useSignal` freeze.** Not a `useSignal` bug and not about tree depth:\\n `react-reconciler@0.33.0` refreshes `useEffectEvent` in\\n `commitBeforeMutationEffects` only for `case 0` (FunctionComponent) —\\n `case 11` (ForwardRef) and `case 15` (SimpleMemoComponent) fall through\\n unrefreshed, so any `useEffectEvent` inside a `memo`/`forwardRef` component\\n is pinned to its mount closure permanently (confirmed upstream,\\n gtkx-org/gtkx#467). It reproduced for us because our `ScrollView` is a\\n `forwardRef` with the `useSignal` calls inside it; simple, shallow\\n components refresh correctly, which is why it survives casual testing. The\\n visible symptom was a virtualized list that blanked on the first scroll.\\n Repro: `tests/gtk/components/list-late-data.gtk.test.tsx`, plus the contract\\n test in `tests/gtk/bridge.smoke.test.tsx`.\\n- **The codegen freshness lie — resolved.** `npm install` prunes\\n `node_modules/.gtkx` (npm sees `@gtkx/gi`/`@gtkx/jsx` as extraneous), and on\\n rc.2 `@gtkx/cli`'s codegen could report \\\"bindings up to date\\\" over a store\\n that was not there; fixed upstream in gtkx-org/gtkx#470 (the freshness check\\n now verifies both stores' manifests and self-links, not just one). Separately,\\n we were never supposed to be exposed to this: `@gtkx/cli` is meant for apps,\\n not libraries generating bindings on a consumer's behalf, so `src/runner`\\n now calls the programmatic `@gtkx/codegen` API directly (see\\n `docs/upstream-gtkx.md` bug 2) — no CLI subprocess, no cwd, no stamp to\\n misread. `rm -rf node_modules/.gtkx` before `npm run codegen` at the repo\\n root is still the right sequence for our own monorepo tooling, which still\\n runs the CLI.\",\n },\n {\n doc: \"docs/gtkx-rc2-notes.md\",\n heading: \"Non-workarounds (quirks that stay)\",\n text: '- 64-bit FFI values arrive as BigInt → `toNumber()` at the boundary\\n (`gtkx/bridge/measure.ts`);\\n- signal names are kebab-case (\"value-changed\"); signals do not pass the\\n emitter (get the widget from a ref);\\n- role queries in tests use the `Gtk.AccessibleRole` enum, not strings;\\n- `npm install` prunes the codegen store (`node_modules/.gtkx` is not in the\\n lockfile) → run `npm run codegen` after installing — npm behavior, not gtkx;\\n- measuring unmapped widgets yields 0 (offscreen Label probes are the\\n exception) → re-measure on the `map` signal + re-commit measured leaves on\\n every flush (`layout/node.ts`);\\n- mixed-session setups only: running an app on a bare compositor (headless\\n sway) while `XDG_RUNTIME_DIR` points at a full GNOME session can segfault in\\n a GTK signal handler when the GNOME settings portal pushes updates into the\\n app (`g_cclosure_marshal_VOID__OBJECTv` via the FFI emit path); cutting\\n `DBUS_SESSION_BUS_ADDRESS` avoids it, which is why the headless scripts do.\\n Normal desktop and container runs are unaffected. Retested on rc.2 (gallery\\n under headless sway with the real session bus attached): the app ran clean\\n and SIGTERM teardown exited 143, so the exit-time segfault we saw on rc.1 no\\n longer reproduces; the portal-push crash needs a live settings change to\\n trigger and stays on the list unconfirmed.',\n },\n {\n doc: \"docs/gtkx-rc2-notes.md\",\n heading: \"Procedure when the next release ships\",\n text: \"1. Update the `@gtkx/*` pins (root, spike, examples, template), then\\n `npm install && rm -rf node_modules/.gtkx && npm run codegen`;\\n2. Run everything on Linux: `npm run typecheck && npm test`, `build:dist`,\\n `check:package`, plus the headless example proofs;\\n3. Walk the live-workaround table: for each row check the removal condition,\\n delete the tag and the row together when it is met, and move the entry into\\n the history section above;\\n4. Re-tag whatever survives (`RC2-WORKAROUND` → the new release) and update\\n `docs/upstream-gtkx.md` if an ask was answered.\",\n },\n {\n doc: \"docs/research/navigation-extensibility.md\",\n heading: \"1. The two layers\",\n text: \"```\\nyour app\\n ├── react-native portable components\\n ├── react-native-gtkx/navigation react-navigation adapter (optional)\\n └── react-native-gtkx/adwaita GTK widgets and primitives\\n```\\n\\n**`react-native-gtkx/gtk` and `react-native-gtkx/adw`** owns the widget: diffing a requested stack\\nof tags into `pushByTag` / `popToTag` / `replaceWithTags`, holding a popped\\npage alive until its exit animation ends, bracketing transitions, reporting\\nnative pops. It imports nothing from `@react-navigation/*`. `NavigationStack`\\ntakes the visible stack as a prop, so a `useState` is a complete router.\\n\\n**`react-native-gtkx/navigation`** is an adapter: react-navigation state to\\nan array of tags, a native pop to `StackActions.pop` (only when the tag is\\nstill in state, otherwise it would double-pop), descriptors to titles, header\\ncontent and `canPop`, plus dev warnings for options we ignore.\\n\\nThis is the same split the React Native ecosystem already uses:\\n`react-native-screens` exposes primitives, `@react-navigation/native-stack`\\nbinds them to a router. It is also what React Navigation's maintainer\\nrecommended when he saw the project (u/satya164, on the r/reactnative\\nannouncement): _keep your own navigator so you can provide options specific\\nto GTK, unless you plan to match native stack API 1:1._\\n\\nThe consequence that matters: **the ceiling of react-navigation's model is\\nnow only in the adapter, never in the primitive.** A GTK capability with no\\ncounterpart in React Native does not have to be squeezed into someone\\nelse's abstraction — it lives in the primitive layer and is reachable\\ndirectly. See [../platform-layer.md](../platform-layer.md).\",\n },\n {\n doc: \"docs/research/navigation-extensibility.md\",\n heading: \"2. What an app can reach today\",\n text: \"Everything below the HeaderBar: each page hosts a full RN tree in its own\\nlayout root. All of react-navigation's state mechanics: params,\\n`setOptions`, dispatch, resets.\\n\\nStack options: `title`, `headerShown`, `headerButtons` (declarative native\\nicon buttons), `headerLeft` / `headerRight` (ordinary RN content rendered\\n_inside_ the HeaderBar), `gestureEnabled`.\\n\\nPast the options, the primitives: any GTK widget we bind, taking `style` so\\nReact Native drives its position and its appearance, plus `wrapReactNative`\\nfor widgets we do not re-export, plus a `ref` to the underlying\\n`Adw.NavigationView`. There is no wall — a missing convenience costs a line,\\nnot a fork.\\n\\n**Resolved since the first snapshot.** Kept here because the reasons are\\nstill instructive:\\n\\n- _RN content could not size a chrome slot_ (HeaderBar start/end, sidebar\\n rows) — one root cause behind the whole `headerLeft`/`headerRight` class.\\n Fixed by the intrinsic-size root, now public as `IntrinsicContent`.\\n- _`usePreventRemove` / `beforeRemove` desynced_, because the native pop had\\n already happened when state heard about it. Fixed through\\n `AdwNavigationPage:can-pop`: a prevented route cannot be popped by the\\n user at all, so there is nothing to race. Covered by\\n `tests/gtk/navigation/prevent-remove.gtk.test.tsx`.\\n- _Unsupported options were ignored silently._ Fixed:\\n `src/navigation/option-warnings.ts` names the screen and the option in\\n development.\\n- _Screen props and options had to be hand-rolled._ Fixed:\\n `createStackNavigator<ParamList>()` types `Stack.Screen`, its options and\\n the screen props (`examples/hn-app` relies on it).\\n\\n`createSidebarNavigator`'s own gaps — sidebar row rendering, collapsed\\nmode and the static content header — are covered in §3 below, alongside\\nthe `examples/tasks-app`/`examples/tasks-nav` narrative that found and\\nthen closed them.\\n\\nOn typing, one clarification worth recording, since it was raised publicly.\\nThe complaint was never that custom navigators cannot be typed — the docs\\nshow how, and we follow them. It is that the upstream v7 signature is\\n`createNavigatorFactory(Navigator: ComponentType<any>): (config?: any) => any`,\\nso nothing flows out of the factory itself and the types have to come from\\nannotating the navigator. React Navigation 8 replaces this with a real typed\\nAPI (`NavigatorTypeBagBase`, `createScreenFactory`); adopting it is the\\n`react-navigation-8` epic.\",\n },\n {\n doc: \"docs/research/navigation-extensibility.md\",\n heading: \"3. Still open\",\n text: \"Meaningful on this platform and not done yet: toolbar top-bar style (the\\n`headerTransparent`/`headerShadowVisible` analogue), search-bar options\\n(`Gtk.SearchBar` / `headerSearchBarOptions` — note v8 renamed its\\n`onChangeText` to `onChange`), and deep links (they parse, but nothing\\ndelivers a URL on the desktop yet). `animation: \\\"none\\\"` is done (a screen\\noption, see docs/api.md).\\n\\n**Resolved by building `examples/tasks-app` (the gtkx tutorial's Tasks app,\\nported), each with a small library change, not a workaround:**\\n\\n- _`Adw.Dialog` presentation_ — confirmed working. `AdwAboutDialog`/\\n `AdwAlertDialog`/`AdwPreferencesDialog`/`AdwShortcutsDialog` are already\\n `wrapReactNative`-wrapped; mounted with no Yoga ancestor anywhere in the\\n tree (this app has none — see the example's README), they hit\\n `wrapReactNative`'s \\\"bare\\\" branch and present correctly, verified live\\n with real screenshots (Preferences, Shortcuts). Nothing to fix here —\\n this item can be dropped from \\\"still open\\\" entirely.\\n- _Breakpoints_ — a real `Adw.Breakpoint`, verified live collapsing the\\n window at a narrow width, but not through the navigator: through a new\\n `AppRegistry.runApplication({ breakpoints })` parameter instead (the\\n navigator itself still had no collapsed-mode concept at the time —\\n closed by `navigation-depth-2`, see below). Also found and recorded:\\n `AdwBreakpoint`'s `onApply`/`onUnapply` never fire under the\\n `@gtkx/vitest` headless-sway gtk test project, in any form tried (JSX\\n prop, imperative `Adw.Breakpoint`+`addBreakpoint`, a genuine `swaymsg`\\n resize) — but fire immediately in a real GNOME session. Treat it as\\n untestable headless today, not broken; see\\n `packages/react-native-gtkx/tests/gtk/bridge/auxiliary-elements.gtk.test.tsx`.\\n (`navigation-depth-2`'s own `collapseWidth`, below, sidesteps this\\n entirely — it drives `Adw.Breakpoint.addSetter` rather than\\n `onApply`/`onUnapply`, and that IS testable headless, see\\n `tests/gtk/adw/breakpoint.gtk.test.tsx`.)\\n- _Actions and menus_ were never on this list by name, but turned out to\\n be the same kind of gap: `AppRegistry.runApplication` had no way to\\n attach a `GSimpleAction`, `actionAccels` or a `GtkShortcutController` to\\n the app/window it builds — required for a `Gio.Notification` action\\n button to route anywhere at all. Closed the same way, with\\n `applicationActions`/`actionAccels`/`windowActions`/`windowControllers`.\\n\\n**Resolved by building `examples/tasks-nav` (`navigation-depth-2` epic),\\nclosing exactly what the tasks-app port above found still narrow:**\\n\\n- _Sidebar row rendering and collapsed mode_ — `createSidebarNavigator`'s\\n `SidebarNavigationOptions` was `{ title }` only: no per-row icon/color/\\n count, and no collapsed/breakpoint wiring of its own (tasks-app had to\\n reach `AppRegistry`'s `breakpoints` directly and drive `collapsed`\\n itself). Fixed: `icon`/`color`/`count` (rendered as `AdwActionRow`, the\\n same widget tasks-app's own hand-rolled sidebar used) and an opt-in\\n `collapseWidth` prop, driving collapse through the navigator itself via\\n a native `Adw.Breakpoint` — not a `useWindowDimensions` conditional; see\\n [../platform-layer.md](../platform-layer.md), \\\"Two ways to react to\\n size\\\", for the mechanism and why no `useBreakpoint` hook exists.\\n- _One static content header shared by the whole navigator_ — the same\\n port's other finding: a filter toggle group vs. a back button,\\n depending on selection, did not fit one static header. The\\n `navigation-depth-2` PRD explicitly allowed this turning out to be a\\n structural gap; it wasn't — descriptor options already merge\\n navigator-level `screenOptions` with a screen's own `options` and\\n re-resolve on `navigation.setOptions()`, core react-navigation behavior.\\n `SidebarNavigationOptions` gained `headerLeft`/`headerRight`/\\n `headerTitle`, mirroring the stack navigator's own `headerLeft`/\\n `headerRight`; a screen that toggles local state and calls\\n `setOptions` in an effect gets a header that changes shape with its own\\n selection, no stack involved — confirming tasks-app's own conclusion\\n that a stack was never the right tool for the \\\"open an item\\\" case.\\n Caveat found while testing this: `setOptions` merges into the\\n previously resolved options rather than replacing them (see\\n docs/api.md).\\n\\n`examples/tasks-nav` is the same navigational shape as `examples/tasks-app`\\n— smart views, colored user lists, an open-item editor — now written\\nthrough `createSidebarNavigator` instead of directly on\\n`AdwNavigationSplitView`/`AdwActionRow`.\\n\\n**Resolved by `collapse-nav` (a live bug report on `examples/tasks-nav`),\\none property lower than `collapseWidth` itself:** `collapseWidth` flips\\n`AdwNavigationSplitView.collapsed` correctly, but `showContent` — WHICH\\npane is visible while collapsed — was only half-wired: a row click already\\nrevealed content, but nothing observed the split view's own back\\naffordance putting it back, and a plain programmatic `navigate()` (no row\\nclick) did not reveal content at all. On read, this looked like it might\\nbe the same \\\"the breakpoint effect sets only `collapsed`\\\" gap all over\\nagain; it mostly was not — see `sidebar.tsx`'s own file header for what was\\nalready there. Three questions were settled empirically, with a throwaway\\nGTK test written BEFORE any implementation code, rather than assumed from\\nlibadwaita's docs:\\n\\n- _Does a cold-started, already-collapsed window default to content or the\\n sidebar?_ Sidebar — `showContent` defaults to `false`, confirmed by\\n mounting a window already narrower than `collapseWidth` and reading the\\n property on first layout, before any code (ours or the app's) ever wrote\\n to it. No fix needed.\\n- _Does resizing back above `collapseWidth` and back below it need to\\n reset `showContent` or the selection?_ No — both persist across the\\n round trip, confirmed the same way (resize wide, resize narrow again,\\n read the property). This is deliberate, not an oversight: it is the same\\n size-class persistence a mobile master-detail app relies on (open an\\n item, rotate to landscape and back, still on that item), which is\\n exactly the \\\"the way a mobile app does\\\" behavior the bug report asked\\n for. Resetting it would have fought the platform's own default for no\\n benefit.\\n- _Does an app need to observe or control the collapsed pane at all?_ One\\n direction, yes: going back. TabRouter's `state` never changes when the\\n user backs out of collapsed content (nothing is removed, the same route\\n stays focused), so there is no existing react-navigation mechanism for\\n an app to notice it happened — unlike a stack pop, which state itself\\n already reveals through the route array shrinking. A new event,\\n `sidebarShown` (`SidebarNavigationEventMap`, the same `navigation.emit`/\\n `addListener` protocol `StackNavigationEventMap`'s `transitionStart`/\\n `transitionEnd` already established — not a second protocol), fires on\\n the active route for exactly this. The forward direction (content being\\n revealed) got no event: it is already an ordinary state change an app\\n can observe the normal way, so an event there would be pure duplication.\\n\\nThe echo risk this raises — state → widget and widget → state both touch\\nthe same property, could they retrigger each other? — resolved the same\\nway the stack navigator's own doc warns about it: by a value asymmetry, not\\na flag. State → widget only ever WRITES `true`; widget → state only ever\\nREACTS to `false`. Two disjoint values, so neither side can mistake the\\nother's write for the other direction.\\n\\nFixed: `sidebar.tsx`'s `state.index` effect now also calls\\n`showContentIfCollapsed()` (previously only `onRowActivated` did, so a\\nclick worked but a programmatic navigation left the user stranded on the\\nsidebar exactly like the report — a real, reproducible gap, not merely a\\ntheoretical one); `onNotifyShowContent` is observed and re-emitted as\\n`sidebarShown`. `examples/gallery` (no `collapseWidth`) is untouched by\\nconstruction — every changed path checks `getCollapsed()` /\\n`collapseWidth !== undefined` live first. See\\n`tests/gtk/navigation/sidebar-collapse.gtk.test.tsx` for the automated\\nversion of all four findings above, and docs/api.md for the public shape.\\n\\n**Found while building `examples/tasks-nav`, narrower, still open:**\\n\\n- _The sidebar PANE's own chrome has no customization hook_ — its\\n `AdwToolbarView`'s `AdwHeaderBar` is hard-coded\\n (`src/navigation/sidebar.tsx`); a navigator consumer can set\\n `sidebarTitle` (a string) on it and nothing else. `examples/tasks-nav`'s\\n \\\"New List\\\" action wanted to live there (matching tasks-app's own\\n `SidebarHeader` component) but had to go on the content header instead,\\n via the navigator-level `headerButtons` prop. Not on the PRD's\\n checklist, so not built.\\n- _Toasts_ — no `AdwToastOverlay`/`Adw.Toast` convenience exists anywhere\\n in `react-native-gtkx` (upstream's own tutorial reaches for\\n `@gtkx/components/adw`'s `ToastProvider`/`useToast`, a package this repo\\n does not depend on). `examples/tasks-app/src/toast.tsx` is a local\\n stand-in; the toast's underlying state change works and is verified live,\\n but the toast's own visual appearance could not be confirmed on screen\\n in that session, for a reason not yet root-caused. Worth a real fix (or\\n at least a live confirmation) before another app leans on it.\\n\\n**Meaningless on desktop, skip forever:** status-bar and home-indicator\\noptions, large titles, blur effects, gesture direction, form sheets,\\nback-button labels. `headerBackButtonMenuEnabled` is free — libadwaita's\\nback button already shows a history menu.\",\n },\n {\n doc: \"docs/research/navigation-extensibility.md\",\n heading: \"4. Porting an existing react-navigation app\",\n text: \"Compatible by construction: a real `@react-navigation/native` v8 peer, the\\nofficial `useNavigationBuilder` and routers, a real `NavigationContainer`.\\nEverything from react-navigation is imported from `@react-navigation/native`\\ndirectly. We used to re-export a partial set from our navigation entry point\\nand dropped it: the set was incomplete, so consumers ended up importing from\\nboth places and could not tell which symbol came from where.\\n\\nMandatory changes: swap `createNativeStackNavigator` for our\\n`createStackNavigator`; drop `react-native-screens`,\\n`react-native-safe-area-context` and `react-native-gesture-handler` (all\\nthree are mobile-native dependencies with nothing to bind to here).\\n\\nKeeping shared code portable: Linux-only options go behind a `.linux.tsx`\\nplatform extension or `Platform.select({ linux: … })`. Options a platform\\ndoes not understand are ignored — and here, warned about in development.\",\n },\n {\n doc: \"docs/research/navigation-extensibility.md\",\n heading: \"5. The desktop-RN landscape\",\n text: \"No other desktop React Native platform has native navigation integration:\\n\\n- **react-native-screens** lists Windows support, but it is a thin\\n old-architecture module; native-stack on modern react-native-windows\\n fails, because screens has no new-architecture Windows implementation and\\n RNW 0.82 removed the old one. Microsoft's own react-native-gallery falls\\n back to the JS drawer.\\n- **react-native-macos** is not supported by react-native-screens at all —\\n AppKit has no navigation-stack primitive to bind to.\\n\\nOur path — a real `Adw.NavigationView` driven from a custom navigator, with\\nreact-navigation state as the source of truth and native pops reported back\\ninto it — is structurally the iOS native-stack / `UINavigationController`\\nmodel, which neither desktop platform reached. GTK's advantage is that the\\nprimitive exists at all: back button, Escape, back gesture, history menu and\\ntransitions ship with the widget.\\n\\nThe trade: a JS stack can render anything into its fake header, while our\\nchrome is real and had to be opened up deliberately — which is what the\\nintrinsic-size root does.\\n\\nSources: react-native-screens README and discussions #1575 / #2541, RNW\\ndiscussions #14273 / issue #4152 / new-architecture docs / 0.82 release\\npost, microsoft/react-native-gallery, reactnavigation.org native-stack docs.\",\n },\n {\n doc: \"docs/gtkx-rc2-notes.md\",\n heading: \"RC2-WORKAROUND(use-signal-stale-handler)\",\n text: \"`useSignal` routes the handler through React's `useEffectEvent`; `react-reconciler@0.33.0` only refreshes it in `commitBeforeMutationEffects` for `case 0` (FunctionComponent) — `case 11` (ForwardRef) and `case 15` (SimpleMemoComponent) fall through unrefreshed, so any `useEffectEvent` in a `memo`/`forwardRef` component is pinned to its mount closure forever (our `ScrollView` is a `forwardRef` with the `useSignal` calls inside it — confirmed upstream, gtkx-org/gtkx#467) — a fetch-fed FlatList empties itself on the first scroll — our workaround: `gtkx/bridge/use-signal.ts` re-pins the latest handler (insertion effect) and hands gtkx a stable wrapper; the bridge exports that hook, not gtkx's — removed when: A stable React 19.3 (React fixed the refresh on the 19.3 line; no stable gtkx 0.34.x yet)\",\n },\n {\n doc: \"docs/gtkx-rc2-notes.md\",\n heading: \"RC2-WORKAROUND(runtime-dedupe)\",\n text: \"Two bundled copies of the gtkx runtime still double-init GLib and abort (`g_log_set_writer_func` called twice); nothing guards against it — our workaround: `src/vite/index.ts` puts `resolve.dedupe` over `@gtkx/*` + `react` (+ `@react-navigation/*` for its context) into the preset every app inherits — removed when: Idempotent runtime init upstream, or an error that names the duplicate\",\n },\n {\n doc: \"docs/gtkx-rc2-notes.md\",\n heading: \"RC2-WORKAROUND(renderhook-no-window)\",\n text: \"`renderHook` still mounts into a bare `Gtk.Box`, so window-dependent APIs have no toplevel to read — our workaround: Hook tests create a window with `render()` first (`tests/gtk/apis/dimensions.test.tsx`); packaged for consumers as `renderHookWithWindow` (`react-native-gtkx/testing`) — removed when: `renderHook` mounts into the same harness window `render` uses\",\n },\n {\n doc: \"docs/gtkx-rc2-notes.md\",\n heading: \"RC2-WORKAROUND(graphene-rect-nested-boxed-props)\",\n text: '`new Graphene.Rect({ origin: new Graphene.Point(...), size: new Graphene.Size(...) })` hits the same native \"Expected an Object for Boxed field write type, got Object\" as the `gsk-colorstop-boxed-write` row below — a boxed struct\\'s constructor writing another boxed value into one of its own fields — our workaround: `gtkx/bridge/svg-node.ts` builds the clip rect through `Graphene.Rect.alloc().init(x, y, w, h)` instead — a working escape hatch `Gsk.ColorStop` does not have — removed when: Upstream fixes boxed-struct fields that are themselves another boxed type',\n },\n {\n doc: \"docs/gtkx-rc2-notes.md\",\n heading: \"RC2-WORKAROUND(gsk-colorstop-boxed-write)\",\n text: 'Constructing a `Gsk.ColorStop` (an inline `{ float offset; GdkRGBA color; }` boxed struct) crashes in the native addon writing the `color` field — \"Expected an Object for Boxed field write type, got Object\". Verified through three independent paths (constructor props, the property setter, and skipping `ColorStop` for a plain `{offset, color}` object, which fails differently with \"No native handle associated with Object\" — the array marshaling genuinely needs a native-backed instance per element) — our workaround: `gtkx/bridge/svg-node.ts`\\'s `makeColorStop` catches the throw and returns `null`; a gradient with zero constructible stops paints nothing for that fill/stroke instead of crashing (the same path as an unresolved `url(#missing)` reference) — SVG `<LinearGradient>`/`<RadialGradient>` ship with this degradation, not cut from the API — removed when: Upstream fixes boxed-struct fields that are themselves another boxed type (nested embed, not a pointer)',\n },\n {\n doc: \"docs/api.md\",\n heading: \"View\",\n text: \"View — GTK implementation: GtkBox (RnGtkxViewBox). Supported: `style`, `onLayout`, `testID`, children, `pointerEvents` (auto/none/box-none/box-only — mapped onto GTK picking: can-target + a contains() vfunc override; also honored from `style.pointerEvents`, the prop wins). Differences from RN: nesting another pointerEvents inside a box-only view is not supported\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"Text\",\n text: \"Text — GTK implementation: GtkLabel (Pango). Supported: wrap, `numberOfLines` (ellipsize END), `textAlign`, font styles, `onLayout`, `testID`. Differences from RN: nested `Text` elements are concatenated without per-span styles; text is always ellipsizable (shrinkable in narrow windows)\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"Image\",\n text: 'Image — GTK implementation: GtkPicture. Supported: `source={{uri}}`/string — local paths, file:// and **http(s)** (Node fetch → disk cache keyed by URL, in-flight de-duplication), `resizeMode` cover/contain/stretch/center, `onLoad`/`onError`; **`.svg` files load like any other image** — `Gdk.Texture.newFromFilename` rasterizes them via librsvg, no extra code needed (for building vector graphics from state instead of a file, see the \"Svg\" section below — a separate import, not part of this table). Differences from RN: no synchronous size from remote images (style sets the size, as in RN); cache is not size-limited yet',\n },\n {\n doc: \"docs/api.md\",\n heading: \"TextInput\",\n text: \"TextInput — GTK implementation: GtkEntry / GtkTextView. Supported: controlled/uncontrolled (`value`/`defaultValue`), `onChangeText`, `onSubmitEditing`, `onFocus`/`onBlur`, `placeholder` (own dim overlay in multiline — GtkTextView has none), `secureTextEntry`, `editable`, `keyboardType`, `multiline`, `clearButtonMode` (GtkEntry's built-in clear icon; RN ships this on iOS only) (real GtkTextView: word wrap, internal scroll, Enter inserts a newline and never fires onSubmitEditing — RN semantics). Differences from RN: multiline needs a height in the style (as RN recommends)\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"Pressable\",\n text: \"Pressable — GTK implementation: GtkFixed + GestureClick/Motion. Supported: `onPress(In/Out)`, `onLongPress` (`delayLongPress`), `onHoverIn/Out`, `disabled`, function-form `style`/`children` receiving `{pressed, hovered}`. Differences from RN: —\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"TouchableOpacity\",\n text: \"TouchableOpacity — GTK implementation: on top of Pressable. Supported: `activeOpacity`. Differences from RN: —\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"ScrollView\",\n text: \"ScrollView — GTK implementation: GtkScrolledWindow. Supported: vertical/`horizontal`, `contentContainerStyle`, `onScroll`, `onContentSizeChange`, `stickyHeaderIndices` (RN model: the REAL child is translated and painted on top — no duplicate), ref: `scrollTo`/`scrollToEnd` (`ScrollViewHandle`). Differences from RN: `animated` in scrollTo is ignored\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"FlatList\",\n text: \"FlatList — GTK implementation: windowed core on ScrollView. Supported: virtualization (`estimatedItemSize` or `getItemLayout`, **`windowSize`/`initialNumToRender` — the primary scroll-performance knobs**, `maxToRenderPerBatch`/`updateCellsBatchingPeriod`), `data`/`renderItem`/`keyExtractor`/`extraData`, `ItemSeparatorComponent`, `ListHeader/Footer/EmptyComponent`, `onEndReached(-Threshold)`, `onViewableItemsChanged`/`viewabilityConfig` (`ViewToken`), `inverted` (RN chat semantics: opens at `data[0]`, stays pinned on prepend), `refreshing`/`onRefresh`, `horizontal`, `stickyHeaderIndices`, ref: `scrollToIndex`/`scrollToItem`/`scrollToOffset` + ScrollView methods (`FlatListHandle`). Differences from RN: 1000 rows mount windowed in ~120 ms (v1 full mount was 879 ms); `windowSize` defaults to **11**, not RN's 5 — desktop has no mobile memory pressure and a wider window means fewer mount+reflow bursts per scrolled pixel (measured: −21% churn, late frames 10/s → 7.7/s); rows beyond the visible ones are mounted `maxToRenderPerBatch` (10) at a time every `updateCellsBatchingPeriod` (50) ms, so a flick or a long `scrollToOffset` fills its window over several frames instead of stalling one; no pull gesture — `onRefresh` must be app-triggered; an inverted list shorter than its viewport anchors to the top, not the bottom\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"SectionList\",\n text: \"SectionList — GTK implementation: on top of FlatList. Supported: `sections`, `renderSectionHeader`, sticky section headers by default (`stickySectionHeadersEnabled`). Differences from RN: viewability props are not exposed (section-aware ViewTokens pending)\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"Switch\",\n text: \"Switch — GTK implementation: GtkSwitch. Supported: `value`/`onValueChange`, `disabled`. Differences from RN: sized by the GTK theme, not iOS metrics\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"ActivityIndicator\",\n text: \"ActivityIndicator — GTK implementation: GtkSpinner. Supported: `animating`, `size` (small/large/number). Differences from RN: no `color` yet\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"Modal\",\n text: \"Modal — GTK implementation: modal GtkWindow (portal). Supported: `visible`, `onRequestClose` (Escape/close button), `title`, `width`/`height`; independently resizable with relayout. Differences from RN: desktop semantics: a separate window, not an overlay; `transparent`/`animationType` are no-ops\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"Animated.View\",\n text: \"Animated.View — GTK implementation: direct widget calls. Supported: `opacity` and the whole `transform` array — `translateX/Y`, `scale`, `scaleX`, `scaleY`, `rotate`/`rotateZ` — driven by Animated nodes, bypassing React (an angle comes from `interpolate` with a `deg`/`rad` outputRange). Differences from RN: `rotateX`/`rotateY`/`perspective` (3D), `skewX`/`skewY` and `matrix` are not supported, and the transform origin is always the view's centre (no `transformOrigin`)\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"SafeAreaView\",\n text: \"SafeAreaView — GTK implementation: = View. Supported: —. Differences from RN: no notches on desktop\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"StatusBar\",\n text: \"StatusBar — GTK implementation: null. Supported: —. Differences from RN: no status bar\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"Root\",\n text: \"Root — GTK implementation: internal root. Supported: `width`/`height`. Differences from RN: extension: required by the test harness\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"NestedRoot\",\n text: \"NestedRoot — GTK implementation: internal root. Supported: —. Differences from RN: extension: a Yoga root inside any GTK container slot (navigation pages, custom containers); the slot allocation is the viewport\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"IntrinsicRoot\",\n text: \"IntrinsicRoot — GTK implementation: internal root. Supported: —. Differences from RN: extension: a content-sized Yoga root for chrome slots (HeaderBar start/end) — reports its content size to GTK\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"StyleSheet\",\n text: \"StyleSheet — Supported: `create`, `flatten`, `compose`, `absoluteFill(Object)`, `hairlineWidth`. Differences: —\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"PlatformColor\",\n text: 'PlatformColor — Supported: Adwaita variables: `PlatformColor(\"accent-bg-color\")` → `var(--...)`, `@named`. Differences: names are Adwaita, not iOS/Android',\n },\n {\n doc: \"docs/api.md\",\n heading: \"AppRegistry\",\n text: 'AppRegistry — Supported: `registerComponent`, `runApplication(appKey, {title,width,height,initialProps,chrome,applicationActions,actionAccels,windowActions,windowControllers,breakpoints})`, `getAppKeys`. Differences: desktop window parameters; `chrome: \"content\"` uses an AdwApplicationWindow with no window titlebar — the app\\'s HeaderBars (navigation) become the chrome. `applicationActions`/`actionAccels` reach the underlying `GtkApplication` (`app.*` actions — what a `Gio.Notification` action button targets); `windowActions`/`windowControllers` reach the window (`win.*` actions, a window-scoped `GtkShortcutController`); `breakpoints` reaches `AdwApplicationWindow`\\'s own prop and only does anything under `chrome: \"content\"` (a dev warning fires otherwise)',\n },\n {\n doc: \"docs/api.md\",\n heading: \"Platform\",\n text: 'Platform — Supported: `OS: \"linux\"`, `Version` (GTK), `select` (linux → native → default), `isTV`, `isTesting`. Differences: —',\n },\n {\n doc: \"docs/api.md\",\n heading: \"Dimensions\",\n text: 'Dimensions — Supported: `get(\"window\"/\"screen\")`, `addEventListener(\"change\")`. Differences: main window only (transient windows are ignored)',\n },\n {\n doc: \"docs/api.md\",\n heading: \"useWindowDimensions\",\n text: \"useWindowDimensions — Supported: reactive main-window dimensions. Differences: —\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"Appearance\",\n text: \"Appearance — Supported: `getColorScheme`, `setColorScheme` (AdwStyleManager), `addChangeListener`. Differences: —\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"useColorScheme\",\n text: \"useColorScheme — Supported: reactive theme. Differences: —\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"AppState\",\n text: \"AppState — Supported: `currentState` active/background, `addEventListener`. Differences: driven by the window's `is-active`\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"Alert\",\n text: \"Alert — Supported: `alert(title, message, buttons, options)` → Adw.AlertDialog. Differences: `cancel`/`destructive`/`isPreferred` styles\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"Linking\",\n text: 'Linking — Supported: `openURL`, `canOpenURL` (http/https/mailto/file), `getInitialURL` (null), `addEventListener(\"url\")`. Differences: system launcher; no deep-link delivery on desktop yet — \"url\" subscriptions never fire',\n },\n {\n doc: \"docs/api.md\",\n heading: \"InteractionManager\",\n text: \"InteractionManager — Supported: `runAfterInteractions(task?)` (cancellable, then-able), `createInteractionHandle`/`clearInteractionHandle`, `addListener`. Differences: navigation transitions register interactions, so screen work deferred with `runAfterInteractions` waits for the push/pop slide\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"DevSettings\",\n text: \"DevSettings — Supported: `addMenuItem(title, handler)` (entries in the Dev Menu — Ctrl+Shift+D in `run-linux --dev`, the react-native-windows shortcut), `reload(reason?)`. Differences: silent no-ops in release builds, like RN\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"I18nManager\",\n text: \"I18nManager — Supported: `isRTL` (live: GTK's read of the locale text direction), `doLeftAndRightSwapInRTL`, `getConstants`. Differences: `allowRTL`/`forceRTL`/`swapLeftAndRightInRTL` are accepted no-ops (mobile persistence has no desktop store)\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"BackHandler\",\n text: 'BackHandler — Supported: `addEventListener(\"hardwareBackPress\")`, `exitApp`. Differences: no hardware back key on desktop — subscriptions are honored but nothing fires them yet',\n },\n {\n doc: \"docs/api.md\",\n heading: \"Animated\",\n text: \"Animated — Supported: `Value`, `timing`, `spring`, `sequence`, `parallel`, `delay`, `loop`, `interpolate` (numbers and deg/rad strings, clamp/extend/identity). Differences: `useNativeDriver` is ignored (with a warning); the direct path is native-speed anyway\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"Easing\",\n text: \"Easing — Supported: linear/ease/quad/cubic/in/out/inOut/bezier. Differences: —\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"version\",\n text: \"version — Supported: package version. Differences: extension\",\n },\n] as const satisfies readonly DocChunk[]\n"]}
1
+ {"version":3,"file":"generated.js","sourceRoot":"","sources":["../../../src/mcp/data/generated.ts"],"names":[],"mappings":"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","sourcesContent":["// GENERATED FILE — do not edit by hand.\n// Produced by scripts/generate-mcp-data.mjs from docs/api.md,\n// docs/platform-layer.md, docs/gtkx-rc3-notes.md, docs/getting-started.md,\n// docs/research/navigation-extensibility.md and\n// scripts/widget-surface/classification.json.\n//\n// Regenerate after touching any of those:\n// node scripts/generate-mcp-data.mjs\n// Check without writing (used in verification):\n// node scripts/generate-mcp-data.mjs --check\n\nexport type PortableRecord = {\n readonly name: string\n readonly subpath: \"react-native\"\n readonly gtkImplementation?: string\n readonly supported: string\n readonly differences: string\n}\n\nexport type CommonRecord = {\n readonly name: string\n readonly subpath: \"react-native-gtkx/common\"\n readonly summary: string\n}\n\nexport type WidgetRecord = {\n readonly name: string\n readonly subpath: \"react-native-gtkx/gtk\" | \"react-native-gtkx/adw\"\n readonly wrapped: boolean\n readonly reason?: string\n}\n\nexport type DocChunk = {\n readonly doc: string\n readonly heading: string\n readonly text: string\n}\n\nexport const PORTABLE_COMPONENTS = [\n {\n name: \"View\",\n subpath: \"react-native\",\n gtkImplementation: \"GtkBox (RnGtkxViewBox)\",\n supported:\n \"`style`, `onLayout`, `testID`, children, `pointerEvents` (auto/none/box-none/box-only — mapped onto GTK picking: can-target + a contains() vfunc override; also honored from `style.pointerEvents`, the prop wins), ref: `measure`/`measureInWindow`/`measureLayout` (`ViewHandle`, RN's argument order; window coordinates come from `gtk_widget_compute_point`, so they are correct inside a scrolled viewport), the responder and touch props (`onStartShouldSetResponder(Capture)`, `onMoveShouldSetResponder(Capture)`, `onResponderGrant/Start/Move/End/Release/Terminate`, `onTouchStart/Move/End/Cancel` + `Capture`) — spread `PanResponder`'s `panHandlers` here\",\n differences:\n \"nesting another pointerEvents inside a box-only view is not supported; responder negotiation is capture-then-bubble as in RN, but there is **no transfer yet**: once a view is granted, `onResponderTerminationRequest`/`onResponderReject` are never called and a second view cannot steal (GTK's `CLAIMED` is irrevocable, so a transfer could not be enforced against native widgets — see docs/research/gestures.md). The lock is one per process as in RN; the negotiation PATH stops at the layout root, so native GTK widgets between or above views take no part. Single-pointer only: a mouse is one fabricated touch, `touches` never exceeds one\",\n },\n {\n name: \"Text\",\n subpath: \"react-native\",\n gtkImplementation: \"GtkLabel (Pango)\",\n supported:\n \"wrap, `numberOfLines` (ellipsize END), `textAlign`, font styles, `onLayout`, `testID`\",\n differences:\n \"nested `Text` elements are concatenated without per-span styles; text is always ellipsizable (shrinkable in narrow windows)\",\n },\n {\n name: \"Image\",\n subpath: \"react-native\",\n gtkImplementation: \"GtkPicture\",\n supported:\n '`source={{uri}}`/string — local paths, file:// and **http(s)** (Node fetch → disk cache keyed by URL, in-flight de-duplication), `resizeMode` cover/contain/stretch/center, `onLoad`/`onError`; **`.svg` files load like any other image** — `Gdk.Texture.newFromFilename` rasterizes them via librsvg, no extra code needed (for building vector graphics from state instead of a file, see the \"Svg\" section below — a separate import, not part of this table)',\n differences:\n \"no synchronous size from remote images (style sets the size, as in RN); cache is not size-limited yet\",\n },\n {\n name: \"TextInput\",\n subpath: \"react-native\",\n gtkImplementation: \"GtkEntry / GtkTextView\",\n supported:\n \"controlled/uncontrolled (`value`/`defaultValue`), `onChangeText`, `onSubmitEditing`, `onFocus`/`onBlur`, `placeholder` (own dim overlay in multiline — GtkTextView has none), `secureTextEntry`, `editable`, `keyboardType`, `multiline`, `clearButtonMode` (GtkEntry's built-in clear icon; RN ships this on iOS only) (real GtkTextView: word wrap, internal scroll, Enter inserts a newline and never fires onSubmitEditing — RN semantics)\",\n differences: \"multiline needs a height in the style (as RN recommends)\",\n },\n {\n name: \"Pressable\",\n subpath: \"react-native\",\n gtkImplementation: \"GtkFixed + GestureClick/Motion\",\n supported:\n \"`onPress(In/Out)`, `onLongPress` (`delayLongPress`), `onHoverIn/Out`, `disabled`, function-form `style`/`children` receiving `{pressed, hovered}`; the `PressEvent` payload is RN's shape (`locationX/Y` target-relative, `pageX/Y` window-relative, `identifier`, `target`, `force`, monotonic `timestamp`, single-element `touches`/`changedTouches` — a desktop pointer is one fabricated touch)\",\n differences: \"—\",\n },\n {\n name: \"TouchableOpacity\",\n subpath: \"react-native\",\n gtkImplementation: \"on top of Pressable\",\n supported: \"`activeOpacity`\",\n differences: \"—\",\n },\n {\n name: \"ScrollView\",\n subpath: \"react-native\",\n gtkImplementation: \"GtkScrolledWindow\",\n supported:\n \"vertical/`horizontal`, `contentContainerStyle`, `onScroll` (`contentOffset`, `contentSize`, `layoutMeasurement`), `onContentSizeChange`, `stickyHeaderIndices` (RN model: the REAL child is translated and painted on top — no duplicate), ref: `scrollTo`/`scrollToEnd` (`ScrollViewHandle`)\",\n differences: \"`animated` in scrollTo is ignored\",\n },\n {\n name: \"FlatList\",\n subpath: \"react-native\",\n gtkImplementation: \"windowed core on ScrollView\",\n supported:\n \"virtualization (`estimatedItemSize` or `getItemLayout`, **`windowSize`/`initialNumToRender` — the primary scroll-performance knobs**, `maxToRenderPerBatch`/`updateCellsBatchingPeriod`), `data`/`renderItem`/`keyExtractor`/`extraData`, `ItemSeparatorComponent`, `ListHeader/Footer/EmptyComponent`, `onEndReached(-Threshold)`, `onViewableItemsChanged`/`viewabilityConfig` (`ViewToken`), `inverted` (RN chat semantics: opens at `data[0]`, stays pinned on prepend), `refreshing`/`onRefresh`, `horizontal`, `stickyHeaderIndices`, ref: `scrollToIndex`/`scrollToItem`/`scrollToOffset` + ScrollView methods (`FlatListHandle`)\",\n differences:\n \"1000 rows mount windowed in ~120 ms (v1 full mount was 879 ms); `windowSize` defaults to **11**, not RN's 5 — desktop has no mobile memory pressure and a wider window means fewer mount+reflow bursts per scrolled pixel (measured: −21% churn, late frames 10/s → 7.7/s); rows beyond the visible ones are mounted `maxToRenderPerBatch` (10) at a time every `updateCellsBatchingPeriod` (50) ms, so a flick or a long `scrollToOffset` fills its window over several frames instead of stalling one; no pull gesture — `onRefresh` must be app-triggered; an inverted list shorter than its viewport anchors to the top, not the bottom\",\n },\n {\n name: \"SectionList\",\n subpath: \"react-native\",\n gtkImplementation: \"on top of FlatList\",\n supported:\n \"`sections`, `renderSectionHeader`, sticky section headers by default (`stickySectionHeadersEnabled`)\",\n differences:\n \"viewability props are not exposed (section-aware ViewTokens pending)\",\n },\n {\n name: \"Switch\",\n subpath: \"react-native\",\n gtkImplementation: \"GtkSwitch\",\n supported: \"`value`/`onValueChange`, `disabled`\",\n differences: \"sized by the GTK theme, not iOS metrics\",\n },\n {\n name: \"ActivityIndicator\",\n subpath: \"react-native\",\n gtkImplementation: \"GtkSpinner\",\n supported: \"`animating`, `size` (small/large/number)\",\n differences: \"no `color` yet\",\n },\n {\n name: \"Modal\",\n subpath: \"react-native\",\n gtkImplementation: \"modal GtkWindow (portal)\",\n supported:\n \"`visible`, `onRequestClose` (Escape/close button), `title`, `width`/`height`; independently resizable with relayout\",\n differences:\n \"desktop semantics: a separate window, not an overlay; `transparent`/`animationType` are no-ops\",\n },\n {\n name: \"Animated.View\",\n subpath: \"react-native\",\n gtkImplementation: \"direct widget calls\",\n supported:\n \"`opacity` and the whole `transform` array — `translateX/Y`, `scale`, `scaleX`, `scaleY`, `rotate`/`rotateZ` — driven by Animated nodes, bypassing React (an angle comes from `interpolate` with a `deg`/`rad` outputRange), plus the same responder and touch props `View` takes — this is where an idiomatic `PanResponder` drag lands\",\n differences:\n \"`rotateX`/`rotateY`/`perspective` (3D), `skewX`/`skewY` and `matrix` are not supported, and the transform origin is always the view's centre (no `transformOrigin`)\",\n },\n {\n name: \"SafeAreaView\",\n subpath: \"react-native\",\n gtkImplementation: \"= View\",\n supported: \"—\",\n differences: \"no notches on desktop\",\n },\n {\n name: \"StatusBar\",\n subpath: \"react-native\",\n gtkImplementation: \"null\",\n supported: \"—\",\n differences: \"no status bar\",\n },\n {\n name: \"Root\",\n subpath: \"react-native\",\n gtkImplementation: \"internal root\",\n supported: \"`width`/`height`\",\n differences: \"extension: required by the test harness\",\n },\n {\n name: \"NestedRoot\",\n subpath: \"react-native\",\n gtkImplementation: \"internal root\",\n supported: \"—\",\n differences:\n \"extension: a Yoga root inside any GTK container slot (navigation pages, custom containers); the slot allocation is the viewport\",\n },\n {\n name: \"IntrinsicRoot\",\n subpath: \"react-native\",\n gtkImplementation: \"internal root\",\n supported: \"—\",\n differences:\n \"extension: a content-sized Yoga root for chrome slots (HeaderBar start/end) — reports its content size to GTK\",\n },\n] as const satisfies readonly PortableRecord[]\n\nexport const PORTABLE_APIS = [\n {\n name: \"StyleSheet\",\n subpath: \"react-native\",\n supported:\n \"`create`, `flatten`, `compose`, `absoluteFill(Object)`, `hairlineWidth`\",\n differences: \"—\",\n },\n {\n name: \"PlatformColor\",\n subpath: \"react-native\",\n supported:\n 'Adwaita variables: `PlatformColor(\"accent-bg-color\")` → `var(--...)`, `@named`',\n differences: \"names are Adwaita, not iOS/Android\",\n },\n {\n name: \"AppRegistry\",\n subpath: \"react-native\",\n supported:\n \"`registerComponent`, `runApplication(appKey, {title,width,height,initialProps,chrome,actionAccels,breakpoints,applicationActions,windowActions,windowControllers})`, `getAppKeys`\",\n differences:\n 'desktop window parameters; `chrome: \"content\"` uses an AdwApplicationWindow with no window titlebar — the app\\'s HeaderBars (navigation) become the chrome. `actionAccels` binds accelerators to action names on the `GtkApplication`; `breakpoints` reaches `AdwApplicationWindow`\\'s own prop and only does anything under `chrome: \"content\"` (a dev warning fires otherwise). **`applicationActions`/`windowActions`/`windowControllers` are deprecated** — reach for [`<ApplicationActions>`/`<WindowActions>`/`<WindowControllers>`](platform-layer.md#actions-and-shortcuts-declared-in-the-app-tree) instead; they still work unchanged',\n },\n {\n name: \"Platform\",\n subpath: \"react-native\",\n supported:\n '`OS: \"linux\"`, `Version` (GTK), `select` (linux → native → default), `isTV`, `isTesting`',\n differences: \"—\",\n },\n {\n name: \"Dimensions\",\n subpath: \"react-native\",\n supported: '`get(\"window\"/\"screen\")`, `addEventListener(\"change\")`',\n differences: \"main window only (transient windows are ignored)\",\n },\n {\n name: \"useWindowDimensions\",\n subpath: \"react-native\",\n supported: \"reactive main-window dimensions\",\n differences: \"—\",\n },\n {\n name: \"Appearance\",\n subpath: \"react-native\",\n supported:\n \"`getColorScheme`, `setColorScheme` (AdwStyleManager), `addChangeListener`\",\n differences: \"—\",\n },\n {\n name: \"useColorScheme\",\n subpath: \"react-native\",\n supported: \"reactive theme\",\n differences: \"—\",\n },\n {\n name: \"AppState\",\n subpath: \"react-native\",\n supported: \"`currentState` active/background, `addEventListener`\",\n differences: \"driven by the window's `is-active`\",\n },\n {\n name: \"Alert\",\n subpath: \"react-native\",\n supported: \"`alert(title, message, buttons, options)` → Adw.AlertDialog\",\n differences: \"`cancel`/`destructive`/`isPreferred` styles\",\n },\n {\n name: \"Linking\",\n subpath: \"react-native\",\n supported:\n '`openURL`, `canOpenURL` (http/https/mailto/file), `getInitialURL` (null), `addEventListener(\"url\")`',\n differences:\n 'system launcher; no deep-link delivery on desktop yet — \"url\" subscriptions never fire',\n },\n {\n name: \"InteractionManager\",\n subpath: \"react-native\",\n supported:\n \"`runAfterInteractions(task?)` (cancellable, then-able), `createInteractionHandle`/`clearInteractionHandle`, `addListener`\",\n differences:\n \"navigation transitions register interactions, so screen work deferred with `runAfterInteractions` waits for the push/pop slide\",\n },\n {\n name: \"DevSettings\",\n subpath: \"react-native\",\n supported:\n \"`addMenuItem(title, handler)` (entries in the Dev Menu — Ctrl+Shift+D in `run-linux --dev`, the react-native-windows shortcut), `reload(reason?)`\",\n differences: \"silent no-ops in release builds, like RN\",\n },\n {\n name: \"I18nManager\",\n subpath: \"react-native\",\n supported:\n \"`isRTL` (live: GTK's read of the locale text direction), `doLeftAndRightSwapInRTL`, `getConstants`\",\n differences:\n \"`allowRTL`/`forceRTL`/`swapLeftAndRightInRTL` are accepted no-ops (mobile persistence has no desktop store)\",\n },\n {\n name: \"BackHandler\",\n subpath: \"react-native\",\n supported: '`addEventListener(\"hardwareBackPress\")`, `exitApp`',\n differences:\n \"no hardware back key on desktop — subscriptions are honored but nothing fires them yet\",\n },\n {\n name: \"PanResponder\",\n subpath: \"react-native\",\n supported:\n \"`create(config)` -> `panHandlers` (spread onto a `View`), full `gestureState` (`dx`/`dy`, `vx`/`vy`, `x0`/`y0`, `moveX`/`moveY`, `numberActiveTouches`) — **react-native's own file, vendored unmodified** (MIT, `Libraries/Interaction/PanResponder.js`), running on our reproduction of RN's `touchHistory` store\",\n differences:\n \"multi-touch `gestureState` is single-touch here (one pointer), and `onShouldBlockNativeResponder`'s return value is not consumed yet\",\n },\n {\n name: \"Animated\",\n subpath: \"react-native\",\n supported:\n \"`Value`, `timing`, `spring`, `sequence`, `parallel`, `delay`, `loop`, `interpolate` (numbers and deg/rad strings, clamp/extend/identity), `ValueXY` (`setValue`/`setOffset`/`flattenOffset`/`extractOffset`, `getLayout`, `getTranslateTransform`) — the value a `PanResponder` drag writes to\",\n differences:\n \"`useNativeDriver` is ignored (with a warning); the direct path is native-speed anyway; `Animated.event` is not implemented — write the value directly (`pan.setValue({x: g.dx, y: g.dy})`), which is what it would do\",\n },\n {\n name: \"Easing\",\n subpath: \"react-native\",\n supported: \"linear/ease/quad/cubic/in/out/inOut/bezier\",\n differences: \"—\",\n },\n {\n name: \"version\",\n subpath: \"react-native\",\n supported: \"package version\",\n differences: \"extension\",\n },\n] as const satisfies readonly PortableRecord[]\n\nexport const COMMON_PRIMITIVES = [\n {\n name: \"NavigationStack\",\n subpath: \"react-native-gtkx/common\",\n summary: \"`Adw.NavigationView` driven by a `stack` array of tags\",\n },\n {\n name: \"NavigationStackPage\",\n subpath: \"react-native-gtkx/common\",\n summary: \"one page of that stack, identified by `tag`\",\n },\n {\n name: \"SlotContent\",\n subpath: \"react-native-gtkx/common\",\n summary:\n \"Sizing: fills the slot. Use for: a page body, a pane, a dialog body.\",\n },\n {\n name: \"IntrinsicContent\",\n subpath: \"react-native-gtkx/common\",\n summary:\n \"Sizing: sized by its own Yoga layout. Use for: an AdwHeaderBar slot, a toolbar area, a list row.\",\n },\n] as const satisfies readonly CommonRecord[]\n\nexport const GTK_WIDGETS = [\n { name: \"GtkActionBar\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n {\n name: \"GtkAppChooserButton\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: true,\n },\n {\n name: \"GtkAppChooserWidget\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: true,\n },\n { name: \"GtkAspectFrame\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkBox\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkButton\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkCalendar\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkCellView\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkCenterBox\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkCheckButton\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkColorButton\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n {\n name: \"GtkColorChooserWidget\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: true,\n },\n {\n name: \"GtkColorDialogButton\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: true,\n },\n { name: \"GtkColumnView\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkComboBox\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkComboBoxText\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkDrawingArea\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkDropDown\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkEditableLabel\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkEmojiChooser\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkEntry\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkExpander\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n {\n name: \"GtkFileChooserWidget\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: true,\n },\n { name: \"GtkFixed\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkFlowBox\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkFontButton\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n {\n name: \"GtkFontChooserWidget\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: true,\n },\n {\n name: \"GtkFontDialogButton\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: true,\n },\n { name: \"GtkFrame\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkGLArea\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n {\n name: \"GtkGraphicsOffload\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: true,\n },\n { name: \"GtkGrid\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkGridView\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkHeaderBar\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkIconView\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkImage\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkInfoBar\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkInscription\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkLabel\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkLevelBar\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkLinkButton\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkListBox\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkListView\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkLockButton\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkMediaControls\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkMenuButton\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkNotebook\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkOverlay\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkPaned\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkPasswordEntry\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkPicture\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkPopover\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkPopoverBin\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkPopoverMenu\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n {\n name: \"GtkPopoverMenuBar\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: true,\n },\n { name: \"GtkProgressBar\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkRange\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkRevealer\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkScale\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkScaleButton\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkScrollbar\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n {\n name: \"GtkScrolledWindow\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: true,\n },\n { name: \"GtkSearchBar\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkSearchEntry\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkSeparator\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkShortcutLabel\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n {\n name: \"GtkShortcutsGroup\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: true,\n },\n {\n name: \"GtkShortcutsSection\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: true,\n },\n {\n name: \"GtkShortcutsShortcut\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: true,\n },\n { name: \"GtkSpinButton\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkSpinner\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkStack\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkStackSidebar\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkStackSwitcher\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkStatusbar\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkSwitch\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkText\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkTextView\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkToggleButton\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkTreeExpander\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkTreeView\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkVideo\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkViewport\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n { name: \"GtkVolumeButton\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n {\n name: \"GtkWindowControls\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: true,\n },\n { name: \"GtkWindowHandle\", subpath: \"react-native-gtkx/gtk\", wrapped: true },\n {\n name: \"GtkAboutDialog\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: false,\n reason: \"toplevel (implements GtkRoot)\",\n },\n {\n name: \"GtkAppChooserDialog\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: false,\n reason: \"toplevel (implements GtkRoot)\",\n },\n {\n name: \"GtkApplicationWindow\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: false,\n reason: \"toplevel (implements GtkRoot)\",\n },\n {\n name: \"GtkAssistant\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: false,\n reason: \"toplevel (implements GtkRoot)\",\n },\n {\n name: \"GtkColorChooserDialog\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: false,\n reason: \"toplevel (implements GtkRoot)\",\n },\n {\n name: \"GtkDialog\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: false,\n reason: \"toplevel (implements GtkRoot)\",\n },\n {\n name: \"GtkDragIcon\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: false,\n reason: \"toplevel (implements GtkRoot)\",\n },\n {\n name: \"GtkFileChooserDialog\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: false,\n reason: \"toplevel (implements GtkRoot)\",\n },\n {\n name: \"GtkFlowBoxChild\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: false,\n reason: \"child-only (derives Gtk.FlowBoxChild)\",\n },\n {\n name: \"GtkFontChooserDialog\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: false,\n reason: \"toplevel (implements GtkRoot)\",\n },\n {\n name: \"GtkListBoxRow\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: false,\n reason: \"child-only (derives Gtk.ListBoxRow)\",\n },\n {\n name: \"GtkMessageDialog\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: false,\n reason: \"toplevel (implements GtkRoot)\",\n },\n {\n name: \"GtkPageSetupUnixDialog\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: false,\n reason: \"toplevel (implements GtkRoot)\",\n },\n {\n name: \"GtkPrintUnixDialog\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: false,\n reason: \"toplevel (implements GtkRoot)\",\n },\n {\n name: \"GtkShortcutsWindow\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: false,\n reason: \"toplevel (implements GtkRoot)\",\n },\n {\n name: \"GtkWindow\",\n subpath: \"react-native-gtkx/gtk\",\n wrapped: false,\n reason: \"toplevel (implements GtkRoot)\",\n },\n] as const satisfies readonly WidgetRecord[]\n\nexport const ADW_WIDGETS = [\n { name: \"AdwAboutDialog\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwAlertDialog\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwAvatar\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwBanner\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwBin\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwBottomSheet\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwBreakpointBin\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwButtonContent\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwCarousel\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n {\n name: \"AdwCarouselIndicatorDots\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: true,\n },\n {\n name: \"AdwCarouselIndicatorLines\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: true,\n },\n { name: \"AdwClamp\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n {\n name: \"AdwClampScrollable\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: true,\n },\n { name: \"AdwDialog\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwFlap\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwHeaderBar\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n {\n name: \"AdwInlineViewSwitcher\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: true,\n },\n { name: \"AdwLayoutSlot\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwLeaflet\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n {\n name: \"AdwMultiLayoutView\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: true,\n },\n {\n name: \"AdwNavigationSplitView\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: true,\n },\n {\n name: \"AdwNavigationView\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: true,\n },\n {\n name: \"AdwOverlaySplitView\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: true,\n },\n {\n name: \"AdwPreferencesDialog\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: true,\n },\n {\n name: \"AdwPreferencesGroup\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: true,\n },\n { name: \"AdwShortcutLabel\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n {\n name: \"AdwShortcutsDialog\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: true,\n },\n { name: \"AdwSidebar\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwSpinner\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwSplitButton\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwSqueezer\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwStatusPage\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwTabBar\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwTabButton\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwTabOverview\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwTabView\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwToastOverlay\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwToggleGroup\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwToolbarView\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwViewStack\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwViewSwitcher\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n {\n name: \"AdwViewSwitcherBar\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: true,\n },\n {\n name: \"AdwViewSwitcherSidebar\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: true,\n },\n {\n name: \"AdwViewSwitcherTitle\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: true,\n },\n { name: \"AdwWindowTitle\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n { name: \"AdwWrapBox\", subpath: \"react-native-gtkx/adw\", wrapped: true },\n {\n name: \"AdwAboutWindow\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"toplevel (implements GtkRoot)\",\n },\n {\n name: \"AdwActionRow\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"child-only (derives Gtk.ListBoxRow)\",\n },\n {\n name: \"AdwApplicationWindow\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"toplevel (implements GtkRoot)\",\n },\n {\n name: \"AdwButtonRow\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"child-only (derives Gtk.ListBoxRow)\",\n },\n {\n name: \"AdwComboRow\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"child-only (derives Gtk.ListBoxRow)\",\n },\n {\n name: \"AdwEntryRow\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"child-only (derives Gtk.ListBoxRow)\",\n },\n {\n name: \"AdwExpanderRow\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"child-only (derives Gtk.ListBoxRow)\",\n },\n {\n name: \"AdwMessageDialog\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"toplevel (implements GtkRoot)\",\n },\n {\n name: \"AdwNavigationPage\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"child-only (denylist — see scripts/widget-surface/classify.ts)\",\n },\n {\n name: \"AdwPasswordEntryRow\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"child-only (derives Gtk.ListBoxRow)\",\n },\n {\n name: \"AdwPreferencesPage\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"child-only (denylist — see scripts/widget-surface/classify.ts)\",\n },\n {\n name: \"AdwPreferencesRow\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"child-only (derives Gtk.ListBoxRow)\",\n },\n {\n name: \"AdwPreferencesWindow\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"toplevel (implements GtkRoot)\",\n },\n {\n name: \"AdwSpinRow\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"child-only (derives Gtk.ListBoxRow)\",\n },\n {\n name: \"AdwSwitchRow\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"child-only (derives Gtk.ListBoxRow)\",\n },\n {\n name: \"AdwWindow\",\n subpath: \"react-native-gtkx/adw\",\n wrapped: false,\n reason: \"toplevel (implements GtkRoot)\",\n },\n] as const satisfies readonly WidgetRecord[]\n\nexport const DOC_CHUNKS = [\n {\n doc: \"docs/api.md\",\n heading: \"Components\",\n text: \"| Export | GTK implementation | Supported | Differences from RN |\\n| ------------------- | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\\n| `View` | GtkBox (RnGtkxViewBox) | `style`, `onLayout`, `testID`, children, `pointerEvents` (auto/none/box-none/box-only — mapped onto GTK picking: can-target + a contains() vfunc override; also honored from `style.pointerEvents`, the prop wins), ref: `measure`/`measureInWindow`/`measureLayout` (`ViewHandle`, RN's argument order; window coordinates come from `gtk_widget_compute_point`, so they are correct inside a scrolled viewport), the responder and touch props (`onStartShouldSetResponder(Capture)`, `onMoveShouldSetResponder(Capture)`, `onResponderGrant/Start/Move/End/Release/Terminate`, `onTouchStart/Move/End/Cancel` + `Capture`) — spread `PanResponder`'s `panHandlers` here | nesting another pointerEvents inside a box-only view is not supported; responder negotiation is capture-then-bubble as in RN, but there is **no transfer yet**: once a view is granted, `onResponderTerminationRequest`/`onResponderReject` are never called and a second view cannot steal (GTK's `CLAIMED` is irrevocable, so a transfer could not be enforced against native widgets — see docs/research/gestures.md). The lock is one per process as in RN; the negotiation PATH stops at the layout root, so native GTK widgets between or above views take no part. Single-pointer only: a mouse is one fabricated touch, `touches` never exceeds one |\\n| `Text` | GtkLabel (Pango) | wrap, `numberOfLines` (ellipsize END), `textAlign`, font styles, `onLayout`, `testID` | nested `Text` elements are concatenated without per-span styles; text is always ellipsizable (shrinkable in narrow windows) |\\n| `Image` | GtkPicture | `source={{uri}}`/string — local paths, file:// and **http(s)** (Node fetch → disk cache keyed by URL, in-flight de-duplication), `resizeMode` cover/contain/stretch/center, `onLoad`/`onError`; **`.svg` files load like any other image** — `Gdk.Texture.newFromFilename` rasterizes them via librsvg, no extra code needed (for building vector graphics from state instead of a file, see the \\\"Svg\\\" section below — a separate import, not part of this table) | no synchronous size from remote images (style sets the size, as in RN); cache is not size-limited yet |\\n| `TextInput` | GtkEntry / GtkTextView | controlled/uncontrolled (`value`/`defaultValue`), `onChangeText`, `onSubmitEditing`, `onFocus`/`onBlur`, `placeholder` (own dim overlay in multiline — GtkTextView has none), `secureTextEntry`, `editable`, `keyboardType`, `multiline`, `clearButtonMode` (GtkEntry's built-in clear icon; RN ships this on iOS only) (real GtkTextView: word wrap, internal scroll, Enter inserts a newline and never fires onSubmitEditing — RN semantics) | multiline needs a height in the style (as RN recommends) |\\n| `Pressable` | GtkFixed + GestureClick/Motion | `onPress(In/Out)`, `onLongPress` (`delayLongPress`), `onHoverIn/Out`, `disabled`, function-form `style`/`children` receiving `{pressed, hovered}`; the `PressEvent` payload is RN's shape (`locationX/Y` target-relative, `pageX/Y` window-relative, `identifier`, `target`, `force`, monotonic `timestamp`, single-element `touches`/`changedTouches` — a desktop pointer is one fabricated touch) | — |\\n| `TouchableOpacity` | on top of Pressable | `activeOpacity` | — |\\n| `ScrollView` | GtkScrolledWindow | vertical/`horizontal`, `contentContainerStyle`, `onScroll` (`contentOffset`, `contentSize`, `layoutMeasurement`), `onContentSizeChange`, `stickyHeaderIndices` (RN model: the REAL child is translated and painted on top — no duplicate), ref: `scrollTo`/`scrollToEnd` (`ScrollViewHandle`) | `animated` in scrollTo is ignored |\\n| `FlatList` | windowed core on ScrollView | virtualization (`estimatedItemSize` or `getItemLayout`, **`windowSize`/`initialNumToRender` — the primary scroll-performance knobs**, `maxToRenderPerBatch`/`updateCellsBatchingPeriod`), `data`/`renderItem`/`keyExtractor`/`extraData`, `ItemSeparatorComponent`, `ListHeader/Footer/EmptyComponent`, `onEndReached(-Threshold)`, `onViewableItemsChanged`/`viewabilityConfig` (`ViewToken`), `inverted` (RN chat semantics: opens at `data[0]`, stays pinned on prepend), `refreshing`/`onRefresh`, `horizontal`, `stickyHeaderIndices`, ref: `scrollToIndex`/`scrollToItem`/`scrollToOffset` + ScrollView methods (`FlatListHandle`) | 1000 rows mount windowed in ~120 ms (v1 full mount was 879 ms); `windowSize` defaults to **11**, not RN's 5 — desktop has no mobile memory pressure and a wider window means fewer mount+reflow bursts per scrolled pixel (measured: −21% churn, late frames 10/s → 7.7/s); rows beyond the visible ones are mounted `maxToRenderPerBatch` (10) at a time every `updateCellsBatchingPeriod` (50) ms, so a flick or a long `scrollToOffset` fills its window over several frames instead of stalling one; no pull gesture — `onRefresh` must be app-triggered; an inverted list shorter than its viewport anchors to the top, not the bottom |\\n| `SectionList` | on top of FlatList | `sections`, `renderSectionHeader`, sticky section headers by default (`stickySectionHeadersEnabled`) | viewability props are not exposed (section-aware ViewTokens pending) |\\n| `Switch` | GtkSwitch | `value`/`onValueChange`, `disabled` | sized by the GTK theme, not iOS metrics |\\n| `ActivityIndicator` | GtkSpinner | `animating`, `size` (small/large/number) | no `color` yet |\\n| `Modal` | modal GtkWindow (portal) | `visible`, `onRequestClose` (Escape/close button), `title`, `width`/`height`; independently resizable with relayout | desktop semantics: a separate window, not an overlay; `transparent`/`animationType` are no-ops |\\n| `Animated.View` | direct widget calls | `opacity` and the whole `transform` array — `translateX/Y`, `scale`, `scaleX`, `scaleY`, `rotate`/`rotateZ` — driven by Animated nodes, bypassing React (an angle comes from `interpolate` with a `deg`/`rad` outputRange), plus the same responder and touch props `View` takes — this is where an idiomatic `PanResponder` drag lands | `rotateX`/`rotateY`/`perspective` (3D), `skewX`/`skewY` and `matrix` are not supported, and the transform origin is always the view's centre (no `transformOrigin`) |\\n| `SafeAreaView` | = View | — | no notches on desktop |\\n| `StatusBar` | null | — | no status bar |\\n| `Root` | internal root | `width`/`height` | extension: required by the test harness |\\n| `NestedRoot` | internal root | — | extension: a Yoga root inside any GTK container slot (navigation pages, custom containers); the slot allocation is the viewport |\\n| `IntrinsicRoot` | internal root | — | extension: a content-sized Yoga root for chrome slots (HeaderBar start/end) — reports its content size to GTK |\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"API modules\",\n text: '| Export | Supported | Differences |\\n| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\\n| `StyleSheet` | `create`, `flatten`, `compose`, `absoluteFill(Object)`, `hairlineWidth` | — |\\n| `PlatformColor` | Adwaita variables: `PlatformColor(\"accent-bg-color\")` → `var(--...)`, `@named` | names are Adwaita, not iOS/Android |\\n| `AppRegistry` | `registerComponent`, `runApplication(appKey, {title,width,height,initialProps,chrome,actionAccels,breakpoints,applicationActions,windowActions,windowControllers})`, `getAppKeys` | desktop window parameters; `chrome: \"content\"` uses an AdwApplicationWindow with no window titlebar — the app\\'s HeaderBars (navigation) become the chrome. `actionAccels` binds accelerators to action names on the `GtkApplication`; `breakpoints` reaches `AdwApplicationWindow`\\'s own prop and only does anything under `chrome: \"content\"` (a dev warning fires otherwise). **`applicationActions`/`windowActions`/`windowControllers` are deprecated** — reach for [`<ApplicationActions>`/`<WindowActions>`/`<WindowControllers>`](platform-layer.md#actions-and-shortcuts-declared-in-the-app-tree) instead; they still work unchanged |\\n| `Platform` | `OS: \"linux\"`, `Version` (GTK), `select` (linux → native → default), `isTV`, `isTesting` | — |\\n| `Dimensions` | `get(\"window\"/\"screen\")`, `addEventListener(\"change\")` | main window only (transient windows are ignored) |\\n| `useWindowDimensions` | reactive main-window dimensions | — |\\n| `Appearance` | `getColorScheme`, `setColorScheme` (AdwStyleManager), `addChangeListener` | — |\\n| `useColorScheme` | reactive theme | — |\\n| `AppState` | `currentState` active/background, `addEventListener` | driven by the window\\'s `is-active` |\\n| `Alert` | `alert(title, message, buttons, options)` → Adw.AlertDialog | `cancel`/`destructive`/`isPreferred` styles |\\n| `Linking` | `openURL`, `canOpenURL` (http/https/mailto/file), `getInitialURL` (null), `addEventListener(\"url\")` | system launcher; no deep-link delivery on desktop yet — \"url\" subscriptions never fire |\\n| `InteractionManager` | `runAfterInteractions(task?)` (cancellable, then-able), `createInteractionHandle`/`clearInteractionHandle`, `addListener` | navigation transitions register interactions, so screen work deferred with `runAfterInteractions` waits for the push/pop slide |\\n| `DevSettings` | `addMenuItem(title, handler)` (entries in the Dev Menu — Ctrl+Shift+D in `run-linux --dev`, the react-native-windows shortcut), `reload(reason?)` | silent no-ops in release builds, like RN |\\n| `I18nManager` | `isRTL` (live: GTK\\'s read of the locale text direction), `doLeftAndRightSwapInRTL`, `getConstants` | `allowRTL`/`forceRTL`/`swapLeftAndRightInRTL` are accepted no-ops (mobile persistence has no desktop store) |\\n| `BackHandler` | `addEventListener(\"hardwareBackPress\")`, `exitApp` | no hardware back key on desktop — subscriptions are honored but nothing fires them yet |\\n| `PanResponder` | `create(config)` -> `panHandlers` (spread onto a `View`), full `gestureState` (`dx`/`dy`, `vx`/`vy`, `x0`/`y0`, `moveX`/`moveY`, `numberActiveTouches`) — **react-native\\'s own file, vendored unmodified** (MIT, `Libraries/Interaction/PanResponder.js`), running on our reproduction of RN\\'s `touchHistory` store | multi-touch `gestureState` is single-touch here (one pointer), and `onShouldBlockNativeResponder`\\'s return value is not consumed yet |\\n| `Animated` | `Value`, `timing`, `spring`, `sequence`, `parallel`, `delay`, `loop`, `interpolate` (numbers and deg/rad strings, clamp/extend/identity), `ValueXY` (`setValue`/`setOffset`/`flattenOffset`/`extractOffset`, `getLayout`, `getTranslateTransform`) — the value a `PanResponder` drag writes to | `useNativeDriver` is ignored (with a warning); the direct path is native-speed anyway; `Animated.event` is not implemented — write the value directly (`pan.setValue({x: g.dx, y: g.dy})`), which is what it would do |\\n| `Easing` | linear/ease/quad/cubic/in/out/inOut/bezier | — |\\n| `version` | package version | extension |\\n\\nStyles (which keys go where and what is unsupported) — [style system table](../packages/react-native-gtkx/src/style/README.md). Includes `boxShadow` (RN 0.76) and `outlineColor`/`outlineOffset`/`outlineStyle`/`outlineWidth` (RN 0.77): both are what Adwaita\\'s own theme uses for the `.card`/`.boxed-list` frame and for every focus ring, so they are the difference between a React Native style approximating the platform look and reproducing it — see [research/react-native-first-showcase.md](research/react-native-first-showcase.md).',\n },\n {\n doc: \"docs/api.md\",\n heading: \"Key differences from React Native (summary)\",\n text: \"1. **Desktop, not mobile**: `Modal` is a real window; `runApplication` accepts a title and dimensions; gestures are mouse-driven (hover works, no touch gestures);\\n2. **Node.js runtime**: all of npm/Node is available (fs, sqlite, napi) — \\\"native modules\\\" are written as regular Node modules; RN libraries with iOS/Android code do not work;\\n3. **Layout is exactly RN's**: every container runs a custom GtkLayoutManager that obeys only the Yoga engine — GTK widget minimums never leak into the layout, windows shrink freely, and `Dimensions.get(\\\"window\\\")` reports the app viewport (the window's content area under the headerbar, like RN's app window);\\n4. **Text**: the ellipsis is opt-in via `numberOfLines`, exactly like RN; plain text wraps naturally and an unbreakable word wider than its box clips to it (text leaves clip; containers keep paint-overflow);\\n5. **transform** is paint-only, like RN: `translateX/Y`, `scale`, `scaleX`, `scaleY` and `rotate`/`rotateZ` apply to any component's style (not just `Animated.View`), the array composes left to right as in RN and CSS, and the origin is the view's centre. A transformed child honestly draws past its container over siblings (later siblings stay on top, RN's default z-order) without moving any ancestor, and GTK routes input through the transform, so a rotated view is clickable in its rotated shape. Rotation and scale reach the widget as the `GskTransform` of its allocation (`docs/research/transforms.md`); 3D (`rotateX`/`rotateY`/`perspective`), `skewX`/`skewY`, `matrix` and `transformOrigin` are not supported;\\n6. **Animations never auto-stop**: the desktop \\\"reduce animations\\\" hint is not applied automatically (GTK-side animations are kept on to match `Animated`, which runs on its own timers) — honoring reduced motion stays an app-level opt-in, as in RN;\\n7. **Lists are windowed like RN's**: FlatList/SectionList mount only the rows around the viewport (prefix-sum offsets, `estimatedItemSize` refined by real measurements or exact `getItemLayout`); sticky headers translate the REAL widget (no duplicate) and `inverted` follows the RN chat contract — `contentOffset` counts from the end where `data[0]` renders. The one RefreshControl compromise: desktop has no pull gesture, so `refreshing`/`onRefresh` are API-compatible but the trigger is app chrome (a button/shortcut);\\n8. The package ships compiled (`dist/`: ESM + `.d.ts` alongside, sources embedded in the maps); consumers — Metro (`react-native-gtkx/metro` preset) and vite (preset) — both consume the built output. Requires Node ≥ 24 (the gtkx runtime floor; the run-linux host also relies on `module.registerHooks`).\\n9. **Pre-commit hooks regenerate derived data**: editing this file (or the other generator inputs) and forgetting to run `scripts/generate-mcp-data.mjs` no longer fails CI — the pre-commit hook regenerates `packages/react-native-gtkx/src/mcp/data/generated.ts` and stages it for you.\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"Navigation (`react-native-gtkx/navigation`)\",\n text: 'A [react-navigation](https://reactnavigation.org) stack navigator backed by\\n`Adw.NavigationView` — native Adwaita page transitions, the HeaderBar back\\nbutton and back gestures stay in sync with react-navigation state (the\\nreact-native-windows / native-stack model). Requires the optional peer\\n`@react-navigation/native` (v8).\\n\\n`@react-navigation/native@8` itself peers on `react-native: \"*\"` (unlike\\n`@react-navigation/core@8`, which has no react-native peer at all). If your\\napp has no `react-native` package anywhere in its tree — a vite+gtkx app\\nwith no Metro side, exactly what `examples/gallery` demonstrates —\\n`npm install` will print an unmet-peer-dependency warning for it. This is\\nharmless: react-native-gtkx never imports anything from the `react-native`\\npackage, so nothing actually needs it at runtime; the warning is npm being\\nstrict about a peer range upstream declared loosely (`\"*\"` — any version\\nsatisfies it, npm just wants the package present at all).\\n\\n```tsx\\nimport { NavigationContainer } from \"@react-navigation/native\"\\nimport { createStackNavigator } from \"react-native-gtkx/navigation\"\\n\\n// Run the app with chrome: \"content\" — the navigator\\'s HeaderBars ARE the\\n// window chrome (the default system chrome would add a second titlebar):\\n// AppRegistry.runApplication(name, { ..., chrome: \"content\" })\\n\\nconst Stack = createStackNavigator()\\n\\nconst App = () => (\\n <NavigationContainer>\\n <Stack.Navigator>\\n <Stack.Screen\\n name=\"Home\"\\n component={HomeScreen}\\n />\\n <Stack.Screen\\n name=\"Details\"\\n component={DetailsScreen}\\n options={{ title: \"Details page\" }}\\n />\\n </Stack.Navigator>\\n </NavigationContainer>\\n)\\n```\\n\\n- Screen `options`: `title` (HeaderBar title, defaults to the route name),\\n `headerShown` (default true).\\n- `createSidebarNavigator` — the desktop drawer equivalent on\\n `Adw.NavigationSplitView`: a persistent native sidebar (`AdwActionRow`\\n per screen, in a GtkListBox with Adwaita `navigation-sidebar` styling)\\n selects between parallel screens (TabRouter semantics). Navigator prop\\n `sidebarTitle`; screen `options`: `title`, `icon` (Adwaita symbolic icon\\n name for the row\\'s prefix), `color` (a CSS color for a colored-dot\\n prefix instead of `icon` — the two are mutually exclusive per row,\\n `color` wins if both are set), `count` (a badge suffix, hidden when 0 or\\n unset). Run the app with `chrome: \"content\"` so the split view\\'s\\n HeaderBars are the window chrome (`examples/gallery` is built on it).\\n Navigator prop `headerButtons` packs declarative native buttons into the\\n content HeaderBar end (`{id, icon, tooltip, onPress}`, `icon` is an\\n Adwaita symbolic name) — the gallery\\'s color-scheme toggle uses it.\\n Navigator prop `collapseWidth` (sp): below this width the split view\\n collapses to the sidebar or the content pane alone, through a native\\n `Adw.Breakpoint` wrapping the view in an `AdwBreakpointBin` — NOT a\\n `useWindowDimensions` conditional (see docs/platform-layer.md, \"Two ways\\n to react to size\"); the property flip happens inside GTK\\'s own\\n allocation pass, costing no React render for the resize itself. Unset by\\n default — no `AdwBreakpointBin` is mounted at all, so existing consumers\\n see no behavior change. Any route becoming active while collapsed\\n reveals content (`AdwNavigationSplitView.showContent`, a plain native\\n property write, not React state) — a row click OR a programmatic\\n `navigate()`/`jumpTo()`; the native back button that then appears\\n reverses it. Re-selecting the same, already-active row after that also\\n reveals content again — GTK\\'s `row-selected` does not refire for a\\n re-click with no selection change, so this is driven by `row-activated`\\n (fires on every click) in addition. The reverse direction — the split\\n view\\'s own back button, Escape or back gesture hiding content again — is\\n observed too: it fires a `sidebarShown` event\\n (`navigation.addListener(\"sidebarShown\", …)`) on the currently active\\n route, the same event-map protocol `createStackNavigator`\\'s\\n `transitionStart`/`transitionEnd` use. Nothing in react-navigation state\\n changes when this fires — TabRouter has no \"closed\" concept, the same\\n route stays focused, only the pane did — so it exists purely for an app\\n that wants to react (`examples/tasks-nav`\\'s `ContentScreen` resets its\\n own in-screen \"open task\" state on it). Never fired for content being\\n revealed (that direction is already an ordinary state change) or when\\n `collapseWidth` is unset. Resizing back above `collapseWidth` and then\\n back below it again does NOT reset `showContent` or the selection —\\n confirmed empirically, not assumed — both simply persist across the\\n round trip, the same size-class behavior a mobile master-detail app\\n relies on; see docs/research/navigation-extensibility.md for the\\n evidence.\\n- **Which rung to reach for.** Three ways to put content in the sidebar,\\n cheapest first — the same ladder react-navigation\\'s own `tabBarIcon` →\\n `drawerLabel` → `drawerContent` climbs: (1) `title`/`icon`/`color`/`count`\\n above — the convenience; composes an `AdwActionRow`. (2) `sidebarRow`\\n (screen option, below) — draw one row yourself; the navigator keeps the\\n list and everything attached to it (selection, click → `jumpTo`, staying\\n in step with navigation state, the collapsed reveal). (3) `sidebarContent`\\n (navigator prop, below) — draw the whole pane, routing surface included.\\n The reason rungs 2 and 3 exist at all, plainly: **`AdwActionRow` carries\\n Adwaita\\'s OWN row metrics, not a default this package picked** — measured\\n at roughly 104px per row (with a prefix and/or count laid out) against\\n ~40px for a plain title-only row — and nothing passed to\\n `title`/`icon`/`color`/`count` changes that height. A screen on rung 1\\n has no lever for it; wanting a different height or density means climbing\\n to `sidebarRow` or `sidebarContent` instead.\\n- Sidebar navigator props `minWidth` / `minHeight` (px, default 360×294 —\\n GNOME\\'s own adaptive floor): the narrowest size this navigator\\'s UI\\n supports, applied to the `AdwBreakpointBin` that `collapseWidth` mounts.\\n Ignored when `collapseWidth` is unset, since no bin exists then. Adwaita\\n cannot measure a breakpoint bin — what it contains changes with the\\n breakpoints — so the bin reports a minimum of ZERO and warns that\\n `width-request`/`height-request` must be set. Under `chrome: \"content\"`\\n the bin is the window\\'s own child, so that zero IS the window\\'s floor:\\n the window resizes straight past what the pane inside can draw, and\\n Adwaita clips the pane instead of adapting it (\"AdwNavigationSplitView\\n exceeds AdwBreakpointBin width: requested 469 px, 360 px available\" in\\n the journal, felt as a list running off the right edge with its trailing\\n controls cut away). An app whose content HeaderBar needs more than the\\n default must raise it — measure the pane rather than guessing: a\\n segmented control as `headerTitle` costs ~110px on its own and, unlike a\\n title label, cannot ellipsize. `examples/tasks-nav` passes `480` for\\n exactly that reason; the value stays below its `collapseWidth`, so the\\n collapsed layout is still fully reachable.\\n- Sidebar screen options `headerLeft` / `headerRight` / `headerTitle`:\\n `() => ReactNode` — the content HeaderBar\\'s own start/end/title, per\\n screen, on top of the one navigator-wide default. This is what lets one\\n screen\\'s header change shape with ITS OWN selection (a filter toggle\\n group for a list, a back button plus star/trash for an open item):\\n call `navigation.setOptions({ headerLeft, headerRight, headerTitle })`\\n from inside the screen, in an effect keyed on whatever local state\\n decides its shape — no stack involved, and no new navigator API beyond\\n the options themselves (`useNavigationBuilder` already re-resolves\\n descriptor options on every `setOptions` call). `headerTitle` replaces\\n the HeaderBar\\'s title widget outright (unset, the page\\'s own title\\n shows automatically, as before). A screen\\'s own `headerButtons`\\n (`HeaderButton[]`, same shape as the navigator prop) replaces the\\n navigator-level default entirely for that screen. **Caveat, found\\n while testing this**: `setOptions` MERGES into the previously resolved\\n options rather than replacing them — a call that omits `headerRight`\\n does not clear a `headerRight` a PREVIOUS call set, it leaves it in\\n place. A screen that flips between shapes must give every one of these\\n four keys an explicit value (`undefined` counts as a real overwrite; an\\n absent key does not) on every call, not just the ones currently in use.\\n- Sidebar screen option `sidebarRow`: `() => ReactNode` — draw the row\\n yourself instead of letting `title`/`icon`/`color`/`count` compose one.\\n Those four are a convenience, not the ceiling: they build an\\n `AdwActionRow`, which brings Adwaita\\'s own row metrics with it, so an app\\n wanting a different shape, density or height had nothing to reach for.\\n Return anything a `GtkListBoxRow` can hold — React Native content, GTK\\n widgets, a differently-configured Adwaita row. The navigator keeps owning\\n row BEHAVIOUR (selection, click → `jumpTo`, staying in step with\\n navigation state, the collapsed reveal), so a custom row cannot drift out\\n of sync with the router; only what is drawn changes. A screen that passes\\n none of `icon`/`color`/`count` gets a compact `GtkListBoxRow` + label\\n automatically — `AdwActionRow`\\'s height is right when there IS a prefix\\n and a count to lay out and pure cost when there is not. The next rung up\\n is `sidebarContent`, below, for replacing the whole pane rather than one\\n row.\\n- Sidebar navigator prop `sidebarContent`:\\n `(props: SidebarContentProps) => ReactNode` — replaces the ENTIRE sidebar\\n pane\\'s body, for a sidebar that needs sections, a search field, a footer,\\n or anything a flat list of rows cannot express. The sidebar\\'s children\\n stop being \"one row per screen\": you draw what you like, and navigation\\n is just the `jumpTo` you were handed. `SidebarContentProps` carries\\n `routes` (key, name, resolved options, title, `focused`), `focusedIndex`\\n and `jumpTo(name)` — use those rather than dispatching yourself, so\\n selection cannot drift from navigation state. The pane\\'s AdwHeaderBar and\\n `sidebarTitle` still belong to the navigator: this is the body under it,\\n not the chrome. Mounted as React Native content (a layout root filling\\n the pane); a sidebar built from GTK widgets wraps its own tree in\\n `WidgetContent`, the same escape hatch `contentLayout: \"widget\"` is for a\\n screen body. Reach for `sidebarRow` (above) first if you only want a\\n different ROW — it keeps the navigator\\'s list and everything attached to\\n it; this one hands over the whole pane, routing included. A sidebar with\\n a search field above the list and a footer below it, still driven by the\\n navigator\\'s own routing:\\n\\n ```tsx\\n <Sidebar.Navigator\\n sidebarContent={({ routes, focusedIndex, jumpTo }) => (\\n <View style={{ flex: 1 }}>\\n <SearchField onSubmit={filterRoutes} />\\n <ScrollView style={{ flex: 1 }}>\\n {routes.map((route, index) => (\\n <Pressable\\n key={route.key}\\n onPress={() => jumpTo(route.name)}\\n >\\n <Text\\n style={{\\n padding: 8,\\n fontWeight: index === focusedIndex ? \"700\" : \"400\",\\n }}\\n >\\n {route.title}\\n </Text>\\n </Pressable>\\n ))}\\n </ScrollView>\\n <StorageUsageFooter />\\n </View>\\n )}\\n >\\n <Sidebar.Screen\\n name=\"Inbox\"\\n component={InboxScreen}\\n />\\n <Sidebar.Screen\\n name=\"Trash\"\\n component={TrashScreen}\\n />\\n </Sidebar.Navigator>\\n ```\\n\\n `route.title` is already resolved (`options.title`, falling back to the\\n route name) — no need to read `options.title` yourself. `jumpTo` reveals\\n the content pane when collapsed, same as a native row click; the\\n navigator, not this callback, decides that.\\n\\n- Sidebar navigator props `sidebarHeaderLeft` / `sidebarHeaderRight` /\\n `sidebarHeaderTitle`: `() => ReactNode` — the SIDEBAR pane\\'s own\\n AdwHeaderBar start/end/title, the exact counterparts of the content\\n header\\'s `headerLeft`/`headerRight`/`headerTitle`. Until these existed the\\n sidebar header was a hard-coded `<AdwHeaderBar />` and `sidebarTitle` (a\\n plain string) was the only thing an app could set on it at all, so a\\n sidebar\\'s own \"new item\" action — where GNOME puts it, next to the pane\\n title — had nowhere to go and ended up on the content header instead\\n (`examples/tasks-nav` shipped with two indistinguishable `+` buttons for\\n exactly this reason). `sidebarHeaderTitle` replaces the title widget the\\n same way a screen\\'s `headerTitle` does; unset, `sidebarTitle` renders as\\n before. Content is mounted through the same `HeaderSlotContent` root the\\n content header uses, so React Native content lays out as a horizontal,\\n content-hugging cluster flush with natively packed buttons — do not\\n hand-roll an `IntrinsicContent` here, a bare Yoga root defaults to\\n `column` and pushes the window controls onto a second row. These are\\n navigator PROPS rather than screen options on purpose: there is one\\n sidebar pane shared by every screen, so its chrome sits at the level\\n `sidebarTitle`/`sidebarContent` already do, and the `sidebar` prefix marks\\n which header a name refers to. There is deliberately no\\n `sidebarHeaderButtons` convenience mirroring `headerButtons` — arbitrary\\n content is the primitive, and a one-button call site reads no better as a\\n `{id, icon, tooltip, onPress}` record than as the `GtkButton` it already\\n is; add it only if a real call site is worse without it.\\n\\n- Sidebar screen option `contentLayout`: `\"react-native\"` (default) or\\n `\"widget\"` — what the screen\\'s body IS. The default mounts it in a Yoga\\n layout root that fills the pane, so `<View style={{ flex: 1 }}>` behaves\\n the way it does anywhere else. `\"widget\"` packs the body into the page\\n directly, with no layout root in between, for a screen whose body is a\\n GTK widget tree (a `GtkScrolledWindow` around an `AdwClamp` around a\\n `.boxed-list` `GtkListBox`, say): GTK\\'s own sizing — `vexpand`, a list\\'s\\n natural height — then applies normally. **Under the default a widget tree\\n collapses instead**, and quietly: every widget becomes a single Yoga LEAF\\n measured for its own natural size, so a container renders its first child,\\n drops the rest, and reports the ~1px it can shrink to, with no error\\n anywhere. `examples/tasks-nav` is built this way. Mixing is per screen,\\n not per subtree — a `\"widget\"` screen that wants React Native content\\n somewhere inside it wraps that part in `SlotContent` itself.\\n- Stack screen options `headerLeft` / `headerRight`: `() => ReactNode` —\\n real RN content in the HeaderBar (inputs included), hosted by an\\n intrinsic-size root; `headerButtons` render after `headerRight`\\n (hn-app\\'s header search filter is the demo).\\n- Stack screen option `gestureEnabled: false` disables the native back\\n button, Escape and the back gesture for that screen (the page\\'s\\n Adwaita `can-pop`); a programmatic `goBack` still pops. `usePreventRemove`\\n works through the same mechanism — a prevented route reports\\n `can-pop: false`, so no native pop can race react-navigation state; the\\n route pops once the app lifts the guard (e.g. after its own\\n confirmation dialog).\\n- Stack screen option `animation` maps onto `Adw.NavigationView`\\'s\\n `animate-transitions` — GTK has exactly one transition style, not a\\n choice of styles like iOS/Android, so the option collapses to a\\n boolean: `\"none\"` turns transitions off, any other value (including\\n native-stack\\'s own style names, e.g. `\"slide_from_bottom\"`, `\"fade\"`)\\n turns them on, with the standard Adwaita transition rather than the\\n one asked for. Requesting a specific type still animates — it is not\\n silently treated as `\"none\"` — and warns once in development.\\n `animate-transitions` is a property of the whole view, not a per-page\\n one, so there is no per-screen granularity to offer: the value used is\\n read from whichever screen is currently on top of the visible stack,\\n recomputed on every navigation. Setting it once via `screenOptions`\\n (the same value for every screen) is the reliable way to use this —\\n the per-screen case only matters if different screens genuinely\\n disagree, and even then only the active one\\'s value is observed.\\n Interactive swipe-back gestures always animate regardless of this\\n setting — Adwaita\\'s own behavior, not overridable here.\\n- The factories are typed: `createStackNavigator<ParamList>()` gives\\n typed `Screen` configs and `StackScreenProps<ParamList, Route>` for\\n screen components (`SidebarScreenProps` likewise).\\n- The stack navigator emits `transitionStart` / `transitionEnd` on a\\n screen\\'s `navigation` object, matching `@react-navigation/stack` and\\n `@react-navigation/native-stack` exactly: `{ data: { closing: boolean } }`,\\n `closing: false` for the screen being pushed in, `closing: true` for the\\n screen being popped out. A screen that stays mounted without actually\\n entering or leaving (e.g. the screen underneath a push) gets neither\\n event, same as upstream. Two things worth knowing before relying on\\n timing:\\n - **`transitionEnd` is tied to `AdwNavigationPage`\\'s own `shown`/`hidden`\\n signals** — contrary to an earlier version of this page, Adwaita DOES\\n expose a transition-finished signal (four of them, in fact: `showing`,\\n `shown`, `hiding`, `hidden`, all per-page). `transitionEnd` on the\\n entering screen fires on that screen\\'s `shown`; on the leaving screen\\n it fires on `hidden`. `transitionDuration` (default 400 ms) is a\\n fallback only, used when a page\\'s own signal never arrives — a\\n signal-less environment, or a page skipped entirely by a multi-hop\\n pop (popping past an intermediate screen never fires anything on it,\\n since it was never the one actually on screen during the transition).\\n When transitions are not animated, the real signals still fire —\\n immediately — so `transitionEnd` is not delayed by the fallback\\n window either.\\n - **Native pops do not fire these events at all today.** A user-driven\\n pop (the Adwaita back button, Escape, the back gesture) is handled by\\n the widget itself before this package\\'s code is told about it, so\\n there is nothing to hook a `transitionStart` into. Only\\n programmatic navigation (`navigate`, `goBack`, `dispatch`, …) fires\\n `transitionStart`/`transitionEnd`.\\n- The sidebar navigator emits `sidebarShown` (`{ data: undefined }`) on a\\n screen\\'s `navigation` object — the collapsed-mode counterpart of a native\\n pop, and the one case where a native, user-driven interaction (the split\\n view\\'s own back button, Escape, the back gesture) DOES get an event: the\\n widget-level property that changes (`showContent`) has no\\n react-navigation state behind it at all, so there is no state change for\\n an app to observe any other way. Fired on the active route only when\\n `showContent` goes from shown back to hidden, and only while\\n `collapseWidth` is set; never fired for content being revealed (that\\n already shows up as an ordinary focused-route change).\\n- The rest of the react-navigation surface — `useNavigation`, `useRoute`,\\n `useFocusEffect`, `useIsFocused`, `useNavigationContainerRef`,\\n `CommonActions`, `StackActions`, `usePreventRemove`, `NavigationContainer`\\n and everything else — comes from `@react-navigation/native` directly, not\\n from this package. **Breaking change**: earlier versions re-exported a\\n subset of these names from `react-native-gtkx/navigation`; the re-export\\n was removed because it was never complete (anything beyond the subset\\n still required importing from `@react-navigation/native`, so it was one\\n more place to look rather than a convenience). This package\\'s navigation\\n entry point now exports exactly its own surface: `createStackNavigator`,\\n `createSidebarNavigator`, and the option/prop types around them.\\n- Each screen mounts its own layout root inside the page: the page\\'s\\n content allocation is that screen\\'s viewport.\\n- Differences from `@react-navigation/native-stack`: `headerRight`/custom\\n header widgets are not supported yet; deep-link \"url\" events never fire\\n on desktop (see `Linking`).',\n },\n {\n doc: \"docs/api.md\",\n heading: \"Svg\",\n text: 'Vector graphics built from state, modeled on\\n[react-native-svg](https://github.com/software-mansion/react-native-svg) (the\\nde-facto standard RN mirrors) rather than invented from scratch — portable\\ncode costs nothing to bring over. Drawing goes through `Gsk.Path`/\\n`Gtk.Snapshot` on a single custom widget (`RnGtkxSvgNode`, `registerClass` +\\nan overridden `snapshot()` vfunc — the same mechanism `RnGtkxLayout` and\\n`RnGtkxViewBox` already use), not a rasterized image: for that, `Image`\\nalready loads `.svg` files today (see the `Image` row above).\\n\\n**Not part of the main `react-native-gtkx` export surface** — unlike every\\ncomponent in the table above, `Svg` and everything below are exported only\\nfrom `react-native-gtkx/svg`, in the shape of the `react-native-svg` package\\nitself. `react-native-svg` is a separate package on every other platform (RN\\nhas no built-in `Svg`), so this project mirrors that split instead of adding\\n`Svg` to the main entry, which would make code written against it fail to\\ncompile anywhere else. See \"`react-native-svg` compatibility\" below for the\\nexact import and how the alias resolves it.\\n\\n```tsx\\nimport Svg, { Circle, G, Path, Rect } from \"react-native-svg\"\\n\\nconst Icon = () => (\\n <Svg\\n width={24}\\n height={24}\\n viewBox=\"0 0 24 24\"\\n >\\n <Circle\\n cx={12}\\n cy={12}\\n r={10}\\n fill=\"#1c71d8\"\\n />\\n <Path\\n d=\"M8 12 l3 3 l5 -6\"\\n stroke=\"white\"\\n strokeWidth={2}\\n fill=\"none\"\\n />\\n </Svg>\\n)\\n```\\n\\n- **`Svg`**: `width`/`height` (or `style`) size it — a Yoga leaf like\\n `Image`, sized entirely by style/flex, never by measuring the widget\\n (nothing here is intrinsic-sized). `viewBox=\"minX minY width height\"` and\\n `preserveAspectRatio` (`xMin/xMid/xMax` × `YMin/YMid/YMax`, `meet`/`slice`,\\n `none`; default `xMidYMid meet`) reshape the internal coordinate system\\n exactly like real SVG — Yoga never sees them. Content always clips to the\\n allocated bounds (no `overflow: visible` opt-out).\\n- **`Path`**: `d` is handed straight to `Gsk.Path.parse()`, which understands\\n SVG path syntax natively — there is no path parser of our own.\\n- **`Rect`** (`x`/`y`/`width`/`height`/`rx`/`ry`), **`Circle`**\\n (`cx`/`cy`/`r`), **`Ellipse`** (`cx`/`cy`/`rx`/`ry`), **`Line`**\\n (`x1`/`y1`/`x2`/`y2`, stroke-only — no `fill` prop at all, not even\\n ignored), **`Polygon`**/**`Polyline`** (`points`, `\"x,y x,y …\"` or\\n space-separated, closed/open respectively): each is a small geometry\\n helper away from the same `d` syntax, so every shape ends up drawn through\\n that one `Gsk.Path.parse()` call.\\n- Every shape accepts `fill`/`stroke` (a static CSS color — hex/`rgb()`/\\n `hsl()`/named/`transparent`/`none`, or `\"url(#id)\"` referencing a\\n gradient; default `fill=\"black\"`, `stroke=\"none\"`, matching SVG),\\n `fillRule` (`nonzero` | `evenodd`), `fillOpacity`/`strokeOpacity`/\\n `opacity`, `strokeWidth`, `strokeLinecap`/`strokeLinejoin`,\\n `strokeDasharray`, `strokeDashoffset`.\\n- **`G`** groups children under an `opacity` and/or a `transform` string —\\n `translate()`/`scale()`/`rotate()`/`rotate(a,cx,cy)`/`matrix()`, the plain\\n SVG transform-list syntax (`matrix()` maps directly onto\\n `Gsk.Transform.matrix2d()`); `skewX`/`skewY` and the structured\\n `transform={[{translateX:...}]}` array form `Animated.View` accepts are\\n not supported here.\\n- **Gradients**: `<Defs>` holds `<LinearGradient id x1 y1 x2 y2>` /\\n `<RadialGradient id cx cy r>` (fractions 0–1 by default —\\n `gradientUnits=\"objectBoundingBox\"`, mapped against the shape\\'s own\\n `Gsk.Path.getBounds()`; `gradientUnits=\"userSpaceOnUse\"` uses the\\n coordinates as-is instead), each with `<Stop offset stopColor\\nstopOpacity>` children (`offset` accepts `0.5` or `\"50%\"`). `Defs` must be\\n a direct child of `Svg` (nested `Defs` are not scanned). No\\n `gradientTransform`, no `spreadMethod` beyond the default pad behavior.\\n An unresolvable `url(#id)` paints nothing for that fill/stroke rather\\n than throwing.\\n- **Animated**: the numeric props above (shape geometry, `opacity`,\\n `strokeWidth`, `strokeDashoffset`) accept an `Animated.Value`/\\n interpolation in place of a number. A tick mutates the widget\\'s paint\\n state directly and calls `queueDraw()` — the same bypass-React pattern\\n `Animated.View` uses for `transform` (`setStoredTransform` +\\n `queueAllocate`), just on its own invalidation channel since none of this\\n touches Yoga. `G`\\'s `transform` string and `d`/`points` are not\\n Animated-aware (they are strings, not numbers).\\n- Not in scope: `<Text>`/`<TSpan>` on a path, `<Mask>`, `<ClipPath>`, SVG\\n filters, `<Use>`/`<Symbol>`/`<Pattern>`, and rasterizing arbitrary SVG\\n strings at runtime (`SvgXml` — `Image` already covers SVG **files**). None\\n of these have a real consumer yet; `Path`/`Rect`/`Circle`/`Ellipse`/\\n `Line`/`Polygon`/`Polyline`/`G` cover icons, charts and indicators, the\\n overwhelming majority of real usage.',\n },\n {\n doc: \"docs/api.md\",\n heading: \"`react-native-svg` compatibility (`react-native-gtkx/svg`)\",\n text: '`react-native-gtkx/svg` re-exports the same set in `react-native-svg`\\'s\\nshape (`Svg` as both the default and a named export). The `react-native-gtkx/\\nmetro` and `react-native-gtkx/vite` presets alias the bare `react-native-svg`\\npackage name to it automatically, the same way they alias `react-native`\\nitself — so portable code that imports from `react-native-svg` runs\\nunmodified:\\n\\n```tsx\\nimport Svg, { Circle, Path } from \"react-native-svg\"\\n```\\n\\nApps using neither preset can point their own bundler alias at\\n`react-native-gtkx/svg` by hand. `react-native-svg` itself is never a\\ndependency of this package and does not need to be installed — the alias\\nworks whether or not the real package is present.',\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"Why you would reach for it\",\n text: \"- A GTK capability that React Native has no concept of: a real\\n `Adw.NavigationView` stack, a `GtkListBox` row, a native `GtkEntry`.\\n- Your own router, or no router: drive navigation from `useState`, a reducer,\\n a URL, a state machine.\\n- A property we did not think to surface in the navigator's options. Every\\n widget below is re-exported straight from the gtkx bindings, so the full\\n GObject property and signal surface is yours — including properties added\\n to gtkx after this page was written.\",\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"Declarative primitives\",\n text: \"These are the two components we wrap, because a raw `Adw.NavigationView` is\\nimperative (`push`, `pop`, `pop_to_tag`) and React is not.\\n\\n| Export | What it is |\\n| --------------------- | ------------------------------------------------------ |\\n| `NavigationStack` | `Adw.NavigationView` driven by a `stack` array of tags |\\n| `NavigationStackPage` | one page of that stack, identified by `tag` |\\n\\nThey **inherit every prop of the underlying widget** and only add to it, so\\nanything you could set on `Adw.NavigationPage` you can set on\\n`NavigationStackPage`.\",\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"React Native content inside GTK slots\",\n text: \"| Export | Sizing | Use for |\\n| ------------------ | ---------------------------- | ------------------------------------------------ |\\n| `SlotContent` | fills the slot | a page body, a pane, a dialog body |\\n| `IntrinsicContent` | sized by its own Yoga layout | an AdwHeaderBar slot, a toolbar area, a list row |\\n\\n`createSidebarNavigator`'s `sidebarRow` screen option (docs/api.md) wraps\\nits content in exactly `IntrinsicContent` for this reason — a row is sized\\nby what it holds, not stretched to fill the list.\\n\\n**Every content area inside a widget needs one of them.** A widget hands out\\nrectangles two ways: as ordinary CHILDREN (a content area) and as SLOTS —\\nproperties that take a widget, `topBar={…}`, `titleWidget={…}`, `sheet={…}`.\\nWhich way a given area arrives is gtkx's business and moves between releases\\n(rc.3 took the `content`/`child` props off single-child widgets and made that\\ncontent a child), and it has never had anything to do with layout. Both are\\nGTK's territory: the layout root is cleared on the way in, so a widget lands\\nbare (what `WidgetContent` does by hand) and React Native content has to bring\\nits own root.\\n\\n```tsx\\n<AdwBottomSheet\\n style={{ flex: 1 }}\\n sheet={\\n <IntrinsicContent>\\n <View style={{ padding: 20, gap: 10 }}>…</View>\\n </IntrinsicContent>\\n }\\n bottomBar={\\n <IntrinsicContent>\\n <View style={{ flexDirection: \\\"row\\\", gap: 8 }}>…</View>\\n </IntrinsicContent>\\n }\\n>\\n {/* the content area — a child under rc.3, and just as much a boundary */}\\n <SlotContent>\\n <View style={{ flex: 1, justifyContent: \\\"center\\\" }}>…</View>\\n </SlotContent>\\n</AdwBottomSheet>\\n```\\n\\nForget the wrapper and you get an error naming the widget and where the\\ncontent landed, not a wrong-looking window: without a root, content inside a\\nwidget would join the ENCLOSING Yoga tree — laid out against the window's\\nviewport while GTK hands it the widget's own rectangle.\\n`examples/bottom-sheet` is that whole story in one screen.\\n\\nWhich of the two is yours to choose, and the platform deliberately does not\\nguess: `AdwBottomSheet` alone FILLS in its content child but HUGS in both\\n`sheet` and `bottomBar`. One widget, three content areas, two answers, with\\nnothing in the name or the GIR type to tell them apart — the answer lives in\\nthe widget's own layout code. Swapping them is visible immediately:\\n`SlotContent` in a bottom bar collapses it to nothing (a filling root reports\\na zero minimum, so a size-to-content area is told \\\"nothing\\\"), and\\n`IntrinsicContent` around a content area leaves `flex: 1` with no viewport to\\nfill.\\n\\nNote the two independent sizes here. `style={{ flex: 1 }}` on the widget is\\nthe WIDGET's size in the surrounding React Native layout (a wrapped widget is\\na Yoga leaf at its natural size until the style says otherwise); the wrapper\\ninside each content area is the CONTENT's size inside the rectangle that\\nwidget then hands out.\",\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"Adwaita chrome, written in React Native\",\n text: \"The opposite direction from everything above: these create no widget an app\\ncould not have created itself, because what they encode is a **look**, not a\\nbehaviour. `docs/research/react-native-first-showcase.md` measured Adwaita's\\n`.boxed-list` out of libadwaita's own compiled stylesheet and found it is a\\nrounded, shadowed card whose rows carry a hairline separator, a hover tint\\nand a press tint — every one of which is a React Native style prop. What an\\napp should not have to do is rediscover the numbers, which are not obvious\\n(the frame is a three-part `box-shadow`, not a border; the corner radii live\\non the first and last ROW, not on the container) and which move when\\nlibadwaita moves.\\n\\n| Export | What it is |\\n| --------------- | ------------------------------------------------------------------------------------------- |\\n| `List` | the `.boxed-list` frame — a `View` with the card background, radius and shadow |\\n| `ListRow` | `AdwActionRow`'s layout and states (`title`/`subtitle`/`prefix`/`suffix`), on a `Pressable` |\\n| `ListSeparator` | the hairline, for a `FlatList`'s `ItemSeparatorComponent` |\\n| `rowPosition` | `(index, count)` → `\\\"first\\\" | \\\"middle\\\" | \\\"last\\\" | \\\"only\\\"`, since RN has no `:first-child` |\\n| `Icon` | a **named** icon from the desktop icon theme |\\n\\n`Icon` is not `Image`: RN's `Image` takes a file path or URI, because on iOS\\nand Android an icon is a bundled asset. Here it is a _name_ resolved against\\nthe current icon theme at paint time, which recolours itself with the label\\ncolour and follows the user's theme — nothing in `Image`'s contract can\\nexpress that. The shape is the one RN apps already use\\n(`<Icon name size />`), with the desktop icon theme behind it instead of a\\nbundled font.\\n\\n`ListRow` does **not** yet do keyboard navigation between rows or draw a\\nfocus ring. `GtkListBox` implements both as widget behaviour, and RN has no\\nfocus model for `View` to hang them on — `Pressable`'s state callback is\\n`{pressed, hovered}` with no `focused`. The ring itself is drawable\\n(`outlineWidth`/`outlineColor`/`outlineStyle`/`outlineOffset`, see the style\\ntable); what is missing is the state, not the paint.\",\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"GTK widgets, driven by React Native\",\n text: 'Every `GtkWidget` subclass gtkx binds — 86 of them at last count, from\\n`GtkBox` and `GtkButton` to `GtkColumnView` and `GtkEmojiChooser`. The list is\\ngenerated, not hand-picked: `scripts/generate-widget-surface.ts` classifies\\ngtkx\\'s full binding by real GObject inheritance (see\\n`scripts/widget-surface/classification.json` for the exact list gtkx binds\\ntoday) and `src/gtk/widgets.generated.ts` is the committed result. Re-run the\\ngenerator after a gtkx upgrade to pick up new widgets — it diffs against its\\nown previous output and prints what changed.\\n\\nThey keep **every prop gtkx binds** and gain `style` and `onLayout`. Position\\nand appearance both come from the style prop, exactly like anywhere else in\\nReact Native:\\n\\n```tsx\\n<View style={{ flexDirection: \"row\", gap: 8, alignItems: \"center\" }}>\\n <GtkEntry\\n style={{ flex: 1 }}\\n placeholderText=\"Filter\"\\n />\\n <GtkButton\\n style={{ width: 72, backgroundColor: \"#3584e4\", borderRadius: 6 }}\\n label=\"Go\"\\n />\\n</View>\\n```\\n\\nThe entry flexes, the button takes its width and its colour. The layout half\\nof the style drives Yoga; the visual half becomes a GTK CSS class **on the\\nwidget itself**, so the button really is blue, not a blue box behind a button.\\nSet no size and the widget\\'s own natural size wins.\\n\\n**Outside React Native layout they step aside.** The same `GtkButton` dropped\\ninto a `AdwHeaderBar`\\'s `start` or a `AdwToolbarView`\\'s `topBar` — where there is no\\nYoga tree to join — renders as the bare widget. One symbol, both worlds, no\\nflag to remember.',\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"Unwrapped by necessity\",\n text: \"Two families of widget are exported **raw** instead of wrapped, because a\\nwrapper box around them would be invalid GTK rather than a convenience:\\n\\n- **toplevels** — everything that implements `GtkRoot`: `GtkWindow` and\\n everything that derives it (every `Gtk*Dialog`, `GtkApplicationWindow`,\\n `GtkAssistant`, `GtkShortcutsWindow`, and their Adwaita counterparts\\n `AdwWindow`, `AdwApplicationWindow`, `AdwAboutWindow`, `AdwMessageDialog`,\\n `AdwPreferencesWindow`) — plus `GtkDragIcon`, which derives `Gtk.Widget`\\n directly and is a toplevel all the same. A wrapper box around a window is\\n not a layout, it is two windows; and a drag icon inside one is a widget\\n GTK cannot present at all. The rule is written against `GtkRoot` (the\\n capability: owns its own surface, is presented, never parented) rather\\n than against `Gtk.Window` (one familiar instance of it) precisely because\\n `GtkDragIcon` is the case a class-shaped rule misses. `GtkPopover` sits on\\n the other side of the line — a `GtkNative` but not a `GtkRoot`, and gtkx\\n parents it with `gtk_popover_set_parent`, so it stays wrapped. Build a\\n drag icon the way GTK does, from the drag itself\\n (`Gtk.DragIcon.getForDrag(drag).setChild(…)`), not by mounting one.\\n- **child-only widgets** — valid solely as the direct child of one specific\\n parent. `GtkListBoxRow` and `GtkFlowBoxChild` (plus everything that derives\\n them — every Adwaita preferences row, `AdwActionRow` included) are caught\\n mechanically, by real inheritance. `AdwNavigationPage` and\\n `AdwPreferencesPage` derive `Gtk.Widget` directly with no shared base to\\n catch them mechanically, so they are a two-entry, doc-verified denylist\\n instead — see `scripts/widget-surface/classify.ts` for the exact reasoning\\n behind each.\\n\\n`GtkGestureClick` is a third, simpler case: an event controller, not a\\nwidget at all, so it was never a candidate for wrapping in the first place.\\n\\nNothing here is unreachable — every raw export above is still exported,\\nby name, from `react-native-gtkx/gtk` or `/adw`, exactly as gtkx binds it.\",\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"Auxiliary objects, not widgets at all\",\n text: 'A further set of real JSX elements gtkx provides are not `Gtk.Widget` or\\n`Adw.Widget` subclasses either, so `scripts/generate-widget-surface.ts`\\nnever sees them at all — same reason `GtkGestureClick` above is hand-kept\\nrather than generated, just a wider set: actions and menus (`GSimpleAction`,\\n`GMenu`), a responsive breakpoint (`AdwBreakpoint`), one option of an\\n`AdwToggleGroup` (`AdwToggle` — a segmented-control entry, not a widget of\\nits own) and the two leaf elements an `AdwShortcutsDialog` is built from\\n(`AdwShortcutsSection`, `AdwShortcutsItem`), a text buffer and an\\nadjustment — the model objects `GtkTextView`/spin- and scale-style widgets\\nbind to (`GtkTextBuffer`, `GtkAdjustment`), keyboard shortcuts\\n(`GtkShortcut`, `GtkShortcutController`), and the two drag-and-drop\\ncontrollers (`GtkDragSource`, `GtkDropTarget`). All of them are exported, by\\nname, from `react-native-gtkx/gtk` or `/adw`, next to `GtkApplication` and\\n`GtkGestureClick`.\\n\\n```tsx\\n<GtkApplicationWindow\\n actions={\\n <GSimpleAction\\n name=\"new\"\\n onActivate={onNew}\\n />\\n }\\n breakpoints={\\n <AdwBreakpoint\\n condition={Adw.BreakpointCondition.parse(\"max-width: 500sp\")}\\n onApply={() => setCollapsed(true)}\\n onUnapply={() => setCollapsed(false)}\\n />\\n }\\n/>\\n```\\n\\n**One caveat found while building `examples/tasks-app`, worth knowing before\\nyou rely on it in a test:** `AdwBreakpoint`\\'s `onApply`/`onUnapply` never\\nfired in the `@gtkx/vitest` headless-sway gtk test project, even with a\\ngenuine `swaymsg` resize past the condition\\'s threshold (see\\n`packages/react-native-gtkx/tests/gtk/bridge/auxiliary-elements.gtk.test.tsx`)\\n— but it works exactly as documented in a real GNOME session (verified with\\na throwaway app launched via `node scripts/vm.ts app`). Treat it as untestable\\nunder headless sway today, not as broken.',\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"The window and application AppRegistry built\",\n text: '`useParentWindow` (the `Gtk.Window` ancestor), `useApplication` (the\\n`Adw.Application` — `.sendNotification(id, notification)` is the common\\nreason to reach it) and `quit` (the same function `AppRegistry` wires to a\\nwindow\\'s own close button) are re-exported from `react-native-gtkx/gtk`.\\nNone of these give you the window or application object ITSELF to build —\\n`AppRegistry.runApplication` already did that — they let already-mounted\\ncode reach back into it, the same way `useBindSetting` needs a `Gtk.Window`\\nto bind a `defaultWidth` property on:\\n\\n```tsx\\nconst window = useParentWindow()\\nuseBindSetting({\\n schema,\\n key: \"window-width\",\\n object: window,\\n property: \"defaultWidth\",\\n})\\n```\\n\\nFor the other half of reaching back into that window — putting things ON it\\nrather than reading it — see the next section.',\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"Actions and shortcuts declared in the app tree\",\n text: '`WindowActions`, `ApplicationActions` and `WindowControllers` register their\\nchildren on the window (or the application) **from wherever they are written\\nin the app tree**. They render nothing where they sit — they are portals in\\nReact\\'s own sense: the children stay part of the tree at that position, with\\nthe context, state and effects they would have there, while the registration\\nlands on the window.\\n\\n```tsx\\nimport { GSimpleAction, WindowActions } from \"react-native-gtkx/gtk\"\\n\\nconst NewTaskAction = () => {\\n const { addTask } = useStore() // an ordinary React context store\\n return (\\n <WindowActions>\\n <GSimpleAction\\n name=\"new\"\\n onActivate={() => addTask()}\\n />\\n </WindowActions>\\n )\\n}\\n```\\n\\nThat is `win.new` — what a HeaderBar button\\'s `actionName`, a `GMenu` item\\nand an `actionAccels` entry all target. `ApplicationActions` is the same\\ncomponent against the application\\'s action map (`app.*`), and the two are\\nNOT interchangeable: a `Gio.Notification`\\'s action button can only ever\\nactivate an application action, and an application action outlives any one\\nwindow. Which prefix you get is decided by which component you write.\\n`WindowControllers` takes `Gtk.EventController` children — a\\n`GtkShortcutController` with `scope={Gtk.ShortcutScope.GLOBAL}` is the whole\\nreason it exists.\\n\\n**Reach for these, not for `runApplication`\\'s `applicationActions` /\\n`windowActions` / `windowControllers` options.** Those options build their\\nchildren as props of the window `AppRegistry` creates, which makes them\\nSIBLINGS of the app tree: no provider inside the app is above them, so an\\naction declared there cannot read a React context — `examples/tasks-nav` had\\nto rewrite its store as a module-level external store before Ctrl+N could\\nsee any app state at all. The options still work and are not going away\\nwithout notice, but they are deprecated, and everything they can express the\\ncomponents can express better:\\n\\n- **context works**, because the declaration is a descendant of its provider;\\n- **registration is dynamic** — the action is added when the declaring\\n component mounts and removed when it unmounts, so one screen can own its\\n own actions instead of the process owning all of them for its lifetime;\\n- **it composes** — two unrelated subtrees each declare their own without\\n meeting in a single options object.\\n\\n`actionAccels` is NOT deprecated and stays a `runApplication` option: it is a\\nflat name→keys table with no children and nothing to read from context, and\\nit is deliberately process-wide (an accelerator naming an action that is not\\nregistered right now simply does nothing). A shortcut that should come and\\ngo with a screen is a `GtkShortcutController` inside `<WindowControllers>`.\\n\\n**Two components, not one, on purpose.** Actions land on the window as a\\n`Gio.ActionMap` (`addAction`/`removeAction`, keyed by NAME); controllers land\\non it as a `Gtk.Widget` (`addController`/`removeController`, keyed by the\\ncontroller object). Different children, different GObject interfaces, and —\\nsee below — different duplicate semantics. One component sorting its children\\nby type would fail silently on a wrong child; two fail at the type level.\\n\\n**A duplicated action name goes to the FIRST declaration**, and a second one\\nis ignored with a development warning naming it. This is not a coin toss\\nbetween first and last. `Gio.ActionMap` is name-keyed at both ends:\\n`addAction` silently replaces a same-named action, and `removeAction` takes a\\nname, not the action object. Under \"last wins\", the first of the two\\ndeclarations to unmount would remove whatever currently answers to that\\nname — leaving the other one mounted but dead. First-wins is the only order\\nin which release always precedes acquire: the loser never registers, and when\\nthe winner unmounts (removing its own action, correctly) the claim passes to\\nthe next declaration still mounted, which registers in a later commit. If you\\nwant a screen to override a shortcut, give it its own name, or move the\\ndeclaration somewhere both screens can reach.\\n\\n**Inside a `Modal`, the enclosing window is the modal\\'s own window**, so\\nactions and controllers declared there belong to it and go away with it —\\nusually what a dialog wants, and worth knowing when it is not. Under\\n`chrome: \"content\"` and inside the navigators nothing changes: the window is\\nstill the one `AppRegistry` built, the navigators own widgets inside it and\\nnot its action map, and a `HeaderBar` button in a page resolves `win.*`\\nthrough the widget hierarchy up to that same window. One consequence worth\\nknowing: react-navigation keeps a popped screen mounted until its exit\\ntransition ends, so a screen\\'s actions outlive the pop by the length of the\\nanimation.',\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"GSettings\",\n text: '`useSetting` and `useBindSetting` come straight from `@gtkx/react`, re-\\nexported from `react-native-gtkx/gtk` next to the `Gio` namespace they read\\nand write through:\\n\\n```tsx\\nconst [value, setValue] = useSetting(schema, \"color-scheme\")\\nuseBindSetting({\\n schema,\\n key: \"window-width\",\\n object: windowRef,\\n property: \"defaultWidth\",\\n})\\n```\\n\\nTurning a `.gschema.xml` file into the `SettingsSchema` object these hooks\\nexpect (`{ id, path, keys }`) is a build-time concern, not something this\\nsubpath does — `#data/your-schema.gschema.xml` resolves for free on the\\n`gtkx dev`/`gtkx build` toolchain (the `gtkx:settings` vite plugin ships\\ninside `@gtkx/cli` itself), the same way `examples/tasks-app` uses it. It is\\nnot wired into the Metro toolchain (`react-native run-linux`) at all — an\\napp on that path has to construct the `SettingsSchema` object by hand\\n(`{ id, path, keys: { \"key-name\": \"s\" } }`, matching the schema\\'s own type\\nstrings) or add its own build step.',\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"Adwaita structure\",\n text: 'Every `Adw.Widget` subclass gtkx binds — 46 wrapped the same way as the GTK\\nwidgets above, from `AdwAvatar` and `AdwCarousel` to `AdwToolbarView` and\\n`AdwViewSwitcher`. `AdwHeaderBar` and `AdwToolbarView` now take `style` too,\\nand still step aside into the bare widget in a slot that has no Yoga tree —\\n`AdwToolbarView`\\'s own `topBar` is exactly that kind of slot:\\n\\n```tsx\\n<View style={{ flex: 1 }}>\\n <AdwToolbarView\\n style={{ flex: 1 }}\\n topBar={<AdwHeaderBar showTitle={false} />}\\n >\\n <SlotContent>{/* … */}</SlotContent>\\n </AdwToolbarView>\\n</View>\\n```\\n\\n`AdwNavigationView` and `AdwNavigationSplitView` are wrapped the same way;\\n`NavigationStack` above is a declarative layer on top of the former, not a\\nreplacement for it — the raw widget is always one import away.\\n\\n`AdwApplicationWindow` (a toplevel) and `AdwNavigationPage` (valid only as a\\ndirect child of `AdwNavigationView`/`AdwNavigationSplitView`) are exported\\nraw — see \"Unwrapped by necessity\" above.',\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"Namespaces\",\n text: \"`Adw`, `Gdk`, `Gio`, `Gtk`, `Pango` — exported as values, because you need\\nboth the runtime enums and the types:\\n\\n```tsx\\n;<GtkScrolledWindow hscrollbarPolicy={Gtk.PolicyType.NEVER} />\\nconst viewRef = useRef<Adw.NavigationView | null>(null)\\n```\",\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"Navigation without a router\",\n text: 'The stack is an array of tags. Change the array, the widget animates.\\n\\n```tsx\\nimport { useState } from \"react\"\\nimport { Pressable, Text, View } from \"react-native\"\\nimport { AdwHeaderBar, AdwToolbarView } from \"react-native-gtkx/adw\"\\nimport {\\n NavigationStack,\\n NavigationStackPage,\\n SlotContent,\\n} from \"react-native-gtkx/common\"\\n\\nconst App = () => {\\n const [stack, setStack] = useState([\"home\"])\\n\\n return (\\n <NavigationStack\\n stack={stack}\\n // The Adwaita back button, Escape, the back gesture and the\\n // back-history menu all arrive here. Follow them in your own state.\\n onPopped={(tag) => setStack((s) => s.filter((entry) => entry !== tag))}\\n >\\n <NavigationStackPage\\n tag=\"home\"\\n title=\"Home\"\\n >\\n <AdwToolbarView topBar={<AdwHeaderBar />}>\\n <SlotContent>\\n <Pressable onPress={() => setStack((s) => [...s, \"detail\"])}>\\n <Text>Open detail</Text>\\n </Pressable>\\n </SlotContent>\\n </AdwToolbarView>\\n </NavigationStackPage>\\n\\n <NavigationStackPage\\n tag=\"detail\"\\n title=\"Detail\"\\n >\\n <AdwToolbarView topBar={<AdwHeaderBar />}>\\n <SlotContent>\\n <View />\\n </SlotContent>\\n </AdwToolbarView>\\n </NavigationStackPage>\\n </NavigationStack>\\n )\\n}\\n```\\n\\nA runnable version is `examples/adwaita-primitives` — three levels deep, with\\nReact Native content in the header bar and a raw `GtkButton` beside it.',\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"`NavigationStack` props\",\n text: \"Everything `Adw.NavigationView` has, plus:\\n\\n| Prop | Meaning |\\n| ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\\n| `stack` | ordered page tags, root first. This is the navigation state |\\n| `animateTransitions` | forwarded straight to `Adw.NavigationView`'s own property. Default true — GTK has one transition style, so this is only ever on/off |\\n| `onPopped(tag)` | the WIDGET popped by itself. Not called for pops you caused by changing `stack` |\\n| `onPageClosed(tag)` | a closing page finished animating out and left the tree |\\n| `onTransitionStart()` / `onTransitionEnd()` | a push/pop/replace began / finished, the latter driven by the transitioning page's own `shown`/`hidden` signal |\\n| `transitionDuration` | ms, default 400 — a fallback window for retention and the callbacks above, used only when a page's own transition signal never arrives; not a measurement of the real transition length |\\n| `ref` | the `Adw.NavigationView` itself, for anything not modelled here |\\n\\nPages not listed in `stack` are still accepted as children and simply are not\\nshown, so a router may hand over all of its screens at once.\\n\\n**Exit animations are handled for you.** When a tag leaves `stack`, the widget\\nstill animates the page out. `NavigationStack` keeps a snapshot of that page\\nuntil its `hidden` signal (with a timer fallback for two cases where that\\nsignal never arrives on its own: compositors that never emit it, and a page\\nskipped over entirely by a multi-hop pop — see `transitionDuration` above),\\nso you never have to keep rendering pages you already consider gone.\",\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"React Native content in native chrome\",\n text: 'An AdwHeaderBar slot wants a widget that knows its own size, which is what\\n`IntrinsicContent` provides:\\n\\n```tsx\\n<AdwHeaderBar\\n start={\\n <IntrinsicContent>\\n <Text>{stack.length} deep</Text>\\n </IntrinsicContent>\\n }\\n end={[\\n <GtkButton\\n key=\"home\"\\n iconName=\"go-home-symbolic\"\\n onClicked={reset}\\n />,\\n ]}\\n/>\\n```',\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"Two ways to react to size\",\n text: 'Two mechanisms answer two different questions, and neither is a replacement\\nfor the other:\\n\\n- **\"Render different content at different widths\"** — `useWindowDimensions`\\n (from `react-native`, portable, already exists). A resize triggers a React\\n render, your component reads the new width, you return different JSX.\\n This is the right and ONLY tool for anything that changes what is\\n rendered — swapping a filter bar for a compact one, hiding a column,\\n changing text.\\n- **\"Flip a widget property natively at a threshold, with no render at all\"**\\n — `AdwBreakpoint` + `AdwBreakpointBin`. `Adw.Breakpoint` is a condition\\n (a size/aspect-ratio threshold) plus a set of property setters: when the\\n condition starts holding, each setter writes its value onto its target\\n object\\'s property directly, through GObject, inside GTK\\'s own allocation\\n pass; when the condition stops holding, the setter puts the property back\\n to whatever it held before. **No React commit, no Yoga pass, no JS\\n callback runs for the flip itself** — a resize costs nothing beyond what\\n GTK\\'s layout was already doing.\\n\\n `Adw.Breakpoint` is not a widget — verified against the real binding,\\n `Adw.Breakpoint.prototype instanceof Gtk.Widget` is `false`; its\\n prototype chain bottoms out at plain `GObject.Object`. It draws nothing\\n and occupies no space, so it is exported raw (`AdwBreakpoint`, from\\n `react-native-gtkx/adw`), the same way `GtkGestureClick` is: running it\\n through `wrapReactNative` would hand it a Yoga node for something that\\n is not a rectangle, which is a layout bug, not a convenience.\\n `Adw.BreakpointBin` (`AdwBreakpointBin`) IS a real widget — a container\\n that scopes breakpoints to its own child subtree instead of a whole\\n window — and is wrapped normally, taking `style`/flex like anything else\\n here.\\n\\n A breakpoint\\'s setters may only target widgets INSIDE the\\n `AdwBreakpointBin` they are attached to, never the bin itself — so the\\n widget whose property you want to flip must be the bin\\'s child:\\n\\n ```tsx\\n import { Adw, AdwBreakpoint, AdwBreakpointBin } from \"react-native-gtkx/adw\"\\n\\n const splitViewRef = useRef<Adw.NavigationSplitView | null>(null)\\n const breakpointRef = useRef<Adw.Breakpoint | null>(null)\\n\\n useEffect(() => {\\n if (!splitViewRef.current || !breakpointRef.current) return\\n const collapsed = new GObject.Value()\\n collapsed.init(GObject.typeFromName(\"gboolean\"))\\n collapsed.setBoolean(true)\\n breakpointRef.current.addSetter(splitViewRef.current, \"collapsed\", collapsed)\\n }, [])\\n\\n <AdwBreakpointBin\\n breakpoints={\\n <AdwBreakpoint\\n ref={breakpointRef}\\n condition={Adw.BreakpointCondition.newLength(\\n Adw.BreakpointConditionLengthType.MAX_WIDTH,\\n 500,\\n Adw.LengthUnit.SP,\\n )}\\n />\\n }\\n >\\n <AdwNavigationSplitView ref={splitViewRef} …>…</AdwNavigationSplitView>\\n </AdwBreakpointBin>\\n ```\\n\\n `addSetter` wants a genuine, boxed `GObject.Value` — found empirically: a\\n bare JS `true` fails a `G_IS_VALUE` assertion on the native side, it does\\n not silently coerce. `createSidebarNavigator`\\'s own `collapseWidth` (see\\n below) is built on exactly this pair; reading `collapsed`/`showContent`\\n back (e.g. to decide whether a click should also reveal content) is a\\n plain native property read through the same ref, not React state — so\\n neither the flip nor a read of it costs a render.\\n\\nNo `useBreakpoint(condition) → boolean` hook exists, and none is planned:\\nit would return a flag to JS and trigger a re-render on every crossing,\\nwhich is precisely what `useWindowDimensions` already does — a second name\\nfor the first mechanism, with none of the second\\'s native-setter value.\\nIf what you want is \"my component\\'s JSX changes\", reach for\\n`useWindowDimensions`; only reach for `AdwBreakpoint` when the thing that\\nshould change is a widget property GTK itself owns, and you want that\\nchange to cost nothing.',\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"Mixing with react-navigation\",\n text: \"They compose, because the navigator is built on these primitives. Use\\n`react-native-gtkx/navigation` for the app's structure and drop to\\n`react-native-gtkx/gtk` and `react-native-gtkx/adw` where you need a widget the options do not cover —\\nfor example a raw `GtkButton` in `headerButtons`, or a `GtkListBox` inside a\\nscreen.\\n\\nKeeping portable code portable: put Linux-only UI behind a `.linux.tsx`\\nplatform extension, or behind `Platform.select({ linux: … })`. Options a\\nplatform does not understand are ignored, and in development the navigator\\nwarns with the screen and option name rather than swallowing them silently.\",\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"Wrapping a widget we do not export\",\n text: 'The generated surface above covers every current `Gtk.Widget`/`Adw.Widget`\\nsubclass gtkx binds, but \"current\" is doing work in that sentence: a gtkx\\nrelease can add a widget before this package\\'s generator has been re-run for\\nit, and non-widget GI classes (an event controller, a filter, an adjustment)\\nwere never candidates for the widget surface in the first place even though\\na handful of them are occasionally worth putting inside RN layout too.\\n`wrapReactNative` is how you reach either without waiting on us — it is\\ngeneric, so the widget\\'s own props keep their types:\\n\\n```tsx\\nimport { GtkPopover } from \"@gtkx/jsx/gtk\"\\nimport { wrapReactNative } from \"react-native-gtkx/common\"\\n\\nconst Popover = wrapReactNative(GtkPopover)\\n// <Popover style={{ width: 240 }} autohide … /> — `autohide` still typed\\n```\\n\\n(`GtkPopover` here is already part of the generated surface — this is the\\nsame mechanism `src/gtk/widgets.generated.ts` uses under the hood, just\\napplied by hand. It stays useful the day gtkx binds something this package\\nhas not regenerated for yet.)\\n\\nTwo lower-level forms exist for cases the wrapper does not fit:\\n\\n- `<Widget style={…}>` — wrap an element you already have in hand;\\n- `useWidgetLayout(ref, { style })` — attach layout to a widget whose ref you\\n own, with no wrapper component at all. Returns the GTK CSS class from the\\n style\\'s visual half, for you to pass to `cssClasses`.',\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"The escape hatch\",\n text: \"If something is missing, reach the widget directly:\\n\\n```tsx\\nconst viewRef = useRef<Adw.NavigationView | null>(null)\\n<NavigationStack ref={viewRef} stack={stack}>…</NavigationStack>\\n// viewRef.current is the real Adw.NavigationView\\n```\\n\\nThere is deliberately no wall here. A missing convenience should cost you one\\nline, not a fork.\",\n },\n {\n doc: \"docs/platform-layer.md\",\n heading: \"Related\",\n text: \"- [API v1](api.md) — the portable React Native surface.\\n- [Navigation research](research/navigation-extensibility.md) — how the\\n adapter maps react-navigation onto these primitives.\\n- [What we need from gtkx](upstream-gtkx.md) — the upstream agenda.\",\n },\n {\n doc: \"docs/getting-started.md\",\n heading: \"Requirements\",\n text: \"- Linux (x64/arm64, glibc), GTK4 ≥ 4.20, libadwaita ≥ 1.8 (Ubuntu 26.04+, Fedora 43+);\\n- Node.js ≥ 24;\\n- dev packages: `sudo apt install libgtk-4-dev libadwaita-1-dev` (Ubuntu).\",\n },\n {\n doc: \"docs/getting-started.md\",\n heading: \"New project from the template\",\n text: \"```bash\\nnpx degit itsmepetrov/react-native-gtkx/template my-app && cd my-app\\nnpm install\\nnpm run dev # window with Fast Refresh (edits apply without a restart)\\nnpm run build && npm start # production bundle, runs with plain node\\n```\\n\\nMeasured in a clean Ubuntu 26.04 container: 63 seconds from install to a window on screen.\",\n },\n {\n doc: \"docs/getting-started.md\",\n heading: \"How it works\",\n text: '```\\nyour code (react-native API)\\n └─ vite preset: aliases react-native → react-native-gtkx, platform\\n extensions .linux.tsx → .native.tsx → base\\n └─ react-native-gtkx: Yoga (WASM) computes flexbox; styles are split into\\n layout (Yoga) and visual (GTK CSS); coordinates are applied to\\n real GTK widgets\\n └─ gtkx: React reconciler → GTK4 via FFI\\n```\\n\\nThe entry point is the same as in RN:\\n\\n```tsx\\nimport { AppRegistry, StyleSheet, Text, View } from \"react-native\"\\n\\nconst App = () => (\\n <View style={styles.screen}>\\n <Text style={styles.title}>Hello, GNOME!</Text>\\n </View>\\n)\\n\\nconst styles = StyleSheet.create({\\n screen: { flex: 1, alignItems: \"center\", justifyContent: \"center\" },\\n title: { fontSize: 24, fontWeight: \"700\" },\\n})\\n\\nAppRegistry.registerComponent(\"app\", () => App)\\nAppRegistry.runApplication(\"app\", { title: \"My App\", width: 800, height: 600 })\\n```\\n\\n`runApplication` accepts desktop parameters (`title`, `width`, `height`) — the only extension over the RN signature.',\n },\n {\n doc: \"docs/getting-started.md\",\n heading: \"Add Linux to an existing React Native app\",\n text: 'Linux is an [out-of-tree platform](https://reactnative.dev/docs/out-of-tree-platforms)\\n(the react-native-windows/macOS model): your app keeps its ios/ and\\nandroid/ folders, its Metro/Babel toolchain, and gains one more target.\\nFour steps:\\n\\n1. **Install the platform package:**\\n\\n ```bash\\n npm install react-native-gtkx\\n ```\\n\\n Its own `react-native.config.js` declares the `linux` platform and the\\n `run-linux` command — nothing to declare app-side.\\n\\n2. **Wrap your Metro config** (`metro.config.js`):\\n\\n ```js\\n const { getDefaultConfig } = require(\"@react-native/metro-config\")\\n const { withLinuxPlatform } = require(\"react-native-gtkx/metro\")\\n\\n module.exports = withLinuxPlatform(getDefaultConfig(__dirname))\\n ```\\n\\n The wrap adds the platform (`.linux.tsx` extensions,\\n `Platform.OS === \"linux\"`), redirects `react-native` imports to the\\n platform package, and keeps host-side modules (GTK bindings, react,\\n yoga) out of the bundle. Babel stays completely stock.\\n\\n3. **Add `gtkx.config.ts`** with the GTK application id:\\n\\n ```ts\\n import { defineConfig } from \"@gtkx/config\"\\n\\n export default defineConfig({\\n libraries: [\"Gtk-4.0\", \"Adw-1\"],\\n applicationId: \"com.example.myapp\",\\n })\\n ```\\n\\n4. **Start the app from the entry** — on desktop the entry launches the\\n app itself (the same pattern as react-native-web\\'s `index.web.js`):\\n\\n ```js\\n // index.js, after AppRegistry.registerComponent(...)\\n if (Platform.OS === \"linux\") {\\n AppRegistry.runApplication(appName, {\\n title: \"My App\",\\n width: 800,\\n height: 600,\\n })\\n }\\n ```\\n\\nRun it:\\n\\n```bash\\nnpx react-native run-linux # release bundle\\nnpx react-native run-linux --dev # Metro dev server + Fast Refresh\\n```\\n\\nThe command ensures the gtkx codegen store, bundles with Metro for\\n`--platform linux` and opens the window. With `--dev` it starts (or\\nreuses) the Metro dev server and edits apply to the live window with\\ncomponent state preserved; syntax errors print readably in the terminal\\nand the app recovers on the next successful build. **Ctrl+Shift+D** (the\\nreact-native-windows shortcut — the desktop stand-in for the shake\\ngesture) opens the Dev Menu: Reload plus any entries the app registers\\nvia `DevSettings.addMenuItem`. `examples/rn-app` is a complete cli-init\\napp with all three platforms wired this way.\\n\\n`run-linux` always runs what it builds — for a release build that stops\\nshort of opening a window (packaging, CI, handing a bundle to someone\\nelse\\'s machine), use `build-linux` instead; see\\n[Shipping an app](#shipping-an-app) below for what it produces and what\\nrunning it later needs.\\n\\nNotes for typed code: add an `env.d.ts` with\\n`import \"react-native-gtkx/types\"` — it augments the stock `react-native`\\ntypes so `Platform.select({ linux: ... })` typechecks, and `Pressable`\\'s\\nstate callback accepts `hovered` (declared optional — a component shared\\nwith ios/android gets `undefined` there, so write\\n`hovered && styles.hovered`). Future platform-specific props land in the\\nsame file. One thing augmentation\\ncannot teach is `Platform.OS === \"linux\"` (property types do not merge) —\\nuse `Platform.select` in typed code. Deep imports\\n(`react-native/Libraries/...`) are not supported — only the public\\n`react-native` surface.',\n },\n {\n doc: \"docs/getting-started.md\",\n heading: \"Navigation\",\n text: \"Multi-screen apps use the standard react-navigation API with a native\\nAdwaita stack navigator: install `@react-navigation/native` and import\\n`createStackNavigator` from `react-native-gtkx/navigation` — pages render\\nas `Adw.NavigationPage` with the HeaderBar back button wired to\\nreact-navigation state. See [docs/api.md](api.md#navigation-react-native-gtkxnavigation), and\\n[docs/research/navigation-extensibility.md](research/navigation-extensibility.md)\\nfor porting an existing react-navigation app (which options carry over,\\nwhich are silently ignored today, and what the desktop cannot mean).\",\n },\n {\n doc: \"docs/getting-started.md\",\n heading: \"Svg\",\n text: '`<Svg>`/`<Path>`/`<Circle>` and the rest of the vector-graphics API come from\\n`react-native-svg`, not from `react-native-gtkx` itself — matching every\\nother platform, where `react-native-svg` is a separate package too (RN has\\nno built-in `Svg`). See [docs/api.md](api.md#svg) for the component set and\\n[the compat-subpath section](api.md#react-native-svg-compatibility-react-native-gtkxsvg)\\nfor how both presets alias the bare `react-native-svg` import to it.\\n\\nThat alias is a bundler-level rewrite, so TypeScript still needs its own\\nanswer for the specifier `\"react-native-svg\"` — an unresolved import in the\\neditor even though the build works fine. Which fix applies depends on what\\nthe project targets:\\n\\n- **Also ships to iOS/Android/web**: install the real `react-native-svg` —\\n the app needs it on those platforms regardless. `react-native-svg` ships\\n its own `.d.ts` (no separate `@types` package exists or is needed), so\\n TypeScript resolves real, complete types for the specifier; the Linux\\n build never actually executes that package\\'s code — the preset rewrites\\n the import to `react-native-gtkx/svg` before it reaches Node. Nothing\\n react-native-gtkx-specific to configure.\\n- **Linux-only project** (the template, or an app with no mobile target):\\n add `react-native-svg` as a **devDependency purely for its types** —\\n `npm install -D react-native-svg`. This is the ordinary fix for a\\n bundler-alias setup once the aliased name has no real package installed —\\n the same shape as react-native-web\\'s own TypeScript guidance (install a\\n real, type-bearing package alongside the alias rather than fabricate\\n one). Side benefit: if this package\\'s compat surface ever drifts from\\n upstream `react-native-svg`\\'s props (see the \"Deliberate gaps\" note in\\n `packages/react-native-gtkx/src/svg-compat/index.ts`), the mismatch shows\\n up as a type error instead of compiling silently.\\n\\nWe deliberately did not ship an ambient `declare module \"react-native-svg\"`\\n— the trick `react-native-gtkx/types` uses to teach the stock `react-native`\\ntypes about the `linux` platform. That works there because it only\\n_augments_ an already-resolved module (interfaces merge). Here the module\\ndoes not resolve at all without one of the two installs above, so the shim\\nwould have to declare the whole module unconditionally to help — and a\\nproject that installs the real `react-native-svg` later (adding a mobile\\ntarget) would then carry two declarations of the same module, the shim and\\nthe real package\\'s own, colliding. Installing the real package, even only\\nas a devDependency, never has that problem: there is only ever one\\ndeclaration of `\"react-native-svg\"` in play.',\n },\n {\n doc: \"docs/getting-started.md\",\n heading: \"Metro or vite?\",\n text: \"- **Adding Linux to an existing RN app** (ios/android + Metro): the\\n section above — standard RN toolchain end to end,\\n `run-linux --dev` for Fast Refresh.\\n- **Linux-first project**: the template with the vite preset\\n (`react-native-gtkx/vite`; `gtkx dev` gives Fast Refresh, builds are\\n single-file bundles). Both paths consume the same published package.\",\n },\n {\n doc: \"docs/getting-started.md\",\n heading: \"Shipping an app\",\n text: \"The two paths get you from source to something installable differently,\\nbecause they take different positions on what stays out of the bundle.\\n\\n**vite path** (`gtkx build`): everything except the native GTK addon is\\ninlined into one file. `dist/bundle.js` + `dist/gtkx.node` (plus\\n`dist/gschemas.compiled` if the app declares a GSettings schema — the\\nbundle's own banner points `GSETTINGS_SCHEMA_DIR` at its own directory) is\\nthe whole runtime: copy those anywhere with Node ≥24, GTK4 ≥4.20 and\\nlibadwaita ≥1.8, and `node bundle.js` runs it. No `node_modules` involved.\\n\\n**Metro path** (`react-native build-linux`): the release counterpart to\\n`run-linux` that iOS, Android and react-native-windows already have and\\nthis platform did not until now — it bundles with Metro and stops, instead\\nof bundling and immediately running like `run-linux` does:\\n\\n```bash\\nnpx react-native build-linux # writes dist/main.jsbundle\\n```\\n\\nThis is **not** self-contained, unlike the vite path. Metro deliberately\\nkeeps `@gtkx/*`, `react` and `yoga-layout` out of the bundle — they have to\\nbe the exact instances the Node+GTK host loads, not a second copy Metro\\ninlines (see `packages/react-native-gtkx/src/metro/index.ts`,\\n`HOST_MODULE_EXTERNALS`, for why). So running `dist/main.jsbundle` needs,\\non top of Node ≥24/GTK4/libadwaita, a real `node_modules` with\\n`react-native-gtkx` installed and the app's `gtkx.config.ts` present at the\\nworking directory:\\n\\n```bash\\nnode node_modules/react-native-gtkx/dist/runner/host.js dist/main.jsbundle\\n```\\n\\n(run from the app root — the config loader reads `gtkx.config.ts` from the\\ncurrent directory, exactly like `run-linux` itself). Any ordinary\\n`npm install` of the app already has that `node_modules`, so this is a fine\\nway to run a release bundle from a checkout. It is a bad thing to _ship_:\\npackaging it means shipping the closure too, and that closure is not the\\nhandful of runtime modules it sounds like. Measured on the release that did\\nexactly this (v0.2.0-alpha.1's `hn-app` `.deb`): **10,515 files, 206 MiB\\ninstalled** to run a 369 KB bundle, because `react-native-gtkx`'s install\\ndrags its build toolchain along — `typescript`, `@swc`, `rolldown`,\\n`@babel`, `lightningcss`, all of it landing under `/opt` on a user's\\nmachine. `scripts/build-deb.ts` no longer packages this shape at all.\\n\\nThat is the **default** artifact, and it is the only one that carries the\\n`node_modules` caveat. `--standalone` below removes it entirely: the same\\nMetro build, emitted as one self-contained file that runs on a system Node\\nwith nothing installed beside it — the vite path's shape, on the Metro\\npath. It is what the release `.deb` ships.\",\n },\n {\n doc: \"docs/getting-started.md\",\n heading: \"One file (Metro path)\",\n text: \"`build-linux` produces three artifacts. Which one you want is a question\\nabout the delivery channel, not about the build — they share the same\\nMetro step and differ only in how much of the runtime travels with the\\napp:\\n\\n| Flag | Artifact | Needs installed | Size (`hn-app`, linux-arm64) |\\n| -------------- | -------------------------- | ---------------------------------- | ---------------------------- |\\n| _(none)_ | `dist/main.jsbundle` | a `node_modules` tree **and** Node | 0.4 MB + the tree |\\n| `--standalone` | `dist/<name>.cjs` | Node only (`Depends: nodejs`) | 6.9 MB |\\n| `--sea` | `dist/<name>` (executable) | nothing at all | 104 MB (30 MB compressed) |\\n\\n```bash\\nnpx react-native build-linux --standalone # in the app root\\nnode ./dist/<your-package-name>.cjs # one script, system node\\n\\nnpx react-native build-linux --sea\\n./dist/<your-package-name> # one executable, nothing else\\n```\\n\\nBoth flags produce the jsbundle exactly as before, then one additional\\nfile next to it. `--sea-output <path>` overrides where it goes; the\\ndefault is `dist/<package name>` with any npm scope stripped (plus `.cjs`\\nfor `--standalone`).\\n\\n**Pick `--standalone` for anything installed through a package manager.**\\nIt is the same shape gtkx's own packaging produces and the same shape the\\nvite path already ships in its `.deb` — a bundle plus a `nodejs`\\ndependency — and it is the lightest of the three by any measure that\\ncounts: the plain jsbundle looks smaller only because its `node_modules`\\ntree is not weighed. **Pick `--sea` for \\\"download this one file and run\\nit\\\"**, where nothing can be assumed to be installed. They are not\\ncompeting implementations: `--sea` is `--standalone` with a copy of Node\\nwrapped around it, and that copy is the entire 97 MB between them.\\n\\nA tagged release of this repo publishes the `--sea` executable for\\n`hn-app`, `zstd`-compressed, alongside the `.deb`s (`zstd -d` it and run\\nit). The `.deb`s remain how you install these apps; the executable is\\nthere for the machine that has no Node to depend on.\\n\\nThat copy is stripped of its debug symbols as part of the build, which is\\nnot a micro-optimisation: the `node` binary NodeSource distributes for\\nUbuntu ships `with debug_info, not stripped` — 117 MB, 98 MB after\\n`strip --strip-all` — so 19 MB of every unstripped SEA is debug\\ninformation for Node's own C++, which nothing in a shipped app can use.\\nThe step is best-effort: a build machine without binutils gets a warning\\nand a larger executable, not a failed build. It also runs strictly before\\npostject, since `--strip-all` removes exactly the kind of non-allocated\\nsection the injected blob is. What remains after that is Node itself, and\\nit does not compress away either — but it does compress: 30 MB with\\n`zstd -19`, which is what a download actually costs.\\n\\nThe native addon (`@gtkx/native-*.node`, a real `dlopen`ed library) cannot\\nbe JavaScript, so both artifacts carry it as bytes — a SEA asset in the\\nexecutable, a base64 literal in the `.cjs` — and extract it to\\n`$XDG_CACHE_HOME/react-native-gtkx-sea` on first run, keyed by content\\nhash. That is what keeps \\\"one file\\\" honest in both cases.\\n\\nNothing extra to install to bundle it. That work is done by **rolldown**,\\nwhich is vite's own engine — vite 8 depends on it outright, `@gtkx/cli`\\ndepends on vite, and this package depends on `@gtkx/cli`, so it is already\\nin every install. (esbuild, which gtkx's tutorial uses for the same job,\\nwould have been the one genuinely new bundler in the tree: vite 8 lists it\\nas an _optional_ peer and does not install it.)\\n\\nOne thing `--sea` does need that a plain `build-linux` does not: **the\\ngtkx codegen store**, and therefore GTK development headers on the build\\nmachine. A plain `build-linux` deliberately needs neither — Metro\\nexternalizes every GTK module — but the SEA inlines `virtual:gtkx-config`,\\nwhich re-exports `@gtkx/jsx/metadata`, a codegen product. `build-linux\\n--sea` runs `gtkx codegen` itself; it just can't do so on a machine\\nwithout the headers.\\n\\n`postject` is fetched through `npx` at build time, so the first run needs\\nnetwork access.\\n\\nThis follows gtkx's own tutorial (`gtkx-org/gtkx examples/tutorial`:\\nbundle to CJS, `node --experimental-sea-config`, postject injects the blob\\ninto a copy of the `node` binary) for the SEA/postject mechanics.\\nIt diverges on the two hard parts specific to this project — full\\nreasoning, including everything found empirically while building it (not\\njust designed on paper), lives in\\n`packages/react-native-gtkx/src/sea/bundle.ts` and `native-shim.ts`; the\\nshort version:\\n\\n- **The native addon** (`@gtkx/native-<platform>-<libc>`, loaded through\\n dlopen) cannot be embedded as bundled code — a SEA is a V8 code cache\\n blob, dlopen needs a real file. The tutorial's own answer is to keep it\\n BESIDE the executable; that's two files, which is exactly what this\\n build exists to stop being. This build embeds it as a Node SEA \\\"asset\\\"\\n instead and extracts it to a per-user cache directory\\n (`$XDG_CACHE_HOME/react-native-gtkx-sea`, falling back to `os.tmpdir()`\\n for a read-only `$HOME`) on first run, keyed by a content hash so\\n repeat launches reuse the extracted file. Loading it back turned out to\\n need `process.dlopen()`, not `require()` — a SEA's main script can only\\n `require()` built-ins and embedded assets (confirmed empirically:\\n `require(anyAbsolutePath)` throws `ERR_UNKNOWN_BUILTIN_MODULE`) — and,\\n found only by actually running the result, an explicit\\n `nativeModule.exports.init()` call right after `dlopen()`: without it\\n the first GTK-driven callback into JS panics on the Rust side (\\\"the\\n Node environment was accessed from a thread it is not installed on\\\").\\n- **Metro's externals** (`HOST_MODULE_EXTERNALS`) are inlined by a\\n generated entry — a third host implementation alongside `host.ts` and\\n `host-dev.ts` — that `await import()`s every externalized name and\\n assembles `globalThis.__hostModules` before running the jsbundle text,\\n instead of the app needing a runtime `node_modules` to load them from.\\n `gtkx.config.ts` is resolved once, at bundle time (like the vite path\\n already does), not on every process start (like `host.ts` does) — a SEA\\n has no \\\"app root\\\" to read a config file from at runtime.\\n\\nSize, measured on the one platform this was built and proven on\\n(linux-arm64): **104 MB** for `hn-app`, 30 MB compressed. Stripped Node is\\n~98 MB of that — the bundled app code plus the embedded native addon is\\nunder 7 MB. Worth saying plainly: that is still a heavy download for what\\na Hacker News reader needs, and it will not shrink further while the\\nartifact carries a full Node binary. That is the trade `--sea` exists to\\nmake, and `--standalone` is the answer whenever it isn't worth it.\\n\\n**Proof, not just a build**: copied the executable alone (no `node_modules`,\\nno source tree) to an isolated directory on the VM, removed `/usr/bin/node`\\nfrom the system (confirmed `command -v node` found nothing), launched the\\nbinary under a headless Wayland compositor, and screenshotted a live,\\nworking \\\"Hacker News\\\" window with real fetched data — not a build log, not\\na run from the source tree.\\n\\n**vite path — not done here.** Investigated, and it does not generalize\\nthe same way: the vite bundle loads the native addon through\\n`createRequire(import.meta.url)(\\\"./gtkx.node\\\")` — a dynamically obtained\\n`require`, not a literal `require(...)` call — which a bundler does not\\nintercept the way it intercepts a static import (verified: the resolve\\nhook never fires for it in a real rebuild of `dist/bundle.js`). The vite\\nbundle also has its own top-level await, incompatible with the CJS format\\na Node SEA main script requires. Both are fixable in principle (a\\ntext-level rewrite of the compiled `require` call before re-bundling,\\nversion-coupled to `@gtkx/cli`'s vite plugin), but that is a different,\\nmore fragile technique than the Metro path's, and wasn't built or proven\\nhere. If a true single file is wanted for the vite path too, that rewrite\\nis where to start — not a repeat of this approach.\",\n },\n {\n doc: \"docs/getting-started.md\",\n heading: \"Examples in the repository\",\n text: \"- `examples/profile` — a static layout; the same source also builds with react-native-web (`examples/profile-web`);\\n- `examples/playground` — interactive: Pressable, TextInput, Switch, FlatList, Modal, Animated, responsive via flexWrap;\\n- `examples/gallery` — a gallery of the entire v1 surface;\\n- `examples/rn-app` — a cli-init React Native app with ios + android + linux;\\n- `examples/hn-app` — a Hacker News reader on the Metro path: live API data over Node fetch, state-based two-screen navigation, a lazily loaded comment tree.\",\n },\n {\n doc: \"docs/getting-started.md\",\n heading: \"Tests\",\n text: 'Unit logic is plain vitest — no special setup, runs anywhere. Component\\ntests render real GTK widgets under a headless Wayland compositor, and\\nreact-native-gtkx ships the whole recipe as two subpaths so a consumer app\\ndoes not have to rediscover it:\\n\\n- `react-native-gtkx/vitest` — `reactNativeGtkxTest()`, a ready Vitest\\n project config: the headless-compositor plugin, the `react-native` alias\\n and Metro-style platform extensions, an inline-deps default for RN\\n libraries that import `react-native` themselves (`@react-navigation`),\\n and the React act-environment setup;\\n- `react-native-gtkx/testing` — re-exports `@gtkx/testing`\\'s\\n render/screen/userEvent/fireEvent surface (already RN-shaped: `getByText`\\n finds a `Text`, `userEvent.click` walks up to a `Pressable`\\'s gesture\\n controller — no wrapper needed) plus `renderHookWithWindow`, for hooks\\n that read the active window (`useWindowDimensions` and similar) —\\n `renderHook` alone mounts into a windowless container.\\n\\nMinimal `vitest.config.ts`:\\n\\n```ts\\nimport { reactNativeGtkxTest } from \"react-native-gtkx/vitest\"\\nimport { defineConfig } from \"vitest/config\"\\n\\nexport default defineConfig(reactNativeGtkxTest())\\n```\\n\\nThe default test glob is `**/*.gtk.test.{ts,tsx}`; override `include` (and\\n`name`, `headless`, `platform`, `inlineDeps`, `setupFiles`,\\n`fileParallelism`) through `reactNativeGtkxTest`\\'s options. For a project\\nthat also has portable unit tests, use the result as one entry of\\n`test.projects` instead of the whole config — `vitest.config.ts` at this\\nrepo\\'s root is the reference (`process.platform === \"linux\"` guards the\\ngtk project so `npm test` still works on a non-Linux dev machine, running\\nonly the unit project there).\\n\\n```tsx\\nimport { Root } from \"react-native\"\\nimport { render, screen } from \"react-native-gtkx/testing\"\\nimport { expect, it } from \"vitest\"\\nimport { App } from \"../src/App\"\\n\\nit(\"renders the greeting\", async () => {\\n // react-native-gtkx components need a layout root — AppRegistry.runApplication()\\n // in the real app, <Root> in a test.\\n await render(\\n <Root\\n width={800}\\n height={600}\\n >\\n <App />\\n </Root>,\\n )\\n expect(screen.getByText(\"Hello, GNOME!\")).toBeTruthy()\\n})\\n```\\n\\nRequirements: a headless Wayland compositor and D-Bus on PATH — the same\\nsystem packages CI installs, `sway xwayland dbus` (Ubuntu:\\n`apt install sway xwayland dbus`). A missing compositor fails a test run\\nwith a readable error (`Cannot find the \"sway\" executable on PATH`) rather\\nthan hanging. `gtkx codegen` must already have generated the project\\'s\\n`@gtkx/gi` bindings before the first test run — a bare `vitest run` does\\nnot trigger codegen itself, unlike `gtkx dev`/`gtkx build`; the template\\'s\\nown `package.json` wires this as a `pretest` script.\\n\\n`packages/react-native-gtkx/tests/gtk/` is this repo\\'s own suite, built on\\nthe same `@gtkx/testing` surface directly (it tests source, not the\\npublished package) — a good place to see more query and `userEvent`\\npatterns in context. Query roles with `Gtk.AccessibleRole` enums (see\\ndocs/gtkx-rc3-notes.md for the live workarounds still baked into that\\nrecipe).',\n },\n {\n doc: \"docs/getting-started.md\",\n heading: \"MCP server for agents\",\n text: 'An agent working inside a project that depends on react-native-gtkx can\\nask the library about itself instead of guessing: `react-native-gtkx-mcp`\\nis a [Model Context Protocol](https://modelcontextprotocol.io) server that\\nships as a `bin` on this package. Register it in `.mcp.json` (Claude\\nCode, project-level) or the equivalent config of any MCP-compatible\\nclient:\\n\\n```json\\n{\\n \"mcpServers\": {\\n \"react-native-gtkx\": { \"command\": \"npx\", \"args\": [\"react-native-gtkx-mcp\"] }\\n }\\n}\\n```\\n\\nRunning it as `npx react-native-gtkx-mcp` from the project root resolves\\nthe locally installed `node_modules/.bin` entry — no separate install,\\nand it always answers for the exact react-native-gtkx version the\\nproject actually has.\\n\\nThree tools:\\n\\n- `rn_gtkx_list_surface` — browse the surface without knowing a name\\n first (portable components/APIs, gtk/adw widgets, common) with counts;\\n- `rn_gtkx_describe_component` — the one to reach for first: does a\\n component/widget exist, which subpath it is exported from, what GTK\\n widget backs it, what differs from React Native, whether a gtk/adw\\n widget is wrapped (takes `style`/`onLayout`) or raw;\\n- `rn_gtkx_search_docs` — free-text fallback for symptoms and known-issue\\n questions the other two cannot answer by name.\\n\\nIt works without GTK installed — plain Node, no `@gtkx/*` import\\nanywhere in it, reading only the package\\'s own bundled docs/manifest data.\\nThat matters in practice: the agent is often reading the project from a\\nMac, with no GTK toolchain around at all.',\n },\n {\n doc: \"docs/getting-started.md\",\n heading: \"Next steps\",\n text: \"- [docs/api.md](api.md) — the entire v1 surface and differences from RN;\\n- [CONTRIBUTING.md](../CONTRIBUTING.md) — developing the library itself (from macOS — via the UTM VM);\\n- [docs/gtkx-rc3-notes.md](gtkx-rc3-notes.md) — the gtkx rc.3 baseline: workarounds, what it fixed, quirks that stay.\",\n },\n {\n doc: \"docs/gtkx-rc3-notes.md\",\n heading: \"Live workarounds\",\n text: \"| Name | What rc.3 does | Our workaround | Removal condition |\\n| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |\\n| `use-signal-stale-handler` | `useSignal` routes the handler through React's `useEffectEvent`; `react-reconciler@0.33.0` only refreshes it in `commitBeforeMutationEffects` for `case 0` (FunctionComponent) — `case 11` (ForwardRef) and `case 15` (SimpleMemoComponent) fall through unrefreshed, so any `useEffectEvent` in a `memo`/`forwardRef` component is pinned to its mount closure forever (our `ScrollView` is a `forwardRef` with the `useSignal` calls inside it) — a fetch-fed FlatList empties itself on the first scroll. **Unchanged in rc.3, deliberately** — see below | `gtkx/bridge/use-signal.ts` re-pins the latest handler (insertion effect) and hands gtkx a stable wrapper; the bridge exports that hook, not gtkx's | A stable React 19.3 (React fixed the refresh on the 19.3 line) |\\n| `runtime-dedupe` | Two bundled copies of the gtkx runtime still double-init GLib and abort (`g_log_set_writer_func` called twice); nothing guards against it | `src/vite/index.ts` puts `resolve.dedupe` over `@gtkx/*` + `react` (+ `@react-navigation/*` for its context) into the preset every app inherits | Idempotent runtime init upstream, or an error that names the duplicate |\\n| `prop-portal` | `createPortal(children, container)` can only target a container's DEFAULT slot (\\\"children\\\"). Every other slot an object exposes declaratively — a window's `Gio.ActionMap` (`actions`), a widget's `controllers`, an `AdwApplicationWindow`'s `breakpoints` — is reached only by passing an element-valued PROP, which the reconciler routes through an internal `\\\"gtkx:prop\\\"` element. That element is exported from neither `@gtkx/react` nor its `/internal` subpath, so there is no supported way to portal into a named slot | `gtkx/bridge/slot-portal.ts` restates the `\\\"gtkx:prop\\\"` element name and wraps it in `createSlotPortal(children, target, slot)` — the one line that would move if gtkx renames it. `WindowActions`/`ApplicationActions`/`WindowControllers` are built on it | gtkx exports a slot-aware portal (or the prop element) from a public entry point |\\n| `renderhook-no-window` | `renderHook` still mounts into a bare `Gtk.Box` — rc.3's `render-hook.js` is byte-identical to rc.2's — so window-dependent APIs have no toplevel to read | Hook tests create a window with `render()` first (`tests/gtk/apis/dimensions.test.tsx`); packaged for consumers as `renderHookWithWindow` (`react-native-gtkx/testing`) | `renderHook` mounts into the same harness window `render` uses |\",\n },\n {\n doc: \"docs/gtkx-rc3-notes.md\",\n heading:\n \"`use-signal-stale-handler` is a decision upstream made, not an oversight\",\n text: \"We shipped the fix as a PR (gtkx-org/gtkx#469) and it was **closed unmerged\\non purpose**. @eugeniodepalo: _\\\"closing this in favour of waiting for\\nupstream… Since React fixes this properly on 19.3 for all fiber tags, I'd\\nrather take the version bump than carry a workaround I'd revert.\\\"_ So this\\nrow does not move on any gtkx release — only a stable React 19.3 retires it,\\nand the hazard is wider than `useSignal`: any hook built on `useEffectEvent`\\ninherits it until then.\",\n },\n {\n doc: \"docs/gtkx-rc3-notes.md\",\n heading: \"Fixed in rc.3\",\n text: \"- **`gsk-colorstop-boxed-write`** — constructing a `Gsk.ColorStop` threw\\n `Expected an Object for Boxed field write type, got Object` in the native\\n addon, so SVG `<LinearGradient>`/`<RadialGradient>` had zero constructible\\n stops and painted nothing. **We fixed this upstream ourselves**\\n (gtkx-org/gtkx#473, closing gtkx-org/gtkx#472): a record field write\\n converts through `toNative` now, the counterpart of the `fromNative` its\\n getter already used. `makeColorStop`'s try/catch and the null-filtering it\\n forced through `collectStops`/`appendGradient` are gone; gradients paint for\\n real, asserted on the stop colors that actually reach Gsk in\\n `tests/gtk/components/svg.gtk.test.tsx`.\\n- **`graphene-rect-nested-boxed-props`** — the same native bug reached through\\n `new Graphene.Rect({ origin, size })`; we had been building the SVG clip\\n rect through `Graphene.Rect.alloc().init(x, y, w, h)`, the escape hatch\\n `Gsk.ColorStop` did not have. Same upstream fix, so `svg-node.ts` uses the\\n plain constructor again.\\n- **The codegen freshness lie** — `npm install` prunes `node_modules/.gtkx`,\\n and rc.2's `@gtkx/cli` could report \\\"bindings up to date\\\" over a store that\\n was not there. Fixed upstream in gtkx-org/gtkx#470 (also ours): both stores'\\n manifests and self-links are checked now. Separately, `src/runner` calls the\\n programmatic `@gtkx/codegen` API rather than the CLI, so a library\\n generating bindings on a consumer's behalf has no cwd or stamp to misread.\",\n },\n {\n doc: \"docs/gtkx-rc3-notes.md\",\n heading: \"Fixed in rc.2 (history, one line each)\",\n text: \"- **`vitest-compositor`** — rc.1 defaulted the headless display to weston;\\n rc.2's default IS sway, so `vitest.config.ts` calls the plugin with no\\n arguments.\\n- **`no-virtual-seat`** — rc.1 had no input seat under sway, so windows never\\n activated and `userEvent` was impossible; rc.2 starts a virtual seat.\\n- **`fixed-layout-child`** — rc.1's declarative `<GtkFixedLayoutChild>`\\n created a detached object; moot since containers moved to our own\\n `RnGtkxLayout` manager and GtkFixed left the codebase.\\n- **`controllers-as-children`** — rc.1 silently ignored controllers passed as\\n JSX; rc.2 has a `controllers` slot on `GtkWidget`. Pressable and TextInput\\n still attach theirs imperatively on purpose — a choice now, not a\\n workaround.\",\n },\n {\n doc: \"docs/gtkx-rc3-notes.md\",\n heading: \"Behaviour rc.3 changed under us\",\n text: \"None of these needed a code change, but they change what the stack does\\nbeneath us and are worth knowing before debugging something odd:\\n\\n- **Blockable signals are no longer suppressed for a whole React commit.**\\n rc.2 suppressed `onChanged`/`onToggled`/`onNotify*`/`onSelectionChanged`\\n from `prepareForCommit` until after `resetAfterCommit`; rc.3 wraps each\\n framework write individually, so an emission the framework did not cause —\\n one raised from a `useLayoutEffect`, or aimed at another `createRoot` tree —\\n now reaches its handler. Our navigators lean on exactly this class of\\n signal; the full suite is unchanged (825 passed + 1 expected fail, same as\\n on rc.2), so nothing of ours was relying on the over-broad suppression.\\n- **`render`'s harness window is undecorated.** rc.2 gave it a `Gtk.HeaderBar`\\n whose window handle, center box and title label sat in the accessibility\\n tree competing with the widgets under test. Role queries now see only what\\n the test rendered.\\n- **A widget with `accessibleLabelledBy` reports the relation as its\\n accessible name**, ahead of its own text — the precedence ARIA defines.\\n Changes what `getByRole(role, { name })` matches.\\n- **`toHaveTextContent` no longer falls back to the accessible name** (we have\\n no uses of it); **`toHaveDisplayValue` throws** on a widget without one\\n instead of comparing to `null`; **checked state is tri-state**.\\n- **Records are constructible only when their bytes can be copied**, a new\\n restriction that could have taken `Gsk.ColorStop` away with one hand while\\n the fix above gave it with the other. Verified on the VM that neither\\n `Gsk.ColorStop` nor `Graphene.Rect` is caught by it — both construct from\\n props — which is what makes the two deletions above real rather than paper.\\n- **Single-child widgets lost their `content`/`child` props** (pass the widget\\n as a child instead). No JSX in this repo used either, and typecheck against\\n the regenerated bindings is clean, so this cost us nothing — but an app\\n built on the raw gtkx surface will feel it.\",\n },\n {\n doc: \"docs/gtkx-rc3-notes.md\",\n heading: \"Non-workarounds (quirks that stay)\",\n text: '- 64-bit FFI values arrive as BigInt → `toNumber()` at the boundary\\n (`gtkx/bridge/measure.ts`);\\n- signal names are kebab-case (\"value-changed\"); signals do not pass the\\n emitter (get the widget from a ref);\\n- role queries in tests use the `Gtk.AccessibleRole` enum, not strings;\\n- `npm install` prunes the codegen store (`node_modules/.gtkx` is not in the\\n lockfile) → run `npm run codegen` after installing — npm behavior, not gtkx;\\n- measuring unmapped widgets yields 0 (offscreen Label probes are the\\n exception) → re-measure on the `map` signal + re-commit measured leaves on\\n every flush (`layout/node.ts`);\\n- mixed-session setups only: running an app on a bare compositor (headless\\n sway) while `XDG_RUNTIME_DIR` points at a full GNOME session can segfault in\\n a GTK signal handler when the GNOME settings portal pushes updates into the\\n app (`g_cclosure_marshal_VOID__OBJECTv` via the FFI emit path); cutting\\n `DBUS_SESSION_BUS_ADDRESS` avoids it, which is why the headless scripts do.\\n Normal desktop and container runs are unaffected. The exit-time segfault\\n seen on rc.1 no longer reproduces; the portal-push crash needs a live\\n settings change to trigger and stays on the list unconfirmed.',\n },\n {\n doc: \"docs/gtkx-rc3-notes.md\",\n heading: \"Procedure when the next release ships\",\n text: \"1. Update the `@gtkx/*` pins (root, spike, examples, template), then\\n `npm install && rm -rf node_modules/.gtkx && npm run codegen`;\\n2. Run everything on Linux: `npm run typecheck && npm test`, `build:dist`,\\n `check:package`, plus the headless example proofs;\\n3. Walk the live-workaround table: for each row check the removal condition,\\n delete the tag and the row together when it is met, and move the entry into\\n the history section above — **with a probe that proves the fix on the real\\n runtime**, not just the release notes claiming it;\\n4. Re-tag whatever survives (`RC3-WORKAROUND` → the new release), rename this\\n file to match the new pin, and update `docs/upstream-gtkx.md` if an ask was\\n answered.\",\n },\n {\n doc: \"docs/research/navigation-extensibility.md\",\n heading: \"1. The two layers\",\n text: \"```\\nyour app\\n ├── react-native portable components\\n ├── react-native-gtkx/navigation react-navigation adapter (optional)\\n └── react-native-gtkx/adwaita GTK widgets and primitives\\n```\\n\\n**`react-native-gtkx/gtk` and `react-native-gtkx/adw`** owns the widget: diffing a requested stack\\nof tags into `pushByTag` / `popToTag` / `replaceWithTags`, holding a popped\\npage alive until its exit animation ends, bracketing transitions, reporting\\nnative pops. It imports nothing from `@react-navigation/*`. `NavigationStack`\\ntakes the visible stack as a prop, so a `useState` is a complete router.\\n\\n**`react-native-gtkx/navigation`** is an adapter: react-navigation state to\\nan array of tags, a native pop to `StackActions.pop` (only when the tag is\\nstill in state, otherwise it would double-pop), descriptors to titles, header\\ncontent and `canPop`, plus dev warnings for options we ignore.\\n\\nThis is the same split the React Native ecosystem already uses:\\n`react-native-screens` exposes primitives, `@react-navigation/native-stack`\\nbinds them to a router. It is also what React Navigation's maintainer\\nrecommended when he saw the project (u/satya164, on the r/reactnative\\nannouncement): _keep your own navigator so you can provide options specific\\nto GTK, unless you plan to match native stack API 1:1._\\n\\nThe consequence that matters: **the ceiling of react-navigation's model is\\nnow only in the adapter, never in the primitive.** A GTK capability with no\\ncounterpart in React Native does not have to be squeezed into someone\\nelse's abstraction — it lives in the primitive layer and is reachable\\ndirectly. See [../platform-layer.md](../platform-layer.md).\",\n },\n {\n doc: \"docs/research/navigation-extensibility.md\",\n heading: \"2. What an app can reach today\",\n text: \"Everything below the HeaderBar: each page hosts a full RN tree in its own\\nlayout root. All of react-navigation's state mechanics: params,\\n`setOptions`, dispatch, resets.\\n\\nStack options: `title`, `headerShown`, `headerButtons` (declarative native\\nicon buttons), `headerLeft` / `headerRight` (ordinary RN content rendered\\n_inside_ the HeaderBar), `gestureEnabled`.\\n\\nPast the options, the primitives: any GTK widget we bind, taking `style` so\\nReact Native drives its position and its appearance, plus `wrapReactNative`\\nfor widgets we do not re-export, plus a `ref` to the underlying\\n`Adw.NavigationView`. There is no wall — a missing convenience costs a line,\\nnot a fork.\\n\\n**Resolved since the first snapshot.** Kept here because the reasons are\\nstill instructive:\\n\\n- _RN content could not size a chrome slot_ (HeaderBar start/end, sidebar\\n rows) — one root cause behind the whole `headerLeft`/`headerRight` class.\\n Fixed by the intrinsic-size root, now public as `IntrinsicContent`.\\n- _`usePreventRemove` / `beforeRemove` desynced_, because the native pop had\\n already happened when state heard about it. Fixed through\\n `AdwNavigationPage:can-pop`: a prevented route cannot be popped by the\\n user at all, so there is nothing to race. Covered by\\n `tests/gtk/navigation/prevent-remove.gtk.test.tsx`.\\n- _Unsupported options were ignored silently._ Fixed:\\n `src/navigation/option-warnings.ts` names the screen and the option in\\n development.\\n- _Screen props and options had to be hand-rolled._ Fixed:\\n `createStackNavigator<ParamList>()` types `Stack.Screen`, its options and\\n the screen props (`examples/hn-app` relies on it).\\n\\n`createSidebarNavigator`'s own gaps — sidebar row rendering, collapsed\\nmode and the static content header — are covered in §3 below, alongside\\nthe `examples/tasks-app`/`examples/tasks-nav` narrative that found and\\nthen closed them.\\n\\nOn typing, one clarification worth recording, since it was raised publicly.\\nThe complaint was never that custom navigators cannot be typed — the docs\\nshow how, and we follow them. It is that the upstream v7 signature is\\n`createNavigatorFactory(Navigator: ComponentType<any>): (config?: any) => any`,\\nso nothing flows out of the factory itself and the types have to come from\\nannotating the navigator. React Navigation 8 replaces this with a real typed\\nAPI (`NavigatorTypeBagBase`, `createScreenFactory`); adopting it is the\\n`react-navigation-8` epic.\",\n },\n {\n doc: \"docs/research/navigation-extensibility.md\",\n heading: \"3. Still open\",\n text: \"Meaningful on this platform and not done yet: toolbar top-bar style (the\\n`headerTransparent`/`headerShadowVisible` analogue), search-bar options\\n(`Gtk.SearchBar` / `headerSearchBarOptions` — note v8 renamed its\\n`onChangeText` to `onChange`), and deep links (they parse, but nothing\\ndelivers a URL on the desktop yet). `animation: \\\"none\\\"` is done (a screen\\noption, see docs/api.md).\\n\\n**Resolved by building `examples/tasks-app` (the gtkx tutorial's Tasks app,\\nported), each with a small library change, not a workaround:**\\n\\n- _`Adw.Dialog` presentation_ — confirmed working. `AdwAboutDialog`/\\n `AdwAlertDialog`/`AdwPreferencesDialog`/`AdwShortcutsDialog` are already\\n `wrapReactNative`-wrapped; mounted with no Yoga ancestor anywhere in the\\n tree (this app has none — see the example's README), they hit\\n `wrapReactNative`'s \\\"bare\\\" branch and present correctly, verified live\\n with real screenshots (Preferences, Shortcuts). Nothing to fix here —\\n this item can be dropped from \\\"still open\\\" entirely.\\n- _Breakpoints_ — a real `Adw.Breakpoint`, verified live collapsing the\\n window at a narrow width, but not through the navigator: through a new\\n `AppRegistry.runApplication({ breakpoints })` parameter instead (the\\n navigator itself still had no collapsed-mode concept at the time —\\n closed by `navigation-depth-2`, see below). Also found and recorded:\\n `AdwBreakpoint`'s `onApply`/`onUnapply` never fire under the\\n `@gtkx/vitest` headless-sway gtk test project, in any form tried (JSX\\n prop, imperative `Adw.Breakpoint`+`addBreakpoint`, a genuine `swaymsg`\\n resize) — but fire immediately in a real GNOME session. Treat it as\\n untestable headless today, not broken; see\\n `packages/react-native-gtkx/tests/gtk/bridge/auxiliary-elements.gtk.test.tsx`.\\n (`navigation-depth-2`'s own `collapseWidth`, below, sidesteps this\\n entirely — it drives `Adw.Breakpoint.addSetter` rather than\\n `onApply`/`onUnapply`, and that IS testable headless, see\\n `tests/gtk/adw/breakpoint.gtk.test.tsx`.)\\n- _Actions and menus_ were never on this list by name, but turned out to\\n be the same kind of gap: `AppRegistry.runApplication` had no way to\\n attach a `GSimpleAction`, `actionAccels` or a `GtkShortcutController` to\\n the app/window it builds — required for a `Gio.Notification` action\\n button to route anywhere at all. Closed the same way, with\\n `applicationActions`/`actionAccels`/`windowActions`/`windowControllers`.\\n\\n**Resolved by building `examples/tasks-nav` (`navigation-depth-2` epic),\\nclosing exactly what the tasks-app port above found still narrow:**\\n\\n- _Sidebar row rendering and collapsed mode_ — `createSidebarNavigator`'s\\n `SidebarNavigationOptions` was `{ title }` only: no per-row icon/color/\\n count, and no collapsed/breakpoint wiring of its own (tasks-app had to\\n reach `AppRegistry`'s `breakpoints` directly and drive `collapsed`\\n itself). Fixed: `icon`/`color`/`count` (rendered as `AdwActionRow`, the\\n same widget tasks-app's own hand-rolled sidebar used) and an opt-in\\n `collapseWidth` prop, driving collapse through the navigator itself via\\n a native `Adw.Breakpoint` — not a `useWindowDimensions` conditional; see\\n [../platform-layer.md](../platform-layer.md), \\\"Two ways to react to\\n size\\\", for the mechanism and why no `useBreakpoint` hook exists.\\n- _One static content header shared by the whole navigator_ — the same\\n port's other finding: a filter toggle group vs. a back button,\\n depending on selection, did not fit one static header. The\\n `navigation-depth-2` PRD explicitly allowed this turning out to be a\\n structural gap; it wasn't — descriptor options already merge\\n navigator-level `screenOptions` with a screen's own `options` and\\n re-resolve on `navigation.setOptions()`, core react-navigation behavior.\\n `SidebarNavigationOptions` gained `headerLeft`/`headerRight`/\\n `headerTitle`, mirroring the stack navigator's own `headerLeft`/\\n `headerRight`; a screen that toggles local state and calls\\n `setOptions` in an effect gets a header that changes shape with its own\\n selection, no stack involved — confirming tasks-app's own conclusion\\n that a stack was never the right tool for the \\\"open an item\\\" case.\\n Caveat found while testing this: `setOptions` merges into the\\n previously resolved options rather than replacing them (see\\n docs/api.md).\\n\\n`examples/tasks-nav` is the same navigational shape as `examples/tasks-app`\\n— smart views, colored user lists, an open-item editor — now written\\nthrough `createSidebarNavigator` instead of directly on\\n`AdwNavigationSplitView`/`AdwActionRow`.\\n\\n**Resolved by `collapse-nav` (a live bug report on `examples/tasks-nav`),\\none property lower than `collapseWidth` itself:** `collapseWidth` flips\\n`AdwNavigationSplitView.collapsed` correctly, but `showContent` — WHICH\\npane is visible while collapsed — was only half-wired: a row click already\\nrevealed content, but nothing observed the split view's own back\\naffordance putting it back, and a plain programmatic `navigate()` (no row\\nclick) did not reveal content at all. On read, this looked like it might\\nbe the same \\\"the breakpoint effect sets only `collapsed`\\\" gap all over\\nagain; it mostly was not — see `sidebar.tsx`'s own file header for what was\\nalready there. Three questions were settled empirically, with a throwaway\\nGTK test written BEFORE any implementation code, rather than assumed from\\nlibadwaita's docs:\\n\\n- _Does a cold-started, already-collapsed window default to content or the\\n sidebar?_ Sidebar — `showContent` defaults to `false`, confirmed by\\n mounting a window already narrower than `collapseWidth` and reading the\\n property on first layout, before any code (ours or the app's) ever wrote\\n to it. No fix needed.\\n- _Does resizing back above `collapseWidth` and back below it need to\\n reset `showContent` or the selection?_ No — both persist across the\\n round trip, confirmed the same way (resize wide, resize narrow again,\\n read the property). This is deliberate, not an oversight: it is the same\\n size-class persistence a mobile master-detail app relies on (open an\\n item, rotate to landscape and back, still on that item), which is\\n exactly the \\\"the way a mobile app does\\\" behavior the bug report asked\\n for. Resetting it would have fought the platform's own default for no\\n benefit.\\n- _Does an app need to observe or control the collapsed pane at all?_ One\\n direction, yes: going back. TabRouter's `state` never changes when the\\n user backs out of collapsed content (nothing is removed, the same route\\n stays focused), so there is no existing react-navigation mechanism for\\n an app to notice it happened — unlike a stack pop, which state itself\\n already reveals through the route array shrinking. A new event,\\n `sidebarShown` (`SidebarNavigationEventMap`, the same `navigation.emit`/\\n `addListener` protocol `StackNavigationEventMap`'s `transitionStart`/\\n `transitionEnd` already established — not a second protocol), fires on\\n the active route for exactly this. The forward direction (content being\\n revealed) got no event: it is already an ordinary state change an app\\n can observe the normal way, so an event there would be pure duplication.\\n\\nThe echo risk this raises — state → widget and widget → state both touch\\nthe same property, could they retrigger each other? — resolved the same\\nway the stack navigator's own doc warns about it: by a value asymmetry, not\\na flag. State → widget only ever WRITES `true`; widget → state only ever\\nREACTS to `false`. Two disjoint values, so neither side can mistake the\\nother's write for the other direction.\\n\\nFixed: `sidebar.tsx`'s `state.index` effect now also calls\\n`showContentIfCollapsed()` (previously only `onRowActivated` did, so a\\nclick worked but a programmatic navigation left the user stranded on the\\nsidebar exactly like the report — a real, reproducible gap, not merely a\\ntheoretical one); `onNotifyShowContent` is observed and re-emitted as\\n`sidebarShown`. `examples/gallery` (no `collapseWidth`) is untouched by\\nconstruction — every changed path checks `getCollapsed()` /\\n`collapseWidth !== undefined` live first. See\\n`tests/gtk/navigation/sidebar-collapse.gtk.test.tsx` for the automated\\nversion of all four findings above, and docs/api.md for the public shape.\\n\\n**Found while building `examples/tasks-nav`, narrower, still open:**\\n\\n- _The sidebar PANE's own chrome has no customization hook_ — its\\n `AdwToolbarView`'s `AdwHeaderBar` is hard-coded\\n (`src/navigation/sidebar.tsx`); a navigator consumer can set\\n `sidebarTitle` (a string) on it and nothing else. `examples/tasks-nav`'s\\n \\\"New List\\\" action wanted to live there (matching tasks-app's own\\n `SidebarHeader` component) but had to go on the content header instead,\\n via the navigator-level `headerButtons` prop. Not on the PRD's\\n checklist, so not built.\\n- _Toasts_ — no `AdwToastOverlay`/`Adw.Toast` convenience exists anywhere\\n in `react-native-gtkx` (upstream's own tutorial reaches for\\n `@gtkx/components/adw`'s `ToastProvider`/`useToast`, a package this repo\\n does not depend on). `examples/tasks-app/src/toast.tsx` is a local\\n stand-in; the toast's underlying state change works and is verified live,\\n but the toast's own visual appearance could not be confirmed on screen\\n in that session, for a reason not yet root-caused. Worth a real fix (or\\n at least a live confirmation) before another app leans on it.\\n\\n**Meaningless on desktop, skip forever:** status-bar and home-indicator\\noptions, large titles, blur effects, gesture direction, form sheets,\\nback-button labels. `headerBackButtonMenuEnabled` is free — libadwaita's\\nback button already shows a history menu.\",\n },\n {\n doc: \"docs/research/navigation-extensibility.md\",\n heading: \"4. Porting an existing react-navigation app\",\n text: \"Compatible by construction: a real `@react-navigation/native` v8 peer, the\\nofficial `useNavigationBuilder` and routers, a real `NavigationContainer`.\\nEverything from react-navigation is imported from `@react-navigation/native`\\ndirectly. We used to re-export a partial set from our navigation entry point\\nand dropped it: the set was incomplete, so consumers ended up importing from\\nboth places and could not tell which symbol came from where.\\n\\nMandatory changes: swap `createNativeStackNavigator` for our\\n`createStackNavigator`; drop `react-native-screens`,\\n`react-native-safe-area-context` and `react-native-gesture-handler` (all\\nthree are mobile-native dependencies with nothing to bind to here).\\n\\nKeeping shared code portable: Linux-only options go behind a `.linux.tsx`\\nplatform extension or `Platform.select({ linux: … })`. Options a platform\\ndoes not understand are ignored — and here, warned about in development.\",\n },\n {\n doc: \"docs/research/navigation-extensibility.md\",\n heading: \"5. The desktop-RN landscape\",\n text: \"No other desktop React Native platform has native navigation integration:\\n\\n- **react-native-screens** lists Windows support, but it is a thin\\n old-architecture module; native-stack on modern react-native-windows\\n fails, because screens has no new-architecture Windows implementation and\\n RNW 0.82 removed the old one. Microsoft's own react-native-gallery falls\\n back to the JS drawer.\\n- **react-native-macos** is not supported by react-native-screens at all —\\n AppKit has no navigation-stack primitive to bind to.\\n\\nOur path — a real `Adw.NavigationView` driven from a custom navigator, with\\nreact-navigation state as the source of truth and native pops reported back\\ninto it — is structurally the iOS native-stack / `UINavigationController`\\nmodel, which neither desktop platform reached. GTK's advantage is that the\\nprimitive exists at all: back button, Escape, back gesture, history menu and\\ntransitions ship with the widget.\\n\\nThe trade: a JS stack can render anything into its fake header, while our\\nchrome is real and had to be opened up deliberately — which is what the\\nintrinsic-size root does.\\n\\nSources: react-native-screens README and discussions #1575 / #2541, RNW\\ndiscussions #14273 / issue #4152 / new-architecture docs / 0.82 release\\npost, microsoft/react-native-gallery, reactnavigation.org native-stack docs.\",\n },\n {\n doc: \"docs/gtkx-rc3-notes.md\",\n heading: \"RC3-WORKAROUND(use-signal-stale-handler)\",\n text: \"`useSignal` routes the handler through React's `useEffectEvent`; `react-reconciler@0.33.0` only refreshes it in `commitBeforeMutationEffects` for `case 0` (FunctionComponent) — `case 11` (ForwardRef) and `case 15` (SimpleMemoComponent) fall through unrefreshed, so any `useEffectEvent` in a `memo`/`forwardRef` component is pinned to its mount closure forever (our `ScrollView` is a `forwardRef` with the `useSignal` calls inside it) — a fetch-fed FlatList empties itself on the first scroll. **Unchanged in rc.3, deliberately** — see below — our workaround: `gtkx/bridge/use-signal.ts` re-pins the latest handler (insertion effect) and hands gtkx a stable wrapper; the bridge exports that hook, not gtkx's — removed when: A stable React 19.3 (React fixed the refresh on the 19.3 line)\",\n },\n {\n doc: \"docs/gtkx-rc3-notes.md\",\n heading: \"RC3-WORKAROUND(runtime-dedupe)\",\n text: \"Two bundled copies of the gtkx runtime still double-init GLib and abort (`g_log_set_writer_func` called twice); nothing guards against it — our workaround: `src/vite/index.ts` puts `resolve.dedupe` over `@gtkx/*` + `react` (+ `@react-navigation/*` for its context) into the preset every app inherits — removed when: Idempotent runtime init upstream, or an error that names the duplicate\",\n },\n {\n doc: \"docs/gtkx-rc3-notes.md\",\n heading: \"RC3-WORKAROUND(prop-portal)\",\n text: '`createPortal(children, container)` can only target a container\\'s DEFAULT slot (\"children\"). Every other slot an object exposes declaratively — a window\\'s `Gio.ActionMap` (`actions`), a widget\\'s `controllers`, an `AdwApplicationWindow`\\'s `breakpoints` — is reached only by passing an element-valued PROP, which the reconciler routes through an internal `\"gtkx:prop\"` element. That element is exported from neither `@gtkx/react` nor its `/internal` subpath, so there is no supported way to portal into a named slot — our workaround: `gtkx/bridge/slot-portal.ts` restates the `\"gtkx:prop\"` element name and wraps it in `createSlotPortal(children, target, slot)` — the one line that would move if gtkx renames it. `WindowActions`/`ApplicationActions`/`WindowControllers` are built on it — removed when: gtkx exports a slot-aware portal (or the prop element) from a public entry point',\n },\n {\n doc: \"docs/gtkx-rc3-notes.md\",\n heading: \"RC3-WORKAROUND(renderhook-no-window)\",\n text: \"`renderHook` still mounts into a bare `Gtk.Box` — rc.3's `render-hook.js` is byte-identical to rc.2's — so window-dependent APIs have no toplevel to read — our workaround: Hook tests create a window with `render()` first (`tests/gtk/apis/dimensions.test.tsx`); packaged for consumers as `renderHookWithWindow` (`react-native-gtkx/testing`) — removed when: `renderHook` mounts into the same harness window `render` uses\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"View\",\n text: \"View — GTK implementation: GtkBox (RnGtkxViewBox). Supported: `style`, `onLayout`, `testID`, children, `pointerEvents` (auto/none/box-none/box-only — mapped onto GTK picking: can-target + a contains() vfunc override; also honored from `style.pointerEvents`, the prop wins), ref: `measure`/`measureInWindow`/`measureLayout` (`ViewHandle`, RN's argument order; window coordinates come from `gtk_widget_compute_point`, so they are correct inside a scrolled viewport), the responder and touch props (`onStartShouldSetResponder(Capture)`, `onMoveShouldSetResponder(Capture)`, `onResponderGrant/Start/Move/End/Release/Terminate`, `onTouchStart/Move/End/Cancel` + `Capture`) — spread `PanResponder`'s `panHandlers` here. Differences from RN: nesting another pointerEvents inside a box-only view is not supported; responder negotiation is capture-then-bubble as in RN, but there is **no transfer yet**: once a view is granted, `onResponderTerminationRequest`/`onResponderReject` are never called and a second view cannot steal (GTK's `CLAIMED` is irrevocable, so a transfer could not be enforced against native widgets — see docs/research/gestures.md). The lock is one per process as in RN; the negotiation PATH stops at the layout root, so native GTK widgets between or above views take no part. Single-pointer only: a mouse is one fabricated touch, `touches` never exceeds one\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"Text\",\n text: \"Text — GTK implementation: GtkLabel (Pango). Supported: wrap, `numberOfLines` (ellipsize END), `textAlign`, font styles, `onLayout`, `testID`. Differences from RN: nested `Text` elements are concatenated without per-span styles; text is always ellipsizable (shrinkable in narrow windows)\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"Image\",\n text: 'Image — GTK implementation: GtkPicture. Supported: `source={{uri}}`/string — local paths, file:// and **http(s)** (Node fetch → disk cache keyed by URL, in-flight de-duplication), `resizeMode` cover/contain/stretch/center, `onLoad`/`onError`; **`.svg` files load like any other image** — `Gdk.Texture.newFromFilename` rasterizes them via librsvg, no extra code needed (for building vector graphics from state instead of a file, see the \"Svg\" section below — a separate import, not part of this table). Differences from RN: no synchronous size from remote images (style sets the size, as in RN); cache is not size-limited yet',\n },\n {\n doc: \"docs/api.md\",\n heading: \"TextInput\",\n text: \"TextInput — GTK implementation: GtkEntry / GtkTextView. Supported: controlled/uncontrolled (`value`/`defaultValue`), `onChangeText`, `onSubmitEditing`, `onFocus`/`onBlur`, `placeholder` (own dim overlay in multiline — GtkTextView has none), `secureTextEntry`, `editable`, `keyboardType`, `multiline`, `clearButtonMode` (GtkEntry's built-in clear icon; RN ships this on iOS only) (real GtkTextView: word wrap, internal scroll, Enter inserts a newline and never fires onSubmitEditing — RN semantics). Differences from RN: multiline needs a height in the style (as RN recommends)\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"Pressable\",\n text: \"Pressable — GTK implementation: GtkFixed + GestureClick/Motion. Supported: `onPress(In/Out)`, `onLongPress` (`delayLongPress`), `onHoverIn/Out`, `disabled`, function-form `style`/`children` receiving `{pressed, hovered}`; the `PressEvent` payload is RN's shape (`locationX/Y` target-relative, `pageX/Y` window-relative, `identifier`, `target`, `force`, monotonic `timestamp`, single-element `touches`/`changedTouches` — a desktop pointer is one fabricated touch). Differences from RN: —\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"TouchableOpacity\",\n text: \"TouchableOpacity — GTK implementation: on top of Pressable. Supported: `activeOpacity`. Differences from RN: —\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"ScrollView\",\n text: \"ScrollView — GTK implementation: GtkScrolledWindow. Supported: vertical/`horizontal`, `contentContainerStyle`, `onScroll` (`contentOffset`, `contentSize`, `layoutMeasurement`), `onContentSizeChange`, `stickyHeaderIndices` (RN model: the REAL child is translated and painted on top — no duplicate), ref: `scrollTo`/`scrollToEnd` (`ScrollViewHandle`). Differences from RN: `animated` in scrollTo is ignored\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"FlatList\",\n text: \"FlatList — GTK implementation: windowed core on ScrollView. Supported: virtualization (`estimatedItemSize` or `getItemLayout`, **`windowSize`/`initialNumToRender` — the primary scroll-performance knobs**, `maxToRenderPerBatch`/`updateCellsBatchingPeriod`), `data`/`renderItem`/`keyExtractor`/`extraData`, `ItemSeparatorComponent`, `ListHeader/Footer/EmptyComponent`, `onEndReached(-Threshold)`, `onViewableItemsChanged`/`viewabilityConfig` (`ViewToken`), `inverted` (RN chat semantics: opens at `data[0]`, stays pinned on prepend), `refreshing`/`onRefresh`, `horizontal`, `stickyHeaderIndices`, ref: `scrollToIndex`/`scrollToItem`/`scrollToOffset` + ScrollView methods (`FlatListHandle`). Differences from RN: 1000 rows mount windowed in ~120 ms (v1 full mount was 879 ms); `windowSize` defaults to **11**, not RN's 5 — desktop has no mobile memory pressure and a wider window means fewer mount+reflow bursts per scrolled pixel (measured: −21% churn, late frames 10/s → 7.7/s); rows beyond the visible ones are mounted `maxToRenderPerBatch` (10) at a time every `updateCellsBatchingPeriod` (50) ms, so a flick or a long `scrollToOffset` fills its window over several frames instead of stalling one; no pull gesture — `onRefresh` must be app-triggered; an inverted list shorter than its viewport anchors to the top, not the bottom\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"SectionList\",\n text: \"SectionList — GTK implementation: on top of FlatList. Supported: `sections`, `renderSectionHeader`, sticky section headers by default (`stickySectionHeadersEnabled`). Differences from RN: viewability props are not exposed (section-aware ViewTokens pending)\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"Switch\",\n text: \"Switch — GTK implementation: GtkSwitch. Supported: `value`/`onValueChange`, `disabled`. Differences from RN: sized by the GTK theme, not iOS metrics\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"ActivityIndicator\",\n text: \"ActivityIndicator — GTK implementation: GtkSpinner. Supported: `animating`, `size` (small/large/number). Differences from RN: no `color` yet\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"Modal\",\n text: \"Modal — GTK implementation: modal GtkWindow (portal). Supported: `visible`, `onRequestClose` (Escape/close button), `title`, `width`/`height`; independently resizable with relayout. Differences from RN: desktop semantics: a separate window, not an overlay; `transparent`/`animationType` are no-ops\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"Animated.View\",\n text: \"Animated.View — GTK implementation: direct widget calls. Supported: `opacity` and the whole `transform` array — `translateX/Y`, `scale`, `scaleX`, `scaleY`, `rotate`/`rotateZ` — driven by Animated nodes, bypassing React (an angle comes from `interpolate` with a `deg`/`rad` outputRange), plus the same responder and touch props `View` takes — this is where an idiomatic `PanResponder` drag lands. Differences from RN: `rotateX`/`rotateY`/`perspective` (3D), `skewX`/`skewY` and `matrix` are not supported, and the transform origin is always the view's centre (no `transformOrigin`)\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"SafeAreaView\",\n text: \"SafeAreaView — GTK implementation: = View. Supported: —. Differences from RN: no notches on desktop\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"StatusBar\",\n text: \"StatusBar — GTK implementation: null. Supported: —. Differences from RN: no status bar\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"Root\",\n text: \"Root — GTK implementation: internal root. Supported: `width`/`height`. Differences from RN: extension: required by the test harness\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"NestedRoot\",\n text: \"NestedRoot — GTK implementation: internal root. Supported: —. Differences from RN: extension: a Yoga root inside any GTK container slot (navigation pages, custom containers); the slot allocation is the viewport\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"IntrinsicRoot\",\n text: \"IntrinsicRoot — GTK implementation: internal root. Supported: —. Differences from RN: extension: a content-sized Yoga root for chrome slots (HeaderBar start/end) — reports its content size to GTK\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"StyleSheet\",\n text: \"StyleSheet — Supported: `create`, `flatten`, `compose`, `absoluteFill(Object)`, `hairlineWidth`. Differences: —\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"PlatformColor\",\n text: 'PlatformColor — Supported: Adwaita variables: `PlatformColor(\"accent-bg-color\")` → `var(--...)`, `@named`. Differences: names are Adwaita, not iOS/Android',\n },\n {\n doc: \"docs/api.md\",\n heading: \"AppRegistry\",\n text: 'AppRegistry — Supported: `registerComponent`, `runApplication(appKey, {title,width,height,initialProps,chrome,actionAccels,breakpoints,applicationActions,windowActions,windowControllers})`, `getAppKeys`. Differences: desktop window parameters; `chrome: \"content\"` uses an AdwApplicationWindow with no window titlebar — the app\\'s HeaderBars (navigation) become the chrome. `actionAccels` binds accelerators to action names on the `GtkApplication`; `breakpoints` reaches `AdwApplicationWindow`\\'s own prop and only does anything under `chrome: \"content\"` (a dev warning fires otherwise). **`applicationActions`/`windowActions`/`windowControllers` are deprecated** — reach for [`<ApplicationActions>`/`<WindowActions>`/`<WindowControllers>`](platform-layer.md#actions-and-shortcuts-declared-in-the-app-tree) instead; they still work unchanged',\n },\n {\n doc: \"docs/api.md\",\n heading: \"Platform\",\n text: 'Platform — Supported: `OS: \"linux\"`, `Version` (GTK), `select` (linux → native → default), `isTV`, `isTesting`. Differences: —',\n },\n {\n doc: \"docs/api.md\",\n heading: \"Dimensions\",\n text: 'Dimensions — Supported: `get(\"window\"/\"screen\")`, `addEventListener(\"change\")`. Differences: main window only (transient windows are ignored)',\n },\n {\n doc: \"docs/api.md\",\n heading: \"useWindowDimensions\",\n text: \"useWindowDimensions — Supported: reactive main-window dimensions. Differences: —\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"Appearance\",\n text: \"Appearance — Supported: `getColorScheme`, `setColorScheme` (AdwStyleManager), `addChangeListener`. Differences: —\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"useColorScheme\",\n text: \"useColorScheme — Supported: reactive theme. Differences: —\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"AppState\",\n text: \"AppState — Supported: `currentState` active/background, `addEventListener`. Differences: driven by the window's `is-active`\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"Alert\",\n text: \"Alert — Supported: `alert(title, message, buttons, options)` → Adw.AlertDialog. Differences: `cancel`/`destructive`/`isPreferred` styles\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"Linking\",\n text: 'Linking — Supported: `openURL`, `canOpenURL` (http/https/mailto/file), `getInitialURL` (null), `addEventListener(\"url\")`. Differences: system launcher; no deep-link delivery on desktop yet — \"url\" subscriptions never fire',\n },\n {\n doc: \"docs/api.md\",\n heading: \"InteractionManager\",\n text: \"InteractionManager — Supported: `runAfterInteractions(task?)` (cancellable, then-able), `createInteractionHandle`/`clearInteractionHandle`, `addListener`. Differences: navigation transitions register interactions, so screen work deferred with `runAfterInteractions` waits for the push/pop slide\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"DevSettings\",\n text: \"DevSettings — Supported: `addMenuItem(title, handler)` (entries in the Dev Menu — Ctrl+Shift+D in `run-linux --dev`, the react-native-windows shortcut), `reload(reason?)`. Differences: silent no-ops in release builds, like RN\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"I18nManager\",\n text: \"I18nManager — Supported: `isRTL` (live: GTK's read of the locale text direction), `doLeftAndRightSwapInRTL`, `getConstants`. Differences: `allowRTL`/`forceRTL`/`swapLeftAndRightInRTL` are accepted no-ops (mobile persistence has no desktop store)\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"BackHandler\",\n text: 'BackHandler — Supported: `addEventListener(\"hardwareBackPress\")`, `exitApp`. Differences: no hardware back key on desktop — subscriptions are honored but nothing fires them yet',\n },\n {\n doc: \"docs/api.md\",\n heading: \"PanResponder\",\n text: \"PanResponder — Supported: `create(config)` -> `panHandlers` (spread onto a `View`), full `gestureState` (`dx`/`dy`, `vx`/`vy`, `x0`/`y0`, `moveX`/`moveY`, `numberActiveTouches`) — **react-native's own file, vendored unmodified** (MIT, `Libraries/Interaction/PanResponder.js`), running on our reproduction of RN's `touchHistory` store. Differences: multi-touch `gestureState` is single-touch here (one pointer), and `onShouldBlockNativeResponder`'s return value is not consumed yet\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"Animated\",\n text: \"Animated — Supported: `Value`, `timing`, `spring`, `sequence`, `parallel`, `delay`, `loop`, `interpolate` (numbers and deg/rad strings, clamp/extend/identity), `ValueXY` (`setValue`/`setOffset`/`flattenOffset`/`extractOffset`, `getLayout`, `getTranslateTransform`) — the value a `PanResponder` drag writes to. Differences: `useNativeDriver` is ignored (with a warning); the direct path is native-speed anyway; `Animated.event` is not implemented — write the value directly (`pan.setValue({x: g.dx, y: g.dy})`), which is what it would do\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"Easing\",\n text: \"Easing — Supported: linear/ease/quad/cubic/in/out/inOut/bezier. Differences: —\",\n },\n {\n doc: \"docs/api.md\",\n heading: \"version\",\n text: \"version — Supported: package version. Differences: extension\",\n },\n] as const satisfies readonly DocChunk[]\n"]}