@gjsify/react-native 0.46.0 → 0.48.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/PROPS.md +319 -92
  2. package/README.md +94 -0
  3. package/SUPPORT.md +14 -9
  4. package/lib/esm/accessibility.js +1 -0
  5. package/lib/esm/apis/alert.js +1 -1
  6. package/lib/esm/app-registry.js +1 -1
  7. package/lib/esm/child-facts.js +1 -0
  8. package/lib/esm/components.js +1 -1
  9. package/lib/esm/generated/own-exports.js +1 -1
  10. package/lib/esm/generated/unsupported-react-native.js +1 -1
  11. package/lib/esm/index.js +1 -1
  12. package/lib/esm/lists/controller.js +1 -1
  13. package/lib/esm/primitives/accessibility.js +1 -0
  14. package/lib/esm/primitives/answers.js +1 -1
  15. package/lib/esm/primitives/defaults.js +1 -1
  16. package/lib/esm/primitives/errors.js +1 -1
  17. package/lib/esm/primitives/index.js +1 -1
  18. package/lib/esm/primitives/resolve.js +1 -1
  19. package/lib/esm/primitives/style.js +1 -1
  20. package/lib/esm/primitives/table.js +1 -1
  21. package/lib/esm/prop-table.js +1 -1
  22. package/lib/esm/router/chrome.js +1 -0
  23. package/lib/esm/router/navigation.js +1 -1
  24. package/lib/esm/router/per-route-cache.js +1 -0
  25. package/lib/esm/router/stack.js +1 -1
  26. package/lib/esm/router/tabs.js +1 -1
  27. package/lib/esm/solid/index.js +1 -1
  28. package/lib/esm/support-table.js +1 -1
  29. package/lib/esm/window-chrome.js +1 -0
  30. package/lib/types/accessibility.d.ts +10 -0
  31. package/lib/types/app-registry.d.ts +95 -5
  32. package/lib/types/app-registry.spec.d.ts +2 -0
  33. package/lib/types/child-facts.d.ts +45 -0
  34. package/lib/types/child-facts.spec.d.ts +2 -0
  35. package/lib/types/components.d.ts +34 -1
  36. package/lib/types/generated/unsupported-react-native.d.ts +8 -4
  37. package/lib/types/index.d.ts +3 -3
  38. package/lib/types/primitives/accessibility.d.ts +112 -0
  39. package/lib/types/primitives/answers.d.ts +18 -0
  40. package/lib/types/primitives/errors.d.ts +9 -0
  41. package/lib/types/primitives/resolve.d.ts +10 -0
  42. package/lib/types/primitives/style.d.ts +23 -0
  43. package/lib/types/primitives/table.d.ts +13 -1
  44. package/lib/types/prop-table.d.ts +29 -0
  45. package/lib/types/router/chrome.d.ts +106 -0
  46. package/lib/types/router/errors.d.ts +3 -1
  47. package/lib/types/router/per-route-cache.d.ts +21 -0
  48. package/lib/types/router/stack.d.ts +6 -1
  49. package/lib/types/solid/index.d.ts +2 -1
  50. package/lib/types/support-table.d.ts +1 -1
  51. package/lib/types/window-chrome.d.ts +39 -0
  52. package/package.json +7 -7
  53. package/react-native-surface.json +18 -9
package/README.md CHANGED
@@ -86,6 +86,40 @@ Native: `AppRegistry.runApplication` there is handed a root tag by a host that
86
86
  already exists, while on a desktop **the application is the host**. That limit is in
87
87
  the table rather than only here.
88
88
 
89
+ Because the application is the host, this layer hands it back (ADR 0043). Two shapes,
90
+ split by question:
91
+
92
+ ```ts
93
+ // 1. Anything that has to happen at a lifecycle moment travels as an option — the
94
+ // whole option set of `@gjsify/adwaita-app` is available here, `createWindow`
95
+ // excepted, because that is what renders your component.
96
+ await registerRootComponent(App, {
97
+ applicationId: 'org.example.App',
98
+ devtools: true, // or { extend, address, instance } — see @gjsify/devtools
99
+ onStartup: (app) => app.set_accels_for_action('app.quit', ['<primary>q']),
100
+ });
101
+
102
+ // 2. "Which application am I in" is an accessor, readable from anywhere in the tree.
103
+ // Both answer from the first render onwards — before the window maps — and `null`
104
+ // outside the loop.
105
+ AppRegistry.getApplication(); // Adw.Application | null
106
+ AppRegistry.getWindow(); // Gtk.Window | null
107
+ ```
108
+
109
+ Those two, and deliberately not the React root or the container widget it renders
110
+ into. Both of those are the bootstrap's own working state — a `render()` from
111
+ outside replaces the tree this layer mounted, an `unmount()` leaves `getWindow()`
112
+ answering with a window whose content is gone — and an accessor that can be put
113
+ into a lying state is worse than one that does not exist. Adding one later is
114
+ additive; removing one from a published API is not.
115
+
116
+ `devtools` is the one worth knowing about: with it (or `GJSIFY_DEVTOOLS=1`) the running
117
+ application answers `DumpTree`, `GetProperty`, `FindWidget`, `ActivateWidget`, `SendKey`
118
+ and `Screenshot` over DBus, so its screens can be driven and photographed by something
119
+ other than itself. On macOS and Windows there is no session bus, and `devtools.address`
120
+ is how the bus-less peer transport gets pinned — which is the reason the option set is
121
+ forwarded whole rather than field by field.
122
+
89
123
  ## Three layers, and where each one lives
90
124
 
91
125
  | layer | where | knows about |
@@ -97,6 +131,34 @@ the table rather than only here.
97
131
  L2 is exported (`import { primitives } from '@gjsify/react-native'`) so any binding
98
132
  can render the same vocabulary without going through the React components.
99
133
 
134
+ ### What a parent asks about its children, and what stays transparent
135
+
136
+ A few decisions cannot be taken by the element that authored them. `position: absolute`
137
+ is the clearest: it positions the element on top of its parent, so the **parent** has
138
+ to be a `Gtk.Overlay` — and a `View` becomes one as soon as one of its children asks.
139
+ The same shape decides whether a text child competes with a prop for a widget's text
140
+ sink, and `justify-between` is refused on a child count.
141
+
142
+ React's parent renders before its children exist, so it reads their **descriptors**.
143
+ Three things are therefore transparent to that read, and each is transparent because
144
+ an application writes it without meaning to change anything:
145
+
146
+ - **a Fragment.** `<>…</>` is transparent to layout in React, so it is transparent
147
+ here: it is expanded away before anything is counted, its children keeping their own
148
+ keys composed behind its own. A card whose `overlay={<>…</>}` holds the absolutely
149
+ positioned child gets the overlay it asked for.
150
+ - **an array**, which is the same statement in a different spelling.
151
+ - **an `<Animated.View>`.** Its style carries `Animated.Value`s, which is exactly what
152
+ the style partition refuses on a plain element — so a parent reads it through the
153
+ same split the component itself uses. An animated fade and an `absolute` compose.
154
+
155
+ What is NOT transparent is a foreign composite component: `<MyCard className="…">` may
156
+ carry any vocabulary at all, and a parent must not throw for one it cannot route, so it
157
+ answers "no" and the child — if it ever reaches L2 — is refused by name. That boundary
158
+ is enumerated in `src/child-facts.spec.ts` as every fact a parent reads × every wrapper
159
+ it can arrive in, with the fact list derived from the record itself: a new fact has no
160
+ row until someone adds one, and the suite says so.
161
+
100
162
  ### The split is measured, not asserted
101
163
 
102
164
  `@gjsify/react-native/solid` exports the same seven primitives as SolidJS components
@@ -222,6 +284,38 @@ The conventions are parsed **in this package, not in the plugin**, so a consumer
222
284
  another bundler — or one writing the nine-line manifest by hand — gets the same
223
285
  refusals. The plugin walks a directory and emits what it found.
224
286
 
