@gjsify/react-native 0.43.0 → 0.45.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.
- package/README.md +127 -31
- package/lib/esm/apis/alert.js +1 -0
- package/lib/esm/apis/appearance.js +1 -0
- package/lib/esm/apis/color-scheme.js +1 -1
- package/lib/esm/apis/dimensions.js +1 -0
- package/lib/esm/apis/display.js +1 -0
- package/lib/esm/apis/index.js +1 -1
- package/lib/esm/apis/keyboard.js +1 -0
- package/lib/esm/components.js +1 -1
- package/lib/esm/generated/own-exports.js +1 -0
- package/lib/esm/generated/unsupported-exports.js +1 -1
- package/lib/esm/generated/unsupported-router-exports.js +1 -0
- package/lib/esm/hooks.js +1 -1
- package/lib/esm/index.js +1 -1
- package/lib/esm/lists/components.js +1 -0
- package/lib/esm/lists/controller.js +1 -0
- package/lib/esm/parent-context.js +1 -0
- package/lib/esm/press.js +1 -0
- package/lib/esm/primitives/intents.js +1 -1
- package/lib/esm/primitives/resolve.js +1 -1
- package/lib/esm/primitives/table.js +1 -1
- package/lib/esm/router/errors.js +1 -0
- package/lib/esm/router/index.js +1 -0
- package/lib/esm/router/navigation.js +1 -0
- package/lib/esm/router/root.js +1 -0
- package/lib/esm/router/routes.js +1 -0
- package/lib/esm/router/screens.js +1 -0
- package/lib/esm/router/stack.js +1 -0
- package/lib/esm/router/tabs.js +1 -0
- package/lib/esm/solid/index.js +1 -1
- package/lib/esm/stylesheet.js +1 -0
- package/lib/esm/support-table.js +1 -1
- package/lib/types/apis/alert.d.ts +46 -0
- package/lib/types/apis/appearance.d.ts +28 -0
- package/lib/types/apis/color-scheme.d.ts +21 -0
- package/lib/types/apis/dimensions.d.ts +42 -0
- package/lib/types/apis/display.d.ts +87 -0
- package/lib/types/apis/index.d.ts +10 -1
- package/lib/types/apis/keyboard.d.ts +22 -0
- package/lib/types/components.d.ts +166 -10
- package/lib/types/generated/own-exports.d.ts +1 -0
- package/lib/types/generated/unsupported-exports.d.ts +0 -19
- package/lib/types/generated/unsupported-router-exports.d.ts +17 -0
- package/lib/types/hooks.d.ts +16 -0
- package/lib/types/index.d.ts +10 -6
- package/lib/types/lists/components.d.ts +102 -0
- package/lib/types/lists/controller.d.ts +45 -0
- package/lib/types/lists/lists.spec.d.ts +2 -0
- package/lib/types/parent-context.d.ts +15 -0
- package/lib/types/press.d.ts +27 -0
- package/lib/types/primitives/index.d.ts +2 -2
- package/lib/types/primitives/resolve.d.ts +36 -0
- package/lib/types/primitives/table.d.ts +79 -2
- package/lib/types/router/errors.d.ts +37 -0
- package/lib/types/router/index.d.ts +10 -0
- package/lib/types/router/navigation.d.ts +72 -0
- package/lib/types/router/root.d.ts +24 -0
- package/lib/types/router/router.spec.d.ts +2 -0
- package/lib/types/router/routes.d.ts +90 -0
- package/lib/types/router/routes.spec.d.ts +2 -0
- package/lib/types/router/screens.d.ts +48 -0
- package/lib/types/router/stack.d.ts +118 -0
- package/lib/types/router/tabs.d.ts +36 -0
- package/lib/types/solid/index.d.ts +9 -4
- package/lib/types/stylesheet.d.ts +75 -0
- package/lib/types/stylesheet.spec.d.ts +2 -0
- package/lib/types/support-table.d.ts +36 -2
- package/package.json +19 -5
package/README.md
CHANGED
|
@@ -116,10 +116,10 @@ indistinguishable from a bug in the application, forever.
|
|
|
116
116
|
|
|
117
117
|
A few that are worth knowing before they surprise you:
|
|
118
118
|
|
|
119
|
-
- **`justify-between`** is refused. ADR 0032 § 6 maps it to `Gtk.CenterBox
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
a
|
|
119
|
+
- **`justify-between`** is refused. ADR 0032 § 6 maps it to `Gtk.CenterBox` — a
|
|
120
|
+
different WIDGET, not another property on this one, and WHICH widget it is depends
|
|
121
|
+
on the child count. This layer resolves properties for the widget it was handed
|
|
122
|
+
and has no children to count. Use a `flex-1` spacer or `gap-*`.
|
|
123
123
|
- **`active:`** is the only variant idiom that pays off, and it costs nothing: it
|
|
124
124
|
becomes a GTK CSS `:active` pseudo-class on the generated class, so GTK animates a
|
|
125
125
|
press with no re-render at all. A variant on a WIDGET property (`active:flex-1`) is
|
|
@@ -129,25 +129,79 @@ A few that are worth knowing before they surprise you:
|
|
|
129
129
|
`g_error()` — SIGABRT and a core dump, measured. It needs a portal seam in the
|
|
130
130
|
host, so it stays a refusing export instead of a `partial` that kills the process.
|
|
131
131
|
|
|
132
|
+
## Routing
|
|
133
|
+
|
|
134
|
+
`@gjsify/react-native/router` is the `expo-router` surface — five names and four file
|
|
135
|
+
conventions — over **`@react-navigation/core` and `@react-navigation/routers`, run
|
|
136
|
+
unmodified**. Both are **peer** dependencies (ADR 0032 § 10), and that kind is not a
|
|
137
|
+
detail: `@react-navigation/core` holds 19 module-level `createContext` calls, so a
|
|
138
|
+
consumer pinning a different major would get a nested second copy, this navigator
|
|
139
|
+
would write one set of contexts and their screen would read the other, and the symptom
|
|
140
|
+
would be react-navigation's own *"Couldn't find a navigation object"*. As a peer, the
|
|
141
|
+
same input is an install-time `ERESOLVE` naming both ranges. It also keeps `react`
|
|
142
|
+
optional here: `@react-navigation/core` declares `react` as a NON-optional peer, so
|
|
143
|
+
depending on it would make a Solid-only consumer install React.
|
|
144
|
+
|
|
145
|
+
```tsx
|
|
146
|
+
// app/_layout.tsx
|
|
147
|
+
import { Stack } from '@gjsify/react-native/router';
|
|
148
|
+
export default function Layout() {
|
|
149
|
+
return <Stack><Stack.Screen name="index" options={{ title: 'Home' }} /></Stack>;
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
// the entry
|
|
155
|
+
import { AppRegistry } from '@gjsify/react-native';
|
|
156
|
+
import { RouterRoot } from '@gjsify/react-native/router';
|
|
157
|
+
import { manifest } from 'virtual:gjsify-rn-routes'; // the bundler plugin
|
|
158
|
+
|
|
159
|
+
AppRegistry.registerComponent('main', () => () => <RouterRoot manifest={manifest} />);
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
| convention | means |
|
|
163
|
+
|---|---|
|
|
164
|
+
| `(group)` | a directory that groups without contributing a URL segment |
|
|
165
|
+
| `[param]` | a dynamic segment; its value lands in `useLocalSearchParams()` |
|
|
166
|
+
| `_layout` | the file that owns its directory — it renders the navigator |
|
|
167
|
+
| `+not-found` | the fallback route, whose pattern is `*` |
|
|
168
|
+
|
|
169
|
+
A directory with **no** `_layout` is not a navigator: its routes flatten into the
|
|
170
|
+
nearest ancestor that is one, under a slash-joined name. So `detail/[id].tsx` works
|
|
171
|
+
with no `detail/_layout.tsx`, and adding one turns that directory into its own stack.
|
|
172
|
+
|
|
173
|
+
`Stack` renders `Adw.NavigationView`; `Tabs` renders `Adw.ViewStack` with an
|
|
174
|
+
`Adw.ViewSwitcher` in the header bar. The switcher is the better widget rather than a
|
|
175
|
+
substitute for a tab bar: it is driven by the stack's own page model, so a route file
|
|
176
|
+
adds a button with no tab-bar bookkeeping, its labels are also its accessible names,
|
|
177
|
+
and its NARROW/WIDE policy is what lets an application's breakpoint restyle it as the
|
|
178
|
+
window widens from one declaration. A React Native tab bar has one shape and the
|
|
179
|
+
application owns every pixel of the other.
|
|
180
|
+
|
|
181
|
+
The conventions are parsed **in this package, not in the plugin**, so a consumer on
|
|
182
|
+
another bundler — or one writing the nine-line manifest by hand — gets the same
|
|
183
|
+
refusals. The plugin walks a directory and emits what it found.
|
|
184
|
+
|
|
132
185
|
## Support
|
|
133
186
|
|
|
134
187
|
<!-- BEGIN generated support table -->
|
|
135
188
|
|
|
136
|
-
### Supported (
|
|
189
|
+
### Supported (4)
|
|
137
190
|
|
|
138
191
|
| export | tier | GTK | why |
|
|
139
192
|
|---|---|---|---|
|
|
140
193
|
| `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. |
|
|
194
|
+
| `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. |
|
|
141
195
|
| `EventEmitter` | — | — | Pure JavaScript; nothing in it touches a platform. |
|
|
142
196
|
| `unstable_batchedUpdates` | — | — | React 19 batches automatically; this is the identity call it already is upstream. |
|
|
143
197
|
|
|
144
|
-
### Supported, with named limits (
|
|
198
|
+
### Supported, with named limits (29)
|
|
145
199
|
|
|
146
200
|
| export | tier | GTK | why |
|
|
147
201
|
|---|---|---|---|
|
|
148
202
|
| `View` | P1 | Gtk.Box, or Gtk.Overlay when a child is absolutely positioned | The container primitive. Which widget it becomes depends on its children, not on the element. |
|
|
149
203
|
| `Text` | P1 | Gtk.Label | Wrapping is ON by default in React Native and OFF on a Gtk.Label, so the default is set explicitly. |
|
|
150
|
-
| `Pressable` | P1 | Gtk.Button (flat) | Press state is a GTK CSS :active pseudo-class; children-as-a-function is
|
|
204
|
+
| `Pressable` | P1 | Gtk.Button (flat) | Press state is a GTK CSS :active pseudo-class; children-as-a-function is implemented over the state flag, and costs nothing when it is unused. |
|
|
151
205
|
| `ScrollView` | P1 | Gtk.ScrolledWindow + an implicit content box | contentContainerStyle styles the inner box, which is a second styleable node. |
|
|
152
206
|
| `ActivityIndicator` | P1 | Adw.Spinner | Direct counterpart. |
|
|
153
207
|
| `TextInput` | P1 | Gtk.Entry / Gtk.TextView | Single- versus multi-line is one prop in React Native and two different widgets in GTK. |
|
|
@@ -156,27 +210,30 @@ A few that are worth knowing before they surprise you:
|
|
|
156
210
|
| `Platform` | P1 | — | OS is "linux" \| "macos" \| "windows"; select() picks the default branch. |
|
|
157
211
|
| `Share` | P1 | Gdk.Clipboard | No desktop share sheet worth pretending about; copying the link is the honest mapping. |
|
|
158
212
|
| `AppRegistry` | P1 | Adw.Application + Adw.ApplicationWindow | The entry point. Nothing renders without a window, so this is P1 despite being a shim. |
|
|
159
|
-
|
|
160
|
-
|
|
213
|
+
| `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. |
|
|
214
|
+
| `FlatList` | P2 | Gtk.ListView + Gio.ListStore, owned by the component | GTK virtualises for real. The list is NOT an ordinary element: a Gtk.ListView takes no children (measured — no append, add, insert, prepend, remove or set_child), so the component owns the view and drives the model from data, with React only inside the item factory. |
|
|
215
|
+
| `SectionList` | P2 | Gtk.ListView + one flattened Gio.ListStore | The same component as FlatList, handed sections instead of data. |
|
|
216
|
+
| `VirtualizedList` | P2 | Gtk.ListView | Its public surface is wide and mostly not worth honouring literally; the useful subset backs FlatList, and this name is that subset plus getItem/getItemCount. |
|
|
217
|
+
| `VirtualizedSectionList` | P2 | Gtk.ListView | The section-shaped sibling of VirtualizedList, which is SectionList here. |
|
|
218
|
+
| `Image` | P2 | Gtk.Picture | resizeMode becomes content-fit, and the default is inverted: React Native defaults to cover, a Gtk.Picture to contain (measured). |
|
|
219
|
+
| `ImageBackground` | P2 | Gtk.Picture in a Gtk.Overlay | A picture with the children stacked over it. The picture is the overlay’s MAIN child, because a Gtk.Overlay paints every overlay child ABOVE it. |
|
|
220
|
+
| `TouchableOpacity` | P2 | Gtk.Button (flat) | The same machinery as Pressable, written over it: one shared record of routes in the primitive table, one line of component. |
|
|
221
|
+
| `TouchableHighlight` | P2 | Gtk.Button (flat) | As TouchableOpacity. The pressed style is Adwaita’s own unless a variant says otherwise. |
|
|
222
|
+
| `TouchableWithoutFeedback` | P2 | Gtk.Box + Gtk.GestureClick | No chrome, so no button: a vertical Gtk.Box like a View, with a Gtk.GestureClick added to it. Measured: Gtk.Button emits activate and clicked, a Gtk.Box emits neither, and Gtk.GestureClick emits pressed/released/stopped/unpaired-release. |
|
|
223
|
+
| `Button` | P2 | Gtk.Button | The one component whose React Native styling story is "you cannot", which GTK agrees with. title, onPress and disabled. |
|
|
224
|
+
| `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. |
|
|
225
|
+
| `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. |
|
|
226
|
+
| `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. |
|
|
227
|
+
| `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. |
|
|
228
|
+
| `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. |
|
|
229
|
+
| `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. |
|
|
230
|
+
| `Keyboard` | P2 | — | Its events are on-screen-keyboard events, which do not occur — so the questions with a correct answer get it and the ones whose answer would have to be invented refuse. |
|
|
231
|
+
|
|
232
|
+
### Planned (28)
|
|
161
233
|
|
|
162
234
|
| export | tier | GTK | why |
|
|
163
235
|
|---|---|---|---|
|
|
164
|
-
| `Modal` | P1 | Adw.Dialog | An Adw.Dialog cannot be an ordinary element. MEASURED on libadwaita 1.
|
|
165
|
-
| `StyleSheet` | P1 | — | create/flatten/hairlineWidth/absoluteFill. Style objects go through the same partition as classes. |
|
|
166
|
-
| `FlatList` | P2 | Gtk.ListView + Gio.ListStore | GTK virtualises for real, so this fits better here than it does on the web. |
|
|
167
|
-
| `SectionList` | P2 | Gtk.ListView + a section model | Sections map onto GTK section models. |
|
|
168
|
-
| `VirtualizedList` | P2 | Gtk.ListView | Its public surface is wide and mostly not worth honouring literally; the useful subset backs FlatList. |
|
|
169
|
-
| `VirtualizedSectionList` | P2 | Gtk.ListView | The section-shaped sibling of VirtualizedList. |
|
|
170
|
-
| `Image` | P2 | Gtk.Picture / Gdk.Texture | resizeMode becomes content-fit. |
|
|
171
|
-
| `ImageBackground` | P2 | Gtk.Picture in a Gtk.Overlay | A picture with children over it. |
|
|
172
|
-
| `TouchableOpacity` | P2 | Gtk.Button (flat) | The same machinery as Pressable, and nearly free once it exists. |
|
|
173
|
-
| `TouchableHighlight` | P2 | Gtk.Button (flat) | As TouchableOpacity, with a different pressed style. |
|
|
174
|
-
| `TouchableWithoutFeedback` | P2 | Gtk.GestureClick | A gesture controller on the child, with no button chrome. |
|
|
175
|
-
| `Button` | P2 | Gtk.Button | The one component whose React Native styling story is "you cannot", which GTK agrees with. |
|
|
176
|
-
| `Dimensions` | P2 | Gdk.Surface | Window size, not screen size — a desktop app is not full-screen. |
|
|
177
|
-
| `useWindowDimensions` | P2 | Gdk.Surface | The hook form of Dimensions, re-rendering on resize. |
|
|
178
|
-
| `Alert` | P2 | Adw.AlertDialog | Direct counterpart. |
|
|
179
|
-
| `Appearance` | P2 | Adw.StyleManager | The imperative sibling of useColorScheme. |
|
|
236
|
+
| `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. |
|
|
180
237
|
| `AppState` | P3 | Gtk.Application / Gdk.Surface state | active/background from window focus and visibility. |
|
|
181
238
|
| `PixelRatio` | P3 | Gdk.Surface.scale-factor | The scale factor of the surface the widget is on. |
|
|
182
239
|
| `PlatformColor` | P3 | Adwaita named colours | Maps unusually well — GTK’s palette is exactly this idea. |
|
|
@@ -196,7 +253,7 @@ A few that are worth knowing before they surprise you:
|
|
|
196
253
|
| `TouchableNativeFeedback` | P3 | Gtk.Button | Android-only ripple; shimmed to its portable sibling. |
|
|
197
254
|
| `ActionSheetIOS` | P3 | Adw.AlertDialog with responses | iOS-only by name; the pattern is a dialog with choices. |
|
|
198
255
|
| `Clipboard` | P3 | Gdk.Clipboard | Deprecated upstream in favour of a community package, but trivial here. |
|
|
199
|
-
| `BackHandler` | P3 | — | An Android hardware back button.
|
|
256
|
+
| `BackHandler` | P3 | — | An Android hardware back button. Routing has landed and this did NOT arrive with it, which the earlier reason assumed it would: BackHandler INTERCEPTS a back press and consumes it, and MEASURED on libadwaita 1.9.3, Adw.NavigationView emits `popped` AFTER the fact and has no vetoable "about to pop" signal at all — its only prevention is Adw.NavigationPage:can-pop, a property rather than an event. The honest counterpart is usePreventRemove, which the routing layer does honour through its popped bridge; this name needs a key controller of its own on the window. |
|
|
200
257
|
| `DynamicColorIOS` | P3 | — | A light/dark colour pair; the Adwaita scheme already provides the switch. |
|
|
201
258
|
| `processColor` | P3 | — | Colour string to a platform value; a Gdk.RGBA on this side. |
|
|
202
259
|
| `UTFSequence` | P3 | — | A table of unicode constants. Pure data, no platform in it. |
|
|
@@ -205,14 +262,10 @@ A few that are worth knowing before they surprise you:
|
|
|
205
262
|
| `NativeEventEmitter` | P3 | — | It would construct and subscribe, but nothing native would ever emit into it — shipping that needs a decision, not a class. |
|
|
206
263
|
| `DeviceEventEmitter` | P3 | — | The global emitter. Lands with NativeEventEmitter, and for the same reason. |
|
|
207
264
|
|
|
208
|
-
### No meaning on a desktop window (
|
|
265
|
+
### No meaning on a desktop window (6)
|
|
209
266
|
|
|
210
267
|
| export | tier | GTK | why |
|
|
211
268
|
|---|---|---|---|
|
|
212
|
-
| `SafeAreaView` | P2 | — | Insets are zero on a desktop window, but it has to exist to be imported. |
|
|
213
|
-
| `StatusBar` | P2 | — | A desktop window has no status bar to configure. |
|
|
214
|
-
| `KeyboardAvoidingView` | P2 | — | No on-screen keyboard eats a desktop window layout. |
|
|
215
|
-
| `Keyboard` | P2 | — | Its events are on-screen-keyboard events, which do not occur. |
|
|
216
269
|
| `LogBox` | P3 | — | A development overlay for a phone; the console is the desktop equivalent. |
|
|
217
270
|
| `Systrace` | — | — | Android systrace has no desktop counterpart. |
|
|
218
271
|
| `Vibration` | — | — | A desktop machine does not vibrate. |
|
|
@@ -251,3 +304,46 @@ A few that are worth knowing before they surprise you:
|
|
|
251
304
|
| `RootTagContext` | — | — | A React Native surface identifier. This layer has one root per Adw window. |
|
|
252
305
|
|
|
253
306
|
<!-- END generated support table -->
|
|
307
|
+
|
|
308
|
+
### Routing surface
|
|
309
|
+
|
|
310
|
+
<!-- BEGIN generated router support table -->
|
|
311
|
+
|
|
312
|
+
### Supported, with named limits (5)
|
|
313
|
+
|
|
314
|
+
| export | tier | GTK | why |
|
|
315
|
+
|---|---|---|---|
|
|
316
|
+
| `router` | P1 | Adw.NavigationView (push/pop) via React Navigation’s StackActions | push, back, replace and navigate — the four methods the measured application calls, 19 of the 27 calls being push. |
|
|
317
|
+
| `useLocalSearchParams` | P1 | — | The current route’s params — the [param] values and the query string — read through React Navigation’s own useRoute(). |
|
|
318
|
+
| `usePathname` | P1 | — | The current URL without its query string, from React Navigation’s getPathFromState over the published root state. |
|
|
319
|
+
| `Stack` | P1 | Adw.NavigationView + Adw.NavigationPage | The stack navigator: React declares which pages exist, the widget owns their order, and the route key is the tag that joins the two. |
|
|
320
|
+
| `Tabs` | P1 | Adw.ViewStack + Adw.ViewSwitcher | The tab navigator. The switcher is driven by the stack’s own page model, so a route file adds a button with no tab-bar bookkeeping. |
|
|
321
|
+
|
|
322
|
+
### Planned (13)
|
|
323
|
+
|
|
324
|
+
| export | tier | GTK | why |
|
|
325
|
+
|---|---|---|---|
|
|
326
|
+
| `Link` | P2 | Gtk.Button (flat) or Gtk.LinkButton | An href as an element rather than a call. Cheap once `router` exists, and the honest widget question — button or link — is worth measuring first. |
|
|
327
|
+
| `Redirect` | P2 | — | A declarative navigate-on-render. It needs a rule for what happens when it redirects during the first commit, which is the commit that must not be empty. |
|
|
328
|
+
| `Slot` | P2 | Adw.Bin | A layout that renders its child route with no navigator around it. It is the one layout shape that has no widget of its own. |
|
|
329
|
+
| `useRouter` | P2 | — | The hook form of `router`. Identical behaviour, and it exists so a test can substitute the object — which is worth having once there is something to substitute. |
|
|
330
|
+
| `useSegments` | P2 | — | The current route split into segments. Derivable from the published root state, and unused in the measured application. |
|
|
331
|
+
| `useGlobalSearchParams` | P2 | — | The params of the focused route anywhere in the tree, rather than of the calling screen. It re-renders on every navigation by design, which is why expo-router documents preferring the local form. |
|
|
332
|
+
| `useNavigation` | P2 | — | React Navigation’s own hook, re-exported by expo-router. It works already through @react-navigation/core; exporting it from here is a decision about what this surface promises, not a build. |
|
|
333
|
+
| `useFocusEffect` | P2 | — | As useNavigation: it is core’s, and it works. The open question is the same one. |
|
|
334
|
+
| `useRootNavigationState` | P3 | — | The root state as a hook. The store `usePathname` reads is already there; this is a second selector over it. |
|
|
335
|
+
| `Drawer` | P3 | Adw.OverlaySplitView | A sidebar navigator. The pattern survives on a desktop better than it does on a phone, and Adwaita has the exact widget — it is a third navigator, not a variation on these two. |
|
|
336
|
+
| `withLayoutContext` | P3 | — | The escape hatch that lets a third-party navigator take its screens from the file tree. It is exactly `useRouteNode` plus screen synthesis, made public — worth doing once a third navigator exists to prove the shape. |
|
|
337
|
+
| `Navigator` | P3 | — | expo-router’s low-level navigator primitive. It belongs with withLayoutContext and for the same reason. |
|
|
338
|
+
| `ErrorBoundary` | P3 | Adw.StatusPage | A per-route error screen. React 19 routes an uncaught error to the root’s handler and @gjsify/gtk-host/react rethrows it from render() — deliberately, so a refusal is not swallowed — and a boundary here has to be reconciled with that rather than bolted beside it. |
|
|
339
|
+
|
|
340
|
+
### Refused (4)
|
|
341
|
+
|
|
342
|
+
| export | tier | GTK | why |
|
|
343
|
+
|---|---|---|---|
|
|
344
|
+
| `ExpoRoot` | — | — | It takes a Metro `require.context`, which does not exist in this build chain. `RouterRoot` takes the manifest a bundler plugin emits instead — the same job, with the one input that is available. |
|
|
345
|
+
| `useUnstableGlobalHref` | — | — | Unstable by its own name, and it answers the question usePathname already answers for the only surface this layer has. |
|
|
346
|
+
| `useNavigationContainerRef` | — | — | The container ref is this layer’s own (one process routes one tree), and handing it out would let a consumer dispatch around the refusals `router` exists to give. |
|
|
347
|
+
| `SplashScreen` | — | — | A native splash screen belongs to a phone launcher. A GTK application maps its window when it is ready, which is the desktop equivalent and is Gio.Application’s job, not the router’s. |
|
|
348
|
+
|
|
349
|
+
<!-- END generated router support table -->
|
|
@@ -0,0 +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};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import{PrimitiveError as e}from"../primitives/errors.js";import{currentColorScheme as t,onColorSchemeChange as n,setColorSchemePreference as r}from"./color-scheme.js";const i={getColorScheme(){return t()},setColorScheme(t){if(t!==null&&t!==`light`&&t!==`dark`)throw new e(`Appearance`,`setColorScheme("${String(t)}")`,`is not a scheme React Native defines. It has three: "light", "dark", and null to follow the system`);r(t)},addChangeListener(e){return{remove:n(t=>e({colorScheme:t}))}}};export{i as Appearance};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"../_virtual/_rolldown/runtime.js";import{PrimitiveError as e}from"../primitives/errors.js";import t from"gi://Adw?version=1";function manager(){let n=t.StyleManager.get_default();if(n===null)throw new e(`useColorScheme`,``,"needs `Adw.StyleManager.get_default()`, which answers null before libadwaita is initialised. Construct the application first — `runAdwaitaApp` and `AppRegistry.runApplication` both do it");return n}const currentColorScheme=()=>manager().dark?`dark`:`light`;function onColorSchemeChange(e){let t=manager(),n=t.connect(`notify::dark`,()=>{e(t.dark?`dark`:`light`)});return()=>t.disconnect(n)}export{currentColorScheme,onColorSchemeChange};
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import{PrimitiveError as e}from"../primitives/errors.js";import t from"gi://Adw?version=1";function manager(){let n=t.StyleManager.get_default();if(n===null)throw new e(`useColorScheme`,``,"needs `Adw.StyleManager.get_default()`, which answers null before libadwaita is initialised. Construct the application first — `runAdwaitaApp` and `AppRegistry.runApplication` both do it");return n}const currentColorScheme=()=>manager().dark?`dark`:`light`;function setColorSchemePreference(e){let n=manager();n.colorScheme=e===null?t.ColorScheme.DEFAULT:e===`dark`?t.ColorScheme.FORCE_DARK:t.ColorScheme.FORCE_LIGHT}const requestedColorScheme=()=>{let e=manager().colorScheme;return e===t.ColorScheme.FORCE_DARK?`dark`:e===t.ColorScheme.FORCE_LIGHT?`light`:null};function onColorSchemeChange(e){let t=manager(),n=t.connect(`notify::dark`,()=>{e(t.dark?`dark`:`light`)});return()=>t.disconnect(n)}export{currentColorScheme,onColorSchemeChange,requestedColorScheme,setColorSchemePreference};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import{PrimitiveError as e}from"../primitives/errors.js";import{onWindowMetricsChange as t,screenMetrics as n,windowMetrics as r}from"./display.js";const i={get(t){if(t===`window`)return r();if(t===`screen`)return n();throw new e(`Dimensions`,`get("${String(t)}")`,`is not a dimension React Native defines. It has two: "window" (the application window, which is what a desktop layout is about) and "screen" (the monitor it is on)`)},addEventListener(n,i){if(n!==`change`)throw new e(`Dimensions`,`addEventListener("${String(n)}")`,`is not an event React Native defines. There is one: "change"`);return{remove:t(()=>{i({window:r(),screen:safeScreen()})})}},set(){throw new e(`Dimensions`,`set`,"is how React Native’s native side PUBLISHES the device metrics to JavaScript. There is no bridge here — GTK is asked directly on every `get`, so a value set from outside would be a second answer that could disagree with the window it describes")}};function safeScreen(){try{return n()}catch(t){if(t instanceof e)return null;throw t}}export{i as Dimensions};
|
|
@@ -0,0 +1 @@
|
|
|
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://Gdk?version=4.0";function activeWindow(){if(n.Display.get_default()===null)return null;let e=t.Window.get_toplevels(),r=null;for(let t=0;t<e.get_n_items();t++){let n=e.get_item(t);if(n!==null){if(n.get_mapped())return n;r??=n}}return r}const scaleOf=e=>{let t=e.get_scale();return t>0?t:e.get_scale_factor()};function hairlineWidth(){let e=n.Display.get_default();if(e===null)return 1;let t=e.get_monitors(),r=0;for(let e=0;e<t.get_n_items();e++){let n=t.get_item(e);if(n===null)continue;let i=scaleOf(n);i>0&&(r===0||i<r)&&(r=i)}return r===0?1:1/r}function fontScale(){let e=t.Settings.get_default();if(e===null)return 1;let n=e.gtkXftDpi;return n>0?n/1024/96:1}function windowScale(e){let t=e.get_surface();if(t===null)return 1/hairlineWidth();let n=t.get_scale();return n>0?n:t.get_scale_factor()}function windowMetrics(){let t=activeWindow();if(t===null)throw new e(`Dimensions`,`get('window')`,"reports the size of the application WINDOW and there is none yet — `Gtk.Window.get_toplevels()` is empty, so this ran before the application built its window (module scope is before it, always). Read it from a component or an effect, or use `useWindowDimensions`, which re-renders when the size changes");let n={width:t.get_width(),height:t.get_height()};return{width:n.width>0?n.width:t.defaultWidth,height:n.height>0?n.height:t.defaultHeight,scale:windowScale(t),fontScale:fontScale()}}function screenMetrics(){let t=n.Display.get_default();if(t===null)throw new e(`Dimensions`,`get('screen')`,"needs a `Gdk.Display`, and `Gdk.Display.get_default()` answers null before `Gtk.init()` (measured). Read it after the application has started");let r=activeWindow()?.get_surface()??null,i=(r===null?null:t.get_monitor_at_surface(r))??t.get_monitors().get_item(0);if(i===null)throw new e(`Dimensions`,`get('screen')`,`found a display with no monitors on it. That is a headless session; there is no screen to measure`);let a=i.get_geometry();return{width:a.width,height:a.height,scale:scaleOf(i),fontScale:fontScale()}}function onWindowMetricsChange(e){let t=activeWindow();if(t===null)return()=>{};let n=[],watchSurface=t=>{for(let r of[`notify::width`,`notify::height`]){let i=t.connect(r,()=>e());n.push(()=>t.disconnect(i))}},r=t.get_surface();if(r!==null)watchSurface(r);else{let r=t.connect(`realize`,()=>{let n=t.get_surface();n!==null&&watchSurface(n),e()});n.push(()=>t.disconnect(r))}return()=>{for(let e of n)e();n.length=0}}let r=null;function windowMetricsSnapshot(){let e=windowMetrics(),t=r;return(t===null||t.width!==e.width||t.height!==e.height||t.scale!==e.scale||t.fontScale!==e.fontScale)&&(r=e),r}function resetWindowMetricsCache(){r=null}export{hairlineWidth,onWindowMetricsChange,resetWindowMetricsCache,screenMetrics,windowMetrics,windowMetricsSnapshot};
|
package/lib/esm/apis/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{currentColorScheme as
|
|
1
|
+
import{Alert as e}from"./alert.js";import{currentColorScheme as t,onColorSchemeChange as n,requestedColorScheme as r,setColorSchemePreference as i}from"./color-scheme.js";import{Appearance as a}from"./appearance.js";import{hairlineWidth as o,onWindowMetricsChange as s,resetWindowMetricsCache as c,screenMetrics as l,windowMetrics as u,windowMetricsSnapshot as d}from"./display.js";import{Dimensions as f}from"./dimensions.js";import{Keyboard as p}from"./keyboard.js";import{Linking as m}from"./linking.js";import{Platform as h,resetPlatformCache as g}from"./platform.js";import{Share as _}from"./share.js";export{e as Alert,a as Appearance,f as Dimensions,p as Keyboard,m as Linking,h as Platform,_ as Share,t as currentColorScheme,o as hairlineWidth,n as onColorSchemeChange,s as onWindowMetricsChange,r as requestedColorScheme,g as resetPlatformCache,c as resetWindowMetricsCache,l as screenMetrics,i as setColorSchemePreference,u as windowMetrics,d as windowMetricsSnapshot};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import{PrimitiveError as e}from"../primitives/errors.js";const t=[`keyboardWillShow`,`keyboardDidShow`,`keyboardWillHide`,`keyboardDidHide`,`keyboardWillChangeFrame`,`keyboardDidChangeFrame`],n={addListener(n){throw new e(`Keyboard`,`addListener("${n??``}")`,`reports an ON-SCREEN keyboard appearing or disappearing (${t.join(`, `)}), and a desktop window never sees one — a hardware keyboard takes no space and has no frame. This refuses instead of handing back a subscription that never fires, because a handler that silently never runs is indistinguishable from a bug in your own code. Delete the subscription, or branch on Platform.OS`)},dismiss(){},removeAllListeners(){},isVisible(){return!1},metrics(){},scheduleLayoutAnimation(){throw new e(`Keyboard`,`scheduleLayoutAnimation`,"asks the LayoutAnimation subsystem to animate the next layout pass. That is `LayoutAnimation`’s own entry (tier P3, `planned`) — an animated layout pass, not a keyboard behaviour — and it needs the same subsystem `Animated` does")}};export{n as Keyboard};
|
package/lib/esm/components.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./_virtual/_rolldown/runtime.js";import{PrimitiveError as e}from"./primitives/errors.js";import{
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import{PrimitiveError as e}from"./primitives/errors.js";import{ParentContext as t,ParentProvider as n}from"./parent-context.js";import{onGesture as r,onPressStateChange as i}from"./press.js";import{declaresAbsolute as a,resolvePrimitive as o}from"./primitives/resolve.js";import{styleConfig as s}from"./style-config.js";import{Children as c,createElement as l,isValidElement as u,useContext as d,useEffect as f,useMemo as p,useRef as m,useState as h}from"react";import g from"gi://Gio";const accessor=e=>e.replace(/-([a-z0-9])/g,(e,t)=>t.toUpperCase()),isTextNode=e=>typeof e==`string`||typeof e==`number`;function isAbsoluteChild(e,t){if(!u(e))return!1;try{return a(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(e,t){let n=m(null),r=m(t);return r.current=t,{props:p(()=>{let t={};for(let i of e)t[`on:${i.signal}`]=()=>{let e=r.current[i.prop];if(typeof e!=`function`)return;if(i.read===null){e();return}let t=n.current;e(t===null?void 0:t[accessor(i.read)])};return t},[e.map(e=>`${e.prop}>${e.signal}>${e.read??``}`).join(`|`)]),widgetRef:n}}function nodeProps(e,t,n){let r={...t,...e.props,...n};return e.cssClasses.length>0&&(r[`css-classes`]=[...e.cssClasses]),r}function usePlan(n,r){let i=r,a=d(t),l=s(),u=c.toArray(i.children),f=o(n,i,{tokens:l.tokens,sheet:l.sheet,...a===null?{}:{parent:a},children:childFacts(u,l.tokens)}),m=Object.keys(f.intent);if(m.length>0)throw new e(n,m.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 h=useSignals(f.events,i),g=i.ref,_=p(()=>e=>{h.widgetRef.current=e,typeof g==`function`?g(e):g!=null&&(g.current=e)},[g,h.widgetRef]);useGestures(f.gestures,i,h.widgetRef);let v=useFiles(f.files),y={...h.props,ref:_,...v.outer};f.slot!==null&&(y.slot=f.slot);let b={...v.content};f.contentSlot!==null&&(b.slot=f.contentSlot);let x={...v.backdrop};f.backdropSlot!==null&&(x.slot=f.backdropSlot);let S=p(()=>f.childContext,[JSON.stringify(f.childContext),f.childContext]);return{plan:f,children:u,inherited:a?.props??{},extra:y,contentExtra:b,backdropExtra:x,published:S,tokens:l.tokens,widgetRef:h.widgetRef}}function useFiles(e){return p(()=>{let t={outer:{},content:{},backdrop:{}};for(let n of e)t[n.on][n.property]=n.kind===`path`?g.File.new_for_path(n.value):g.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 i=m(t);i.current=t;let a=e.map(e=>`${e.prop}>${e.signal}`).join(`|`);f(()=>{let e=n.current;if(a===``||e==null)return;let t=a.split(`|`).map(t=>{let[n,a]=t.split(`>`);return r(e,a,()=>{let e=i.current[n];typeof e==`function`&&e()})});return()=>{for(let e of t)e()}},[a,n])}function render(e){let{plan:t,children:r,inherited:i,extra:a,contentExtra:o,backdropExtra:s,published:c,tokens:u}=e,wrap=e=>l(n,{value:c},...e);if(t.content===null){let e=r.some(isTextNode)?r:[wrap(r)];return l(t.node.tag,nodeProps(t.node,i,a),...e)}let d=t.absoluteSlot===null?[]:r.filter(e=>isAbsoluteChild(e,u)),f=t.absoluteSlot===null?r:r.filter(e=>!isAbsoluteChild(e,u)),p=l(t.content.tag,nodeProps(t.content,{},o),wrap(f)),m=t.backdrop===null?[]:[l(t.backdrop.tag,nodeProps(t.backdrop,{},s))];return l(t.node.tag,nodeProps(t.node,i,a),...m,p,...d.length===0?[]:[wrap(d)])}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]=h(!1),a=usePlan(`Pressable`,t===null?e:{...e,children:t({pressed:n})}),o=a.widgetRef;return f(()=>{if(t===null)return;let e=o.current;if(e!=null)return i(e,r)},[t===null,o]),render(a)}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 _="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 e(`StatusBar`,`setBarStyle`,_)},setHidden:()=>{throw new e(`StatusBar`,`setHidden`,_)},setBackgroundColor:()=>{throw new e(`StatusBar`,`setBackgroundColor`,_)},setTranslucent:()=>{throw new e(`StatusBar`,`setTranslucent`,_)},setNetworkActivityIndicatorVisible:()=>{throw new e(`StatusBar`,`setNetworkActivityIndicatorVisible`,_)},pushStackEntry:()=>{throw new e(`StatusBar`,`pushStackEntry`,_)},popStackEntry:()=>{throw new e(`StatusBar`,`popStackEntry`,_)},replaceStackEntry:()=>{throw new e(`StatusBar`,`replaceStackEntry`,_)},get currentHeight(){throw new e(`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")}}));export{ActivityIndicator,Button,Image,ImageBackground,KeyboardAvoidingView,Pressable,SafeAreaView,ScrollView,StatusBar,Switch,Text,TextInput,TouchableHighlight,TouchableOpacity,TouchableWithoutFeedback,View,nodeProps,usePlan};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=[`OWN_EXPORT_NAMES`,`PrimitiveError`,`SUPPORTED_NAMES`,`SUPPORT_TABLE`,`UnsupportedError`,`configureStyle`,`explainUnsupported`,`isImportable`,`isOwnExport`,`primitives`,`registerRootComponent`,`resetStyleConfig`,`styleConfig`];export{e as OWN_EXPORT_NAMES};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{unsupported as e}from"../unsupported.js";const t=e(`Modal`),n=e(`
|
|
1
|
+
import{unsupported as e}from"../unsupported.js";const t=e(`Modal`),n=e(`RefreshControl`),r=e(`AppState`),i=e(`PixelRatio`),a=e(`PlatformColor`),o=e(`AccessibilityInfo`),s=e(`Animated`),c=e(`Easing`),l=e(`LayoutAnimation`),u=e(`InteractionManager`),d=e(`useAnimatedValue`),f=e(`useAnimatedValueXY`),p=e(`useAnimatedColor`),m=e(`PanResponder`),h=e(`usePressability`),g=e(`DrawerLayoutAndroid`),_=e(`I18nManager`),v=e(`LogBox`),y=e(`Systrace`),b=e(`Vibration`),x=e(`ToastAndroid`),S=e(`InputAccessoryView`),C=e(`TouchableNativeFeedback`),w=e(`ActionSheetIOS`),T=e(`PushNotificationIOS`),E=e(`PermissionsAndroid`),D=e(`Settings`),O=e(`Clipboard`),k=e(`BackHandler`),A=e(`DynamicColorIOS`),j=e(`processColor`),M=e(`UTFSequence`),N=e(`experimental_LayoutConformance`),P=e(`unstable_VirtualView`),F=e(`VirtualViewMode`),I=e(`unstable_NativeText`),L=e(`unstable_NativeView`),R=e(`unstable_TextAncestorContext`),z=e(`ReactNativeVersion`),B=e(`DeviceInfo`),V=e(`DevMenu`),H=e(`DevSettings`),U=e(`NativeModules`),W=e(`TurboModuleRegistry`),G=e(`NativeComponentRegistry`),K=e(`requireNativeComponent`),q=e(`codegenNativeComponent`),J=e(`codegenNativeCommands`),Y=e(`UIManager`),X=e(`findNodeHandle`),Z=e(`registerCallableModule`),Q=e(`Networking`),$=e(`NativeDialogManagerAndroid`),ee=e(`ProgressBarAndroid`),te=e(`Touchable`),ne=e(`NativeEventEmitter`),re=e(`DeviceEventEmitter`),ie=e(`NativeAppEventEmitter`),ae=e(`RootTagContext`);export{o as AccessibilityInfo,w as ActionSheetIOS,s as Animated,r as AppState,k as BackHandler,O as Clipboard,V as DevMenu,H as DevSettings,re as DeviceEventEmitter,B as DeviceInfo,g as DrawerLayoutAndroid,A as DynamicColorIOS,c as Easing,_ as I18nManager,S as InputAccessoryView,u as InteractionManager,l as LayoutAnimation,v as LogBox,t as Modal,ie as NativeAppEventEmitter,G as NativeComponentRegistry,$ as NativeDialogManagerAndroid,ne as NativeEventEmitter,U as NativeModules,Q as Networking,m as PanResponder,E as PermissionsAndroid,i as PixelRatio,a as PlatformColor,ee as ProgressBarAndroid,T as PushNotificationIOS,z as ReactNativeVersion,n as RefreshControl,ae as RootTagContext,D as Settings,y as Systrace,x as ToastAndroid,te as Touchable,C as TouchableNativeFeedback,W as TurboModuleRegistry,Y as UIManager,M as UTFSequence,b as Vibration,F as VirtualViewMode,J as codegenNativeCommands,q as codegenNativeComponent,N as experimental_LayoutConformance,X as findNodeHandle,j as processColor,Z as registerCallableModule,K as requireNativeComponent,I as unstable_NativeText,L as unstable_NativeView,R as unstable_TextAncestorContext,P as unstable_VirtualView,p as useAnimatedColor,d as useAnimatedValue,f as useAnimatedValueXY,h as usePressability};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{unsupported as e}from"../unsupported.js";const t=e(`Link`),n=e(`Redirect`),r=e(`Slot`),i=e(`useRouter`),a=e(`useSegments`),o=e(`useGlobalSearchParams`),s=e(`useNavigation`),c=e(`useFocusEffect`),l=e(`useRootNavigationState`),u=e(`Drawer`),d=e(`withLayoutContext`),f=e(`Navigator`),p=e(`ErrorBoundary`),m=e(`ExpoRoot`),h=e(`useUnstableGlobalHref`),g=e(`useNavigationContainerRef`),_=e(`SplashScreen`);export{u as Drawer,p as ErrorBoundary,m as ExpoRoot,t as Link,f as Navigator,n as Redirect,r as Slot,_ as SplashScreen,c as useFocusEffect,o as useGlobalSearchParams,s as useNavigation,g as useNavigationContainerRef,l as useRootNavigationState,i as useRouter,a as useSegments,h as useUnstableGlobalHref,d as withLayoutContext};
|
package/lib/esm/hooks.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./_virtual/_rolldown/runtime.js";import{currentColorScheme as e,onColorSchemeChange as t}from"./apis/color-scheme.js";import{
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import{currentColorScheme as e,onColorSchemeChange as t}from"./apis/color-scheme.js";import{onWindowMetricsChange as n,windowMetricsSnapshot as r}from"./apis/display.js";import{useSyncExternalStore as i}from"react";function useColorScheme(){return i(subscribe,e,e)}const subscribe=e=>t(()=>e());function useWindowDimensions(){return i(subscribeToWindow,r,r)}const subscribeToWindow=e=>n(()=>e());export{useColorScheme,useWindowDimensions};
|
package/lib/esm/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./_virtual/_rolldown/runtime.js";import{PrimitiveError as e}from"./primitives/errors.js";import{
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import{PrimitiveError as e}from"./primitives/errors.js";import{Alert as t}from"./apis/alert.js";import{Appearance as n}from"./apis/appearance.js";import{Dimensions as r}from"./apis/dimensions.js";import{Keyboard as i}from"./apis/keyboard.js";import{Linking as a}from"./apis/linking.js";import{Platform as o}from"./apis/platform.js";import{Share as s}from"./apis/share.js";import"./apis/index.js";import{OWN_EXPORT_NAMES as c}from"./generated/own-exports.js";import{SUPPORTED_NAMES as l,SUPPORT_TABLE as u,explainUnsupported as d,isImportable as f,isOwnExport as p}from"./support-table.js";import{UnsupportedError as m}from"./unsupported.js";import{AppRegistry as h,registerRootComponent as g}from"./app-registry.js";import{configureStyle as _,resetStyleConfig as v,styleConfig as y}from"./style-config.js";import{ActivityIndicator as b,Button as x,Image as S,ImageBackground as C,KeyboardAvoidingView as w,Pressable as T,SafeAreaView as E,ScrollView as D,StatusBar as O,Switch as k,Text as A,TextInput as j,TouchableHighlight as M,TouchableOpacity as N,TouchableWithoutFeedback as P,View as F}from"./components.js";import{EventEmitter as I}from"./event-emitter.js";import{AccessibilityInfo as L,ActionSheetIOS as R,Animated as z,AppState as B,BackHandler as V,Clipboard as H,DevMenu as U,DevSettings as W,DeviceEventEmitter as G,DeviceInfo as K,DrawerLayoutAndroid as q,DynamicColorIOS as J,Easing 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-exports.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";function unstable_batchedUpdates(e,t){return e(t)}export{L as AccessibilityInfo,R as ActionSheetIOS,b as ActivityIndicator,t as Alert,z as Animated,h as AppRegistry,B as AppState,n as Appearance,V as BackHandler,x as Button,H as Clipboard,U as DevMenu,W as DevSettings,G as DeviceEventEmitter,K as DeviceInfo,r as Dimensions,q as DrawerLayoutAndroid,J as DynamicColorIOS,Y as Easing,I as EventEmitter,We as FlatList,X as I18nManager,S as Image,C as ImageBackground,Z as InputAccessoryView,Q as InteractionManager,i as Keyboard,w as KeyboardAvoidingView,$ as LayoutAnimation,a 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,c as OWN_EXPORT_NAMES,ce as PanResponder,le as PermissionsAndroid,ue as PixelRatio,o as Platform,de as PlatformColor,T as Pressable,e as PrimitiveError,fe as ProgressBarAndroid,pe as PushNotificationIOS,me as ReactNativeVersion,he as RefreshControl,ge as RootTagContext,l as SUPPORTED_NAMES,u as SUPPORT_TABLE,E as SafeAreaView,D as ScrollView,Ge as SectionList,_e as Settings,s as Share,O as StatusBar,Je as StyleSheet,k as Switch,ve as Systrace,A as Text,j as TextInput,ye as ToastAndroid,be as Touchable,M as TouchableHighlight,xe as TouchableNativeFeedback,N as TouchableOpacity,P as TouchableWithoutFeedback,Se as TurboModuleRegistry,Ce as UIManager,we as UTFSequence,m as UnsupportedError,Te as Vibration,F as View,Ee as VirtualViewMode,Ke as VirtualizedList,qe as VirtualizedSectionList,De as codegenNativeCommands,Oe as codegenNativeComponent,_ as configureStyle,ke as experimental_LayoutConformance,d as explainUnsupported,Ae as findNodeHandle,f as isImportable,p as isOwnExport,Ye as primitives,je as processColor,Me as registerCallableModule,g as registerRootComponent,Ne as requireNativeComponent,v as resetStyleConfig,y 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};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import{PrimitiveError as e}from"../primitives/errors.js";import{ParentProvider as t}from"../parent-context.js";import{nodeProps as n,usePlan as r}from"../components.js";import{createListController as i,onScrollNearEnd as a,rowKey as o}from"./controller.js";import{createElement as s,useEffect as c,useRef as l}from"react";const u="restyles the separator around a row, and a `Gtk.ListView` has no separator widget to restyle — `Gtk.ListView:show-separators` makes GTK draw the Adwaita line itself, between rows it owns. Give the row its own border instead (`border-b`), which is a real widget property you can change",d={highlight(){throw new e(`FlatList`,`separators.highlight`,u)},unhighlight(){throw new e(`FlatList`,`separators.unhighlight`,u)},updateProps(){throw new e(`FlatList`,`separators.updateProps`,u)}};function slot(e){return typeof e==`function`?s(e,{}):e??null}function useListFrame(e,t,n,o,s,u){let d=t,f=r(e,t),p=l(null),m=l(null),h=l(null),g=l(n);g.current=n,c(()=>{let e=p.current;if(s||e==null)return;let t=i(u===void 0?{}:{onRowError:u});return h.current=t,t.attach(e),t.setRows(g.current),()=>{h.current=null,t.dispose()}},[s]),c(()=>{h.current?.setRows(g.current)},[o,d.data,d.sections,d.extraData,d.renderItem]);let _=d.onEndReachedThreshold??.5,v=d.horizontal===!0?`horizontal`:`vertical`,y=d.onEndReached;return c(()=>{let e=m.current;if(!(y===void 0||e==null))return a(e,v,_,e=>y({distanceFromEnd:e}))},[y,v,_,s]),{rendered:f,listRef:e=>{p.current=e},scrollerRef:e=>{m.current=e}}}function renderFrame(r,i,a,o){let{rendered:c,listRef:l,scrollerRef:u}=r,{plan:d,inherited:f,extra:p,contentExtra:m,published:h}=c;if(d.content===null)throw new e(d.primitive,``,`has no content node, so there is no scroller to put the list in — the primitive table is wrong, not the call`);let wrap=(e,n)=>e===null?null:s(t,{value:h,key:n},e),g=a?wrap(slot(i.ListEmptyComponent),`empty`):s(d.content.tag,{...n(d.content,{},m),key:`scroller`,ref:u},s(`GtkListView`,{ref:l,...o?{orientation:`horizontal`}:{}}));return s(d.node.tag,n(d.node,f,p),wrap(slot(i.ListHeaderComponent),`header`),g,wrap(slot(i.ListFooterComponent),`footer`))}function flattenData(e){let t=e.data??null,n=e.getItemCount===void 0?t?.length??0:e.getItemCount(t),at=n=>e.getItem===void 0?t[n]:e.getItem(t,n),r=[];for(let t=0;t<n;t++){let n=o(at(t),t,e.keyExtractor);r.push({key:n,render:()=>renderOne(e.renderItem,at(t),t)})}return{rows:r,rowsKey:r.map(e=>e.key).join(`\0`)}}function flattenSections(e){let t=[];return(e.sections??[]).forEach((n,r)=>{let i=n.key??n.title??`section-${r}`;e.renderSectionHeader!==void 0&&t.push({key:`header:${i}`,render:()=>e.renderSectionHeader?.({section:n})??null}),n.data.forEach((n,r)=>{let a=o(n,r,e.keyExtractor);t.push({key:`${i}:${a}`,render:()=>renderOne(e.renderItem,n,r)})})}),{rows:t,rowsKey:t.map(e=>e.key).join(`\0`)}}function renderOne(t,n,r){if(t===void 0)throw new e(`FlatList`,`renderItem`,`was not given, so there is nothing to put in a row. React Native requires it too — and a list of empty rows is exactly the silent failure this layer refuses`);return t({item:n,index:r,separators:d})}function FlatList(e){let{rows:t,rowsKey:n}=flattenData(e),r=t.length===0&&e.ListEmptyComponent!==void 0;return renderFrame(useListFrame(`FlatList`,e,t,n,r,e.onRowError),e,r,e.horizontal===!0)}function VirtualizedList(e){let{rows:t,rowsKey:n}=flattenData(e),r=t.length===0&&e.ListEmptyComponent!==void 0;return renderFrame(useListFrame(`FlatList`,e,t,n,r,e.onRowError),e,r,e.horizontal===!0)}function SectionList(e){let{rows:t,rowsKey:n}=flattenSections(e),r=t.length===0&&e.ListEmptyComponent!==void 0;return renderFrame(useListFrame(`FlatList`,e,t,n,r,e.onRowError),e,r,e.horizontal===!0)}function VirtualizedSectionList(e){return SectionList(e)}export{FlatList,SectionList,VirtualizedList,VirtualizedSectionList};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import{ParentProvider as e}from"../parent-context.js";import{createRoot as t}from"@gjsify/gtk-host/react";import{createElement as n}from"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 n=i(`GtkBox`,{orientation:`vertical`});a(n,r(e));let c=s.onRowError;return t(o(n),c===void 0?{}:{onUncaughtError:c})},showRow(t,r){c.set(t,r===null?null:n(e,{value:l},n(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";import{createContext as e,createElement as t}from"react";const n=e(null);function ParentProvider(e){return t(n.Provider,{value:e.value},e.children)}export{n as ParentContext,ParentProvider};
|
package/lib/esm/press.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import e from"gi://Gtk?version=4.0";let t=0;const pressWatchCount=()=>t,isPressed=t=>(t.get_state_flags()&e.StateFlags.ACTIVE)!==0;function onPressStateChange(e,n){let r=isPressed(e),i=e.connect(`state-flags-changed`,()=>{let t=isPressed(e);t!==r&&(r=t,n(t))});return t+=1,n(r),()=>{e.disconnect(i),--t}}function onGesture(t,n,r){let i=new e.GestureClick,a=i.connect(n,()=>r());return t.add_controller(i),()=>{t.remove_controller(i),i.disconnect(a)}}export{onGesture,onPressStateChange,pressWatchCount};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"../_virtual/_rolldown/runtime.js";import{PrimitiveError as e}from"./errors.js";const t={"flex-start":`start`,"flex-end":`end`,center:`center`,stretch:`fill`,baseline:`baseline`},n={"flex-start":`start`,"flex-end":`end`,center:`center`},r={left:{xalign:0,justify:`left`},center:{xalign:.5,justify:`center`},right:{xalign:1,justify:`right`},justify:{xalign:0,justify:`fill`}},cross=e=>e===`horizontal`?`valign`:`halign`,main=e=>e===`horizontal`?`halign`:`valign`;function resolveIntent(i){let{primitive:a,intent:o,orientation:s,widget:c,parent:l}=i,u={},d=[],f={},p={},m=null,h=l?.textAlign;if(o.alignChildren!==void 0){if(!c.box)throw new e(a,`items-*`,`aligns CHILDREN, and this primitive has none to align — the widget it becomes is not a box. Move the utility to the container`);f[cross(s)]=t[o.alignChildren]}if(o.distribute!==void 0){if(!c.box)throw new e(a,`justify-*`,`distributes CHILDREN along the main axis, and the widget this primitive becomes is not a box. Move the utility to the container`);let t=n[o.distribute];if(t===void 0)throw new e(a,`justify-${label(o.distribute)}`,"GTK's box has no main-axis justification, and ADR 0032 § 6's mapping for this one is `Gtk.CenterBox
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import{PrimitiveError as e}from"./errors.js";const t={"flex-start":`start`,"flex-end":`end`,center:`center`,stretch:`fill`,baseline:`baseline`},n={"flex-start":`start`,"flex-end":`end`,center:`center`},r={left:{xalign:0,justify:`left`},center:{xalign:.5,justify:`center`},right:{xalign:1,justify:`right`},justify:{xalign:0,justify:`fill`}},cross=e=>e===`horizontal`?`valign`:`halign`,main=e=>e===`horizontal`?`halign`:`valign`;function resolveIntent(i){let{primitive:a,intent:o,orientation:s,widget:c,parent:l}=i,u={},d=[],f={},p={},m=null,h=l?.textAlign;if(o.alignChildren!==void 0){if(!c.box)throw new e(a,`items-*`,`aligns CHILDREN, and this primitive has none to align — the widget it becomes is not a box. Move the utility to the container`);f[cross(s)]=t[o.alignChildren]}if(o.distribute!==void 0){if(!c.box)throw new e(a,`justify-*`,`distributes CHILDREN along the main axis, and the widget this primitive becomes is not a box. Move the utility to the container`);let t=n[o.distribute];if(t===void 0)throw new e(a,`justify-${label(o.distribute)}`,"GTK's box has no main-axis justification, and ADR 0032 § 6's mapping for this one is `Gtk.CenterBox` — a different WIDGET, not another property on this one. The host's `slotted` policy used to be what blocked it, because it named a `remove` that gtk 4.22.4's `Gtk.CenterBox` does not install (it clears a slot with `set_center_widget(null)`); that block is gone, since `children.remove` is optional for a policy whose slots are all setters. What is missing is the CHILD COUNT — two or three children pick the widget, and this layer resolves properties for the widget it was handed, with no children to count. Spell the distribution with a spacer child (`flex-1`) or with `gap-*`");u[main(s)]=t}if(o.axisSpacing!==void 0){if(!c.box)throw new e(a,`gap-x-*/gap-y-*`,"is a `Gtk.Box:spacing`, and the widget this primitive becomes has none (measured, gtk-props.ts)");o.axisSpacing.axis===s&&(u.spacing=o.axisSpacing.pixels)}if(o.textAlign!==void 0&&(h=o.textAlign),h!==void 0&&c.alignsText){let e=r[h];u.xalign=e.xalign,u.justify=e.justify,h=void 0}if(o.expand!==void 0&&(l===void 0?p.expand=o.expand:u[l.orientation===`horizontal`?`hexpand`:`vexpand`]=!0),o.alignSelf!==void 0&&(l===void 0?p.alignSelf=o.alignSelf:u[cross(l.orientation)]=t[o.alignSelf]),o.overlay?.role===`child`)if(l===void 0)p.overlay=o.overlay;else if(l.overlay)m=`overlay`,placeAbsolute(a,o.overlay.edges,i.emittedProps,u,d);else throw new e(a,`absolute`,"positions this element on top of its parent, so the PARENT has to be a `Gtk.Overlay` — and it is not. A `View` becomes one as soon as one of its children is absolutely positioned, so the parent here is either not a `View` (a `ScrollView`, a `Pressable`, a `Text`) or the element is a root");return{props:u,css:d,childContext:{orientation:s,props:f,overlay:!1,...h===void 0?{}:{textAlign:h}},slot:m,remaining:p}}function placeAbsolute(t,n,r,i,a){let{top:o,right:s,bottom:c,left:l}=n;if((o!==void 0||c!==void 0)&&(i.valign=o!==void 0&&c!==void 0?`fill`:o===void 0?`end`:`start`,o!==void 0&&(i[`margin-top`]=o),c!==void 0&&(i[`margin-bottom`]=c)),!(l===void 0&&s===void 0)){if(r[`margin-start`]!==void 0||r[`margin-end`]!==void 0)throw new e(t,`absolute + ms-*/me-*`,"offsets a PHYSICAL edge (`left-*`/`right-*`/`inset-*`), which becomes GTK CSS, while `ms-*`/`me-*` become the widget properties `margin-start`/`margin-end`. GTK applies both and they ADD, where CSS would have let one win. Spell the horizontal margin one way");i.halign=l!==void 0&&s!==void 0?`fill`:l===void 0?`end`:`start`,l!==void 0&&a.push(`margin-left: ${l}px`),s!==void 0&&a.push(`margin-right: ${s}px`)}}const label=e=>e.replace(/^space-/,``);export{resolveIntent};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"../_virtual/_rolldown/runtime.js";import{PrimitiveError as e}from"./errors.js";import{resolveIntent as t}from"./intents.js";import{mintClass as n,normalise as r,partition as i,variantDeclarations as a}from"./style.js";import{FRAMEWORK_PROPS as o,PRIMITIVES as s}from"./table.js";const c=[`orientation`,`spacing`],withOrientationClass=(e,t)=>{if(t.length===0)return t;let n=e.orientation;return typeof n==`string`?[n,...t]:t};function declaresAbsolute(e,t,n=`View`){let{props:a}=r(e,t,n);return i(a).intent.overlay?.role===`child`}function resolvePrimitive(l,u,d){let f=s[l];if(f===void 0)throw new e(l,``,`is not a primitive this layer answers for. Known: ${Object.keys(s).sort().join(`, `)}`);let p=f.switchOn!==void 0&&u[f.switchOn.prop]===!0?f.switchOn.whenTrue:f,m=p.content,h={...p.widgetProps},g={...m?.widgetProps},_={},v=[],
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import{PrimitiveError as e}from"./errors.js";import{resolveIntent as t}from"./intents.js";import{mintClass as n,normalise as r,partition as i,variantDeclarations as a}from"./style.js";import{FRAMEWORK_PROPS as o,PRIMITIVES as s}from"./table.js";const c=[`orientation`,`spacing`],withOrientationClass=(e,t)=>{if(t.length===0)return t;let n=e.orientation;return typeof n==`string`?[n,...t]:t};function declaresAbsolute(e,t,n=`View`){let{props:a}=r(e,t,n);return i(a).intent.overlay?.role===`child`}function resolvePrimitive(l,u,d){let f=s[l];if(f===void 0)throw new e(l,``,`is not a primitive this layer answers for. Known: ${Object.keys(s).sort().join(`, `)}`);let p=f.switchOn!==void 0&&u[f.switchOn.prop]===!0?f.switchOn.whenTrue:f,m=p.content,h={...p.widgetProps},g={...m?.widgetProps},_={...p.backdrop?.widgetProps},v={},y=[],b=[],x=[],S=new Set([m?.styleProp,m?.classNameProp,p.backdrop?.styleProp,p.backdrop?.classNameProp].filter(e=>typeof e==`string`));if(p.refusesStyle!==void 0&&(u.className!==void 0||u.style!==void 0))throw new e(l,u.className===void 0?`prop "style"`:`prop "className"`,p.refusesStyle);for(let t of Object.keys(u)){if(o.has(t)||S.has(t))continue;let n=u[t];if(n===void 0)continue;let r=p.props[t];if(r===void 0)throw new e(l,`prop "${t}"`,`is not a prop this primitive answers for. It takes: ${Object.keys(p.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`);for(let e of Array.isArray(r)?r:[r])applyRoute(e,t,n,{primitive:l,spec:p,outerProps:h,contentProps:g,backdropProps:_,styleExtra:v,events:y,files:b,gestures:x})}let C=r(u,d.tokens,l),w=i({...C.props,...v}),T=orientationOf(w.props.orientation??h.orientation,p.orientation),E=m===void 0?T:orientationOf(g.orientation,m.orientation),D=t({primitive:l,intent:w.intent,orientation:E,widget:p.widget,...d.parent===void 0?{}:{parent:d.parent},...d.children===void 0?{}:{children:d.children},emittedProps:w.props}),O=n(d.sheet,[...w.css,...D.css],a(C.groups,d.tokens,l));Object.assign(h,w.props,D.props),assertOneTextAuthority(l,p,h,d.children);let k=[...p.cssClasses,...O===null?[]:[O]],A=p.overlayOnAbsoluteChild;if(A!==void 0&&(d.children?.absolute??0)>0){let e={...p.widgetProps};for(let t of c)h[t]!==void 0&&(e[t]=h[t],delete h[t]);return{primitive:l,node:{tag:A.tag,props:h,cssClasses:withOrientationClass(h,k)},content:{tag:p.tag,props:e,cssClasses:[]},backdrop:null,backdropSlot:null,contentSlot:null,slot:D.slot,absoluteSlot:A.slot,events:y,files:b,gestures:x,textSink:p.textSink,childContext:{...D.childContext,orientation:E,overlay:!0},intent:D.remaining}}let j=m===void 0?null:resolveNode(m,u,g,d,l),M=p.backdrop===void 0?null:resolveNode(p.backdrop,u,_,d,l);return{primitive:l,node:{tag:p.tag,props:h,cssClasses:withOrientationClass(h,k)},content:j===null?null:j.node,backdrop:M===null?null:M.node,backdropSlot:p.backdrop?.slot??null,contentSlot:m?.slot??null,slot:D.slot,absoluteSlot:null,events:y,files:b,gestures:x,textSink:p.textSink,childContext:j===null?{...D.childContext,overlay:!1}:{...j.childContext,...j.childContext.textAlign===void 0&&D.childContext.textAlign!==void 0?{textAlign:D.childContext.textAlign}:{},overlay:!1},intent:D.remaining}}function resolveNode(e,o,s,c,l){let u=`${l} ${e.styleProp??`content`}`,d=r({...e.classNameProp===null?{}:{className:o[e.classNameProp]},...e.styleProp===null?{}:{style:o[e.styleProp]}},c.tokens,u),f=i(d.props),p=orientationOf(f.props.orientation??s.orientation,e.orientation),m=t({primitive:u,intent:f.intent,orientation:p,widget:e.widget,parent:{orientation:p,props:{},overlay:!1},emittedProps:f.props}),h=n(c.sheet,[...f.css,...m.css],a(d.groups,c.tokens,u));return Object.assign(s,f.props,m.props),{node:{tag:e.tag,props:s,cssClasses:withOrientationClass(s,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`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 +1 @@
|
|
|
1
|
-
const e={box:!0,alignsText:!1},t={box:!1,alignsText:!1},n={box:!1,alignsText:!0},r="GTK carries accessibility through `Gtk.Accessible.update_property()`, an imperative call, not through a widget property — so there is nothing for this layer to set as data. `AccessibilityInfo` (tier P3) is the entry that owns this, and GTK’s model maps onto the props well once it exists",i="would write `Gtk.Widget:name`, and so does `testID`. Two props for one property is the silent-drop shape the host refuses by name (`signalTaken`), so this layer picks one: use `testID`",a={testID:{to:`property`,names:[`name`],as:`string`},id:{to:`refused`,why:i},nativeID:{to:`refused`,why:i},onLayout:{to:`refused`,why:"GTK reports its allocation through `Gtk.Widget.vfunc_size_allocate`, a SUBCLASS override rather than a signal, so there is no handler to bind. `useWindowDimensions` (tier P2) is the window-level answer"},accessible:{to:`refused`,why:r},accessibilityLabel:{to:`refused`,why:r},accessibilityRole:{to:`refused`,why:r},accessibilityHint:{to:`refused`,why:r},accessibilityState:{to:`refused`,why:r}},o={to:`property`,names:[`can-target`],as:`map`,map:{auto:!0,none:!1}},s={...a,multiline:{to:`ignored`,why:`it chose the widget; it is not also a property`},editable:{to:`property`,names:[`editable`],as:`boolean`},keyboardType:{to:`property`,names:[`input-purpose`],as:`map`,map:{default:`free-form`,"email-address":`email`,"phone-pad":`phone`,"number-pad":`digits`,numeric:`number`,"decimal-pad":`number`,url:`url`}},autoFocus:{to:`refused`,why:"focus is `Gtk.Widget.grab_focus()`, which only works once the widget is mapped — an imperative call at a moment this layer does not own. Call it from a ref in an effect"},onFocus:{to:`refused`,why:"focus arrives through a `Gtk.EventControllerFocus`, a controller rather than a signal on the widget, so it is not a prop this layer can route"},onBlur:{to:`refused`,why:"see `onFocus` — the same controller"},returnKeyType:{to:`ignored`,why:`a desktop keyboard has one Return key and no label to change`},autoCapitalize:{to:`ignored`,why:`an on-screen keyboard behaviour; a hardware keyboard has no shift state to preset`},autoCorrect:{to:`ignored`,why:`an on-screen keyboard behaviour`},keyboardAppearance:{to:`ignored`,why:`there is no on-screen keyboard to theme`}},c="`Gtk.TextView` keeps its content in a `Gtk.TextBuffer` rather than in a property (measured: 61 properties, no `text`), so there is nothing for this layer to set as data. Drop `multiline` for a `Gtk.Entry`, or reach the buffer through a ref",l={tag:`GtkTextView`,widgetProps:{"wrap-mode":`word-char`},cssClasses:[],orientation:`vertical`,widget:t,textSink:null,props:{...s,value:{to:`refused`,why:c},defaultValue:{to:`refused`,why:c},onChangeText:{to:`refused`,why:c},placeholder:{to:`refused`,why:"`Gtk.TextView` installs no `placeholder-text` (measured); the Adwaita idiom is a label above the field"},maxLength:{to:`refused`,why:"`Gtk.TextView` installs no `max-length` (measured) — the limit belongs to the buffer"},secureTextEntry:{to:`refused`,why:"`Gtk.TextView` installs no `visibility` (measured), and a multiline password field is not a thing a desktop offers"},onSubmitEditing:{to:`refused`,why:`Return inserts a newline in a multiline field; there is nothing to submit`}}},u={View:{tag:`GtkBox`,widgetProps:{orientation:`vertical`},cssClasses:[],orientation:`vertical`,widget:e,textSink:null,overlayOnAbsoluteChild:{tag:`GtkOverlay`,slot:`overlay`},props:{...a,pointerEvents:o}},Text:{tag:`GtkLabel`,widgetProps:{wrap:!0},cssClasses:[],orientation:`vertical`,widget:n,textSink:`label`,props:{...a,numberOfLines:{to:`property`,names:[`lines`],as:`int`,also:{ellipsize:`end`,wrap:!0}},ellipsizeMode:{to:`property`,names:[`ellipsize`],as:`map`,map:{head:`start`,middle:`middle`,tail:`end`}},selectable:{to:`property`,names:[`selectable`],as:`boolean`},onPress:{to:`refused`,why:"a `Gtk.Label` emits no `clicked` (measured: `activate-current-link`, `activate-link`, `copy-clipboard`, `move-cursor` and nothing else). Wrap it in a `<Pressable>`, which is a real `Gtk.Button`"},allowFontScaling:{to:`ignored`,why:`text scaling is a desktop-wide GNOME setting, not a per-label opt-in`},maxFontSizeMultiplier:{to:`ignored`,why:"see `allowFontScaling`"},adjustsFontSizeToFit:{to:`refused`,why:"GTK has no shrink-to-fit text; a label ellipsizes or wraps. Use `numberOfLines` with `ellipsizeMode`"}}},Pressable:{tag:`GtkButton`,widgetProps:{},cssClasses:[`flat`],orientation:`vertical`,widget:t,textSink:`label`,props:{...a,pointerEvents:o,onPress:{to:`event`,signal:`clicked`},onPressIn:{to:`refused`,why:"press state is the GTK CSS `:active` pseudo-class, not React state (ADR 0032 § 7) — write `active:opacity-70` and GTK animates it with no re-render at all"},onPressOut:{to:`refused`,why:"see `onPressIn` — `active:` is the mechanism"},onLongPress:{to:`refused`,why:"a long press is a `Gtk.GestureLongPress` controller added to the widget, not a property or a signal on it, so it is not something this layer can route as data"},delayLongPress:{to:`refused`,why:"see `onLongPress`"},hitSlop:{to:`refused`,why:"GTK hit-tests the allocation and has no way to grow it past the widget. Pad the button (`p-*`), which enlarges the real target"},android_ripple:{to:`ignored`,why:`an Android-only ripple; Adwaita has its own press feedback`},disabled:{to:`property`,names:[`sensitive`],as:`not`}}},ScrollView:{tag:`GtkScrolledWindow`,widgetProps:{"hscrollbar-policy":`never`},cssClasses:[],orientation:`vertical`,widget:t,textSink:null,content:{tag:`GtkBox`,widgetProps:{orientation:`vertical`},orientation:`vertical`,widget:e,styleProp:`contentContainerStyle`,classNameProp:`contentContainerClassName`},props:{...a,horizontal:[{to:`property`,on:`content`,names:[`orientation`],as:`map`,map:{true:`horizontal`,false:`vertical`}},{to:`property`,on:`outer`,names:[`hscrollbar-policy`],as:`map`,map:{true:`automatic`,false:`never`}},{to:`property`,on:`outer`,names:[`vscrollbar-policy`],as:`map`,map:{true:`never`,false:`automatic`}}],showsVerticalScrollIndicator:{to:`property`,names:[`vscrollbar-policy`],as:`map`,map:{true:`automatic`,false:`external`}},showsHorizontalScrollIndicator:{to:`property`,names:[`hscrollbar-policy`],as:`map`,map:{true:`automatic`,false:`external`}},scrollEnabled:{to:`refused`,why:"a `Gtk.ScrolledWindow` has no switch that stops scrolling — setting both policies to `never` hides the bars AND clamps the child, which is a different thing. Render the content without the ScrollView when it must not scroll"},onScroll:{to:`refused`,why:"GTK reports scroll position through the `Gtk.Adjustment` objects behind `hadjustment`/`vadjustment` — `notify::value` on an adjustment, not a signal on the scrolled window — so there is no prop to route. Reach the adjustment through a ref"},scrollEventThrottle:{to:`refused`,why:"see `onScroll`"},refreshControl:{to:`refused`,why:"GTK has no pull-to-refresh idiom and `RefreshControl` is `refused` in the support table for that reason. Give the desktop build a refresh action"},keyboardShouldPersistTaps:{to:`ignored`,why:`there is no on-screen keyboard to dismiss`},keyboardDismissMode:{to:`ignored`,why:"see `keyboardShouldPersistTaps`"},contentContainerStyle:{to:`ignored`,why:`read directly as the content node’s style set`},contentContainerClassName:{to:`ignored`,why:`read directly as the content node’s class list`}}},ActivityIndicator:{tag:`AdwSpinner`,widgetProps:{},cssClasses:[],orientation:`vertical`,widget:t,textSink:null,props:{...a,animating:{to:`property`,names:[`visible`],as:`boolean`},hidesWhenStopped:{to:`ignored`,why:"a stopped `Adw.Spinner` is a hidden one here — there is no property that stops it while it is on screen (measured), so this is already the behaviour"},size:{to:`property`,names:[`width-request`,`height-request`],as:`pixels-or-map`,map:{small:16,large:32}},color:{to:`style-property`,name:`color`}}},TextInput:{tag:`GtkEntry`,widgetProps:{},cssClasses:[],orientation:`vertical`,widget:t,textSink:`text`,switchOn:{prop:`multiline`,whenTrue:l},props:{...s,value:{to:`property`,names:[`text`],as:`string`},defaultValue:{to:`property`,names:[`text`],as:`string`},placeholder:{to:`property`,names:[`placeholder-text`],as:`string`},maxLength:{to:`property`,names:[`max-length`],as:`int`},secureTextEntry:{to:`property`,names:[`visibility`],as:`not`},onChangeText:{to:`event`,signal:`notify::text`,read:`text`},onSubmitEditing:{to:`event`,signal:`activate`}}},Switch:{tag:`GtkSwitch`,widgetProps:{},cssClasses:[],orientation:`vertical`,widget:t,textSink:null,props:{...a,value:{to:`property`,names:[`active`],as:`boolean`},onValueChange:{to:`event`,signal:`notify::active`,read:`active`},disabled:{to:`property`,names:[`sensitive`],as:`not`},trackColor:{to:`refused`,why:"Adwaita paints the switch from the theme’s accent colour, and its track is a CSS `slider`/`trough` subnode rather than a property. Style it from the application stylesheet"},thumbColor:{to:`refused`,why:"see `trackColor`"},ios_backgroundColor:{to:`ignored`,why:`an iOS-only fallback colour`}}}},d=Object.keys(u),f=new Set([`children`,`key`,`ref`,`className`,`style`]);export{f as FRAMEWORK_PROPS,u as PRIMITIVES,d as PRIMITIVE_NAMES};
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";const e={box:!0,alignsText:!1},t={box:!1,alignsText:!1},n={box:!1,alignsText:!0},r="GTK carries accessibility through `Gtk.Accessible.update_property()`, an imperative call, not through a widget property — so there is nothing for this layer to set as data. `AccessibilityInfo` (tier P3) is the entry that owns this, and GTK’s model maps onto the props well once it exists",i="would write `Gtk.Widget:name`, and so does `testID`. Two props for one property is the silent-drop shape the host refuses by name (`signalTaken`), so this layer picks one: use `testID`",a={testID:{to:`property`,names:[`name`],as:`string`},id:{to:`refused`,why:i},nativeID:{to:`refused`,why:i},onLayout:{to:`refused`,why:"GTK reports its allocation through `Gtk.Widget.vfunc_size_allocate`, a SUBCLASS override rather than a signal, so there is no handler to bind. `useWindowDimensions` (tier P2) is the window-level answer"},accessible:{to:`refused`,why:r},accessibilityLabel:{to:`refused`,why:r},accessibilityRole:{to:`refused`,why:r},accessibilityHint:{to:`refused`,why:r},accessibilityState:{to:`refused`,why:r}},o={to:`property`,names:[`can-target`],as:`map`,map:{auto:!0,none:!1}},s={...a,multiline:{to:`ignored`,why:`it chose the widget; it is not also a property`},editable:{to:`property`,names:[`editable`],as:`boolean`},keyboardType:{to:`property`,names:[`input-purpose`],as:`map`,map:{default:`free-form`,"email-address":`email`,"phone-pad":`phone`,"number-pad":`digits`,numeric:`number`,"decimal-pad":`number`,url:`url`}},autoFocus:{to:`refused`,why:"focus is `Gtk.Widget.grab_focus()`, which only works once the widget is mapped — an imperative call at a moment this layer does not own. Call it from a ref in an effect"},onFocus:{to:`refused`,why:"focus arrives through a `Gtk.EventControllerFocus`, a controller rather than a signal on the widget, so it is not a prop this layer can route"},onBlur:{to:`refused`,why:"see `onFocus` — the same controller"},returnKeyType:{to:`ignored`,why:`a desktop keyboard has one Return key and no label to change`},autoCapitalize:{to:`ignored`,why:`an on-screen keyboard behaviour; a hardware keyboard has no shift state to preset`},autoCorrect:{to:`ignored`,why:`an on-screen keyboard behaviour`},keyboardAppearance:{to:`ignored`,why:`there is no on-screen keyboard to theme`}},c="`Gtk.TextView` keeps its content in a `Gtk.TextBuffer` rather than in a property (measured: 61 properties, no `text`), so there is nothing for this layer to set as data. Drop `multiline` for a `Gtk.Entry`, or reach the buffer through a ref",l={tag:`GtkTextView`,widgetProps:{"wrap-mode":`word-char`},cssClasses:[],orientation:`vertical`,widget:t,textSink:null,props:{...s,value:{to:`refused`,why:c},defaultValue:{to:`refused`,why:c},onChangeText:{to:`refused`,why:c},placeholder:{to:`refused`,why:"`Gtk.TextView` installs no `placeholder-text` (measured); the Adwaita idiom is a label above the field"},maxLength:{to:`refused`,why:"`Gtk.TextView` installs no `max-length` (measured) — the limit belongs to the buffer"},secureTextEntry:{to:`refused`,why:"`Gtk.TextView` installs no `visibility` (measured), and a multiline password field is not a thing a desktop offers"},onSubmitEditing:{to:`refused`,why:`Return inserts a newline in a multiline field; there is nothing to submit`}}},u={cover:`cover`,contain:`contain`,stretch:`fill`,center:`scale-down`},d="is a load event, and `Gtk.Picture` emits NO signals at all (measured: its GType lists none) — it is handed a file or a paintable and draws it, reporting neither progress nor failure. A missing file leaves `paintable` null with no diagnostic, so a callback that never fires would hide exactly the case it exists to report. Load the bytes yourself and set `paintable` through a ref",f="is a per-pixel effect. GTK composites a `Gdk.Paintable` and has no filter property on the widget that draws it — the counterpart is a `Gsk` render node or a `Gtk.Snapshot` subclass, which is a widget of its own rather than a prop on this one",PRESSED_STYLE_IS_CSS=e=>`sets the pressed appearance, which on GTK is the CSS \`:active\` pseudo-class rather than a prop (ADR 0032 § 7). Write \`${e}\` — it resolves through the same variant mechanism as every other utility, reads the project's own token scale, and GTK animates it with no re-render at all`,p="tunes React Native’s own virtualisation, and `Gtk.ListView` does that job itself — it creates and recycles rows through the factory as the viewport moves (measured: 205 of 500 rows set up in a 400×300 window) and installs no property that changes the batching. There is nothing for this to set",m="is pull-to-refresh, which GTK has no idiom for and should not grow one — `RefreshControl` is `refused` in the support table for the same reason. Give the desktop build a refresh action in the header bar",h={...a,disabled:{to:`property`,names:[`sensitive`],as:`not`},onPressIn:{to:`refused`,why:"press state is the GTK CSS `:active` pseudo-class, not React state (ADR 0032 § 7) — write `active:opacity-70` and GTK animates it with no re-render at all"},onPressOut:{to:`refused`,why:"see `onPressIn` — `active:` is the mechanism"},onLongPress:{to:`refused`,why:"a long press is a `Gtk.GestureLongPress` controller added to the widget, not a property or a signal on it, so it is not something this layer can route as data"},delayLongPress:{to:`refused`,why:"see `onLongPress`"},delayPressIn:{to:`refused`,why:"see `onPressIn` — there is no press-in event to delay"},delayPressOut:{to:`refused`,why:"see `onPressIn`"},hitSlop:{to:`refused`,why:"GTK hit-tests the allocation and has no way to grow it past the widget. Pad the element (`p-*`), which enlarges the real target"},pressRetentionOffset:{to:`refused`,why:"see `hitSlop` — GTK hit-tests the allocation and nothing around it"},touchSoundDisabled:{to:`ignored`,why:`an Android touch sound; a desktop button makes none`}},g={View:{tag:`GtkBox`,widgetProps:{orientation:`vertical`},cssClasses:[],orientation:`vertical`,widget:e,textSink:null,overlayOnAbsoluteChild:{tag:`GtkOverlay`,slot:`overlay`},props:{...a,pointerEvents:o}},Text:{tag:`GtkLabel`,widgetProps:{wrap:!0},cssClasses:[],orientation:`vertical`,widget:n,textSink:`label`,props:{...a,numberOfLines:{to:`property`,names:[`lines`],as:`int`,also:{ellipsize:`end`,wrap:!0}},ellipsizeMode:{to:`property`,names:[`ellipsize`],as:`map`,map:{head:`start`,middle:`middle`,tail:`end`}},selectable:{to:`property`,names:[`selectable`],as:`boolean`},onPress:{to:`refused`,why:"a `Gtk.Label` emits no `clicked` (measured: `activate-current-link`, `activate-link`, `copy-clipboard`, `move-cursor` and nothing else). Wrap it in a `<Pressable>`, which is a real `Gtk.Button`"},allowFontScaling:{to:`ignored`,why:`text scaling is a desktop-wide GNOME setting, not a per-label opt-in`},maxFontSizeMultiplier:{to:`ignored`,why:"see `allowFontScaling`"},adjustsFontSizeToFit:{to:`refused`,why:"GTK has no shrink-to-fit text; a label ellipsizes or wraps. Use `numberOfLines` with `ellipsizeMode`"}}},Pressable:{tag:`GtkButton`,widgetProps:{},cssClasses:[`flat`],orientation:`vertical`,widget:t,textSink:`label`,props:{...a,pointerEvents:o,onPress:{to:`event`,signal:`clicked`},onPressIn:{to:`refused`,why:"press state is the GTK CSS `:active` pseudo-class, not React state (ADR 0032 § 7) — write `active:opacity-70` and GTK animates it with no re-render at all"},onPressOut:{to:`refused`,why:"see `onPressIn` — `active:` is the mechanism"},onLongPress:{to:`refused`,why:"a long press is a `Gtk.GestureLongPress` controller added to the widget, not a property or a signal on it, so it is not something this layer can route as data"},delayLongPress:{to:`refused`,why:"see `onLongPress`"},hitSlop:{to:`refused`,why:"GTK hit-tests the allocation and has no way to grow it past the widget. Pad the button (`p-*`), which enlarges the real target"},android_ripple:{to:`ignored`,why:`an Android-only ripple; Adwaita has its own press feedback`},disabled:{to:`property`,names:[`sensitive`],as:`not`}}},ScrollView:{tag:`GtkScrolledWindow`,widgetProps:{"hscrollbar-policy":`never`},cssClasses:[],orientation:`vertical`,widget:t,textSink:null,content:{tag:`GtkBox`,widgetProps:{orientation:`vertical`},orientation:`vertical`,widget:e,styleProp:`contentContainerStyle`,classNameProp:`contentContainerClassName`},props:{...a,horizontal:[{to:`property`,on:`content`,names:[`orientation`],as:`map`,map:{true:`horizontal`,false:`vertical`}},{to:`property`,on:`outer`,names:[`hscrollbar-policy`],as:`map`,map:{true:`automatic`,false:`never`}},{to:`property`,on:`outer`,names:[`vscrollbar-policy`],as:`map`,map:{true:`never`,false:`automatic`}}],showsVerticalScrollIndicator:{to:`property`,names:[`vscrollbar-policy`],as:`map`,map:{true:`automatic`,false:`external`}},showsHorizontalScrollIndicator:{to:`property`,names:[`hscrollbar-policy`],as:`map`,map:{true:`automatic`,false:`external`}},scrollEnabled:{to:`refused`,why:"a `Gtk.ScrolledWindow` has no switch that stops scrolling — setting both policies to `never` hides the bars AND clamps the child, which is a different thing. Render the content without the ScrollView when it must not scroll"},onScroll:{to:`refused`,why:"GTK reports scroll position through the `Gtk.Adjustment` objects behind `hadjustment`/`vadjustment` — `notify::value` on an adjustment, not a signal on the scrolled window — so there is no prop to route. Reach the adjustment through a ref"},scrollEventThrottle:{to:`refused`,why:"see `onScroll`"},refreshControl:{to:`refused`,why:"GTK has no pull-to-refresh idiom and `RefreshControl` is `refused` in the support table for that reason. Give the desktop build a refresh action"},keyboardShouldPersistTaps:{to:`ignored`,why:`there is no on-screen keyboard to dismiss`},keyboardDismissMode:{to:`ignored`,why:"see `keyboardShouldPersistTaps`"},contentContainerStyle:{to:`ignored`,why:`read directly as the content node’s style set`},contentContainerClassName:{to:`ignored`,why:`read directly as the content node’s class list`}}},ActivityIndicator:{tag:`AdwSpinner`,widgetProps:{},cssClasses:[],orientation:`vertical`,widget:t,textSink:null,props:{...a,animating:{to:`property`,names:[`visible`],as:`boolean`},hidesWhenStopped:{to:`ignored`,why:"a stopped `Adw.Spinner` is a hidden one here — there is no property that stops it while it is on screen (measured), so this is already the behaviour"},size:{to:`property`,names:[`width-request`,`height-request`],as:`pixels-or-map`,map:{small:16,large:32}},color:{to:`style-property`,name:`color`}}},TextInput:{tag:`GtkEntry`,widgetProps:{},cssClasses:[],orientation:`vertical`,widget:t,textSink:`text`,switchOn:{prop:`multiline`,whenTrue:l},props:{...s,value:{to:`property`,names:[`text`],as:`string`},defaultValue:{to:`property`,names:[`text`],as:`string`},placeholder:{to:`property`,names:[`placeholder-text`],as:`string`},maxLength:{to:`property`,names:[`max-length`],as:`int`},secureTextEntry:{to:`property`,names:[`visibility`],as:`not`},onChangeText:{to:`event`,signal:`notify::text`,read:`text`},onSubmitEditing:{to:`event`,signal:`activate`}}},Switch:{tag:`GtkSwitch`,widgetProps:{},cssClasses:[],orientation:`vertical`,widget:t,textSink:null,props:{...a,value:{to:`property`,names:[`active`],as:`boolean`},onValueChange:{to:`event`,signal:`notify::active`,read:`active`},disabled:{to:`property`,names:[`sensitive`],as:`not`},trackColor:{to:`refused`,why:"Adwaita paints the switch from the theme’s accent colour, and its track is a CSS `slider`/`trough` subnode rather than a property. Style it from the application stylesheet"},thumbColor:{to:`refused`,why:"see `trackColor`"},ios_backgroundColor:{to:`ignored`,why:`an iOS-only fallback colour`}}},Image:{tag:`GtkPicture`,widgetProps:{"content-fit":`cover`},cssClasses:[],orientation:`vertical`,widget:t,textSink:null,props:{...a,source:{to:`file`,property:`file`},resizeMode:{to:`property`,names:[`content-fit`],as:`map`,map:u},alt:{to:`property`,names:[`alternative-text`],as:`string`},onLoad:{to:`refused`,why:d},onLoadStart:{to:`refused`,why:d},onLoadEnd:{to:`refused`,why:d},onError:{to:`refused`,why:d},onProgress:{to:`refused`,why:d},blurRadius:{to:`refused`,why:f},tintColor:{to:`refused`,why:f},capInsets:{to:`refused`,why:"is iOS nine-part stretching. GTK’s counterpart is a CSS `border-image` on a widget’s background, which is a different widget and a different property set"},defaultSource:{to:`refused`,why:"is the placeholder shown while the real image loads, and `Gtk.Picture` has one file at a time with no load event to swap on (measured: it emits no signals). Render a placeholder widget beside it and remove it yourself"},loadingIndicatorSource:{to:`refused`,why:"see `defaultSource`"},progressiveRenderingEnabled:{to:`ignored`,why:`GTK decodes an image in one pass`},fadeDuration:{to:`ignored`,why:`an Android cross-fade on load; there is no load event here to fade from (measured)`},resizeMethod:{to:`ignored`,why:`an Android decoder hint`},resizeMultiplier:{to:`ignored`,why:`an Android decoder hint`}}},ImageBackground:{tag:`GtkOverlay`,widgetProps:{},cssClasses:[],orientation:`vertical`,widget:t,textSink:null,backdrop:{tag:`GtkPicture`,widgetProps:{"content-fit":`cover`},orientation:`vertical`,widget:t,styleProp:`imageStyle`,classNameProp:null,slot:`child`},content:{tag:`GtkBox`,widgetProps:{orientation:`vertical`},orientation:`vertical`,widget:e,styleProp:null,classNameProp:null,slot:`overlay`},props:{...a,pointerEvents:o,source:{to:`file`,on:`backdrop`,property:`file`},resizeMode:{to:`property`,on:`backdrop`,names:[`content-fit`],as:`map`,map:u},alt:{to:`property`,on:`backdrop`,names:[`alternative-text`],as:`string`},imageStyle:{to:`ignored`,why:`read directly as the picture node’s style set`},imageRef:{to:`refused`,why:"hands back the inner `Image`’s instance. This element’s `ref` is the `Gtk.Overlay`; the picture is its main child and `overlay.get_child()` reaches it, so a second ref would be a second way to say the same thing"}}},TouchableOpacity:{tag:`GtkButton`,cssClasses:[`flat`],widgetProps:{},orientation:`vertical`,widget:t,textSink:`label`,props:{...h,pointerEvents:o,onPress:{to:`event`,signal:`clicked`},activeOpacity:{to:`refused`,why:PRESSED_STYLE_IS_CSS(`active:opacity-70`)}}},TouchableHighlight:{tag:`GtkButton`,cssClasses:[`flat`],widgetProps:{},orientation:`vertical`,widget:t,textSink:`label`,props:{...h,pointerEvents:o,onPress:{to:`event`,signal:`clicked`},activeOpacity:{to:`refused`,why:PRESSED_STYLE_IS_CSS(`active:opacity-70`)},underlayColor:{to:`refused`,why:PRESSED_STYLE_IS_CSS(`active:bg-<token>`)},onShowUnderlay:{to:`refused`,why:"see `underlayColor` — there is no underlay to show"},onHideUnderlay:{to:`refused`,why:"see `underlayColor`"}}},TouchableWithoutFeedback:{tag:`GtkBox`,widgetProps:{orientation:`vertical`},cssClasses:[],orientation:`vertical`,widget:e,textSink:null,overlayOnAbsoluteChild:{tag:`GtkOverlay`,slot:`overlay`},props:{...h,pointerEvents:o,onPress:{to:`gesture`,signal:`released`},disabled:{to:`property`,names:[`can-target`],as:`not`}}},Button:{tag:`GtkButton`,widgetProps:{},cssClasses:[],orientation:`vertical`,widget:t,textSink:null,refusesStyle:"takes no `style` and no `className`. React Native’s own `Button` takes neither — its documented styling story is that you cannot, and you use `Pressable` when you need to — and GTK agrees: an Adwaita button is painted by the theme and by its own classes (`suggested-action`, `destructive-action`), which an application stylesheet sets. Use `<Pressable>`",props:{...a,title:{to:`property`,names:[`label`],as:`string`},onPress:{to:`event`,signal:`clicked`},disabled:{to:`property`,names:[`sensitive`],as:`not`},color:{to:`refused`,why:"is the button’s background on Android and its text colour on iOS — one prop, two meanings, and GTK has a third answer: `suggested-action` and `destructive-action` are Adwaita’s own classes for the two cases a colour is usually asking for. Set them from the application stylesheet, or use `<Pressable>`"},touchSoundDisabled:{to:`ignored`,why:`an Android touch sound; a desktop button makes none`},hasTVPreferredFocus:{to:`ignored`,why:`an Android TV focus hint`},nextFocusDown:{to:`ignored`,why:`an Android TV focus hint`},nextFocusForward:{to:`ignored`,why:`an Android TV focus hint`},nextFocusLeft:{to:`ignored`,why:`an Android TV focus hint`},nextFocusRight:{to:`ignored`,why:`an Android TV focus hint`},nextFocusUp:{to:`ignored`,why:`an Android TV focus hint`}}},SafeAreaView:{tag:`GtkBox`,widgetProps:{orientation:`vertical`},cssClasses:[],orientation:`vertical`,widget:e,textSink:null,overlayOnAbsoluteChild:{tag:`GtkOverlay`,slot:`overlay`},props:{...a,pointerEvents:o}},KeyboardAvoidingView:{tag:`GtkBox`,widgetProps:{orientation:`vertical`},cssClasses:[],orientation:`vertical`,widget:e,textSink:null,overlayOnAbsoluteChild:{tag:`GtkOverlay`,slot:`overlay`},props:{...a,pointerEvents:o,behavior:{to:`ignored`,why:`describes how to move out of an on-screen keyboard’s way, and none appears`},keyboardVerticalOffset:{to:`ignored`,why:"see `behavior`"},enabled:{to:`ignored`,why:"see `behavior` — the avoidance is already off"},contentContainerStyle:{to:`refused`,why:"styles the inner view React Native adds to do the avoiding, and there is no avoiding here — so there is no second node to style. Put it on `style`, which lands on the one box this element is"}}},FlatList:{tag:`GtkBox`,widgetProps:{orientation:`vertical`},cssClasses:[],orientation:`vertical`,widget:e,textSink:null,content:{tag:`GtkScrolledWindow`,widgetProps:{"hscrollbar-policy":`never`,vexpand:!0,hexpand:!0},orientation:`vertical`,widget:t,styleProp:null,classNameProp:null},props:{...a,horizontal:[{to:`property`,on:`outer`,names:[`orientation`],as:`map`,map:{true:`horizontal`,false:`vertical`}},{to:`property`,on:`content`,names:[`hscrollbar-policy`],as:`map`,map:{true:`automatic`,false:`never`}},{to:`property`,on:`content`,names:[`vscrollbar-policy`],as:`map`,map:{true:`never`,false:`automatic`}}],showsVerticalScrollIndicator:{to:`property`,on:`content`,names:[`vscrollbar-policy`],as:`map`,map:{true:`automatic`,false:`external`}},showsHorizontalScrollIndicator:{to:`property`,on:`content`,names:[`hscrollbar-policy`],as:`map`,map:{true:`automatic`,false:`external`}},data:{to:`ignored`,why:`read by the component, which drives the Gio.ListStore from it`},renderItem:{to:`ignored`,why:`read by the item factory`},keyExtractor:{to:`ignored`,why:`read by the component, to key the model rows`},getItem:{to:`ignored`,why:"read by the component — VirtualizedList’s accessor form of `data`"},getItemCount:{to:`ignored`,why:"see `getItem`"},sections:{to:`ignored`,why:"read by the component — SectionList’s form of `data`"},renderSectionHeader:{to:`ignored`,why:`read by the item factory`},ListEmptyComponent:{to:`ignored`,why:`rendered by the component instead of the scroller`},ListHeaderComponent:{to:`ignored`,why:`rendered by the component, before the scroller`},ListFooterComponent:{to:`ignored`,why:`rendered by the component, after the scroller`},onEndReached:{to:`ignored`,why:`bound by the component to the scroller’s own Gtk.Adjustment`},onEndReachedThreshold:{to:`ignored`,why:"see `onEndReached`"},extraData:{to:`ignored`,why:`read by the component; a change re-renders every bound row`},onRowError:{to:`ignored`,why:`read by the component, and handed to each row’s own React root`},initialNumToRender:{to:`refused`,why:p},maxToRenderPerBatch:{to:`refused`,why:p},updateCellsBatchingPeriod:{to:`refused`,why:p},windowSize:{to:`refused`,why:p},removeClippedSubviews:{to:`refused`,why:p},getItemLayout:{to:`refused`,why:p},initialScrollIndex:{to:`refused`,why:"scrolls to a row before the first paint. `Gtk.ListView.scroll_to(position, flags, scroll_info)` is the counterpart and it is an imperative call on a realised view, not a property — reach the view through a ref and call it"},onViewableItemsChanged:{to:`refused`,why:"reports which rows are on screen. `Gtk.ListView` binds and unbinds rows itself and exposes no viewport range — the closest fact is `Gtk.ListItem:position` inside the factory, which is per row rather than a set, so a faithful answer would be a guess assembled from bind order"},viewabilityConfig:{to:`refused`,why:"see `onViewableItemsChanged`"},viewabilityConfigCallbackPairs:{to:`refused`,why:"see `onViewableItemsChanged`"},onScroll:{to:`refused`,why:"GTK reports scroll position through the `Gtk.Adjustment` objects behind the scroller’s `hadjustment`/`vadjustment` — `notify::value` on an adjustment, not a signal on the widget. `onEndReached` is the one question this layer answers from it; reach the adjustment through a ref for the rest"},scrollEventThrottle:{to:`refused`,why:"see `onScroll`"},numColumns:{to:`refused`,why:"lays the rows out in a grid, and a `Gtk.ListView` is one column of rows by construction. `Gtk.GridView` is the widget that does this and it is a different tag with a different model contract, so it is a primitive of its own rather than a prop on this one"},columnWrapperStyle:{to:`refused`,why:"see `numColumns`"},inverted:{to:`refused`,why:"draws the list bottom-up. GTK has no reversed list view; the honest equivalent is to reverse `data` yourself, which is one line and visible in the code"},refreshing:{to:`refused`,why:m},onRefresh:{to:`refused`,why:m},refreshControl:{to:`refused`,why:m},ItemSeparatorComponent:{to:`refused`,why:"puts a widget BETWEEN rows, and a `Gtk.ListView` has no between — it has rows. `Gtk.ListView:show-separators` draws the Adwaita separator itself; set it through a ref, or give the row its own bottom border with `border-b`"},stickySectionHeadersEnabled:{to:`refused`,why:"GTK’s own sticky headers are a `Gtk.ListView:header-factory` over a model that implements `Gtk.SectionModel` (MEASURED: `Gio.ListStore` does not, every selection model and `Gtk.FlattenListModel` do). This layer flattens the sections into one model with header ROWS instead, so a header scrolls with its section — which is what `stickySectionHeadersEnabled={false}` asks for and the only thing it can deliver"},keyboardShouldPersistTaps:{to:`ignored`,why:`there is no on-screen keyboard to dismiss`},keyboardDismissMode:{to:`ignored`,why:"see `keyboardShouldPersistTaps`"},contentContainerStyle:{to:`refused`,why:"styles the box React Native puts the rows in, and there is no such box: `Gtk.ListView` builds each row from the factory and owns the space between them. Style the row inside `renderItem`, or the list itself through `style`"}}}},_=Object.keys(g),v=new Set([`children`,`key`,`ref`,`className`,`style`]);export{v as FRAMEWORK_PROPS,g as PRIMITIVES,_ as PRIMITIVE_NAMES};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";var RouterError=class extends Error{constructor(e,t,n){super(`@gjsify/react-native/router: ${t===``?``:`${t} — `}${n} [${e}]`),this.name=`RouterError`,this.code=e,this.subject=t}};export{RouterError};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ROUTER_NAMES as e,ROUTER_SUPPORT_TABLE as t,explainUnsupported as n,isImportable as r}from"../support-table.js";import{Drawer as i,ErrorBoundary as a,ExpoRoot as o,Link as s,Navigator as c,Redirect as l,Slot as u,SplashScreen as d,useFocusEffect as f,useGlobalSearchParams as p,useNavigation as m,useNavigationContainerRef as h,useRootNavigationState as g,useRouter as _,useSegments as v,useUnstableGlobalHref as y,withLayoutContext as b}from"../generated/unsupported-router-exports.js";import{RouterError as x}from"./errors.js";import{buildRouteTree as S,pathConfigOf as C,screenUrls as w}from"./routes.js";import{navigationRef as T,router as E,useLocalSearchParams as D,usePathname as O}from"./navigation.js";import{componentFor as k,provideRouteNode as A,screenOptionsFrom as j,useRouteNode as M,useSynthesisedScreens as N}from"./screens.js";import{Stack as P}from"./stack.js";import{Tabs as F}from"./tabs.js";import{RouterRoot as I}from"./root.js";export{i as Drawer,a as ErrorBoundary,o as ExpoRoot,s as Link,c as Navigator,e as ROUTER_NAMES,t as ROUTER_SUPPORT_TABLE,l as Redirect,x as RouterError,I as RouterRoot,u as Slot,d as SplashScreen,P as Stack,F as Tabs,S as buildRouteTree,k as componentFor,n as explainUnsupported,r as isImportable,T as navigationRef,C as pathConfigOf,A as provideRouteNode,E as router,j as screenOptionsFrom,w as screenUrls,f as useFocusEffect,p as useGlobalSearchParams,D as useLocalSearchParams,m as useNavigation,h as useNavigationContainerRef,O as usePathname,g as useRootNavigationState,M as useRouteNode,_ as useRouter,v as useSegments,N as useSynthesisedScreens,y as useUnstableGlobalHref,b as withLayoutContext};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import{RouterError as e}from"./errors.js";import{pathConfigOf as t,screenUrls as n}from"./routes.js";import{useSyncExternalStore as r}from"react";import{CommonActions as i,StackActions as a,createNavigationContainerRef as o,getActionFromState as s,getPathFromState as c,getStateFromPath as l,useRoute as u}from"@react-navigation/core";const d=o(),upstream=e=>e;let f=null;const p=new Set,liveRootState=()=>d.isReady()?d.getRootState():void 0;function installRouter(n){if(f!==null)throw new e(`no-router-mounted`,`RouterRoot`,"is already mounted. `router` is a module-level object — the shape of the name being reproduced — so one process routes one tree. Render one RouterRoot and nest navigators inside it");f={tree:n,config:t(n)}}function uninstallRouter(){f=null,notifyStateChanged()}function notifyStateChanged(){for(let e of p)e()}function required(t){if(f===null)throw new e(`no-router-mounted`,`router.${t}()`,`was called with no router mounted. Render <RouterRoot manifest={…}> above the tree that calls it — the manifest is the bundler plugin’s virtual module`);return f}function readyContainer(t){if(required(t),!d.isReady())throw new e(`no-router-mounted`,`router.${t}()`,`was called before the navigation container was ready. A container becomes ready during the first commit, so this is a call from a module body or from a render — move it into an effect or an event handler`);return d}function resolve(t,r){let{tree:i,config:a}=required(t),o=l(r,upstream(a));if(o===void 0)throw new e(`unresolved-href`,r,`matches no route. The manifest holds: ${n(i).join(`, `)}. A \`+not-found.tsx\` catches everything else`);return o}function focusChain(e){let t=[],n=e;for(;n!==void 0;){let e=n.index??n.routes.length-1,r=n.routes[e];if(r===void 0)break;t.push({name:r.name,...r.params===void 0?{}:{params:r.params}}),n=r.state}return t}function targetFor(e){let t=liveRootState();for(let[n,r]of e.entries()){if(t===void 0)return null;if(n===e.length-1)return t.routeNames.includes(r.name)?{key:t.key,type:t.type}:null;let i=t.routes.find(e=>e.name===r.name);if(i===void 0)return null;t=i.state}return null}function pushOrReplace(e,t){let n=readyContainer(e),{config:r}=required(e),o=resolve(e,t),c=focusChain(o),l=c[c.length-1],u=targetFor(c);if(l!==void 0&&u!==null&&u.type===`stack`){let t=e===`push`?a.push(l.name,l.params):a.replace(l.name,l.params);n.dispatch({...t,target:u.key});return}let d=s(o,upstream(r));n.dispatch(d??i.reset(o))}const m={push(e){pushOrReplace(`push`,e)},navigate(e){let t=readyContainer(`navigate`),{config:n}=required(`navigate`),r=resolve(`navigate`,e),a=s(r,upstream(n));t.dispatch(a??i.reset(r))},replace(e){pushOrReplace(`replace`,e)},back(){let t=readyContainer(`back`);if(!t.canGoBack())throw new e(`unresolved-href`,`router.back()`,`has nothing to go back to — this is the first screen in the history. Guard the call, or use router.replace() to leave a screen that cannot be popped`);t.dispatch(i.goBack())}},subscribe=e=>(p.add(e),()=>{p.delete(e)}),h=new Set([`screen`,`params`,`initial`,`state`,`path`,`pop`,`merge`]),currentPathname=()=>{let e=liveRootState();if(f===null||e===void 0)return`/`;let t=c(e,upstream(f.config)),n=t.indexOf(`?`);return n===-1?t:t.slice(0,n)};function usePathname(){return r(subscribe,currentPathname,currentPathname)}function useLocalSearchParams(){let e=u().params??{},t={};for(let[n,r]of Object.entries(e))h.has(n)||(typeof r==`string`?t[n]=r:(typeof r==`number`||typeof r==`boolean`)&&(t[n]=String(r)));return t}export{installRouter,d as navigationRef,notifyStateChanged,m as router,uninstallRouter,useLocalSearchParams,usePathname};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import{RouterError as e}from"./errors.js";import{buildRouteTree as t}from"./routes.js";import{installRouter as n,navigationRef as r,notifyStateChanged as i,uninstallRouter as a}from"./navigation.js";import{componentFor as o}from"./screens.js";import{createElement as s,useCallback as c,useLayoutEffect as l,useMemo as u}from"react";import{BaseNavigationContainer as d}from"@react-navigation/core";function RouterRoot(f){let p=u(()=>t(f.manifest),[f.manifest]);if(p.contextKey===null)throw new e(`bad-manifest`,`the routes directory`,"has no `_layout` file, so nothing says what the top-level navigator is. Add `_layout.tsx` beside your routes, default-exporting a component that renders <Stack/> or <Tabs/>");return l(()=>(n(p),a),[p]),s(d,{ref:r,onStateChange:c(()=>{i()},[]),onReady:c(()=>{i()},[]),children:s(o(p))})}export{RouterRoot};
|