287
+ ### One header bar per window, owned by the outermost navigator
288
+
289
+ An `Adw.NavigationPage` carries its own `Adw.HeaderBar`, so a `_layout` inside a
290
+ `_layout` describes a header bar inside a header bar. Measured on a five-tab
291
+ application entered at its index route, that drew **three** bars with **three close
292
+ buttons**, only one of which closed the window (#1460). Nothing in a file-system route
293
+ tree says which level owns the chrome, so this package decides it:
294
+
295
+ - The **outermost navigator owns the window's chrome** while it has a header bar on
296
+ screen. It claims the bar `AppRegistry` puts in the window; the window takes it back
297
+ when the root unmounts, and when the screen on top asks for none — an `Adw.Window`
298
+ carries no titlebar of its own, so a `headerShown: false` screen that also took the
299
+ window's bar away would be a window with nothing to close or move it with. For
300
+ `<Stack>` ownership means the pages carry the chrome, which is Adwaita's own
301
+ composition and the only one where the back button and the page title appear at all.
302
+ - An **inner `<Tabs>` contributes its `Adw.ViewSwitcher`** to the enclosing page's
303
+ header bar title, where a hand-written Adwaita application puts it, instead of
304
+ building a second bar. `headerShown: false` on the enclosing screen leaves no bar to
305
+ contribute to, and the tab level then renders its own.
306
+ - **The window controls go on the outermost bar of each path.** An inner `<Stack>`'s
307
+ pages still need their own back buttons, so their bars stay — without window
308
+ controls. `Adw.NavigationSplitView` splits the same decoration across its two
309
+ visible bars, which is why the rule that holds this is *one set of window controls
310
+ per side*, not *one header bar*.
311
+
312
+ That rule is machine-checked from outside, over the widgets that actually DRAW:
313
+ `windowChromeProblems()` in `@gjsify/gtk-host/conformance` counts mapped, non-empty
314
+ `GtkWindowControls` per side of a presented window and names every duplicate — and
315
+ also refuses a window whose chrome draws nothing at all, which is the failure the fix
316
+ above can overshoot into. `headerRight`, `headerLeft` and a custom header component
317
+ are still not answered for; the support table says so by name.
318
+
225
319
  ## Support
226
320
 
227
321
  See **[SUPPORT.md](SUPPORT.md)** — one section per declared surface, generated from
package/SUPPORT.md CHANGED
@@ -20,9 +20,9 @@ Imported from `react-native`; answered by `@gjsify/react-native`.
20
20
  | `useColorScheme` | P1 | Adw.StyleManager.dark | Follows the Adwaita colour scheme — the dark property, which is what the user is looking at, not color-scheme, which is what the application asked for. |
21
21
  | `Appearance` | P2 | Adw.StyleManager | The imperative sibling of useColorScheme, over the SAME reader — getColorScheme reads Adw.StyleManager:dark (what the user is looking at) and setColorScheme writes :color-scheme (what the application asked for), which is exactly the split React Native’s getter and setter have. |
22
22
  | `EventEmitter` | — | — | Pure JavaScript; nothing in it touches a platform. |
23
- | `unstable_batchedUpdates` | — | — | React 19 batches automatically; this is the identity call it already is upstream. |
23
+ | `unstable_batchedUpdates` | — | — | React 19 batches automatically; this is the identity call it already is upstream — literally so since 0.86, where the getter became a method whose body is `fn(bookkeeping)`. |
24
24
 
25
- ### Supported, with named limits (31)
25
+ ### Supported, with named limits (32)
26
26
 
27
27
  | export | tier | GTK | why |
28
28
  |---|---|---|---|
@@ -35,6 +35,7 @@ Imported from `react-native`; answered by `@gjsify/react-native`.
35
35
  | `Linking` | P1 | Gtk.UriLauncher | openURL and canOpenURL only. |
36
36
  | `Switch` | P1 | Gtk.Switch | Direct counterpart. |
37
37
  | `Platform` | P1 | — | OS is "linux" \| "macos" \| "windows"; select() picks the default branch. |
38
+ | `Modal` | P1 | Adw.Dialog | A PORTAL: the element’s host node is not its parent node. An Adw.Dialog is PRESENTED against a parent and never parented by it — MEASURED on libadwaita 1.9.3 / GTK 4.22.4, box.append(dialog) with the box ROOTED IN A WINDOW is g_error() (SIGABRT, exit 134, a core dump), while a detached box takes the same append in silence, which is how a re-test on a bare box appears to disprove it. So @gjsify/gtk-host grew a placement axis (ADR 0045) and AdwDialog declares present/force_close on it; nothing is appended and the abort is unreachable. |
38
39
  | `Share` | P1 | Gdk.Clipboard | No desktop share sheet worth pretending about; copying the link is the honest mapping. |
39
40
  | `AppRegistry` | P1 | Adw.Application + Adw.ApplicationWindow | The entry point. Nothing renders without a window, so this is P1 despite being a shim. |
40
41
  | `StyleSheet` | P1 | Gdk.Monitor.scale for hairlineWidth | create/flatten/compose/hairlineWidth/absoluteFill. Style objects go through the same partition as classes (ADR 0032 § 4), which is why create can be identity. |
@@ -50,7 +51,7 @@ Imported from `react-native`; answered by `@gjsify/react-native`.
50
51
  | `Button` | P2 | Gtk.Button | The one component whose React Native styling story is "you cannot", which GTK agrees with. title, onPress and disabled. |
51
52
  | `Dimensions` | P2 | Gtk.Window allocation, Gdk.Monitor geometry | get("window") is the window, not the screen — a desktop app is not full-screen, so the screen’s number would be wrong in the ordinary case. get("screen") is the monitor, because that is what it asks for. |
52
53
  | `useWindowDimensions` | P2 | Gdk.Surface notify::width/height, Gtk.Window allocation | The hook form of Dimensions, through useSyncExternalStore so a resize between render and commit cannot tear. |
53
- | `Alert` | P2 | Adw.AlertDialog | Direct counterpart, and buildable where Modal is not: Alert is a FUNCTION CALL, so no element is ever inserted into a widget. Measured on libadwaita 1.9.3 — present(null) from a plain function, with no parent and no window, returned with no diagnostic. |
54
+ | `Alert` | P2 | Adw.AlertDialog | Direct counterpart, and it needed no placement seam to be one: Alert is a FUNCTION CALL, so no element is ever inserted into a widget (Modal is the same widget family as an ELEMENT, and reaches the same call through the host portal placement of ADR 0045). Measured on libadwaita 1.9.3 — present(null) from a plain function, with no parent and no window, returned with no diagnostic. |
54
55
  | `SafeAreaView` | P2 | Gtk.Box | The INSET has no desktop meaning; the layout does. It is a View in every other respect, and it has to be a real export to be imported. |
55
56
  | `StatusBar` | P2 | — | A desktop window has no status bar to configure, and <StatusBar/> is in the first ten lines of most React Native screens — so it renders NOTHING and says so, rather than failing to import. |
56
57
  | `KeyboardAvoidingView` | P2 | Gtk.Box | No on-screen keyboard eats a desktop window layout, so the AVOIDING is the no-op. React Native’s KeyboardAvoidingView is a View that changes its own height; what is left here is the View. |
@@ -58,17 +59,15 @@ Imported from `react-native`; answered by `@gjsify/react-native`.
58
59
  | `Animated` | P3 | Adw.TimedAnimation, over Adw.CallbackAnimationTarget | Value, timing and View — the three names a measured application uses, in one file of 28 routes. The rest of the subsystem is a graph evaluated per frame, and every other member refuses BY NAME. |
59
60
  | `Easing` | P3 | AdwEasing, through Adw.TimedAnimation:easing | Not arithmetic, which the planning entry called it: React Native’s easings are FUNCTIONS and AdwEasing is an ENUM with no callback form, so this is a name-to-enum mapping and every pair in it is measured. |
60
61
 
61
- ### Planned (26)
62
+ ### Planned (32)
62
63
 
63
64
  | export | tier | GTK | why |
64
65
  |---|---|---|---|
65
- | `Modal` | P1 | Adw.Dialog | An Adw.Dialog cannot be an ordinary element. MEASURED on libadwaita 1.9.3: box.append(dialog) calls g_error() — SIGABRT and a core dump, not a catchable exception — but ONLY when the box is rooted in a window. A detached box accepts the append in silence, so a re-test on a bare box appears to disprove this and puts the primitive back. A dialog is PRESENTED against a parent, never parented by it, so this is a PORTAL and needs a host seam that does not exist yet. |
66
66
  | `AppState` | P3 | Gtk.Application / Gdk.Surface state | active/background from window focus and visibility. |
67
67
  | `PixelRatio` | P3 | Gdk.Surface.scale-factor | The scale factor of the surface the widget is on. |
68
68
  | `PlatformColor` | P3 | Adwaita named colours | Maps unusually well — GTK’s palette is exactly this idea. |
69
69
  | `AccessibilityInfo` | P3 | Gtk.Accessible / AT-SPI | The highest-value P3 entry: GTK’s accessibility model is strong and the props map onto it well. |
70
70
  | `LayoutAnimation` | P3 | — | Needs an animated layout pass, which is the same subsystem as Animated. |
71
- | `InteractionManager` | P3 | — | Deferring work until interactions settle; a main-loop idle source is the counterpart. |
72
71
  | `useAnimatedValue` | P3 | — | Part of the Animated subsystem. |
73
72
  | `useAnimatedValueXY` | P3 | — | Part of the Animated subsystem. |
74
73
  | `useAnimatedColor` | P3 | — | Part of the Animated subsystem. |
@@ -88,6 +87,14 @@ Imported from `react-native`; answered by `@gjsify/react-native`.
88
87
  | `ProgressBarAndroid` | P3 | Gtk.ProgressBar | Android-only by name; GTK has the widget. |
89
88
  | `NativeEventEmitter` | P3 | — | It would construct and subscribe, but nothing native would ever emit into it — shipping that needs a decision, not a class. |
90
89
  | `DeviceEventEmitter` | P3 | — | The global emitter. Lands with NativeEventEmitter, and for the same reason. |
90
+ | `AssetRegistry` | P3 | the bundler’s own asset map | undefined |
91
+ | `unstable_VirtualArray` | P3 | Gio.ListStore | The array-backed implementation of the `VirtualCollection` interface — `size` plus `at(index)`. Its own doc warns it is not for large arrays, because the constructor copies the input; the LAZY case is the interface, not this class. `Gio.ListStore` is the same array-backed shape, and a Gio.ListModel of one\u2019s own is the lazy one. |
92
+ | `unstable_createVirtualCollectionView` | P3 | Gtk.ListView / Gtk.GridView | Builds a view component from a layout component and a generator. The per-item render is the returned component\u2019s `children` render prop — which is what `Gtk.SignalListItemFactory` answers; the generator is a different thing (see below). |
93
+ | `unstable_VirtualColumn` | P3 | Gtk.ListView (vertical) | The collection view built over the column generator. Its layout component renders children plus a spacer and nothing else — the AXIS is in the generator\u2019s spacer style, not in the layout. |
94
+ | `unstable_VirtualColumnGenerator` | P3 | Gtk.ListView\u2019s own recycling window | NOT per item: `{ initial: { itemCount, spacerStyle }, next(event) }` \u2014 how many items to render and how tall the spacer is, recomputed on a mode change. It never sees an item. GTK computes the same thing itself from the viewport. |
95
+ | `unstable_VirtualRow` | P3 | Gtk.ListView (horizontal) | The row twin of the column view. Its layout component is identical to the column\u2019s; on GTK the pair is one view with its orientation set. Upstream exports no row GENERATOR, so only one half of the pair is configurable from outside. |
96
+ | `unstable_getScrollParent` | P3 | the enclosing Gtk.ScrolledWindow | The nearest scrollable ancestor of a node. GTK answers it by walking parents to a Gtk.ScrolledWindow, and returns nothing at the root for the same reason React Native does. |
97
+ | `unstable_DEFAULT_INITIAL_NUM_TO_RENDER` | P3 | — | The constant 7, upstream’s initial window size. GTK sizes its own recycling window from the viewport, so this is a number to expose rather than to obey. |
91
98
 
92
99
  ### No meaning on a desktop window (6)
93
100
 
@@ -100,7 +107,7 @@ Imported from `react-native`; answered by `@gjsify/react-native`.
100
107
  | `DevMenu` | — | — | The shake-to-open developer menu. |
101
108
  | `DevSettings` | — | — | Development-client settings for a phone runtime. |
102
109
 
103
- ### Refused (25)
110
+ ### Refused (23)
104
111
 
105
112
  | export | tier | GTK | why |
106
113
  |---|---|---|---|
@@ -125,8 +132,6 @@ Imported from `react-native`; answered by `@gjsify/react-native`.
125
132
  | `findNodeHandle` | — | — | Returns a native view tag. A ref here is the Gtk.Widget itself, which is more useful. |
126
133
  | `registerCallableModule` | — | — | Registers a module callable from the native side. There is no native side. |
127
134
  | `Networking` | — | — | React Native’s XHR internals. Use fetch, which gjsify provides. |
128
- | `NativeDialogManagerAndroid` | — | — | An Android dialog native module. Alert is the portable spelling. |
129
- | `Touchable` | — | — | The legacy mixin behind the Touchable family, not a public component. |
130
135
  | `NativeAppEventEmitter` | — | — | The legacy iOS app-event emitter. |
131
136
  | `RootTagContext` | — | — | A React Native surface identifier. This layer has one root per Adw window. |
132
137
 
@@ -0,0 +1 @@
1
+ import"./_virtual/_rolldown/runtime.js";import e from"gi://GObject?version=2.0";import t from"gi://Gtk?version=4.0";function member(e,t){return e[t.toUpperCase().replace(/-/g,`_`)]}const n=t.AccessibleProperty,r=t.AccessibleState;function valueFor(t){let n=new e.Value;return typeof t==`string`?(n.init(e.TYPE_STRING),n.set_string(t),n):typeof t==`boolean`?(n.init(e.TYPE_BOOLEAN),n.set_boolean(t),n):(n.init(e.TYPE_INT),n.set_int(t),n)}const unknownAttribute=e=>Error(`@gjsify/react-native: the prop "${e.prop}" is routed to the GTK accessible ${e.set} "${e.name}", which Gtk.Accessible${e.set===`property`?`Property`:`State`} does not carry. The table is wrong, not the call`);function applyAccessibility(e,t){let i=[],a=[],o=[],s=[];for(let e of t){let t=e.set===`property`,c=member(t?n:r,e.name);if(c===void 0)throw unknownAttribute(e);(t?i:o).push(c),(t?a:s).push(valueFor(e.value))}return i.length>0&&e.update_property(i,a),o.length>0&&e.update_state(o,s),()=>{for(let t of i)e.reset_property(t);for(let t of o)e.reset_state(t)}}export{applyAccessibility};
@@ -1 +1 @@
1
- import"../_virtual/_rolldown/runtime.js";import{PrimitiveError as e}from"../primitives/errors.js";import t from"gi://Adw?version=1";import n from"gi://Gtk?version=4.0";function anchor(){let e=n.Window.get_toplevels();for(let t=0;t<e.get_n_items();t++){let n=e.get_item(t);if(n!==null&&n.get_mapped())return n}return null}const appearanceOf=e=>e===`destructive`?t.ResponseAppearance.DESTRUCTIVE:t.ResponseAppearance.DEFAULT,r={alert(e,n,r,i){let a=new t.AlertDialog({heading:e,...n===void 0?{}:{body:n}});i?.cancelable===!1&&(a.canClose=!1);let o=r===void 0||r.length===0?[{text:`OK`}]:r,s=new Map,c=null;o.forEach((e,t)=>{let n=`response-${t}`;a.add_response(n,e.text??`Button ${t+1}`),a.set_response_appearance(n,appearanceOf(e.style)),e.onPress!==void 0&&s.set(n,e.onPress),e.style===`cancel`?a.set_close_response(n):c??=n}),c!==null&&a.set_default_response(c);let l=a.connect(`response`,(e,t)=>{a.disconnect(l),s.get(t)?.()});if(i?.onDismiss!==void 0){let e=a.connect(`closed`,()=>{a.disconnect(e),i.onDismiss?.()})}a.present(anchor())},prompt(){throw new e(`Alert`,`prompt`,"is iOS-only in React Native, and its contract — four overloads, a login/password variant, and a callback whose arity depends on the type — is what makes it a refusal rather than a port. `Adw.AlertDialog:extra-child` holds a `Gtk.Entry`, so build the dialog you actually want")}};export{r as Alert};
1
+ import"../_virtual/_rolldown/runtime.js";import{PrimitiveError as e}from"../primitives/errors.js";import t from"gi://Gtk?version=4.0";import n from"gi://Adw?version=1";function anchor(){let e=t.Window.get_toplevels();for(let t=0;t<e.get_n_items();t++){let n=e.get_item(t);if(n!==null&&n.get_mapped())return n}return null}const appearanceOf=e=>e===`destructive`?n.ResponseAppearance.DESTRUCTIVE:n.ResponseAppearance.DEFAULT,r={alert(e,t,r,i){let a=new n.AlertDialog({heading:e,...t===void 0?{}:{body:t}});i?.cancelable===!1&&(a.canClose=!1);let o=r===void 0||r.length===0?[{text:`OK`}]:r,s=new Map,c=null;o.forEach((e,t)=>{let n=`response-${t}`;a.add_response(n,e.text??`Button ${t+1}`),a.set_response_appearance(n,appearanceOf(e.style)),e.onPress!==void 0&&s.set(n,e.onPress),e.style===`cancel`?a.set_close_response(n):c??=n}),c!==null&&a.set_default_response(c);let l=a.connect(`response`,(e,t)=>{a.disconnect(l),s.get(t)?.()});if(i?.onDismiss!==void 0){let e=a.connect(`closed`,()=>{a.disconnect(e),i.onDismiss?.()})}a.present(anchor())},prompt(){throw new e(`Alert`,`prompt`,"is iOS-only in React Native, and its contract — four overloads, a login/password variant, and a callback whose arity depends on the type — is what makes it a refusal rather than a port. `Adw.AlertDialog:extra-child` holds a `Gtk.Entry`, so build the dialog you actually want")}};export{r as Alert};
@@ -1 +1 @@
1
- import"./_virtual/_rolldown/runtime.js";import{UnsupportedError as e}from"./unsupported.js";import t from"gi://Adw?version=1";import{createElement as n}from"react";import r from"gi://Gtk?version=4.0";import{runAdwaitaApp as i}from"@gjsify/adwaita-app";import{createRoot as a}from"@gjsify/gtk-host/react";const o=new Map;function buildWindow(e,n,i){let a=new t.ApplicationWindow({application:e,title:i.title??n,defaultWidth:i.defaultWidth??900,defaultHeight:i.defaultHeight??700}),o=new t.ToolbarView;o.add_top_bar(new t.HeaderBar);let s=new r.Box({orientation:r.Orientation.VERTICAL});return o.set_content(s),a.set_content(o),{window:a,content:s}}const s={registerComponent(e,t){return o.set(e,{provider:t}),e},getAppKeys(){return[...o.keys()]},getRunnable(e){return o.get(e)},async runApplication(e,t){let r=o.get(e);if(r===void 0){let t=[...o.keys()];throw Error(`@gjsify/react-native: no component is registered as "${e}". `+(t.length>0?`Registered: ${t.join(`, `)}.`:`Nothing is registered — call AppRegistry.registerComponent(key, () => Component) first.`))}let s={root:null},c=await i({applicationId:t.applicationId,css:t.css,createWindow:i=>{let{window:o,content:c}=buildWindow(i,e,t),l=r.provider();return s.root=a(c),s.root.render(n(l,t.initialProps??{})),o}});return s.root?.unmount(),c},unmountApplicationComponentAtRootTag(){throw new e(`AppRegistry`)}};function registerRootComponent(e,t){return s.registerComponent(`main`,()=>e),s.runApplication(`main`,t)}export{s as AppRegistry,registerRootComponent};
1
+ import"./_virtual/_rolldown/runtime.js";import{UnsupportedError as e}from"./unsupported.js";import{buildWindowShell as t,provideWindowChrome as n}from"./window-chrome.js";import r from"gi://Adw?version=1";import{createElement as i}from"react";import a from"gi://GLib?version=2.0";import{runAdwaitaApp as o}from"@gjsify/adwaita-app";import{registerBuiltinWidgets as s}from"@gjsify/gtk-host";import{windowChromeProblems as c}from"@gjsify/gtk-host/conformance";import{createRoot as l}from"@gjsify/gtk-host/react";const u=new Map;let d=null,f=null,p=[],m=0;const lastWindowChromeProblems=()=>p,windowChromeChecks=()=>m;function checkWindowChrome(e){let t=e.connect(`map`,()=>{e.disconnect(t),a.idle_add(a.PRIORITY_DEFAULT_IDLE,()=>{if(!e.get_mapped())return a.SOURCE_REMOVE;p=c(e),m++;for(let e of p)console.warn(`@gjsify/react-native: ${e}`);return a.SOURCE_REMOVE})})}function toShellOptions(e,t){return{...e,createWindow:t}}function buildWindow(e,n,i){let a=new r.ApplicationWindow({application:e,title:i.title??n,defaultWidth:i.defaultWidth??900,defaultHeight:i.defaultHeight??700}),o=t();return a.set_content(o.root),{window:a,content:o.content,chrome:o.chrome}}function mountApplicationRoot(e,t,r,a){let{window:o,content:s,chrome:c}=buildWindow(e,t,r),u=a(),f=l(s);return d={app:e,window:o,content:s,root:f},f.render(n(c,i(u,r.initialProps??{}))),checkWindowChrome(o),o}async function ownTheApplication(e,t){if(f!==null)throw Error(`@gjsify/react-native: AppRegistry.runApplication("${e}") was called while "${f}" is still running. One process is one GApplication here — this layer CREATES the application, which is the declared divergence from React Native — so a second call has no window of its own to build and would take the first one’s handle away from it. Await the first call, or render both trees under one root component.`);f=e;try{return await t()}finally{let e=d;d=null,f=null,e?.root.unmount()}}const h={registerComponent(e,t){return u.set(e,{provider:t}),e},getAppKeys(){return[...u.keys()]},getRunnable(e){return u.get(e)},getApplication(){return d?.app??null},getWindow(){return d?.window??null},async runApplication(e,t){let n=u.get(e);if(n===void 0){let t=[...u.keys()];throw Error(`@gjsify/react-native: no component is registered as "${e}". `+(t.length>0?`Registered: ${t.join(`, `)}.`:`Nothing is registered — call AppRegistry.registerComponent(key, () => Component) first.`))}return s(),ownTheApplication(e,()=>o(toShellOptions(t,r=>mountApplicationRoot(r,e,t,n.provider))))},unmountApplicationComponentAtRootTag(){throw new e(`AppRegistry`)}};function registerRootComponent(e,t){return h.registerComponent(`main`,()=>e),h.runApplication(`main`,t)}export{h as AppRegistry,lastWindowChromeProblems,mountApplicationRoot,ownTheApplication,registerRootComponent,toShellOptions,windowChromeChecks};
@@ -0,0 +1 @@
1
+ import"./_virtual/_rolldown/runtime.js";import{splitAnimatedStyle as e}from"./primitives/style.js";import{declaresAbsolute as t}from"./primitives/resolve.js";import{Children as n,Fragment as r,cloneElement as i,isValidElement as a}from"react";const isTextNode=e=>typeof e==`string`||typeof e==`number`,isFragment=e=>a(e)&&e.type===r;function childNodes(e){return expand(n.toArray(e))}function expand(e){if(!e.some(isFragment))return e;let t=[];for(let r of e){if(!isFragment(r)){t.push(r);continue}let e=r.key??``;for(let o of expand(n.toArray(r.props.children))){if(!a(o)){t.push(o);continue}t.push(i(o,{key:`${e}:${o.key??``}`}))}}return t}function readableProps(t){let n=t.props;if(n.style===void 0)return n;let{plain:r,animated:i}=e(n.style);return Object.keys(i).length===0?n:{...n,style:r}}function isAbsoluteChild(e,n){if(!a(e))return!1;try{return t(readableProps(e),n)}catch{return!1}}function childFacts(e,t){let n=0,r=!1;for(let i of e)isTextNode(i)?r=!0:isAbsoluteChild(i,t)&&n++;return{absolute:n,count:e.length,text:r}}export{childFacts,childNodes,isAbsoluteChild,isTextNode,readableProps};
@@ -1 +1 @@
1
- import"./_virtual/_rolldown/runtime.js";import{accessor as e}from"./accessor.js";import{isAnimatedValue as t}from"./animated/brand.js";import{PrimitiveError as n}from"./primitives/errors.js";import{onLiveRegion as r}from"./announce.js";import{ParentContext as i,ParentProvider as a}from"./parent-context.js";import{onGesture as o,onPressStateChange as s}from"./press.js";import{createHandle as c}from"./primitives/handles.js";import{flattenStyle as l}from"./primitives/style.js";import{declaresAbsolute as u,resolvePrimitive as d}from"./primitives/resolve.js";import{animatedProperty as f,assertNoStaticClash as p}from"./animated/properties.js";import{styleConfig as m}from"./style-config.js";import h from"gi://Gio?version=2.0";import{Children as g,createElement as _,isValidElement as v,useContext as y,useEffect as b,useMemo as x,useRef as S,useState as C}from"react";const isTextNode=e=>typeof e==`string`||typeof e==`number`;function isAbsoluteChild(e,t){if(!v(e))return!1;try{return u(e.props,t)}catch{return!1}}function childFacts(e,t){let n=0,r=!1;for(let i of e)isTextNode(i)?r=!0:isAbsoluteChild(i,t)&&n++;return{absolute:n,count:e.length,text:r}}function useSignals(t,n){let r=S(null),i=S(n);return i.current=n,{props:x(()=>{let n={};for(let a of t)n[`on:${a.signal}`]=()=>{let t=i.current[a.prop];if(typeof t!=`function`)return;if(a.read===null){t();return}let n=r.current;t(n===null?void 0:n[e(a.read)])};return n},[t.map(e=>`${e.prop}>${e.signal}>${e.read??``}`).join(`|`)]),widgetRef:r}}function nodeProps(e,t,n){let r={...t,...e.props,...n};return e.cssClasses.length>0&&(r[`css-classes`]=[...e.cssClasses]),r}function usePlan(e,t){let r=t,a=y(i),o=m(),s=g.toArray(r.children),l=d(e,r,{tokens:o.tokens,sheet:o.sheet,...a===null?{}:{parent:a},children:childFacts(s,o.tokens)}),u=Object.keys(l.intent);if(u.length>0)throw new n(e,u.join(`, `),"carries layout that cannot be resolved at this position. These need a parent to resolve against — `flex-1` and `self-*` need the parent orientation, `absolute` needs the parent to be an overlay — and this element is the root of its tree, or its parent is not a box. Wrap it in a <View>, or move the utility to a child.");let f=useSignals(l.events,r),p=r.ref,h=l.handle,_=l.node.tag,v=x(()=>e=>{f.widgetRef.current=e;let t=e==null?e:c(h,e,_);typeof p==`function`?p(t):p!=null&&(p.current=t)},[p,f.widgetRef,h,_]);useGestures(l.gestures,r,f.widgetRef),useLiveRegions(l.announcements,f.widgetRef);let b=useFiles(l.files),S={...f.props,ref:v,...b.outer};l.slot!==null&&(S.slot=l.slot);let C={...b.content};l.contentSlot!==null&&(C.slot=l.contentSlot);let w={...b.backdrop};l.backdropSlot!==null&&(w.slot=l.backdropSlot);let T=x(()=>l.childContext,[JSON.stringify(l.childContext),l.childContext]);return{plan:l,children:s,inherited:a?.props??{},extra:S,contentExtra:C,backdropExtra:w,published:T,tokens:o.tokens,widgetRef:f.widgetRef}}function useFiles(e){return x(()=>{let t={outer:{},content:{},backdrop:{}};for(let n of e)t[n.on][n.property]=n.kind===`path`?h.File.new_for_path(n.value):h.File.new_for_uri(n.value);return t},[e.map(e=>`${e.on}>${e.property}>${e.kind}>${e.value}`).join(`|`)])}function useGestures(e,t,n){let r=S(t);r.current=t;let i=e.map(e=>`${e.prop}>${e.signal}`).join(`|`);b(()=>{let e=n.current;if(i===``||e==null)return;let t=i.split(`|`).map(t=>{let[n,i]=t.split(`>`);return o(e,i,()=>{let e=r.current[n];typeof e==`function`&&e()})});return()=>{for(let e of t)e()}},[i,n])}function useLiveRegions(e,t){let n=e.map(e=>`${e.signal}>${e.read}>${e.priority}`).join(`|`);b(()=>{let e=t.current;if(n===``||e==null)return;let i=n.split(`|`).map(t=>{let[n,i,a]=t.split(`>`);return r(e,{prop:`accessibilityLiveRegion`,signal:n,read:i,priority:a})});return()=>{for(let e of i)e()}},[n,t])}function render(e){let{plan:t,children:n,inherited:r,extra:i,contentExtra:o,backdropExtra:s,published:c,tokens:l}=e,wrap=e=>_(a,{value:c},...e);if(t.content===null){let e=n.some(isTextNode)?n:[wrap(n)];return _(t.node.tag,nodeProps(t.node,r,i),...e)}let u=t.absoluteSlot===null?[]:n.filter(e=>isAbsoluteChild(e,l)),d=t.absoluteSlot===null?n:n.filter(e=>!isAbsoluteChild(e,l)),f=_(t.content.tag,nodeProps(t.content,{},o),wrap(d)),p=t.backdrop===null?[]:[_(t.backdrop.tag,nodeProps(t.backdrop,{},s))];return _(t.node.tag,nodeProps(t.node,r,i),...p,f,...u.length===0?[]:[wrap(u)])}function View(e){return render(usePlan(`View`,e))}function Text(e){return render(usePlan(`Text`,e))}function Pressable(e){let t=typeof e.children==`function`?e.children:null,[n,r]=C(!1),i=usePlan(`Pressable`,t===null?e:{...e,children:t({pressed:n})}),a=i.widgetRef;return b(()=>{if(t===null)return;let e=a.current;if(e!=null)return s(e,r)},[t===null,a]),render(i)}function ScrollView(e){return render(usePlan(`ScrollView`,e))}function ActivityIndicator(e){return render(usePlan(`ActivityIndicator`,e))}function TextInput(e){return render(usePlan(`TextInput`,e))}function Switch(e){return render(usePlan(`Switch`,e))}function Image(e){return render(usePlan(`Image`,e))}function ImageBackground(e){return render(usePlan(`ImageBackground`,e))}function TouchableOpacity(e){return render(usePlan(`TouchableOpacity`,e))}function TouchableHighlight(e){return render(usePlan(`TouchableHighlight`,e))}function TouchableWithoutFeedback(e){return render(usePlan(`TouchableWithoutFeedback`,e))}function Button(e){return render(usePlan(`Button`,e))}function SafeAreaView(e){return render(usePlan(`SafeAreaView`,e))}function KeyboardAvoidingView(e){return render(usePlan(`KeyboardAvoidingView`,e))}function StatusBar(e){return null}const w="configures the status bar above a phone screen, and a desktop window has none — the space above it belongs to the compositor and the header bar inside it is `Adw.HeaderBar`, an ordinary widget you render. This refuses rather than accepting the call, because a setter that appears to work is indistinguishable from one that does";Object.defineProperties(StatusBar,Object.getOwnPropertyDescriptors({setBarStyle:()=>{throw new n(`StatusBar`,`setBarStyle`,w)},setHidden:()=>{throw new n(`StatusBar`,`setHidden`,w)},setBackgroundColor:()=>{throw new n(`StatusBar`,`setBackgroundColor`,w)},setTranslucent:()=>{throw new n(`StatusBar`,`setTranslucent`,w)},setNetworkActivityIndicatorVisible:()=>{throw new n(`StatusBar`,`setNetworkActivityIndicatorVisible`,w)},pushStackEntry:()=>{throw new n(`StatusBar`,`pushStackEntry`,w)},popStackEntry:()=>{throw new n(`StatusBar`,`popStackEntry`,w)},replaceStackEntry:()=>{throw new n(`StatusBar`,`replaceStackEntry`,w)},get currentHeight(){throw new n(`StatusBar`,`currentHeight`,"is the height of a phone’s status bar, and code reads it straight into a layout (`paddingTop: StatusBar.currentHeight`). A desktop window has no such bar, so any number here would inset every ported screen by a bar that is not there. Use 0 explicitly if that is what you mean")}}));function splitAnimatedStyle(e,n){let r=l(n),i={},a=[];for(let[n,o]of Object.entries(r)){if(!t(o)){i[n]=o;continue}f(e,n),a.push({key:n,value:o})}return{plain:i,bindings:a}}function AnimatedView(t){let n=m(),{plain:r,bindings:i}=splitAnimatedStyle(`Animated.View`,t.style),a={...t,style:r};p(`Animated.View`,a,i.map(e=>e.key),n.tokens);let o=usePlan(`View`,a),s=o.widgetRef,c=i.map(e=>`${e.key}#${e.value.id}`).join(`|`),l=S(i);l.current=i,b(()=>{let t=s.current;if(c===``||t==null)return;let n=t,r=l.current.map(r=>{let i=e(f(`Animated.View`,r.key).property);return r.value.__attach({widget:t,write:e=>{n[i]=e}})});return()=>{for(let e of r)e()}},[c,s]);let u={};for(let t of i)u[e(f(`Animated.View`,t.key).property)]=t.value.__getValue();return render({...o,extra:{...o.extra,...u}})}function Icon(e){return render(usePlan(`Icon`,e))}export{ActivityIndicator,AnimatedView,Button,Icon,Image,ImageBackground,KeyboardAvoidingView,Pressable,SafeAreaView,ScrollView,StatusBar,Switch,Text,TextInput,TouchableHighlight,TouchableOpacity,TouchableWithoutFeedback,View,nodeProps,usePlan};
1
+ import"./_virtual/_rolldown/runtime.js";import{applyAccessibility as e}from"./accessibility.js";import{accessor as t}from"./accessor.js";import{PrimitiveError as n}from"./primitives/errors.js";import{onLiveRegion as r}from"./announce.js";import{splitAnimatedStyle as i}from"./primitives/style.js";import{resolvePrimitive as a}from"./primitives/resolve.js";import{childFacts as o,childNodes as s,isAbsoluteChild as c,isTextNode as l}from"./child-facts.js";import{ParentContext as u,ParentProvider as d}from"./parent-context.js";import{onGesture as f,onPressStateChange as p}from"./press.js";import{createHandle as m}from"./primitives/handles.js";import{animatedProperty as h,assertNoStaticClash as g}from"./animated/properties.js";import{styleConfig as _}from"./style-config.js";import v from"gi://Gio?version=2.0";import{createElement as y,useContext as b,useEffect as x,useMemo as S,useRef as C,useState as w}from"react";function useSignals(e,n){let r=C(null),i=C(n);return i.current=n,{props:S(()=>{let n={};for(let a of e)n[`on:${a.signal}`]=()=>{let e=i.current[a.prop];if(typeof e!=`function`)return;if(a.read===null){e();return}let n=r.current;e(n===null?void 0:n[t(a.read)])};return n},[e.map(e=>`${e.prop}>${e.signal}>${e.read??``}`).join(`|`)]),widgetRef:r}}function nodeProps(e,t,n){let r={...t,...e.props,...n};return e.cssClasses.length>0&&(r[`css-classes`]=[...e.cssClasses]),r}function usePlan(e,t){let r=t,i=b(u),c=_(),l=s(r.children),d=a(e,r,{tokens:c.tokens,sheet:c.sheet,...i===null?{}:{parent:i},children:o(l,c.tokens)}),f=Object.keys(d.intent);if(f.length>0)throw new n(e,f.join(`, `),"carries layout that cannot be resolved at this position. These need a parent to resolve against — `flex-1` and `self-*` need the parent orientation, `absolute` needs the parent to be an overlay — and this element is the root of its tree, or its parent is not a box. Wrap it in a <View>, or move the utility to a child.");let p=useSignals(d.events,r),h=r.ref,g=d.handle,v=d.node.tag,y=S(()=>e=>{p.widgetRef.current=e;let t=e==null?e:m(g,e,v);typeof h==`function`?h(t):h!=null&&(h.current=t)},[h,p.widgetRef,g,v]);useGestures(d.gestures,r,p.widgetRef),useLiveRegions(d.announcements,p.widgetRef),useAccessibility(d.accessibility,p.widgetRef);let x=useFiles(d.files),C={...p.props,ref:y,...x.outer};d.slot!==null&&(C.slot=d.slot);let w={...x.content};d.contentSlot!==null&&(w.slot=d.contentSlot);let T={...x.backdrop};d.backdropSlot!==null&&(T.slot=d.backdropSlot);let E=S(()=>d.childContext,[JSON.stringify(d.childContext),d.childContext]);return{plan:d,children:l,inherited:i?.props??{},extra:C,contentExtra:w,backdropExtra:T,published:E,tokens:c.tokens,widgetRef:p.widgetRef}}function useFiles(e){return S(()=>{let t={outer:{},content:{},backdrop:{}};for(let n of e)t[n.on][n.property]=n.kind===`path`?v.File.new_for_path(n.value):v.File.new_for_uri(n.value);return t},[e.map(e=>`${e.on}>${e.property}>${e.kind}>${e.value}`).join(`|`)])}function useGestures(e,t,n){let r=C(t);r.current=t;let i=e.map(e=>`${e.prop}>${e.signal}`).join(`|`);x(()=>{let e=n.current;if(i===``||e==null)return;let t=i.split(`|`).map(t=>{let[n,i]=t.split(`>`);return f(e,i,()=>{let e=r.current[n];typeof e==`function`&&e()})});return()=>{for(let e of t)e()}},[i,n])}function useLiveRegions(e,t){let n=e.map(e=>`${e.signal}>${e.read}>${e.priority}`).join(`|`);x(()=>{let e=t.current;if(n===``||e==null)return;let i=n.split(`|`).map(t=>{let[n,i,a]=t.split(`>`);return r(e,{prop:`accessibilityLiveRegion`,signal:n,read:i,priority:a})});return()=>{for(let e of i)e()}},[n,t])}function useAccessibility(t,n){let r=t.length===0?``:JSON.stringify(t);x(()=>{let t=n.current;if(!(r===``||t==null))return e(t,JSON.parse(r))},[r,n])}function render(e){let{plan:t,children:n,inherited:r,extra:i,contentExtra:a,backdropExtra:o,published:s,tokens:u}=e,wrap=e=>y(d,{value:s},...e);if(t.content===null){let e=n.some(l)?n:[wrap(n)];return y(t.node.tag,nodeProps(t.node,r,i),...e)}let f=t.absoluteSlot===null?[]:n.filter(e=>c(e,u)),p=t.absoluteSlot===null?n:n.filter(e=>!c(e,u)),m=y(t.content.tag,nodeProps(t.content,{},a),wrap(p)),h=t.backdrop===null?[]:[y(t.backdrop.tag,nodeProps(t.backdrop,{},o))];return y(t.node.tag,nodeProps(t.node,r,i),...h,m,...f.length===0?[]:[wrap(f)])}function View(e){return render(usePlan(`View`,e))}function Text(e){return render(usePlan(`Text`,e))}function Pressable(e){let t=typeof e.children==`function`?e.children:null,[n,r]=w(!1),i=usePlan(`Pressable`,t===null?e:{...e,children:t({pressed:n})}),a=i.widgetRef;return x(()=>{if(t===null)return;let e=a.current;if(e!=null)return p(e,r)},[t===null,a]),render(i)}function ScrollView(e){return render(usePlan(`ScrollView`,e))}function ActivityIndicator(e){return render(usePlan(`ActivityIndicator`,e))}function TextInput(e){return render(usePlan(`TextInput`,e))}function Switch(e){return render(usePlan(`Switch`,e))}function Image(e){return render(usePlan(`Image`,e))}function ImageBackground(e){return render(usePlan(`ImageBackground`,e))}function TouchableOpacity(e){return render(usePlan(`TouchableOpacity`,e))}function TouchableHighlight(e){return render(usePlan(`TouchableHighlight`,e))}function TouchableWithoutFeedback(e){return render(usePlan(`TouchableWithoutFeedback`,e))}function Button(e){return render(usePlan(`Button`,e))}function SafeAreaView(e){return render(usePlan(`SafeAreaView`,e))}function Modal(e){let t=usePlan(`Modal`,e);return e.visible===!1?null:render(t)}function KeyboardAvoidingView(e){return render(usePlan(`KeyboardAvoidingView`,e))}function StatusBar(e){return null}const T="configures the status bar above a phone screen, and a desktop window has none — the space above it belongs to the compositor and the header bar inside it is `Adw.HeaderBar`, an ordinary widget you render. This refuses rather than accepting the call, because a setter that appears to work is indistinguishable from one that does";Object.defineProperties(StatusBar,Object.getOwnPropertyDescriptors({setBarStyle:()=>{throw new n(`StatusBar`,`setBarStyle`,T)},setHidden:()=>{throw new n(`StatusBar`,`setHidden`,T)},setBackgroundColor:()=>{throw new n(`StatusBar`,`setBackgroundColor`,T)},setTranslucent:()=>{throw new n(`StatusBar`,`setTranslucent`,T)},setNetworkActivityIndicatorVisible:()=>{throw new n(`StatusBar`,`setNetworkActivityIndicatorVisible`,T)},pushStackEntry:()=>{throw new n(`StatusBar`,`pushStackEntry`,T)},popStackEntry:()=>{throw new n(`StatusBar`,`popStackEntry`,T)},replaceStackEntry:()=>{throw new n(`StatusBar`,`replaceStackEntry`,T)},get currentHeight(){throw new n(`StatusBar`,`currentHeight`,"is the height of a phone’s status bar, and code reads it straight into a layout (`paddingTop: StatusBar.currentHeight`). A desktop window has no such bar, so any number here would inset every ported screen by a bar that is not there. Use 0 explicitly if that is what you mean")}}));function animatedBindings(e,t){let{plain:n,animated:r}=i(t),a=[];for(let[t,n]of Object.entries(r))h(e,t),a.push({key:t,value:n});return{plain:n,bindings:a}}function AnimatedView(e){let n=_(),{plain:r,bindings:i}=animatedBindings(`Animated.View`,e.style),a={...e,style:r};g(`Animated.View`,a,i.map(e=>e.key),n.tokens);let o=usePlan(`View`,a),s=o.widgetRef,c=i.map(e=>`${e.key}#${e.value.id}`).join(`|`),l=C(i);l.current=i,x(()=>{let e=s.current;if(c===``||e==null)return;let n=e,r=l.current.map(r=>{let i=t(h(`Animated.View`,r.key).property);return r.value.__attach({widget:e,write:e=>{n[i]=e}})});return()=>{for(let e of r)e()}},[c,s]);let u={};for(let e of i)u[t(h(`Animated.View`,e.key).property)]=e.value.__getValue();return render({...o,extra:{...o.extra,...u}})}function Icon(e){return render(usePlan(`Icon`,e))}export{ActivityIndicator,AnimatedView,Button,Icon,Image,ImageBackground,KeyboardAvoidingView,Modal,Pressable,SafeAreaView,ScrollView,StatusBar,Switch,Text,TextInput,TouchableHighlight,TouchableOpacity,TouchableWithoutFeedback,View,nodeProps,usePlan};
@@ -1 +1 @@
1
- const e=[`OWN_EXPORT_NAMES`,`PRIMITIVE_VARIANTS`,`PrimitiveError`,`SUPPORTED_NAMES`,`SUPPORT_TABLE`,`UnsupportedError`,`acceptsProp`,`configureStyle`,`explainProp`,`explainUnsupported`,`isImportable`,`isOwnExport`,`primitives`,`propAnswer`,`propNames`,`propTable`,`registerRootComponent`,`resetStyleConfig`,`styleConfig`];export{e as OWN_EXPORT_NAMES};
1
+ const e=[`OWN_EXPORT_NAMES`,`PRIMITIVE_VARIANTS`,`PrimitiveError`,`SUPPORTED_NAMES`,`SUPPORT_TABLE`,`UnsupportedError`,`acceptsProp`,`configureStyle`,`explainProp`,`explainUnsupported`,`isImportable`,`isOwnExport`,`lastWindowChromeProblems`,`primitives`,`propAnswer`,`propNames`,`propTable`,`registerRootComponent`,`resetStyleConfig`,`styleConfig`];export{e as OWN_EXPORT_NAMES};
@@ -1 +1 @@
1
- import{unsupported as e}from"../unsupported.js";const t=e(`Modal`,`react-native`),n=e(`RefreshControl`,`react-native`),r=e(`AppState`,`react-native`),i=e(`PixelRatio`,`react-native`),a=e(`PlatformColor`,`react-native`),o=e(`AccessibilityInfo`,`react-native`),s=e(`LayoutAnimation`,`react-native`),c=e(`InteractionManager`,`react-native`),l=e(`useAnimatedValue`,`react-native`),u=e(`useAnimatedValueXY`,`react-native`),d=e(`useAnimatedColor`,`react-native`),f=e(`PanResponder`,`react-native`),p=e(`usePressability`,`react-native`),m=e(`DrawerLayoutAndroid`,`react-native`),h=e(`I18nManager`,`react-native`),g=e(`LogBox`,`react-native`),_=e(`Systrace`,`react-native`),v=e(`Vibration`,`react-native`),y=e(`ToastAndroid`,`react-native`),b=e(`InputAccessoryView`,`react-native`),x=e(`TouchableNativeFeedback`,`react-native`),S=e(`ActionSheetIOS`,`react-native`),C=e(`PushNotificationIOS`,`react-native`),w=e(`PermissionsAndroid`,`react-native`),T=e(`Settings`,`react-native`),E=e(`Clipboard`,`react-native`),D=e(`BackHandler`,`react-native`),O=e(`DynamicColorIOS`,`react-native`),k=e(`processColor`,`react-native`),A=e(`UTFSequence`,`react-native`),j=e(`experimental_LayoutConformance`,`react-native`),M=e(`unstable_VirtualView`,`react-native`),N=e(`VirtualViewMode`,`react-native`),P=e(`unstable_NativeText`,`react-native`),F=e(`unstable_NativeView`,`react-native`),I=e(`unstable_TextAncestorContext`,`react-native`),L=e(`ReactNativeVersion`,`react-native`),R=e(`DeviceInfo`,`react-native`),z=e(`DevMenu`,`react-native`),B=e(`DevSettings`,`react-native`),V=e(`NativeModules`,`react-native`),H=e(`TurboModuleRegistry`,`react-native`),U=e(`NativeComponentRegistry`,`react-native`),W=e(`requireNativeComponent`,`react-native`),G=e(`codegenNativeComponent`,`react-native`),K=e(`codegenNativeCommands`,`react-native`),q=e(`UIManager`,`react-native`),J=e(`findNodeHandle`,`react-native`),Y=e(`registerCallableModule`,`react-native`),X=e(`Networking`,`react-native`),Z=e(`NativeDialogManagerAndroid`,`react-native`),Q=e(`ProgressBarAndroid`,`react-native`),$=e(`Touchable`,`react-native`),ee=e(`NativeEventEmitter`,`react-native`),te=e(`DeviceEventEmitter`,`react-native`),ne=e(`NativeAppEventEmitter`,`react-native`),re=e(`RootTagContext`,`react-native`);export{o as AccessibilityInfo,S as ActionSheetIOS,r as AppState,D as BackHandler,E as Clipboard,z as DevMenu,B as DevSettings,te as DeviceEventEmitter,R as DeviceInfo,m as DrawerLayoutAndroid,O as DynamicColorIOS,h as I18nManager,b as InputAccessoryView,c as InteractionManager,s as LayoutAnimation,g as LogBox,t as Modal,ne as NativeAppEventEmitter,U as NativeComponentRegistry,Z as NativeDialogManagerAndroid,ee as NativeEventEmitter,V as NativeModules,X as Networking,f as PanResponder,w as PermissionsAndroid,i as PixelRatio,a as PlatformColor,Q as ProgressBarAndroid,C as PushNotificationIOS,L as ReactNativeVersion,n as RefreshControl,re as RootTagContext,T as Settings,_ as Systrace,y as ToastAndroid,$ as Touchable,x as TouchableNativeFeedback,H as TurboModuleRegistry,q as UIManager,A as UTFSequence,v as Vibration,N as VirtualViewMode,K as codegenNativeCommands,G as codegenNativeComponent,j as experimental_LayoutConformance,J as findNodeHandle,k as processColor,Y as registerCallableModule,W as requireNativeComponent,P as unstable_NativeText,F as unstable_NativeView,I as unstable_TextAncestorContext,M as unstable_VirtualView,d as useAnimatedColor,l as useAnimatedValue,u as useAnimatedValueXY,p as usePressability};
1
+ import{unsupported as e}from"../unsupported.js";const t=e(`RefreshControl`,`react-native`),n=e(`AppState`,`react-native`),r=e(`PixelRatio`,`react-native`),i=e(`PlatformColor`,`react-native`),a=e(`AccessibilityInfo`,`react-native`),o=e(`LayoutAnimation`,`react-native`),s=e(`useAnimatedValue`,`react-native`),c=e(`useAnimatedValueXY`,`react-native`),l=e(`useAnimatedColor`,`react-native`),u=e(`PanResponder`,`react-native`),d=e(`usePressability`,`react-native`),f=e(`DrawerLayoutAndroid`,`react-native`),p=e(`I18nManager`,`react-native`),m=e(`LogBox`,`react-native`),h=e(`Systrace`,`react-native`),g=e(`Vibration`,`react-native`),_=e(`ToastAndroid`,`react-native`),v=e(`InputAccessoryView`,`react-native`),y=e(`TouchableNativeFeedback`,`react-native`),b=e(`ActionSheetIOS`,`react-native`),x=e(`PushNotificationIOS`,`react-native`),S=e(`PermissionsAndroid`,`react-native`),C=e(`Settings`,`react-native`),w=e(`Clipboard`,`react-native`),T=e(`BackHandler`,`react-native`),E=e(`DynamicColorIOS`,`react-native`),D=e(`processColor`,`react-native`),O=e(`UTFSequence`,`react-native`),k=e(`experimental_LayoutConformance`,`react-native`),A=e(`unstable_VirtualView`,`react-native`),j=e(`VirtualViewMode`,`react-native`),M=e(`unstable_NativeText`,`react-native`),N=e(`unstable_NativeView`,`react-native`),P=e(`unstable_TextAncestorContext`,`react-native`),F=e(`ReactNativeVersion`,`react-native`),I=e(`DeviceInfo`,`react-native`),L=e(`DevMenu`,`react-native`),R=e(`DevSettings`,`react-native`),z=e(`NativeModules`,`react-native`),B=e(`TurboModuleRegistry`,`react-native`),V=e(`NativeComponentRegistry`,`react-native`),H=e(`requireNativeComponent`,`react-native`),U=e(`codegenNativeComponent`,`react-native`),W=e(`codegenNativeCommands`,`react-native`),G=e(`UIManager`,`react-native`),K=e(`findNodeHandle`,`react-native`),q=e(`registerCallableModule`,`react-native`),J=e(`Networking`,`react-native`),Y=e(`ProgressBarAndroid`,`react-native`),X=e(`NativeEventEmitter`,`react-native`),Z=e(`DeviceEventEmitter`,`react-native`),Q=e(`NativeAppEventEmitter`,`react-native`),$=e(`RootTagContext`,`react-native`),ee=e(`AssetRegistry`,`react-native`),te=e(`unstable_VirtualArray`,`react-native`),ne=e(`unstable_createVirtualCollectionView`,`react-native`),re=e(`unstable_VirtualColumn`,`react-native`),ie=e(`unstable_VirtualColumnGenerator`,`react-native`),ae=e(`unstable_VirtualRow`,`react-native`),oe=e(`unstable_getScrollParent`,`react-native`),se=e(`unstable_DEFAULT_INITIAL_NUM_TO_RENDER`,`react-native`);export{a as AccessibilityInfo,b as ActionSheetIOS,n as AppState,ee as AssetRegistry,T as BackHandler,w as Clipboard,L as DevMenu,R as DevSettings,Z as DeviceEventEmitter,I as DeviceInfo,f as DrawerLayoutAndroid,E as DynamicColorIOS,p as I18nManager,v as InputAccessoryView,o as LayoutAnimation,m as LogBox,Q as NativeAppEventEmitter,V as NativeComponentRegistry,X as NativeEventEmitter,z as NativeModules,J as Networking,u as PanResponder,S as PermissionsAndroid,r as PixelRatio,i as PlatformColor,Y as ProgressBarAndroid,x as PushNotificationIOS,F as ReactNativeVersion,t as RefreshControl,$ as RootTagContext,C as Settings,h as Systrace,_ as ToastAndroid,y as TouchableNativeFeedback,B as TurboModuleRegistry,G as UIManager,O as UTFSequence,g as Vibration,j as VirtualViewMode,W as codegenNativeCommands,U as codegenNativeComponent,k as experimental_LayoutConformance,K as findNodeHandle,D as processColor,q as registerCallableModule,H as requireNativeComponent,se as unstable_DEFAULT_INITIAL_NUM_TO_RENDER,M as unstable_NativeText,N as unstable_NativeView,P as unstable_TextAncestorContext,te as unstable_VirtualArray,re as unstable_VirtualColumn,ie as unstable_VirtualColumnGenerator,ae as unstable_VirtualRow,A as unstable_VirtualView,ne as unstable_createVirtualCollectionView,oe as unstable_getScrollParent,l as useAnimatedColor,s as useAnimatedValue,c as useAnimatedValueXY,d as usePressability};
package/lib/esm/index.js CHANGED
@@ -1 +1 @@
1
- import"./_virtual/_rolldown/runtime.js";import{PrimitiveError as e}from"./primitives/errors.js";import{Easing as t}from"./animated/easing.js";import{configureStyle as n,resetStyleConfig as r,styleConfig as i}from"./style-config.js";import{ActivityIndicator as a,Button as o,Image as s,ImageBackground as c,KeyboardAvoidingView as l,Pressable as u,SafeAreaView as d,ScrollView as f,StatusBar as p,Switch as m,Text as h,TextInput as g,TouchableHighlight as _,TouchableOpacity as v,TouchableWithoutFeedback as y,View as b}from"./components.js";import{Animated as x}from"./animated/index.js";import{Alert as S}from"./apis/alert.js";import{Appearance as C}from"./apis/appearance.js";import{Dimensions as w}from"./apis/dimensions.js";import{Keyboard as T}from"./apis/keyboard.js";import{Linking as E}from"./apis/linking.js";import{Platform as D}from"./apis/platform.js";import{Share as O}from"./apis/share.js";import"./apis/index.js";import{OWN_EXPORT_NAMES as k}from"./generated/own-exports.js";import{SUPPORTED_NAMES as A,SUPPORT_TABLE as j,explainUnsupported as M,isImportable as N,isOwnExport as P}from"./support-table.js";import{UnsupportedError as F}from"./unsupported.js";import{AppRegistry as I,registerRootComponent as L}from"./app-registry.js";import{EventEmitter as R}from"./event-emitter.js";import{AccessibilityInfo as z,ActionSheetIOS as B,AppState as V,BackHandler as H,Clipboard as U,DevMenu as W,DevSettings as G,DeviceEventEmitter as K,DeviceInfo as q,DrawerLayoutAndroid as J,DynamicColorIOS as Y,I18nManager as X,InputAccessoryView as Z,InteractionManager as Q,LayoutAnimation as $,LogBox as ee,Modal as te,NativeAppEventEmitter as ne,NativeComponentRegistry as re,NativeDialogManagerAndroid as ie,NativeEventEmitter as ae,NativeModules as oe,Networking as se,PanResponder as ce,PermissionsAndroid as le,PixelRatio as ue,PlatformColor as de,ProgressBarAndroid as fe,PushNotificationIOS as pe,ReactNativeVersion as me,RefreshControl as he,RootTagContext as ge,Settings as _e,Systrace as ve,ToastAndroid as ye,Touchable as be,TouchableNativeFeedback as xe,TurboModuleRegistry as Se,UIManager as Ce,UTFSequence as we,Vibration as Te,VirtualViewMode as Ee,codegenNativeCommands as De,codegenNativeComponent as Oe,experimental_LayoutConformance as ke,findNodeHandle as Ae,processColor as je,registerCallableModule as Me,requireNativeComponent as Ne,unstable_NativeText as Pe,unstable_NativeView as Fe,unstable_TextAncestorContext as Ie,unstable_VirtualView as Le,useAnimatedColor as Re,useAnimatedValue as ze,useAnimatedValueXY as Be,usePressability as Ve}from"./generated/unsupported-react-native.js";import{useColorScheme as He,useWindowDimensions as Ue}from"./hooks.js";import{FlatList as We,SectionList as Ge,VirtualizedList as Ke,VirtualizedSectionList as qe}from"./lists/components.js";import{StyleSheet as Je}from"./stylesheet.js";import{primitives_exports as Ye}from"./primitives/index.js";import{PRIMITIVE_VARIANTS as Xe,acceptsProp as Ze,explainProp as Qe,propAnswer as $e,propNames as et,propTable as tt}from"./prop-table.js";function unstable_batchedUpdates(e,t){return e(t)}export{z as AccessibilityInfo,B as ActionSheetIOS,a as ActivityIndicator,S as Alert,x as Animated,I as AppRegistry,V as AppState,C as Appearance,H as BackHandler,o as Button,U as Clipboard,W as DevMenu,G as DevSettings,K as DeviceEventEmitter,q as DeviceInfo,w as Dimensions,J as DrawerLayoutAndroid,Y as DynamicColorIOS,t as Easing,R as EventEmitter,We as FlatList,X as I18nManager,s as Image,c as ImageBackground,Z as InputAccessoryView,Q as InteractionManager,T as Keyboard,l as KeyboardAvoidingView,$ as LayoutAnimation,E as Linking,ee as LogBox,te as Modal,ne as NativeAppEventEmitter,re as NativeComponentRegistry,ie as NativeDialogManagerAndroid,ae as NativeEventEmitter,oe as NativeModules,se as Networking,k as OWN_EXPORT_NAMES,Xe as PRIMITIVE_VARIANTS,ce as PanResponder,le as PermissionsAndroid,ue as PixelRatio,D as Platform,de as PlatformColor,u as Pressable,e as PrimitiveError,fe as ProgressBarAndroid,pe as PushNotificationIOS,me as ReactNativeVersion,he as RefreshControl,ge as RootTagContext,A as SUPPORTED_NAMES,j as SUPPORT_TABLE,d as SafeAreaView,f as ScrollView,Ge as SectionList,_e as Settings,O as Share,p as StatusBar,Je as StyleSheet,m as Switch,ve as Systrace,h as Text,g as TextInput,ye as ToastAndroid,be as Touchable,_ as TouchableHighlight,xe as TouchableNativeFeedback,v as TouchableOpacity,y as TouchableWithoutFeedback,Se as TurboModuleRegistry,Ce as UIManager,we as UTFSequence,F as UnsupportedError,Te as Vibration,b as View,Ee as VirtualViewMode,Ke as VirtualizedList,qe as VirtualizedSectionList,Ze as acceptsProp,De as codegenNativeCommands,Oe as codegenNativeComponent,n as configureStyle,ke as experimental_LayoutConformance,Qe as explainProp,M as explainUnsupported,Ae as findNodeHandle,N as isImportable,P as isOwnExport,Ye as primitives,je as processColor,$e as propAnswer,et as propNames,tt as propTable,Me as registerCallableModule,L as registerRootComponent,Ne as requireNativeComponent,r as resetStyleConfig,i as styleConfig,Pe as unstable_NativeText,Fe as unstable_NativeView,Ie as unstable_TextAncestorContext,Le as unstable_VirtualView,unstable_batchedUpdates,Re as useAnimatedColor,ze as useAnimatedValue,Be as useAnimatedValueXY,He as useColorScheme,Ve as usePressability,Ue as useWindowDimensions};
1
+ import"./_virtual/_rolldown/runtime.js";import{PrimitiveError as e}from"./primitives/errors.js";import{Easing as t}from"./animated/easing.js";import{configureStyle as n,resetStyleConfig as r,styleConfig as i}from"./style-config.js";import{ActivityIndicator as a,Button as o,Image as s,ImageBackground as c,KeyboardAvoidingView as l,Modal as u,Pressable as d,SafeAreaView as f,ScrollView as p,StatusBar as m,Switch as h,Text as g,TextInput as _,TouchableHighlight as v,TouchableOpacity as y,TouchableWithoutFeedback as b,View as x}from"./components.js";import{Animated as S}from"./animated/index.js";import{Alert as C}from"./apis/alert.js";import{Appearance as w}from"./apis/appearance.js";import{Dimensions as T}from"./apis/dimensions.js";import{Keyboard as E}from"./apis/keyboard.js";import{Linking as D}from"./apis/linking.js";import{Platform as O}from"./apis/platform.js";import{Share as k}from"./apis/share.js";import"./apis/index.js";import{OWN_EXPORT_NAMES as A}from"./generated/own-exports.js";import{SUPPORTED_NAMES as j,SUPPORT_TABLE as M,explainUnsupported as N,isImportable as P,isOwnExport as F}from"./support-table.js";import{UnsupportedError as I}from"./unsupported.js";import{AppRegistry as L,lastWindowChromeProblems as R,registerRootComponent as z}from"./app-registry.js";import{EventEmitter as B}from"./event-emitter.js";import{AccessibilityInfo as V,ActionSheetIOS as H,AppState as U,AssetRegistry as W,BackHandler as G,Clipboard as K,DevMenu as q,DevSettings as J,DeviceEventEmitter as Y,DeviceInfo as X,DrawerLayoutAndroid as Z,DynamicColorIOS as Q,I18nManager as $,InputAccessoryView as ee,LayoutAnimation as te,LogBox as ne,NativeAppEventEmitter as re,NativeComponentRegistry as ie,NativeEventEmitter as ae,NativeModules as oe,Networking as se,PanResponder as ce,PermissionsAndroid as le,PixelRatio as ue,PlatformColor as de,ProgressBarAndroid as fe,PushNotificationIOS as pe,ReactNativeVersion as me,RefreshControl as he,RootTagContext as ge,Settings as _e,Systrace as ve,ToastAndroid as ye,TouchableNativeFeedback as be,TurboModuleRegistry as xe,UIManager as Se,UTFSequence as Ce,Vibration as we,VirtualViewMode as Te,codegenNativeCommands as Ee,codegenNativeComponent as De,experimental_LayoutConformance as Oe,findNodeHandle as ke,processColor as Ae,registerCallableModule as je,requireNativeComponent as Me,unstable_DEFAULT_INITIAL_NUM_TO_RENDER as Ne,unstable_NativeText as Pe,unstable_NativeView as Fe,unstable_TextAncestorContext as Ie,unstable_VirtualArray as Le,unstable_VirtualColumn as Re,unstable_VirtualColumnGenerator as ze,unstable_VirtualRow as Be,unstable_VirtualView as Ve,unstable_createVirtualCollectionView as He,unstable_getScrollParent as Ue,useAnimatedColor as We,useAnimatedValue as Ge,useAnimatedValueXY as Ke,usePressability as qe}from"./generated/unsupported-react-native.js";import{useColorScheme as Je,useWindowDimensions as Ye}from"./hooks.js";import{FlatList as Xe,SectionList as Ze,VirtualizedList as Qe,VirtualizedSectionList as $e}from"./lists/components.js";import{StyleSheet as et}from"./stylesheet.js";import{primitives_exports as tt}from"./primitives/index.js";import{PRIMITIVE_VARIANTS as nt,acceptsProp as rt,explainProp as it,propAnswer as at,propNames as ot,propTable as st}from"./prop-table.js";function unstable_batchedUpdates(e,t){return e(t)}export{V as AccessibilityInfo,H as ActionSheetIOS,a as ActivityIndicator,C as Alert,S as Animated,L as AppRegistry,U as AppState,w as Appearance,W as AssetRegistry,G as BackHandler,o as Button,K as Clipboard,q as DevMenu,J as DevSettings,Y as DeviceEventEmitter,X as DeviceInfo,T as Dimensions,Z as DrawerLayoutAndroid,Q as DynamicColorIOS,t as Easing,B as EventEmitter,Xe as FlatList,$ as I18nManager,s as Image,c as ImageBackground,ee as InputAccessoryView,E as Keyboard,l as KeyboardAvoidingView,te as LayoutAnimation,D as Linking,ne as LogBox,u as Modal,re as NativeAppEventEmitter,ie as NativeComponentRegistry,ae as NativeEventEmitter,oe as NativeModules,se as Networking,A as OWN_EXPORT_NAMES,nt as PRIMITIVE_VARIANTS,ce as PanResponder,le as PermissionsAndroid,ue as PixelRatio,O as Platform,de as PlatformColor,d as Pressable,e as PrimitiveError,fe as ProgressBarAndroid,pe as PushNotificationIOS,me as ReactNativeVersion,he as RefreshControl,ge as RootTagContext,j as SUPPORTED_NAMES,M as SUPPORT_TABLE,f as SafeAreaView,p as ScrollView,Ze as SectionList,_e as Settings,k as Share,m as StatusBar,et as StyleSheet,h as Switch,ve as Systrace,g as Text,_ as TextInput,ye as ToastAndroid,v as TouchableHighlight,be as TouchableNativeFeedback,y as TouchableOpacity,b as TouchableWithoutFeedback,xe as TurboModuleRegistry,Se as UIManager,Ce as UTFSequence,I as UnsupportedError,we as Vibration,x as View,Te as VirtualViewMode,Qe as VirtualizedList,$e as VirtualizedSectionList,rt as acceptsProp,Ee as codegenNativeCommands,De as codegenNativeComponent,n as configureStyle,Oe as experimental_LayoutConformance,it as explainProp,N as explainUnsupported,ke as findNodeHandle,P as isImportable,F as isOwnExport,R as lastWindowChromeProblems,tt as primitives,Ae as processColor,at as propAnswer,ot as propNames,st as propTable,je as registerCallableModule,z as registerRootComponent,Me as requireNativeComponent,r as resetStyleConfig,i as styleConfig,Ne as unstable_DEFAULT_INITIAL_NUM_TO_RENDER,Pe as unstable_NativeText,Fe as unstable_NativeView,Ie as unstable_TextAncestorContext,Le as unstable_VirtualArray,Re as unstable_VirtualColumn,ze as unstable_VirtualColumnGenerator,Be as unstable_VirtualRow,Ve as unstable_VirtualView,unstable_batchedUpdates,He as unstable_createVirtualCollectionView,Ue as unstable_getScrollParent,We as useAnimatedColor,Ge as useAnimatedValue,Ke as useAnimatedValueXY,Je as useColorScheme,qe as usePressability,Ye as useWindowDimensions};
@@ -1 +1 @@
1
- import"../_virtual/_rolldown/runtime.js";import{ParentProvider as e}from"../parent-context.js";import{createElement as t}from"react";import{createRoot as n}from"@gjsify/gtk-host/react";import{adopt as r,createElement as i,insert as a,widgetOf as o}from"@gjsify/gtk-host";import{ListController as s,onScrollNearEnd as c}from"@gjsify/gtk-host/list";const l={orientation:`vertical`,props:{},overlay:!1},RowBody=({row:e})=>e.render();function reactRows(s){let c=new Map,u=[],d=!1,schedule=()=>{d||(d=!0,queueMicrotask(()=>{d=!1;let e=[...c];c.clear();for(let[t,n]of e)t.render(n);let t=u.splice(0,u.length);for(let e of t)e.unmount()}))};return{mountRow(e){let t=i(`GtkBox`,{orientation:`vertical`});a(t,r(e));let c=s.onRowError;return n(o(t),c===void 0?{}:{onUncaughtError:c})},showRow(n,r){c.set(n,r===null?null:t(e,{value:l},t(RowBody,{row:r}))),schedule()},disposeRow(e){c.delete(e),u.push(e),schedule()}}}function createListController(e={}){return new s(reactRows(e))}function rowKey(e,t,n){if(n!==void 0)return n(e,t);if(typeof e==`object`&&e){let t=e;if(typeof t.key==`string`)return t.key;if(typeof t.id==`string`||typeof t.id==`number`)return String(t.id)}return String(t)}export{createListController,c as onScrollNearEnd,rowKey};
1
+ import"../_virtual/_rolldown/runtime.js";import{ParentProvider as e}from"../parent-context.js";import{createElement as t}from"react";import{adopt as n,createElement as r,insert as i,widgetOf as a}from"@gjsify/gtk-host";import{createRoot as o}from"@gjsify/gtk-host/react";import{ListController as s,onScrollNearEnd as c}from"@gjsify/gtk-host/list";const l={orientation:`vertical`,props:{},overlay:!1},RowBody=({row:e})=>e.render();function reactRows(s){let c=new Map,u=[],d=!1,schedule=()=>{d||(d=!0,queueMicrotask(()=>{d=!1;let e=[...c];c.clear();for(let[t,n]of e)t.render(n);let t=u.splice(0,u.length);for(let e of t)e.unmount()}))};return{mountRow(e){let t=r(`GtkBox`,{orientation:`vertical`});i(t,n(e));let c=s.onRowError;return o(a(t),c===void 0?{}:{onUncaughtError:c})},showRow(n,r){c.set(n,r===null?null:t(e,{value:l},t(RowBody,{row:r}))),schedule()},disposeRow(e){c.delete(e),u.push(e),schedule()}}}function createListController(e={}){return new s(reactRows(e))}function rowKey(e,t,n){if(n!==void 0)return n(e,t);if(typeof e==`object`&&e){let t=e;if(typeof t.key==`string`)return t.key;if(typeof t.id==`string`||typeof t.id==`number`)return String(t.id)}return String(t)}export{createListController,c as onScrollNearEnd,rowKey};
@@ -0,0 +1 @@
1
+ import"../_virtual/_rolldown/runtime.js";const e={false:0,true:1,mixed:2};function coerceAttribute(t,n){switch(t.as){case`string`:return typeof n==`string`?n:null;case`boolean`:return typeof n==`boolean`?n:null;case`tristate`:return typeof n==`boolean`?n?e.true:e.false:n===`mixed`?e.mixed:null}}const t={string:`a string`,boolean:`true or false`,tristate:`true, false or "mixed" — GTK reads it as a Gtk.AccessibleTristate`};function resolveAccessible(e,n,r){if(e.from===`value`){let i=coerceAttribute(e.attribute,r);return i===null?{entries:[],problem:`writes the GTK accessible ${e.attribute.set} "${e.attribute.name}" and needs ${t[e.attribute.as]}`}:{entries:[{prop:n,set:e.attribute.set,name:e.attribute.name,value:i}],problem:null}}if(typeof r!=`object`||!r||Array.isArray(r))return{entries:[],problem:`is a record of accessibility states and needs an object — its keys are ${Object.keys(e.members).sort().join(`, `)}`};let i=[];for(let[a,o]of Object.entries(r)){if(o===void 0)continue;let r=e.refuses[a];if(r!==void 0)return{entries:[],problem:`carries "${a}", which ${r}`};let s=e.members[a];if(s===void 0)return{entries:[],problem:`carries "${a}", which is not a state this layer answers for. It takes: ${Object.keys(e.members).sort().join(`, `)}`};let c=coerceAttribute(s,o);if(c===null)return{entries:[],problem:`carries "${a}", which needs ${t[s.as]}`};i.push({prop:n,set:s.set,name:s.name,value:c})}return{entries:i,problem:null}}export{resolveAccessible};
@@ -1 +1 @@
1
- import"../_virtual/_rolldown/runtime.js";const isAccepted=e=>e!==`refused`&&e!==`unknown`,unknownPropDetail=e=>`is not a prop this primitive answers for. It takes: ${Object.keys(e.props).sort().join(`, `)}. An unlisted prop is refused rather than dropped: a prop that silently does nothing is indistinguishable from a bug in the application, forever`,unknownPrimitiveDetail=e=>`is not a primitive this layer answers for. Known: ${[...e].sort().join(`, `)}`;function answerForRoute(e){switch(e.to){case`property`:return{status:`property`,why:``,gtk:e.names};case`style-property`:return{status:`style`,why:``,gtk:[`style: ${e.name}`]};case`event`:return{status:`event`,why:``,gtk:[e.signal]};case`file`:return{status:`file`,why:``,gtk:[e.property]};case`gesture`:return{status:`gesture`,why:``,gtk:[`Gtk.GestureClick::${e.signal}`]};case`announce`:return{status:`announcement`,why:``,gtk:[e.signal,`Gtk.Accessible.announce()`]};case`ignored`:return{status:`ignored`,why:e.why,gtk:[]};case`refused`:return{status:`refused`,why:e.why,gtk:[]}}}function answerFor(e,t,n,r){if(t.refusesStyle!==void 0&&(n===`style`||n===`className`))return{primitive:e,prop:n,status:`refused`,why:t.refusesStyle,gtk:[]};if(r.has(n))return{primitive:e,prop:n,status:`framework`,why:``,gtk:[]};let i=t.props[n];if(i===void 0)return{primitive:e,prop:n,status:`unknown`,why:unknownPropDetail(t),gtk:[]};let a=(Array.isArray(i)?i:[i]).map(answerForRoute),o=a[0];return{primitive:e,prop:n,status:o.status,why:o.why,gtk:a.flatMap(e=>e.gtk)}}function propNamesOf(e){return Object.keys(e.props).sort()}export{answerFor,isAccepted,propNamesOf,unknownPrimitiveDetail,unknownPropDetail};
1
+ import"../_virtual/_rolldown/runtime.js";function accessibleReach(e){let call=e=>e===`property`?`Gtk.Accessible.update_property()`:`Gtk.Accessible.update_state()`;return e.from===`value`?[`${call(e.attribute.set)}: ${e.attribute.name}`]:Object.keys(e.members).sort().map(t=>{let n=e.members[t];return`${t} → ${call(n.set)}: ${n.name}`})}const isAccepted=e=>e!==`refused`&&e!==`unknown`,unknownPropDetail=e=>`is not a prop this primitive answers for. It takes: ${Object.keys(e.props).sort().join(`, `)}. An unlisted prop is refused rather than dropped: a prop that silently does nothing is indistinguishable from a bug in the application, forever`,unknownPrimitiveDetail=e=>`is not a primitive this layer answers for. Known: ${[...e].sort().join(`, `)}`,e={};function answerForRoute(t){switch(t.to){case`property`:return{status:`property`,why:``,gtk:t.names,refuses:t.refuses??e};case`style-property`:return{status:`style`,why:``,gtk:[`style: ${t.name}`],refuses:e};case`event`:return{status:`event`,why:``,gtk:[t.signal],refuses:e};case`file`:return{status:`file`,why:``,gtk:[t.property],refuses:e};case`gesture`:return{status:`gesture`,why:``,gtk:[`Gtk.GestureClick::${t.signal}`],refuses:e};case`announce`:return{status:`announcement`,why:``,gtk:[t.signal,`Gtk.Accessible.announce()`],refuses:e};case`accessible`:return{status:`accessible`,why:``,gtk:accessibleReach(t),refuses:t.from===`members`?t.refuses:e};case`ignored`:return{status:`ignored`,why:t.why,gtk:[],refuses:e};case`refused`:return{status:`refused`,why:t.why,gtk:[],refuses:e}}}function answerFor(t,n,r,i){if(n.refusesStyle!==void 0&&(r===`style`||r===`className`))return{primitive:t,prop:r,status:`refused`,why:n.refusesStyle,gtk:[],refuses:e};if(i.has(r))return{primitive:t,prop:r,status:`framework`,why:``,gtk:[],refuses:e};let a=n.props[r];if(a===void 0)return{primitive:t,prop:r,status:`unknown`,why:unknownPropDetail(n),gtk:[],refuses:e};let o=(Array.isArray(a)?a:[a]).map(answerForRoute),s=o[0];return{primitive:t,prop:r,status:s.status,why:s.why,gtk:o.flatMap(e=>e.gtk),refuses:Object.assign({},...o.map(e=>e.refuses))}}function propNamesOf(e){return Object.keys(e.props).sort()}export{answerFor,isAccepted,propNamesOf,unknownPrimitiveDetail,unknownPropDetail};
@@ -1 +1 @@
1
- import"../_virtual/_rolldown/runtime.js";const e=[{gtype:`GtkBox`,property:`orientation`,gtk:`horizontal`,reactNative:`column`,source:"Yoga’s own default — `ReactCommon/yoga/yoga/style/Style.h`: `FlexDirection::Column`. CSS defaults to `row`; React Native deliberately does not.",verdict:`normalised`,normalisedTo:`vertical`,reason:`The first inversion this layer met, and the loudest: a screen written as a column would have come out as a row.`},{gtype:`GtkBox`,property:`spacing`,gtk:0,reactNative:"0 (`gap` is unset)",source:`Yoga: an unset gap is 0.`,verdict:`agrees`,reason:`Nothing to do.`},{gtype:`GtkBox`,property:`homogeneous`,gtk:!1,reactNative:`no counterpart — children are sized by flex`,source:`Yoga has no "all children equal" mode.`,verdict:`agrees`,reason:"GTK’s `false` is what a flex container does, so the absent concept and the default coincide."},{gtype:`GtkLabel`,property:`wrap`,gtk:!1,reactNative:`text wraps`,source:"React Native’s `<Text>` wraps unless `numberOfLines` says otherwise.",verdict:`normalised`,normalisedTo:!0,reason:`Without it a long line forces the window wider instead of wrapping — which reads as a layout bug anywhere but here.`},{gtype:`GtkLabel`,property:`xalign`,gtk:.5,reactNative:`the script’s natural alignment — start, i.e. left in LTR`,source:'`ReactCommon/react/renderer/attributedstring/TextAttributes.h`: `std::optional<TextAlignment> alignment{}` is UNSET by default, and `primitives.h` documents `TextAlignment::Natural` as "the default alignment for script". Observed in a 25-route port: every string on every screen rendered centred.',verdict:`normalised`,normalisedTo:0,reason:"MEASURED as a position, not as a property: a `Gtk.Label` allocated 400×100 reports `get_layout_offsets()` = (193, 41) with GTK’s defaults and (0, 0) with xalign/yalign 0. Nothing anywhere reports the difference."},{gtype:`GtkLabel`,property:`yalign`,gtk:.5,reactNative:`the top of the text’s box`,source:"The same unset `alignment`; vertical centring is `textAlignVertical`/`verticalAlign`, which is also unset. Same layout-offset measurement as `xalign` — the 41 in (193, 41) is this one.",verdict:`normalised`,normalisedTo:0,reason:"Only visible when the label is given more height than its text — a `flex-1` or an explicit height — which is exactly when it is hardest to attribute."},{gtype:`GtkLabel`,property:`justify`,gtk:`left`,reactNative:`natural, i.e. left in LTR`,source:"As `xalign`: unset means natural.",verdict:`agrees`,reason:"GTK’s enum default already is the LTR answer. It is `xalign` that positions the BLOCK and this that positions the lines within it, which is why only one of the pair was wrong."},{gtype:`GtkLabel`,property:`ellipsize`,gtk:`none`,reactNative:"no truncation until `numberOfLines` is set",source:"React Native applies `ellipsizeMode` only together with `numberOfLines`.",verdict:`agrees`,reason:`Both truncate nothing until asked.`},{gtype:`GtkLabel`,property:`selectable`,gtk:!1,reactNative:"`selectable` defaults to false",source:"React Native’s `TextProps`.",verdict:`agrees`,reason:`Nothing to do.`},{gtype:`GtkTextView`,property:`wrap-mode`,gtk:`none`,reactNative:`a multiline input wraps`,source:"React Native’s multiline `TextInput` wraps, as `<Text>` does.",verdict:`normalised`,normalisedTo:`word-char`,reason:"The same disagreement as `Gtk.Label:wrap`, one widget over: without it the field scrolls sideways for ever."},{gtype:`GtkTextView`,property:`editable`,gtk:!0,reactNative:"`editable` defaults to true",source:"React Native’s `TextInputProps`.",verdict:`agrees`,reason:`Nothing to do.`},{gtype:`GtkPicture`,property:`content-fit`,gtk:`contain`,reactNative:`cover`,source:"React Native’s `Image` defaults `resizeMode` to `cover`.",verdict:`normalised`,normalisedTo:`cover`,reason:`Inverted between the two platforms, and an image that fits where it should fill looks deliberate.`},{gtype:`GtkScrolledWindow`,property:`hscrollbar-policy`,gtk:`automatic`,reactNative:"vertical only — `horizontal` defaults to false",source:"React Native’s `ScrollViewProps`.",verdict:`normalised`,normalisedTo:`never`,reason:`GTK would scroll sideways as well, which is a second scroll axis the author did not ask for.`},{gtype:`GtkScrolledWindow`,property:`vexpand`,gtk:!1,reactNative:"`flexGrow` 0, as for any widget",source:"Yoga: an unset `flexGrow` is 0.",verdict:`primitive`,reason:"`FlatList` writes it on its scroller, and it is a layout decision rather than a default: the scroller is one of up to three children of the outer box and it is the one that takes the leftover space, because a header and a footer are their own natural height."},{gtype:`GtkScrolledWindow`,property:`hexpand`,gtk:!1,reactNative:"`flexGrow` 0, as for any widget",source:"Yoga: an unset `flexGrow` is 0.",verdict:`primitive`,reason:"As `vexpand`, one axis over — `FlatList`’s scroller fills its box."},{gtype:`GtkScrolledWindow`,property:`kinetic-scrolling`,gtk:!0,reactNative:`no counterpart on a desktop`,source:`—`,verdict:`kept`,reason:`Touch-and-flick scrolling is GTK’s own behaviour on a touchscreen and costs nothing with a mouse. Turning it off would remove a desktop affordance to match a phone API that does not describe it.`},{gtype:`GtkEntry`,property:`has-frame`,gtk:!0,reactNative:`unstyled — a bare text field with no border`,source:"React Native’s `TextInput` draws no chrome of its own on either platform.",verdict:`kept`,reason:`DELIBERATE, and the one row here that is a design choice rather than a match: an Adwaita entry without its frame is not a text field a desktop user recognises. The divergence is visible, which is what separates it from the silent ones — an author sees the frame immediately and can remove it from the stylesheet.`},{gtype:`GtkEntry`,property:`visibility`,gtk:!0,reactNative:"`secureTextEntry` defaults to false",source:"React Native’s `TextInputProps`.",verdict:`agrees`,reason:`Nothing to do.`},{gtype:`GtkSwitch`,property:`active`,gtk:!1,reactNative:"`value` defaults to false",source:"React Native’s `SwitchProps`.",verdict:`agrees`,reason:`Nothing to do.`},{gtype:`GtkWidget`,property:`halign`,gtk:`fill`,reactNative:`stretch`,source:"Yoga’s own default — `ReactCommon/yoga/yoga/style/Style.h`: `Align alignItems_ = Align::Stretch`.",verdict:`agrees`,reason:"GTK’s `fill` and CSS’s `stretch` are the same instruction under different words — `intents.ts` maps them to each other for the explicit case too."},{gtype:`GtkWidget`,property:`hexpand`,gtk:!1,reactNative:"`flexGrow` 0",source:"Yoga: an unset `flexGrow` is 0.",verdict:`agrees`,reason:"Neither grows until asked. `flex-1` is what asks, and `intents.ts` resolves it against the PARENT’s axis."},{gtype:`GtkWidget`,property:`opacity`,gtk:1,reactNative:`1`,source:`React Native’s style default.`,verdict:`agrees`,reason:"Nothing to do. `Animated.View` writes this property, which is why it is worth having checked."},{gtype:`GtkWidget`,property:`overflow`,gtk:`visible`,reactNative:`visible`,source:"React Native’s `overflow` style default.",verdict:`agrees`,reason:`Nothing to do.`},{gtype:`GtkWidget`,property:`can-target`,gtk:!0,reactNative:"`pointerEvents` defaults to `auto`",source:"React Native’s `ViewProps`.",verdict:`agrees`,reason:`Nothing to do.`}],t=e.filter(e=>e.verdict===`normalised`),defaultRowFor=(t,n)=>e.find(e=>e.gtype===t&&e.property===n)??e.find(e=>e.gtype===`GtkWidget`&&e.property===n);export{e as DEFAULT_ROWS,t as NORMALISED_DEFAULTS,defaultRowFor};
1
+ import"../_virtual/_rolldown/runtime.js";const e=[{gtype:`GtkBox`,property:`orientation`,gtk:`horizontal`,reactNative:`column`,source:"Yoga’s own default — `ReactCommon/yoga/yoga/style/Style.h`: `FlexDirection::Column`. CSS defaults to `row`; React Native deliberately does not.",verdict:`normalised`,normalisedTo:`vertical`,reason:`The first inversion this layer met, and the loudest: a screen written as a column would have come out as a row.`},{gtype:`GtkBox`,property:`spacing`,gtk:0,reactNative:"0 (`gap` is unset)",source:`Yoga: an unset gap is 0.`,verdict:`agrees`,reason:`Nothing to do.`},{gtype:`GtkBox`,property:`homogeneous`,gtk:!1,reactNative:`no counterpart — children are sized by flex`,source:`Yoga has no "all children equal" mode.`,verdict:`agrees`,reason:"GTK’s `false` is what a flex container does, so the absent concept and the default coincide."},{gtype:`GtkLabel`,property:`wrap`,gtk:!1,reactNative:`text wraps`,source:"React Native’s `<Text>` wraps unless `numberOfLines` says otherwise.",verdict:`normalised`,normalisedTo:!0,reason:`Without it a long line forces the window wider instead of wrapping — which reads as a layout bug anywhere but here.`},{gtype:`GtkLabel`,property:`xalign`,gtk:.5,reactNative:`the script’s natural alignment — start, i.e. left in LTR`,source:'`ReactCommon/react/renderer/attributedstring/TextAttributes.h`: `std::optional<TextAlignment> alignment{}` is UNSET by default, and `primitives.h` documents `TextAlignment::Natural` as "the default alignment for script". Observed in a 25-route port: every string on every screen rendered centred.',verdict:`normalised`,normalisedTo:0,reason:"MEASURED as a position, not as a property: a `Gtk.Label` allocated 400×100 reports `get_layout_offsets()` = (193, 41) with GTK’s defaults and (0, 0) with xalign/yalign 0. Nothing anywhere reports the difference."},{gtype:`GtkLabel`,property:`yalign`,gtk:.5,reactNative:`the top of the text’s box`,source:"The same unset `alignment`; vertical centring is `textAlignVertical`/`verticalAlign`, which is also unset. Same layout-offset measurement as `xalign` — the 41 in (193, 41) is this one.",verdict:`normalised`,normalisedTo:0,reason:"Only visible when the label is given more height than its text — a `flex-1` or an explicit height — which is exactly when it is hardest to attribute."},{gtype:`GtkLabel`,property:`justify`,gtk:`left`,reactNative:`natural, i.e. left in LTR`,source:"As `xalign`: unset means natural.",verdict:`agrees`,reason:"GTK’s enum default already is the LTR answer. It is `xalign` that positions the BLOCK and this that positions the lines within it, which is why only one of the pair was wrong."},{gtype:`GtkLabel`,property:`ellipsize`,gtk:`none`,reactNative:"no truncation until `numberOfLines` is set",source:"React Native applies `ellipsizeMode` only together with `numberOfLines`.",verdict:`agrees`,reason:`Both truncate nothing until asked.`},{gtype:`GtkLabel`,property:`selectable`,gtk:!1,reactNative:"`selectable` defaults to false",source:"React Native’s `TextProps`.",verdict:`agrees`,reason:`Nothing to do.`},{gtype:`GtkTextView`,property:`wrap-mode`,gtk:`none`,reactNative:`a multiline input wraps`,source:"React Native’s multiline `TextInput` wraps, as `<Text>` does.",verdict:`normalised`,normalisedTo:`word-char`,reason:"The same disagreement as `Gtk.Label:wrap`, one widget over: without it the field scrolls sideways for ever."},{gtype:`GtkTextView`,property:`editable`,gtk:!0,reactNative:"`editable` defaults to true",source:"React Native’s `TextInputProps`.",verdict:`agrees`,reason:`Nothing to do.`},{gtype:`GtkPicture`,property:`content-fit`,gtk:`contain`,reactNative:`cover`,source:"React Native’s `Image` defaults `resizeMode` to `cover`.",verdict:`normalised`,normalisedTo:`cover`,reason:`Inverted between the two platforms, and an image that fits where it should fill looks deliberate.`},{gtype:`GtkScrolledWindow`,property:`hscrollbar-policy`,gtk:`automatic`,reactNative:"vertical only — `horizontal` defaults to false",source:"React Native’s `ScrollViewProps`.",verdict:`normalised`,normalisedTo:`never`,reason:`GTK would scroll sideways as well, which is a second scroll axis the author did not ask for.`},{gtype:`GtkScrolledWindow`,property:`vexpand`,gtk:!1,reactNative:"`flexGrow` 0, as for any widget",source:"Yoga: an unset `flexGrow` is 0.",verdict:`primitive`,reason:"`FlatList` writes it on its scroller, and it is a layout decision rather than a default: the scroller is one of up to three children of the outer box and it is the one that takes the leftover space, because a header and a footer are their own natural height."},{gtype:`GtkScrolledWindow`,property:`hexpand`,gtk:!1,reactNative:"`flexGrow` 0, as for any widget",source:"Yoga: an unset `flexGrow` is 0.",verdict:`primitive`,reason:"As `vexpand`, one axis over — `FlatList`’s scroller fills its box."},{gtype:`GtkScrolledWindow`,property:`kinetic-scrolling`,gtk:!0,reactNative:`no counterpart on a desktop`,source:`—`,verdict:`kept`,reason:`Touch-and-flick scrolling is GTK’s own behaviour on a touchscreen and costs nothing with a mouse. Turning it off would remove a desktop affordance to match a phone API that does not describe it.`},{gtype:`GtkEntry`,property:`has-frame`,gtk:!0,reactNative:`unstyled — a bare text field with no border`,source:"React Native’s `TextInput` draws no chrome of its own on either platform.",verdict:`kept`,reason:`DELIBERATE, and the one row here that is a design choice rather than a match: an Adwaita entry without its frame is not a text field a desktop user recognises. The divergence is visible, which is what separates it from the silent ones — an author sees the frame immediately and can remove it from the stylesheet.`},{gtype:`GtkEntry`,property:`visibility`,gtk:!0,reactNative:"`secureTextEntry` defaults to false",source:"React Native’s `TextInputProps`.",verdict:`agrees`,reason:`Nothing to do.`},{gtype:`GtkSwitch`,property:`active`,gtk:!1,reactNative:"`value` defaults to false",source:"React Native’s `SwitchProps`.",verdict:`agrees`,reason:`Nothing to do.`},{gtype:`GtkWidget`,property:`halign`,gtk:`fill`,reactNative:`stretch`,source:"Yoga’s own default — `ReactCommon/yoga/yoga/style/Style.h`: `Align alignItems_ = Align::Stretch`.",verdict:`agrees`,reason:"GTK’s `fill` and CSS’s `stretch` are the same instruction under different words — `intents.ts` maps them to each other for the explicit case too."},{gtype:`GtkWidget`,property:`hexpand`,gtk:!1,reactNative:"`flexGrow` 0",source:"Yoga: an unset `flexGrow` is 0.",verdict:`agrees`,reason:"Neither grows until asked. `flex-1` is what asks, and `intents.ts` resolves it against the PARENT’s axis."},{gtype:`AdwDialog`,property:`can-close`,gtk:!0,reactNative:"a modal is dismissed by its `visible` prop and by nothing else",source:"React Native’s `Modal`: `visible` is the only thing that shows or hides it, and `onRequestClose` is documented as required on Android and tvOS precisely because the modal does not dismiss itself.",verdict:`primitive`,reason:"Not a default divergence but the contract that makes the two models agree. A dialog left able to close itself would take the sheet down on Escape while the element stayed mounted with `visible` still true — nothing on screen, and no prop change left to re-present it. With `can-close: false` the user’s dismissal arrives as `close-attempt` (that is `onRequestClose`) and only unrendering the element closes the dialog, through the portal placement’s `force_close`."},{gtype:`GtkWidget`,property:`opacity`,gtk:1,reactNative:`1`,source:`React Native’s style default.`,verdict:`agrees`,reason:"Nothing to do. `Animated.View` writes this property, which is why it is worth having checked."},{gtype:`GtkWidget`,property:`overflow`,gtk:`visible`,reactNative:`visible`,source:"React Native’s `overflow` style default.",verdict:`agrees`,reason:`Nothing to do.`},{gtype:`GtkWidget`,property:`can-target`,gtk:!0,reactNative:"`pointerEvents` defaults to `auto`",source:"React Native’s `ViewProps`.",verdict:`agrees`,reason:`Nothing to do.`}],t=e.filter(e=>e.verdict===`normalised`),defaultRowFor=(t,n)=>e.find(e=>e.gtype===t&&e.property===n)??e.find(e=>e.gtype===`GtkWidget`&&e.property===n);export{e as DEFAULT_ROWS,t as NORMALISED_DEFAULTS,defaultRowFor};
@@ -1 +1 @@
1
- import"../_virtual/_rolldown/runtime.js";const primitiveErrorMessage=(e,t,n)=>`@gjsify/react-native: <${e}>${t===``?``:` ${t}`} — ${n}`;var PrimitiveError=class extends Error{constructor(e,t,n){super(primitiveErrorMessage(e,t,n)),this.name=`PrimitiveError`,this.primitive=e,this.subject=t}};export{PrimitiveError,primitiveErrorMessage};
1
+ import"../_virtual/_rolldown/runtime.js";const primitiveErrorMessage=(e,t,n)=>`@gjsify/react-native: <${e}>${t===``?``:` ${t}`} — ${n}`,describeValue=e=>typeof e==`string`?`"${e}"`:typeof e==`object`&&e?Object.prototype.toString.call(e):String(e);var PrimitiveError=class extends Error{constructor(e,t,n){super(primitiveErrorMessage(e,t,n)),this.name=`PrimitiveError`,this.primitive=e,this.subject=t}};export{PrimitiveError,describeValue,primitiveErrorMessage};
@@ -1 +1 @@
1
- import{__exportAll as e}from"../_virtual/_rolldown/runtime.js";import{PrimitiveError as t}from"./errors.js";import{createHandle as n}from"./handles.js";import{answerFor as r,isAccepted as i,propNamesOf as a,unknownPrimitiveDetail as o,unknownPropDetail as s}from"./answers.js";import{resolveIntent as c}from"./intents.js";import{splitVariants as l}from"./classes.js";import{flattenStyle as u,mintClass as d,normalise as f,variantDeclarations as p}from"./style.js";import{FRAMEWORK_PROPS as m,PRIMITIVES as h,PRIMITIVE_NAMES as g}from"./table.js";import{declaresAbsolute as _,resolvePrimitive as v}from"./resolve.js";import{DEFAULT_ROWS as y,NORMALISED_DEFAULTS as b,defaultRowFor as x}from"./defaults.js";var S=e({DEFAULT_ROWS:()=>y,FRAMEWORK_PROPS:()=>m,NORMALISED_DEFAULTS:()=>b,PRIMITIVES:()=>h,PRIMITIVE_NAMES:()=>g,PrimitiveError:()=>t,answerFor:()=>r,createHandle:()=>n,declaresAbsolute:()=>_,defaultRowFor:()=>x,flattenStyle:()=>u,isAccepted:()=>i,mintClass:()=>d,normalise:()=>f,propNamesOf:()=>a,resolveIntent:()=>c,resolvePrimitive:()=>v,splitVariants:()=>l,unknownPrimitiveDetail:()=>o,unknownPropDetail:()=>s,variantDeclarations:()=>p});export{y as DEFAULT_ROWS,m as FRAMEWORK_PROPS,b as NORMALISED_DEFAULTS,h as PRIMITIVES,g as PRIMITIVE_NAMES,t as PrimitiveError,r as answerFor,n as createHandle,_ as declaresAbsolute,x as defaultRowFor,u as flattenStyle,i as isAccepted,d as mintClass,f as normalise,S as primitives_exports,a as propNamesOf,c as resolveIntent,v as resolvePrimitive,l as splitVariants,o as unknownPrimitiveDetail,s as unknownPropDetail,p as variantDeclarations};
1
+ import{__exportAll as e}from"../_virtual/_rolldown/runtime.js";import{PrimitiveError as t}from"./errors.js";import{answerFor as n,isAccepted as r,propNamesOf as i,unknownPrimitiveDetail as a,unknownPropDetail as o}from"./answers.js";import{resolveIntent as s}from"./intents.js";import{splitVariants as c}from"./classes.js";import{flattenStyle as l,mintClass as u,normalise as d,variantDeclarations as f}from"./style.js";import{FRAMEWORK_PROPS as p,PRIMITIVES as m,PRIMITIVE_NAMES as h}from"./table.js";import{declaresAbsolute as g,resolvePrimitive as _}from"./resolve.js";import{createHandle as v}from"./handles.js";import{DEFAULT_ROWS as y,NORMALISED_DEFAULTS as b,defaultRowFor as x}from"./defaults.js";var S=e({DEFAULT_ROWS:()=>y,FRAMEWORK_PROPS:()=>p,NORMALISED_DEFAULTS:()=>b,PRIMITIVES:()=>m,PRIMITIVE_NAMES:()=>h,PrimitiveError:()=>t,answerFor:()=>n,createHandle:()=>v,declaresAbsolute:()=>g,defaultRowFor:()=>x,flattenStyle:()=>l,isAccepted:()=>r,mintClass:()=>u,normalise:()=>d,propNamesOf:()=>i,resolveIntent:()=>s,resolvePrimitive:()=>_,splitVariants:()=>c,unknownPrimitiveDetail:()=>a,unknownPropDetail:()=>o,variantDeclarations:()=>f});export{y as DEFAULT_ROWS,p as FRAMEWORK_PROPS,b as NORMALISED_DEFAULTS,m as PRIMITIVES,h as PRIMITIVE_NAMES,t as PrimitiveError,n as answerFor,v as createHandle,g as declaresAbsolute,x as defaultRowFor,l as flattenStyle,r as isAccepted,u as mintClass,d as normalise,S as primitives_exports,i as propNamesOf,s as resolveIntent,_ as resolvePrimitive,c as splitVariants,a as unknownPrimitiveDetail,o as unknownPropDetail,f as variantDeclarations};
@@ -1 +1 @@
1
- import"../_virtual/_rolldown/runtime.js";import{PrimitiveError as e}from"./errors.js";import{unknownPrimitiveDetail as t,unknownPropDetail as n}from"./answers.js";import{resolveIntent as r}from"./intents.js";import{mintClass as i,normalise as a,partition as o,variantDeclarations as s}from"./style.js";import{FRAMEWORK_PROPS as c,PRIMITIVES as l,PRIMITIVE_NAMES as u}from"./table.js";const d=[`orientation`,`spacing`],withOrientationClass=(e,t)=>{if(t.length===0)return t;let n=e.orientation;return typeof n==`string`?[n,...t]:t},wrapped=(e,t,n)=>{if(n===null)return{tag:e,props:t};let{spacing:r,...i}=t;return{tag:n.tag,props:{...i,...n.props}}};function declaresAbsolute(e,t,n=`View`){let{props:r}=a(e,t,n);return o(r).intent.overlay?.role===`child`}function resolvePrimitive(f,p,m){let h=l[f];if(h===void 0)throw new e(f,``,t(u));let g=h.switchOn!==void 0&&p[h.switchOn.prop]===!0?h.switchOn.whenTrue:h,_=g.content,v={...g.widgetProps},y={..._?.widgetProps},b={...g.backdrop?.widgetProps},x={},S=[],C=[],w=[],T=[],E=new Set([_?.styleProp,_?.classNameProp,g.backdrop?.styleProp,g.backdrop?.classNameProp].filter(e=>typeof e==`string`));if(g.refusesStyle!==void 0&&(p.className!==void 0||p.style!==void 0))throw new e(f,p.className===void 0?`prop "style"`:`prop "className"`,g.refusesStyle);for(let t of Object.keys(p)){if(c.has(t)||E.has(t))continue;let r=p[t];if(r===void 0)continue;let i=g.props[t];if(i===void 0)throw new e(f,`prop "${t}"`,n(g));for(let e of Array.isArray(i)?i:[i])applyRoute(e,t,r,{primitive:f,spec:g,outerProps:v,contentProps:y,backdropProps:b,styleExtra:x,events:S,files:C,gestures:w,announcements:T})}let D=a(p,m.tokens,f),O=o({...D.props,...x}),k=orientationOf(O.props.orientation??v.orientation,g.orientation),A=_===void 0?k:orientationOf(y.orientation,_.orientation),j=r({primitive:f,intent:O.intent,orientation:A,widget:g.widget,...m.parent===void 0?{}:{parent:m.parent},...m.children===void 0?{}:{children:m.children},emittedProps:O.props}),M=i(m.sheet,[...O.css,...j.css],s(D.groups,m.tokens,f));Object.assign(v,O.props,j.props),assertOneTextAuthority(f,g,v,m.children);let N=[...g.cssClasses,...M===null?[]:[M]],P=g.overlayOnAbsoluteChild;if(P!==void 0&&(m.children?.absolute??0)>0){let e={...g.widgetProps};for(let t of d)v[t]!==void 0&&(e[t]=v[t],delete v[t]);let t=wrapped(g.tag,e,j.wrapping);return{primitive:f,node:{tag:P.tag,props:v,cssClasses:withOrientationClass(v,N)},content:{tag:t.tag,props:t.props,cssClasses:[]},backdrop:null,backdropSlot:null,contentSlot:null,slot:j.slot,absoluteSlot:P.slot,events:S,files:C,gestures:w,announcements:T,handle:g.handle??null,textSink:g.textSink,childContext:{...j.childContext,orientation:A,overlay:!0},intent:j.remaining}}let F=_===void 0?null:resolveNode(_,p,y,m,f),I=g.backdrop===void 0?null:resolveNode(g.backdrop,p,b,m,f),L=wrapped(g.tag,v,j.wrapping);return{primitive:f,node:{tag:L.tag,props:L.props,cssClasses:withOrientationClass(L.props,N)},content:F===null?null:F.node,backdrop:I===null?null:I.node,backdropSlot:g.backdrop?.slot??null,contentSlot:_?.slot??null,slot:j.slot,absoluteSlot:null,events:S,files:C,gestures:w,announcements:T,handle:g.handle??null,textSink:g.textSink,childContext:F===null?{...j.childContext,overlay:!1}:{...F.childContext,...F.childContext.textAlign===void 0&&j.childContext.textAlign!==void 0?{textAlign:j.childContext.textAlign}:{},overlay:!1},intent:j.remaining}}function resolveNode(e,t,n,c,l){let u=`${l} ${e.styleProp??`content`}`,d=a({...e.classNameProp===null?{}:{className:t[e.classNameProp]},...e.styleProp===null?{}:{style:t[e.styleProp]}},c.tokens,u),f=o(d.props),p=orientationOf(f.props.orientation??n.orientation,e.orientation),m=r({primitive:u,intent:f.intent,orientation:p,widget:e.widget,parent:{orientation:p,props:{},overlay:!1},emittedProps:f.props}),h=i(c.sheet,[...f.css,...m.css],s(d.groups,c.tokens,u));Object.assign(n,f.props,m.props);let g=wrapped(e.tag,n,m.wrapping);return{node:{tag:g.tag,props:g.props,cssClasses:withOrientationClass(g.props,h===null?[]:[h])},childContext:{...m.childContext,orientation:p}}}function applyRoute(t,n,r,i){switch(t.to){case`refused`:throw new e(i.primitive,`prop "${n}"`,t.why);case`ignored`:return;case`style-property`:i.styleExtra[t.name]=r;return;case`event`:if(typeof r!=`function`)throw new e(i.primitive,`prop "${n}"`,`binds the GTK signal "${t.signal}" and needs a function; got ${describe(r)}`);i.events.push({prop:n,signal:t.signal,read:t.read??null});return;case`file`:i.files.push({on:nodeOf(t.on,i,n),property:t.property,...normaliseSource(i.primitive,n,r)});return;case`gesture`:if(typeof r!=`function`)throw new e(i.primitive,`prop "${n}"`,`binds a Gtk.GestureClick's "${t.signal}" and needs a function; got ${describe(r)}`);i.gestures.push({prop:n,signal:t.signal});return;case`announce`:{let a=t.map[String(r)];if(a===void 0)throw new e(i.primitive,`prop "${n}"`,`has no GTK equivalent for ${describe(r)}. Known: ${Object.keys(t.map).sort().join(`, `)}. A value absent from that list is absent because GTK has no member for it, not because the table is short`);if(a===null)return;i.announcements.push({prop:n,signal:t.signal,read:t.read,priority:a});return}case`property`:{let e=nodeOf(t.on,i,n),a=e===`content`?i.contentProps:e===`backdrop`?i.backdropProps:i.outerProps,o=coerce(t,n,r,i.primitive);for(let e of t.names)a[e]=o;t.also!==void 0&&Object.assign(a,t.also);return}}}function nodeOf(t,n,r){if(t===`content`&&n.spec.content===void 0)throw new e(n.primitive,`prop "${r}"`,`is routed to a content node this primitive does not declare — the table is wrong, not the call`);if(t===`backdrop`&&n.spec.backdrop===void 0)throw new e(n.primitive,`prop "${r}"`,`is routed to a backdrop node this primitive does not declare — the table is wrong, not the call`);return t??`outer`}function normaliseSource(t,n,r){let refuse=r=>{throw new e(t,`prop "${n}"`,r)};if(typeof r==`number`)return refuse("is a number, which is what `require('./image.png')` returns: an opaque id into React Native’s own asset registry. This build chain has no such registry (ADR 0032 § 12 leaves the build to the consumer), so there is nothing to resolve it against. Use `{ uri: '/path/to/image.png' }`, or ship the image in a GResource and use `{ uri: 'resource:///…' }`");if(Array.isArray(r))return refuse("is an array, which is React Native’s per-device-scale picker (`@2x`, `@3x`). GTK draws ONE texture and scales it by the surface’s own scale factor, so there is no candidate to choose between. Give one source");if(typeof r==`string`)return refuse("is a bare string. React Native’s own type is `{ uri }`, and accepting both spellings here would make one string ambiguous between a path and a URI at exactly the layer that has to decide. Write `{ uri: … }`");if(typeof r!=`object`||!r)return refuse(`expects { uri }; got ${describe(r)}`);let i=r,a=Object.keys(i).filter(e=>e!==`uri`);if(a.length>0)return refuse(`carries ${a.join(`, `)} beside \`uri\`. Those describe a remote image React Native measures before it arrives (\`width\`/\`height\`) or fetches with headers, and neither reaches a \`Gtk.Picture\` — it takes a file and draws it. Keep \`uri\` alone`);let o=i.uri;if(typeof o!=`string`||o===``)return refuse(`expects { uri: string }; got uri = ${describe(o)}`);let s=/^([a-zA-Z][a-zA-Z0-9+.-]*):/.exec(o)?.[1]?.toLowerCase();return s===void 0?{kind:`path`,value:o}:s===`file`||s===`resource`?{kind:`uri`,value:o}:refuse(s===`http`||s===`https`||s===`data`?`is a \`${s}:\` URI, and loading one needs a fetch, a decoder and a cache — an asynchronous pipeline this layer does not own. Handing a non-native \`Gio.File\` to \`Gtk.Picture:file\` would decode on the main loop instead. Fetch the bytes yourself, build a \`Gdk.Texture\`, and set \`paintable\` through a ref`:`is a \`${s}:\` URI, and this layer only opens what GTK can read synchronously: a local path, \`file:\` and \`resource:\` (measured). Anything else needs a loader that is not here`)}function coerce(t,n,r,i){let bad=t=>{throw new e(i,`prop "${n}"`,`expects ${t}; got ${describe(r)}`)};switch(t.as){case`string`:return typeof r==`string`?r:typeof r==`number`||typeof r==`boolean`?String(r):bad(`a string`);case`boolean`:return typeof r==`boolean`?r:bad(`a boolean`);case`not`:return typeof r==`boolean`?!r:bad(`a boolean`);case`int`:return typeof r==`number`&&Number.isFinite(r)?Math.trunc(r):bad(`a number`);case`map`:return lookup(t,n,r,i);case`pixels-or-map`:return typeof r==`number`&&Number.isFinite(r)?Math.trunc(r):lookup(t,n,r,i)}}function lookup(t,n,r,i){let a=t.map??{},o=a[String(r)];if(o!==void 0)return o;throw new e(i,`prop "${n}"`,`has no GTK equivalent for ${describe(r)}. Known: ${Object.keys(a).sort().join(`, `)}. A value absent from that list is absent because GTK has no member for it, not because the table is short`)}function assertOneTextAuthority(t,n,r,i){if(!(n.textSink===null||i?.text!==!0)&&r[n.textSink]!==void 0)throw new e(t,`prop → "${n.textSink}"`,`is the same widget property a text CHILD writes, and both were given. Whichever the reconciler applied last would win, possibly differently on a first render and on an update — so it is refused. Keep one`)}const orientationOf=(e,t)=>e===`horizontal`||e===`vertical`?e:t,describe=e=>typeof e==`string`?`"${e}"`:typeof e==`object`&&e?Object.prototype.toString.call(e):String(e);export{declaresAbsolute,resolvePrimitive};
1
+ import"../_virtual/_rolldown/runtime.js";import{PrimitiveError as e,describeValue as t}from"./errors.js";import{resolveAccessible as n}from"./accessibility.js";import{unknownPrimitiveDetail as r,unknownPropDetail as i}from"./answers.js";import{resolveIntent as a}from"./intents.js";import{mintClass as o,normalise as s,partition as c,variantDeclarations as l}from"./style.js";import{FRAMEWORK_PROPS as u,PRIMITIVES as d,PRIMITIVE_NAMES as f}from"./table.js";const p=[`orientation`,`spacing`],withOrientationClass=(e,t)=>{if(t.length===0)return t;let n=e.orientation;return typeof n==`string`?[n,...t]:t},wrapped=(e,t,n)=>{if(n===null)return{tag:e,props:t};let{spacing:r,...i}=t;return{tag:n.tag,props:{...i,...n.props}}};function declaresAbsolute(e,t,n=`View`){let{props:r}=s(e,t,n);return c(r).intent.overlay?.role===`child`}function resolvePrimitive(t,n,m){let h=d[t];if(h===void 0)throw new e(t,``,r(f));let g=h.switchOn!==void 0&&n[h.switchOn.prop]===!0?h.switchOn.whenTrue:h,_=g.content,v={...g.widgetProps},y={..._?.widgetProps},b={...g.backdrop?.widgetProps},x={},S=[],C=[],w=[],T=[],E=[],D=new Set([_?.styleProp,_?.classNameProp,g.backdrop?.styleProp,g.backdrop?.classNameProp].filter(e=>typeof e==`string`));if(g.refusesStyle!==void 0&&(n.className!==void 0||n.style!==void 0))throw new e(t,n.className===void 0?`prop "style"`:`prop "className"`,g.refusesStyle);for(let r of Object.keys(n)){if(u.has(r)||D.has(r))continue;let a=n[r];if(a===void 0)continue;let o=g.props[r];if(o===void 0)throw new e(t,`prop "${r}"`,i(g));for(let e of Array.isArray(o)?o:[o])applyRoute(e,r,a,{primitive:t,spec:g,outerProps:v,contentProps:y,backdropProps:b,styleExtra:x,events:S,files:C,gestures:w,announcements:T,accessibility:E})}let O=s(n,m.tokens,t),k=c({...O.props,...x}),A=orientationOf(k.props.orientation??v.orientation,g.orientation),j=_===void 0?A:orientationOf(y.orientation,_.orientation),M=a({primitive:t,intent:k.intent,orientation:j,widget:g.widget,...m.parent===void 0?{}:{parent:m.parent},...m.children===void 0?{}:{children:m.children},emittedProps:k.props}),N=o(m.sheet,[...k.css,...M.css],l(O.groups,m.tokens,t));Object.assign(v,k.props,M.props),assertOneTextAuthority(t,g,v,m.children);let P=[...g.cssClasses,...N===null?[]:[N]],F=g.overlayOnAbsoluteChild;if(F!==void 0&&(m.children?.absolute??0)>0){let e={...g.widgetProps};for(let t of p)v[t]!==void 0&&(e[t]=v[t],delete v[t]);let n=wrapped(g.tag,e,M.wrapping);return{primitive:t,node:{tag:F.tag,props:v,cssClasses:withOrientationClass(v,P)},content:{tag:n.tag,props:n.props,cssClasses:[]},backdrop:null,backdropSlot:null,contentSlot:null,slot:M.slot,absoluteSlot:F.slot,events:S,files:C,gestures:w,announcements:T,accessibility:E,handle:g.handle??null,textSink:g.textSink,childContext:{...M.childContext,orientation:j,overlay:!0},intent:M.remaining}}let I=_===void 0?null:resolveNode(_,n,y,m,t),L=g.backdrop===void 0?null:resolveNode(g.backdrop,n,b,m,t),R=wrapped(g.tag,v,M.wrapping);return{primitive:t,node:{tag:R.tag,props:R.props,cssClasses:withOrientationClass(R.props,P)},content:I===null?null:I.node,backdrop:L===null?null:L.node,backdropSlot:g.backdrop?.slot??null,contentSlot:_?.slot??null,slot:M.slot,absoluteSlot:null,events:S,files:C,gestures:w,announcements:T,accessibility:E,handle:g.handle??null,textSink:g.textSink,childContext:I===null?{...M.childContext,overlay:!1}:{...I.childContext,...I.childContext.textAlign===void 0&&M.childContext.textAlign!==void 0?{textAlign:M.childContext.textAlign}:{},overlay:!1},intent:M.remaining}}function resolveNode(e,t,n,r,i){let u=`${i} ${e.styleProp??`content`}`,d=s({...e.classNameProp===null?{}:{className:t[e.classNameProp]},...e.styleProp===null?{}:{style:t[e.styleProp]}},r.tokens,u),f=c(d.props),p=orientationOf(f.props.orientation??n.orientation,e.orientation),m=a({primitive:u,intent:f.intent,orientation:p,widget:e.widget,parent:{orientation:p,props:{},overlay:!1},emittedProps:f.props}),h=o(r.sheet,[...f.css,...m.css],l(d.groups,r.tokens,u));Object.assign(n,f.props,m.props);let g=wrapped(e.tag,n,m.wrapping);return{node:{tag:g.tag,props:g.props,cssClasses:withOrientationClass(g.props,h===null?[]:[h])},childContext:{...m.childContext,orientation:p}}}function applyRoute(r,i,a,o){switch(r.to){case`refused`:throw new e(o.primitive,`prop "${i}"`,r.why);case`ignored`:return;case`style-property`:o.styleExtra[r.name]=a;return;case`event`:if(typeof a!=`function`)throw new e(o.primitive,`prop "${i}"`,`binds the GTK signal "${r.signal}" and needs a function; got ${t(a)}`);o.events.push({prop:i,signal:r.signal,read:r.read??null});return;case`file`:o.files.push({on:nodeOf(r.on,o,i),property:r.property,...normaliseSource(o.primitive,i,a)});return;case`gesture`:if(typeof a!=`function`)throw new e(o.primitive,`prop "${i}"`,`binds a Gtk.GestureClick's "${r.signal}" and needs a function; got ${t(a)}`);o.gestures.push({prop:i,signal:r.signal});return;case`announce`:{let n=r.map[String(a)];if(n===void 0)throw new e(o.primitive,`prop "${i}"`,`has no GTK equivalent for ${t(a)}. Known: ${Object.keys(r.map).sort().join(`, `)}. A value absent from that list is absent because GTK has no member for it, not because the table is short`);if(n===null)return;o.announcements.push({prop:i,signal:r.signal,read:r.read,priority:n});return}case`accessible`:{let{entries:s,problem:c}=n(r,i,a);if(c!==null)throw new e(o.primitive,`prop "${i}"`,`${c}; got ${t(a)}`);o.accessibility.push(...s);return}case`property`:{let e=nodeOf(r.on,o,i),t=e===`content`?o.contentProps:e===`backdrop`?o.backdropProps:o.outerProps,n=coerce(r,i,a,o.primitive);for(let e of r.names)t[e]=n;r.also!==void 0&&Object.assign(t,r.also);return}}}function nodeOf(t,n,r){if(t===`content`&&n.spec.content===void 0)throw new e(n.primitive,`prop "${r}"`,`is routed to a content node this primitive does not declare — the table is wrong, not the call`);if(t===`backdrop`&&n.spec.backdrop===void 0)throw new e(n.primitive,`prop "${r}"`,`is routed to a backdrop node this primitive does not declare — the table is wrong, not the call`);return t??`outer`}function normaliseSource(n,r,i){let refuse=t=>{throw new e(n,`prop "${r}"`,t)};if(typeof i==`number`)return refuse("is a number, which is what `require('./image.png')` returns: an opaque id into React Native’s own asset registry. This build chain has no such registry (ADR 0032 § 12 leaves the build to the consumer), so there is nothing to resolve it against. Use `{ uri: '/path/to/image.png' }`, or ship the image in a GResource and use `{ uri: 'resource:///…' }`");if(Array.isArray(i))return refuse("is an array, which is React Native’s per-device-scale picker (`@2x`, `@3x`). GTK draws ONE texture and scales it by the surface’s own scale factor, so there is no candidate to choose between. Give one source");if(typeof i==`string`)return refuse("is a bare string. React Native’s own type is `{ uri }`, and accepting both spellings here would make one string ambiguous between a path and a URI at exactly the layer that has to decide. Write `{ uri: … }`");if(typeof i!=`object`||!i)return refuse(`expects { uri }; got ${t(i)}`);let a=i,o=Object.keys(a).filter(e=>e!==`uri`);if(o.length>0)return refuse(`carries ${o.join(`, `)} beside \`uri\`. Those describe a remote image React Native measures before it arrives (\`width\`/\`height\`) or fetches with headers, and neither reaches a \`Gtk.Picture\` — it takes a file and draws it. Keep \`uri\` alone`);let s=a.uri;if(typeof s!=`string`||s===``)return refuse(`expects { uri: string }; got uri = ${t(s)}`);let c=/^([a-zA-Z][a-zA-Z0-9+.-]+):/.exec(s)?.[1]?.toLowerCase();return c===void 0?{kind:`path`,value:s}:c===`file`||c===`resource`?{kind:`uri`,value:s}:refuse(c===`http`||c===`https`||c===`data`?`is a \`${c}:\` URI, and loading one needs a fetch, a decoder and a cache — an asynchronous pipeline this layer does not own. Handing a non-native \`Gio.File\` to \`Gtk.Picture:file\` would decode on the main loop instead. Fetch the bytes yourself, build a \`Gdk.Texture\`, and set \`paintable\` through a ref`:`is a \`${c}:\` URI, and this layer only opens what GTK can read synchronously: a local path, \`file:\` and \`resource:\` (measured). Anything else needs a loader that is not here`)}function coerce(n,r,i,a){let bad=n=>{throw new e(a,`prop "${r}"`,`expects ${n}; got ${t(i)}`)};switch(n.as){case`string`:return typeof i==`string`?i:typeof i==`number`||typeof i==`boolean`?String(i):bad(`a string`);case`boolean`:return typeof i==`boolean`?i:bad(`a boolean`);case`not`:return typeof i==`boolean`?!i:bad(`a boolean`);case`int`:return typeof i==`number`&&Number.isFinite(i)?Math.trunc(i):bad(`a number`);case`map`:return lookup(n,r,i,a);case`pixels-or-map`:return typeof i==`number`&&Number.isFinite(i)?Math.trunc(i):lookup(n,r,i,a)}}function lookup(n,r,i,a){let o=n.map??{},s=o[String(i)];if(s!==void 0)return s;let c=n.refuses?.[String(i)];throw c===void 0?new e(a,`prop "${r}"`,`has no GTK equivalent for ${t(i)}. Known: ${Object.keys(o).sort().join(`, `)}. A value absent from that list is absent because GTK has no member for it, not because the table is short`):new e(a,`prop "${r}" = ${t(i)}`,c)}function assertOneTextAuthority(t,n,r,i){if(!(n.textSink===null||i?.text!==!0)&&r[n.textSink]!==void 0)throw new e(t,`prop → "${n.textSink}"`,`is the same widget property a text CHILD writes, and both were given. Whichever the reconciler applied last would win, possibly differently on a first render and on an update — so it is refused. Keep one`)}const orientationOf=(e,t)=>e===`horizontal`||e===`vertical`?e:t;export{declaresAbsolute,resolvePrimitive};
@@ -1 +1 @@
1
- import"../_virtual/_rolldown/runtime.js";import{isAnimatedValue as e}from"../animated/brand.js";import{PrimitiveError as t}from"./errors.js";import{splitVariants as n}from"./classes.js";import{partition as r,resolveUtilities as i}from"@gjsify/gtk-host/style";function flattenStyle(e){if(e==null||e===!1)return{};if(!Array.isArray(e))return e;let t={};for(let n of e)Object.assign(t,flattenStyle(n));return t}const a=new Set([`flexGrow`,`flexShrink`,`flex`,`opacity`,`fontWeight`,`zIndex`,`aspectRatio`]);function normalise(e,t,r){let a=n(e.className,r),o={...i(a.base,t)};for(let[t,n]of Object.entries(flattenStyle(e.style)))n!=null&&(typeof n!=`number`&&typeof n!=`string`&&scalarOnly(r,t,n),o[t]=typeof n==`number`?stringify(t,n):n);return{props:o,groups:a}}function variantDeclarations(e,n,a){let o={};for(let[s,c]of Object.entries(e.variants)){let e=r(i(c,n)),l=Object.keys(e.props),u=Object.keys(e.intent);if(l.length>0||u.length>0)throw new t(a,`className "${s}:${c.join(` ${s}:`)}"`,`resolves to ${[...l,...u].join(`, `)}, which ${l.length>0?`is a GTK WIDGET PROPERTY`:`is a layout INTENT`} rather than a CSS declaration. A variant becomes a GTK CSS pseudo-class, and a widget property has no pseudo-class form — only the paint half of the vocabulary (colour, opacity, radius, border, font) can carry a variant`);o[s]=e.css}return o}function scalarOnly(n,r,i){throw new t(n,`style={{ ${r}: … }}`,e(i)?'carries an `Animated.Value`, and this element is not an `Animated.View`. A plain element partitions its style into GTK CSS and widget properties before a widget sees it, so the value would land in a CSS declaration as "[object Object]" — which GTK drops without a diagnostic. Render `<Animated.View>` instead':`is a ${Array.isArray(i)?`array`:typeof i}, and the style partition reads numbers and strings. GTK CSS is composed by interpolating the value into a declaration, so anything else becomes a declaration GTK’s parser drops in silence`)}const stringify=(e,t)=>a.has(e)?`${t}`:`${t}px`;function mintClass(e,t,n){let r=Object.values(n).some(e=>e.length>0);return t.length===0&&!r?null:e.classFor(t,n)}export{flattenStyle,mintClass,normalise,r as partition,variantDeclarations};
1
+ import"../_virtual/_rolldown/runtime.js";import{isAnimatedValue as e}from"../animated/brand.js";import{PrimitiveError as t}from"./errors.js";import{splitVariants as n}from"./classes.js";import{partition as r,resolveUtilities as i}from"@gjsify/gtk-host/style";function flattenStyle(e){if(e==null||e===!1)return{};if(!Array.isArray(e))return e;let t={};for(let n of e)Object.assign(t,flattenStyle(n));return t}function splitAnimatedStyle(t){let n={},r={};for(let[i,a]of Object.entries(flattenStyle(t)))e(a)?r[i]=a:n[i]=a;return{plain:n,animated:r}}const a=new Set([`flexGrow`,`flexShrink`,`flex`,`opacity`,`fontWeight`,`zIndex`,`aspectRatio`]);function normalise(e,t,r){let a=n(e.className,r),o={...i(a.base,t)};for(let[t,n]of Object.entries(flattenStyle(e.style)))n!=null&&(typeof n!=`number`&&typeof n!=`string`&&scalarOnly(r,t,n),o[t]=typeof n==`number`?stringify(t,n):n);return{props:o,groups:a}}function variantDeclarations(e,n,a){let o={};for(let[s,c]of Object.entries(e.variants)){let e=r(i(c,n)),l=Object.keys(e.props),u=Object.keys(e.intent);if(l.length>0||u.length>0)throw new t(a,`className "${s}:${c.join(` ${s}:`)}"`,`resolves to ${[...l,...u].join(`, `)}, which ${l.length>0?`is a GTK WIDGET PROPERTY`:`is a layout INTENT`} rather than a CSS declaration. A variant becomes a GTK CSS pseudo-class, and a widget property has no pseudo-class form — only the paint half of the vocabulary (colour, opacity, radius, border, font) can carry a variant`);o[s]=e.css}return o}function scalarOnly(n,r,i){throw new t(n,`style={{ ${r}: … }}`,e(i)?'carries an `Animated.Value`, and this element is not an `Animated.View`. A plain element partitions its style into GTK CSS and widget properties before a widget sees it, so the value would land in a CSS declaration as "[object Object]" — which GTK drops without a diagnostic. Render `<Animated.View>` instead':`is a ${Array.isArray(i)?`array`:typeof i}, and the style partition reads numbers and strings. GTK CSS is composed by interpolating the value into a declaration, so anything else becomes a declaration GTK’s parser drops in silence`)}const stringify=(e,t)=>a.has(e)?`${t}`:`${t}px`;function mintClass(e,t,n){let r=Object.values(n).some(e=>e.length>0);return t.length===0&&!r?null:e.classFor(t,n)}export{flattenStyle,mintClass,normalise,r as partition,splitAnimatedStyle,variantDeclarations};