@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
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { type ReactElement, type ReactNode, type Ref } from 'react';
|
|
2
2
|
import type { ClassNameInput } from './primitives/classes.js';
|
|
3
|
+
import { type ChildContext, type PrimitivePlan, type WidgetNode } from './primitives/resolve.js';
|
|
3
4
|
import type { StyleInput } from './primitives/style.js';
|
|
5
|
+
import type { StyleTokens } from '@gjsify/gtk-host/style';
|
|
4
6
|
/** What every primitive accepts on top of its own props. */
|
|
5
7
|
export interface CommonProps {
|
|
6
8
|
className?: ClassNameInput;
|
|
@@ -10,6 +12,36 @@ export interface CommonProps {
|
|
|
10
12
|
ref?: Ref<unknown>;
|
|
11
13
|
testID?: string;
|
|
12
14
|
}
|
|
15
|
+
type AnyProps = Readonly<Record<string, unknown>>;
|
|
16
|
+
/** One plan node → its host props, in the order that makes precedence explicit. */
|
|
17
|
+
export declare function nodeProps(node: WidgetNode, inherited: AnyProps, extra: AnyProps): AnyProps;
|
|
18
|
+
export interface Rendered {
|
|
19
|
+
readonly plan: PrimitivePlan;
|
|
20
|
+
readonly children: readonly ReactNode[];
|
|
21
|
+
readonly inherited: AnyProps;
|
|
22
|
+
readonly extra: AnyProps;
|
|
23
|
+
/** `Gio.File` values and the slot, for the content node. */
|
|
24
|
+
readonly contentExtra: AnyProps;
|
|
25
|
+
/** `Gio.File` values and the slot, for the backdrop node. */
|
|
26
|
+
readonly backdropExtra: AnyProps;
|
|
27
|
+
readonly published: ChildContext;
|
|
28
|
+
readonly tokens: StyleTokens;
|
|
29
|
+
/** The element's own `Gtk.Widget`, once it is attached. The press and gesture seams need it. */
|
|
30
|
+
readonly widgetRef: {
|
|
31
|
+
current: unknown;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The shared body of all seven components.
|
|
36
|
+
*
|
|
37
|
+
* `props` is `object` and cast ONCE here, rather than each component's own props
|
|
38
|
+
* interface. An interface without an index signature is not assignable to
|
|
39
|
+
* `Record<string, unknown>` (TS2345), and widening every one of the seven with
|
|
40
|
+
* `[key: string]: unknown` would make a MISSPELLED prop type-check — which is
|
|
41
|
+
* exactly the refusal L2's unknown-prop throw exists to give at build time through
|
|
42
|
+
* these declarations.
|
|
43
|
+
*/
|
|
44
|
+
export declare function usePlan(primitive: string, authored: object): Rendered;
|
|
13
45
|
export interface ViewProps extends CommonProps {
|
|
14
46
|
/** `auto` and `none` only — GTK's `can-target` covers the widget AND its subtree. */
|
|
15
47
|
pointerEvents?: 'auto' | 'none';
|
|
@@ -21,22 +53,27 @@ export interface TextProps extends CommonProps {
|
|
|
21
53
|
selectable?: boolean;
|
|
22
54
|
}
|
|
23
55
|
export declare function Text(props: TextProps): ReactElement;
|
|
24
|
-
|
|
56
|
+
/** What React Native hands a `Pressable`'s function child. */
|
|
57
|
+
export interface PressableState {
|
|
58
|
+
readonly pressed: boolean;
|
|
59
|
+
}
|
|
60
|
+
export interface PressableProps extends Omit<CommonProps, 'children'> {
|
|
25
61
|
onPress?: () => void;
|
|
26
62
|
disabled?: boolean;
|
|
27
63
|
pointerEvents?: 'auto' | 'none';
|
|
28
64
|
/**
|
|
29
|
-
*
|
|
65
|
+
* A node, or a function of `{ pressed }`.
|
|
30
66
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* the
|
|
36
|
-
*
|
|
37
|
-
*
|
|
67
|
+
* THE FUNCTION FORM IS THE EXPENSIVE ONE AND IT IS NOT THE DEFAULT PATH. ADR 0032
|
|
68
|
+
* § 7: press styling is the GTK CSS `:active` pseudo-class, `active:opacity-70`
|
|
69
|
+
* costs nothing, and GTK animates the state itself with no re-render — measured in
|
|
70
|
+
* the application ADR 0032 read, the function form occurs ZERO times. So the
|
|
71
|
+
* function form is implemented for the code that does use it, and an element that
|
|
72
|
+
* does not use it subscribes to nothing at all: `press.ts`' `pressWatchCount()`
|
|
73
|
+
* exists so a spec can hold that apart, because both render and only a count tells
|
|
74
|
+
* them apart.
|
|
38
75
|
*/
|
|
39
|
-
children?: ReactNode;
|
|
76
|
+
children?: ReactNode | ((state: PressableState) => ReactNode);
|
|
40
77
|
}
|
|
41
78
|
export declare function Pressable(props: PressableProps): ReactElement;
|
|
42
79
|
export interface ScrollViewProps extends CommonProps {
|
|
@@ -75,3 +112,122 @@ export interface SwitchProps extends CommonProps {
|
|
|
75
112
|
disabled?: boolean;
|
|
76
113
|
}
|
|
77
114
|
export declare function Switch(props: SwitchProps): ReactElement;
|
|
115
|
+
/** React Native's `ImageSourcePropType`, as much of it as GTK can open. */
|
|
116
|
+
export interface ImageURISource {
|
|
117
|
+
/** A local path, a `file:` URI or a `resource:` URI. Anything else is refused by name. */
|
|
118
|
+
uri: string;
|
|
119
|
+
}
|
|
120
|
+
export interface ImageProps extends Omit<CommonProps, 'children'> {
|
|
121
|
+
source?: ImageURISource;
|
|
122
|
+
/** `repeat` is absent on purpose: `Gtk.ContentFit` has no tiling member (measured). */
|
|
123
|
+
resizeMode?: 'cover' | 'contain' | 'stretch' | 'center';
|
|
124
|
+
/** React Native 0.71's own name for the accessible description — `Gtk.Picture:alternative-text`. */
|
|
125
|
+
alt?: string;
|
|
126
|
+
}
|
|
127
|
+
export declare function Image(props: ImageProps): ReactElement;
|
|
128
|
+
export interface ImageBackgroundProps extends CommonProps {
|
|
129
|
+
source?: ImageURISource;
|
|
130
|
+
resizeMode?: 'cover' | 'contain' | 'stretch' | 'center';
|
|
131
|
+
alt?: string;
|
|
132
|
+
/** Styles the picture behind the children, not the container. React Native's own name. */
|
|
133
|
+
imageStyle?: StyleInput;
|
|
134
|
+
pointerEvents?: 'auto' | 'none';
|
|
135
|
+
}
|
|
136
|
+
export declare function ImageBackground(props: ImageBackgroundProps): ReactElement;
|
|
137
|
+
/**
|
|
138
|
+
* The Touchable family, written OVER `Pressable` rather than beside it.
|
|
139
|
+
*
|
|
140
|
+
* ADR 0032's planning entries say "the same machinery as Pressable, and nearly free
|
|
141
|
+
* once it exists", and this is what that costs when it is true: the three components
|
|
142
|
+
* are one line each over the same `usePlan`/`render` pair, and the only thing that
|
|
143
|
+
* differs is the row L2 looks up — `TouchableOpacity` and `TouchableHighlight` spread
|
|
144
|
+
* `Pressable`'s own routes out of one shared record, and `TouchableWithoutFeedback` is
|
|
145
|
+
* a `Gtk.Box` with a gesture controller because it has no chrome to press.
|
|
146
|
+
*
|
|
147
|
+
* `activeOpacity` and `underlayColor` are refusals rather than mappings, and the
|
|
148
|
+
* reason is ADR 0032 § 3 rather than ADR 0032 § 7: honouring them would put an opacity
|
|
149
|
+
* and a colour into the styling path that did not come from the project's token scale.
|
|
150
|
+
* `active:opacity-70` and `active:bg-<token>` do the same thing through the mechanism
|
|
151
|
+
* that reads it.
|
|
152
|
+
*/
|
|
153
|
+
export interface TouchableProps extends PressableProps {
|
|
154
|
+
/** Refused by name — write `active:opacity-70`. Declared so the type says so too. */
|
|
155
|
+
activeOpacity?: never;
|
|
156
|
+
}
|
|
157
|
+
export declare function TouchableOpacity(props: TouchableProps): ReactElement;
|
|
158
|
+
export interface TouchableHighlightProps extends TouchableProps {
|
|
159
|
+
/** Refused by name — write `active:bg-<token>`. */
|
|
160
|
+
underlayColor?: never;
|
|
161
|
+
}
|
|
162
|
+
export declare function TouchableHighlight(props: TouchableHighlightProps): ReactElement;
|
|
163
|
+
export interface TouchableWithoutFeedbackProps extends Omit<TouchableProps, 'children'> {
|
|
164
|
+
children?: ReactNode;
|
|
165
|
+
}
|
|
166
|
+
export declare function TouchableWithoutFeedback(props: TouchableWithoutFeedbackProps): ReactElement;
|
|
167
|
+
/**
|
|
168
|
+
* The one component whose styling story is "you cannot", in both vocabularies.
|
|
169
|
+
*
|
|
170
|
+
* `ButtonProps` does NOT extend `CommonProps`, which is the build-time half of the
|
|
171
|
+
* refusal: `<Button style={…}>` is a type error naming the property. The runtime half
|
|
172
|
+
* is L2's `refusesStyle`, checked before any prop is routed, so a JavaScript caller and
|
|
173
|
+
* the second L3 get the same sentence.
|
|
174
|
+
*/
|
|
175
|
+
export interface ButtonProps {
|
|
176
|
+
title: string;
|
|
177
|
+
onPress?: () => void;
|
|
178
|
+
disabled?: boolean;
|
|
179
|
+
testID?: string;
|
|
180
|
+
ref?: Ref<unknown>;
|
|
181
|
+
}
|
|
182
|
+
export declare function Button(props: ButtonProps): ReactElement;
|
|
183
|
+
/**
|
|
184
|
+
* A no-op that still lays out — which is what keeps it a no-op rather than a bug.
|
|
185
|
+
*
|
|
186
|
+
* The insets a `SafeAreaView` exists to apply are zero on a desktop window, so the
|
|
187
|
+
* INSET is what disappears. Everything else about it is a `View`: a vertical box, its
|
|
188
|
+
* children in a column, the same overlay switch when one of them is absolutely
|
|
189
|
+
* positioned, the same style vocabulary. A component that rendered nothing, or that
|
|
190
|
+
* rendered a `Gtk.Box` with the children dropped, would be a layout that silently
|
|
191
|
+
* lost a screen.
|
|
192
|
+
*/
|
|
193
|
+
export declare function SafeAreaView(props: ViewProps): ReactElement;
|
|
194
|
+
export interface KeyboardAvoidingViewProps extends ViewProps {
|
|
195
|
+
/** A declared no-op: there is no on-screen keyboard to move out of the way of. */
|
|
196
|
+
behavior?: 'height' | 'position' | 'padding';
|
|
197
|
+
keyboardVerticalOffset?: number;
|
|
198
|
+
enabled?: boolean;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* The same no-op, and the same reason it still lays out.
|
|
202
|
+
*
|
|
203
|
+
* React Native's `KeyboardAvoidingView` IS a `View` that changes its own height,
|
|
204
|
+
* padding or position while a keyboard is up. No keyboard comes up here, so what is
|
|
205
|
+
* left is the `View` — and `behavior`, `keyboardVerticalOffset` and `enabled` are
|
|
206
|
+
* declared no-ops in the table rather than refusals, because they describe the
|
|
207
|
+
* behaviour that is already off.
|
|
208
|
+
*/
|
|
209
|
+
export declare function KeyboardAvoidingView(props: KeyboardAvoidingViewProps): ReactElement;
|
|
210
|
+
export interface StatusBarProps {
|
|
211
|
+
barStyle?: 'default' | 'light-content' | 'dark-content';
|
|
212
|
+
hidden?: boolean;
|
|
213
|
+
backgroundColor?: string;
|
|
214
|
+
translucent?: boolean;
|
|
215
|
+
animated?: boolean;
|
|
216
|
+
networkActivityIndicatorVisible?: boolean;
|
|
217
|
+
showHideTransition?: 'fade' | 'slide' | 'none';
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Renders NOTHING, and that is the whole of it — there is no status bar.
|
|
221
|
+
*
|
|
222
|
+
* The one component in this file with no widget. `<StatusBar barStyle="light-content"/>`
|
|
223
|
+
* is in the first ten lines of most React Native screens, so it has to render; a
|
|
224
|
+
* desktop window has no bar above it to configure, so it must not render a box that
|
|
225
|
+
* takes space in the column. `null` is both.
|
|
226
|
+
*
|
|
227
|
+
* Its props are ACCEPTED rather than refused, which is the one place this component
|
|
228
|
+
* differs from `Keyboard`: they are declarative appearance hints with nothing to apply
|
|
229
|
+
* them to, like `hidesWhenStopped` on the spinner. Its imperative statics are a
|
|
230
|
+
* different question and refuse by name — see `StatusBarStatics`.
|
|
231
|
+
*/
|
|
232
|
+
export declare function StatusBar(_props: StatusBarProps): null;
|
|
233
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const OWN_EXPORT_NAMES: readonly string[];
|
|
@@ -1,23 +1,4 @@
|
|
|
1
1
|
export declare const Modal: never;
|
|
2
|
-
export declare const StyleSheet: never;
|
|
3
|
-
export declare const FlatList: never;
|
|
4
|
-
export declare const SectionList: never;
|
|
5
|
-
export declare const VirtualizedList: never;
|
|
6
|
-
export declare const VirtualizedSectionList: never;
|
|
7
|
-
export declare const Image: never;
|
|
8
|
-
export declare const ImageBackground: never;
|
|
9
|
-
export declare const TouchableOpacity: never;
|
|
10
|
-
export declare const TouchableHighlight: never;
|
|
11
|
-
export declare const TouchableWithoutFeedback: never;
|
|
12
|
-
export declare const Button: never;
|
|
13
|
-
export declare const Dimensions: never;
|
|
14
|
-
export declare const useWindowDimensions: never;
|
|
15
|
-
export declare const Alert: never;
|
|
16
|
-
export declare const Appearance: never;
|
|
17
|
-
export declare const SafeAreaView: never;
|
|
18
|
-
export declare const StatusBar: never;
|
|
19
|
-
export declare const KeyboardAvoidingView: never;
|
|
20
|
-
export declare const Keyboard: never;
|
|
21
2
|
export declare const RefreshControl: never;
|
|
22
3
|
export declare const AppState: never;
|
|
23
4
|
export declare const PixelRatio: never;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare const Link: never;
|
|
2
|
+
export declare const Redirect: never;
|
|
3
|
+
export declare const Slot: never;
|
|
4
|
+
export declare const useRouter: never;
|
|
5
|
+
export declare const useSegments: never;
|
|
6
|
+
export declare const useGlobalSearchParams: never;
|
|
7
|
+
export declare const useNavigation: never;
|
|
8
|
+
export declare const useFocusEffect: never;
|
|
9
|
+
export declare const useRootNavigationState: never;
|
|
10
|
+
export declare const Drawer: never;
|
|
11
|
+
export declare const withLayoutContext: never;
|
|
12
|
+
export declare const Navigator: never;
|
|
13
|
+
export declare const ErrorBoundary: never;
|
|
14
|
+
export declare const ExpoRoot: never;
|
|
15
|
+
export declare const useUnstableGlobalHref: never;
|
|
16
|
+
export declare const useNavigationContainerRef: never;
|
|
17
|
+
export declare const SplashScreen: never;
|
package/lib/types/hooks.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type ColorSchemeName } from './apis/color-scheme.js';
|
|
2
|
+
import { type DisplayMetrics } from './apis/display.js';
|
|
2
3
|
/**
|
|
3
4
|
* The desktop's current colour scheme, re-rendering when it changes.
|
|
4
5
|
*
|
|
@@ -11,3 +12,18 @@ import { type ColorSchemeName } from './apis/color-scheme.js';
|
|
|
11
12
|
* environment that has none.
|
|
12
13
|
*/
|
|
13
14
|
export declare function useColorScheme(): ColorSchemeName;
|
|
15
|
+
/**
|
|
16
|
+
* The application window's size, re-rendering when it changes.
|
|
17
|
+
*
|
|
18
|
+
* The WINDOW and not the screen: a desktop application is not full-screen, so the
|
|
19
|
+
* screen's number would be wrong in the ordinary case rather than the rare one (ADR
|
|
20
|
+
* 0032's own planning entry). `apis/display.ts` holds the measurements — including the
|
|
21
|
+
* one that makes this hook's mechanism look odd: the notification comes from the
|
|
22
|
+
* `Gdk.Surface` and the VALUE comes from the window, because `Gtk.Widget` installs no
|
|
23
|
+
* size property and emits no size-allocate signal.
|
|
24
|
+
*
|
|
25
|
+
* The snapshot is cached by value (`windowMetricsSnapshot`), because
|
|
26
|
+
* `useSyncExternalStore` compares snapshots by identity and a fresh record per call is
|
|
27
|
+
* React's own "getSnapshot should be cached" loop.
|
|
28
|
+
*/
|
|
29
|
+
export declare function useWindowDimensions(): DisplayMetrics;
|
package/lib/types/index.d.ts
CHANGED
|
@@ -2,11 +2,15 @@ export { AppRegistry, registerRootComponent } from './app-registry.js';
|
|
|
2
2
|
export type { ComponentProvider, RunApplicationOptions } from './app-registry.js';
|
|
3
3
|
export { EventEmitter } from './event-emitter.js';
|
|
4
4
|
export type { EventSubscription } from './event-emitter.js';
|
|
5
|
-
export { ActivityIndicator, Pressable, ScrollView, Switch, Text, TextInput, View } from './components.js';
|
|
6
|
-
export type { ActivityIndicatorProps, CommonProps, PressableProps, ScrollViewProps, SwitchProps, TextInputProps, TextProps, ViewProps, } from './components.js';
|
|
7
|
-
export {
|
|
8
|
-
export type {
|
|
9
|
-
export {
|
|
5
|
+
export { ActivityIndicator, Button, Image, ImageBackground, KeyboardAvoidingView, Pressable, SafeAreaView, ScrollView, StatusBar, Switch, Text, TextInput, TouchableHighlight, TouchableOpacity, TouchableWithoutFeedback, View, } from './components.js';
|
|
6
|
+
export type { ActivityIndicatorProps, ButtonProps, CommonProps, ImageBackgroundProps, ImageProps, ImageURISource, KeyboardAvoidingViewProps, PressableProps, PressableState, ScrollViewProps, StatusBarProps, SwitchProps, TextInputProps, TextProps, TouchableHighlightProps, TouchableProps, TouchableWithoutFeedbackProps, ViewProps, } from './components.js';
|
|
7
|
+
export { FlatList, SectionList, VirtualizedList, VirtualizedSectionList } from './lists/components.js';
|
|
8
|
+
export type { FlatListProps, ListRenderItemInfo, ListSeparators, ListSlot, SectionListProps, SectionListSection, VirtualizedListProps, } from './lists/components.js';
|
|
9
|
+
export { Alert, Appearance, Dimensions, Keyboard, Linking, Platform, Share } from './apis/index.js';
|
|
10
|
+
export type { AlertButton, AlertOptions, AppearancePreferences, ColorSchemeName, DimensionKey, DimensionsPayload, DisplayMetrics, PlatformOS, PlatformSelectSpec, ShareAction, ShareContent, } from './apis/index.js';
|
|
11
|
+
export { useColorScheme, useWindowDimensions } from './hooks.js';
|
|
12
|
+
export { StyleSheet } from './stylesheet.js';
|
|
13
|
+
export type { NamedStyles } from './stylesheet.js';
|
|
10
14
|
export { configureStyle, resetStyleConfig, styleConfig } from './style-config.js';
|
|
11
15
|
export type { StyleConfig } from './style-config.js';
|
|
12
16
|
export * as primitives from './primitives/index.js';
|
|
@@ -18,5 +22,5 @@ export { PrimitiveError } from './primitives/errors.js';
|
|
|
18
22
|
*/
|
|
19
23
|
export declare function unstable_batchedUpdates<T, R>(callback: (argument: T) => R, argument: T): R;
|
|
20
24
|
export * from './generated/unsupported-exports.js';
|
|
21
|
-
export { SUPPORT_TABLE, SUPPORTED_NAMES, explainUnsupported, isImportable, type SupportEntry, type SupportStatus, type SupportTier, } from './support-table.js';
|
|
25
|
+
export { OWN_EXPORT_NAMES, SUPPORT_TABLE, SUPPORTED_NAMES, explainUnsupported, isImportable, isOwnExport, type SupportEntry, type SupportStatus, type SupportTier, } from './support-table.js';
|
|
22
26
|
export { UnsupportedError } from './unsupported.js';
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { type ComponentType, type ReactElement, type ReactNode } from 'react';
|
|
2
|
+
import { type CommonProps } from '../components.js';
|
|
3
|
+
/** What React Native's `renderItem` receives. */
|
|
4
|
+
export interface ListRenderItemInfo<T> {
|
|
5
|
+
readonly item: T;
|
|
6
|
+
readonly index: number;
|
|
7
|
+
readonly separators: ListSeparators;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* React Native's `separators`, refusing all three of its methods by name.
|
|
11
|
+
*
|
|
12
|
+
* They ask the list to restyle the separator above and below a row — and a
|
|
13
|
+
* `Gtk.ListView` has no separator widget to restyle: `show-separators` makes GTK draw
|
|
14
|
+
* the Adwaita line itself, between rows it owns. `ItemSeparatorComponent` is refused in
|
|
15
|
+
* the table for the same reason, so this is that refusal reaching the one other place
|
|
16
|
+
* it can be asked for.
|
|
17
|
+
*/
|
|
18
|
+
export interface ListSeparators {
|
|
19
|
+
highlight(): void;
|
|
20
|
+
unhighlight(): void;
|
|
21
|
+
updateProps(select: 'leading' | 'trailing', newProps: object): void;
|
|
22
|
+
}
|
|
23
|
+
/** A header/footer/empty slot: an element, or a component to render. */
|
|
24
|
+
export type ListSlot = ReactNode | ComponentType<Record<string, never>>;
|
|
25
|
+
/** The props every list in this file answers for. Each name is in L2's row. */
|
|
26
|
+
export interface ListFrameProps extends Omit<CommonProps, 'children'> {
|
|
27
|
+
/**
|
|
28
|
+
* Where a ROW's own render error goes. Not a React Native prop, and it earns its
|
|
29
|
+
* place: a row is a React root of its own, so an error inside `renderItem` has no
|
|
30
|
+
* ancestor boundary in the outer tree to reach. Absent means the host's default —
|
|
31
|
+
* logged and rethrown, which is loud.
|
|
32
|
+
*/
|
|
33
|
+
onRowError?: (error: Error) => void;
|
|
34
|
+
horizontal?: boolean;
|
|
35
|
+
showsVerticalScrollIndicator?: boolean;
|
|
36
|
+
showsHorizontalScrollIndicator?: boolean;
|
|
37
|
+
ListEmptyComponent?: ListSlot;
|
|
38
|
+
ListHeaderComponent?: ListSlot;
|
|
39
|
+
ListFooterComponent?: ListSlot;
|
|
40
|
+
onEndReached?: (info: {
|
|
41
|
+
distanceFromEnd: number;
|
|
42
|
+
}) => void;
|
|
43
|
+
/** Page-lengths from the end at which `onEndReached` fires. React Native's default is 0.5. */
|
|
44
|
+
onEndReachedThreshold?: number;
|
|
45
|
+
/** A change re-renders every bound row, for the rows whose keys did not change. */
|
|
46
|
+
extraData?: unknown;
|
|
47
|
+
}
|
|
48
|
+
export interface FlatListProps<T> extends ListFrameProps {
|
|
49
|
+
data?: readonly T[] | null;
|
|
50
|
+
renderItem?: (info: ListRenderItemInfo<T>) => ReactNode;
|
|
51
|
+
keyExtractor?: (item: T, index: number) => string;
|
|
52
|
+
}
|
|
53
|
+
export interface VirtualizedListProps<T> extends FlatListProps<T> {
|
|
54
|
+
/** `VirtualizedList`'s accessor form of `data` — three lines here, and honest. */
|
|
55
|
+
getItem?: (data: readonly T[] | null | undefined, index: number) => T;
|
|
56
|
+
getItemCount?: (data: readonly T[] | null | undefined) => number;
|
|
57
|
+
}
|
|
58
|
+
export interface SectionListSection<T> {
|
|
59
|
+
readonly data: readonly T[];
|
|
60
|
+
readonly key?: string;
|
|
61
|
+
readonly title?: string;
|
|
62
|
+
}
|
|
63
|
+
export interface SectionListProps<T> extends ListFrameProps {
|
|
64
|
+
sections?: readonly SectionListSection<T>[];
|
|
65
|
+
renderItem?: (info: ListRenderItemInfo<T>) => ReactNode;
|
|
66
|
+
renderSectionHeader?: (info: {
|
|
67
|
+
section: SectionListSection<T>;
|
|
68
|
+
}) => ReactNode;
|
|
69
|
+
keyExtractor?: (item: T, index: number) => string;
|
|
70
|
+
}
|
|
71
|
+
export declare function FlatList<T>(props: FlatListProps<T>): ReactElement;
|
|
72
|
+
/**
|
|
73
|
+
* `VirtualizedList`, as the honest subset ADR 0032 asks for.
|
|
74
|
+
*
|
|
75
|
+
* Its own public surface is wide and most of it configures React Native's
|
|
76
|
+
* virtualisation, which `Gtk.ListView` does itself — those props are refused by name in
|
|
77
|
+
* L2's row. What is left is a real API and three lines: `getItemCount(data)` for the
|
|
78
|
+
* length and `getItem(data, i)` for a row, which is `FlatList` with the array
|
|
79
|
+
* behind an accessor.
|
|
80
|
+
*/
|
|
81
|
+
export declare function VirtualizedList<T>(props: VirtualizedListProps<T>): ReactElement;
|
|
82
|
+
/**
|
|
83
|
+
* `SectionList`, with the sections FLATTENED into one model.
|
|
84
|
+
*
|
|
85
|
+
* MEASURED on gtk 4.22.4: GTK does have section models — `Gtk.SectionModel` exists,
|
|
86
|
+
* `Gtk.FlattenListModel` and every selection model implement it (`Gio.ListStore` and
|
|
87
|
+
* `Gtk.StringList` do not), `Gtk.ListView.set_header_factory` is there, and a
|
|
88
|
+
* `Gtk.FlattenListModel` over two stores answered `get_section(0) = [0, 2]`. So the
|
|
89
|
+
* sticky-header route is real and available.
|
|
90
|
+
*
|
|
91
|
+
* It is not the one taken, and the reason is what the sticky route costs: a second
|
|
92
|
+
* factory with its own React roots, a `Gtk.ListHeader` whose `start`/`end`/`n-items`
|
|
93
|
+
* have to be reconciled with React Native's `section` object, and a model of models
|
|
94
|
+
* whose splice semantics are one level deeper than the flat one. A flattened model with
|
|
95
|
+
* header ROWS is one model, one factory and one splice — and it delivers exactly what
|
|
96
|
+
* `stickySectionHeadersEnabled={false}` asks for, which is the support table's declared
|
|
97
|
+
* limit. The measurement is written down here so the sticky version is an upgrade with
|
|
98
|
+
* a known starting point rather than a rediscovery.
|
|
99
|
+
*/
|
|
100
|
+
export declare function SectionList<T>(props: SectionListProps<T>): ReactElement;
|
|
101
|
+
/** The section-shaped sibling of `VirtualizedList`, which is `SectionList` here. */
|
|
102
|
+
export declare function VirtualizedSectionList<T>(props: SectionListProps<T>): ReactElement;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { ListController, onScrollNearEnd } from '@gjsify/gtk-host/list';
|
|
2
|
+
import { type ReactRoot } from '@gjsify/gtk-host/react';
|
|
3
|
+
import { type ReactNode } from 'react';
|
|
4
|
+
/** One row: an identity, and the React tree it renders to. */
|
|
5
|
+
export interface ListRow {
|
|
6
|
+
/** `keyExtractor`'s answer. It decides whether the model has to be rebuilt at all. */
|
|
7
|
+
readonly key: string;
|
|
8
|
+
/** Called on every bind, so it always reads the latest `data`. */
|
|
9
|
+
render(): ReactNode;
|
|
10
|
+
}
|
|
11
|
+
/** The controller a list component owns: the shared core, wearing React's row sink. */
|
|
12
|
+
export type ReactListController = ListController<ListRow, ReactRoot>;
|
|
13
|
+
/** What a list component may tell its controller, beyond the rows themselves. */
|
|
14
|
+
export interface ListControllerOptions {
|
|
15
|
+
/**
|
|
16
|
+
* Where a row's own render error goes.
|
|
17
|
+
*
|
|
18
|
+
* Absent means the host adapter's default: log it AND rethrow it from the
|
|
19
|
+
* `render()` call — which here is inside the microtask drain, so the rethrow leaves
|
|
20
|
+
* JS as an uncaught exception. That is loud and correct in an application; a caller
|
|
21
|
+
* with its own error surface (or a spec asserting a named refusal) passes a recorder
|
|
22
|
+
* instead, which is exactly what the adapter documents the option for.
|
|
23
|
+
*/
|
|
24
|
+
readonly onRowError?: (error: Error) => void;
|
|
25
|
+
}
|
|
26
|
+
/** The list controller a React component owns. */
|
|
27
|
+
export declare function createListController(options?: ListControllerOptions): ReactListController;
|
|
28
|
+
/**
|
|
29
|
+
* `keyExtractor`, with React Native's own default.
|
|
30
|
+
*
|
|
31
|
+
* `item.key`, then `item.id`, then the index — the order React Native uses, and the
|
|
32
|
+
* index last because a key that is the position makes every row after an insertion
|
|
33
|
+
* change identity, which here means every row after it is re-bound.
|
|
34
|
+
*/
|
|
35
|
+
export declare function rowKey(item: unknown, index: number, keyExtractor?: (item: unknown, index: number) => string): string;
|
|
36
|
+
/**
|
|
37
|
+
* The scroll edge behind `onEndReached`, re-exported rather than reimplemented.
|
|
38
|
+
*
|
|
39
|
+
* It lived here, and it was never React's: `Gtk.Adjustment` arithmetic with no React in
|
|
40
|
+
* it and no toolkit value import. `@gjsify/gtk-host/list` owns it now, so a Vue or Solid
|
|
41
|
+
* list gets the same measured behaviour instead of re-deriving it — which is the failure
|
|
42
|
+
* this whole extraction exists to prevent. `components.ts` imports it from here, so the
|
|
43
|
+
* move costs no consumer a rewrite.
|
|
44
|
+
*/
|
|
45
|
+
export { onScrollNearEnd };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type ReactElement, type ReactNode } from 'react';
|
|
2
|
+
import type { ChildContext } from './primitives/resolve.js';
|
|
3
|
+
/** `null` at a root, which is what makes an unresolvable `flex-1` there a refusal. */
|
|
4
|
+
export declare const ParentContext: import("react").Context<ChildContext | null>;
|
|
5
|
+
/**
|
|
6
|
+
* Publish `value` to everything rendered inside.
|
|
7
|
+
*
|
|
8
|
+
* A named component rather than `ParentContext.Provider` at each call site, so the
|
|
9
|
+
* two places that publish a context (an element's own children, and a list row's
|
|
10
|
+
* fresh root) spell it the same way.
|
|
11
|
+
*/
|
|
12
|
+
export declare function ParentProvider(props: {
|
|
13
|
+
readonly value: ChildContext;
|
|
14
|
+
readonly children?: ReactNode;
|
|
15
|
+
}): ReactElement;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import Gtk from 'gi://Gtk?version=4.0';
|
|
2
|
+
/**
|
|
3
|
+
* How many elements are currently reporting their press state to JavaScript.
|
|
4
|
+
*
|
|
5
|
+
* Exported for the specs, and it is the only way to assert the distinction ADR 0032
|
|
6
|
+
* § 7 rests on: `<Pressable className="active:opacity-70">` must resolve to CSS and
|
|
7
|
+
* subscribe to nothing, while `<Pressable>{({ pressed }) => …}</Pressable>` must
|
|
8
|
+
* subscribe to exactly one thing. Both render, both look right, and only a count
|
|
9
|
+
* tells them apart — which is why the cheap path would otherwise disappear quietly.
|
|
10
|
+
*/
|
|
11
|
+
export declare const pressWatchCount: () => number;
|
|
12
|
+
/**
|
|
13
|
+
* Report `widget`'s press state to `listener` as it changes; returns the unsubscribe.
|
|
14
|
+
*
|
|
15
|
+
* The listener is called once immediately, because a subscriber that only hears about
|
|
16
|
+
* CHANGES starts out disagreeing with the widget — and the first render of a
|
|
17
|
+
* function child has to know whether the button is already down.
|
|
18
|
+
*/
|
|
19
|
+
export declare function onPressStateChange(widget: Gtk.Widget, listener: (pressed: boolean) => void): () => void;
|
|
20
|
+
/**
|
|
21
|
+
* Add a `Gtk.GestureClick` to `widget` and call `listener` on `signal`; returns the removal.
|
|
22
|
+
*
|
|
23
|
+
* The controller is REMOVED and the handler disconnected, in that order: a controller
|
|
24
|
+
* left on a widget outlives every JS reference to it, and its handler is then one of
|
|
25
|
+
* the callbacks GJS blocks during GC.
|
|
26
|
+
*/
|
|
27
|
+
export declare function onGesture(widget: Gtk.Widget, signal: string, listener: () => void): () => void;
|
|
@@ -4,8 +4,8 @@ export { PrimitiveError } from './errors.js';
|
|
|
4
4
|
export { resolveIntent } from './intents.js';
|
|
5
5
|
export type { ChildContext, ChildFacts, IntentInput, IntentResolution, Orientation, WidgetFacts } from './intents.js';
|
|
6
6
|
export { declaresAbsolute, resolvePrimitive } from './resolve.js';
|
|
7
|
-
export type { PrimitiveContext, PrimitivePlan, PrimitiveProps, ResolvedEvent, WidgetNode } from './resolve.js';
|
|
7
|
+
export type { PrimitiveContext, PrimitivePlan, PrimitiveProps, ResolvedEvent, ResolvedFile, ResolvedGesture, WidgetNode, } from './resolve.js';
|
|
8
8
|
export { flattenStyle, mintClass, normalise, variantDeclarations } from './style.js';
|
|
9
9
|
export type { ClassNameSink, StyleAuthored, StyleInput, StyleObject } from './style.js';
|
|
10
10
|
export { FRAMEWORK_PROPS, PRIMITIVE_NAMES, PRIMITIVES } from './table.js';
|
|
11
|
-
export type { Coercion, ContentSpec, EventRoute, IgnoredRoute, PrimitiveSpec, PropRoute, PropertyRoute, RefusedRoute, StylePropertyRoute, } from './table.js';
|
|
11
|
+
export type { Coercion, ContentSpec, EventRoute, FileRoute, GestureRoute, IgnoredRoute, NodeKind, PrimitiveSpec, PropRoute, PropertyRoute, RefusedRoute, StylePropertyRoute, } from './table.js';
|
|
@@ -2,6 +2,7 @@ import type { LayoutIntent, StyleTokens } from '@gjsify/gtk-host/style';
|
|
|
2
2
|
import type { ClassNameInput } from './classes.js';
|
|
3
3
|
import { type ChildContext, type ChildFacts, type Orientation, type WidgetFacts } from './intents.js';
|
|
4
4
|
import { type ClassNameSink, type StyleInput } from './style.js';
|
|
5
|
+
import { type NodeKind } from './table.js';
|
|
5
6
|
/** Everything L2 needs that is not the primitive and not its props. */
|
|
6
7
|
export interface PrimitiveContext {
|
|
7
8
|
/** The project's own token scales. ADR 0032 § 3: the families are declared, the values are the project's. */
|
|
@@ -31,6 +32,31 @@ export interface ResolvedEvent {
|
|
|
31
32
|
/** The widget property to read for the callback's argument, or null for no argument. */
|
|
32
33
|
readonly read: string | null;
|
|
33
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* A widget property whose value is a `Gio.File`, decided here and BUILT one layer up.
|
|
37
|
+
*
|
|
38
|
+
* L2 holds every decision — which schemes have a synchronous loader, which shapes
|
|
39
|
+
* React Native accepts that this build chain cannot honour — and none of the
|
|
40
|
+
* construction, because building a `Gio.File` needs `gi://Gio` and nothing under
|
|
41
|
+
* `primitives/` imports `gi://`. That is not a stylistic rule: it is what lets this
|
|
42
|
+
* whole layer be asserted by comparison, with no display and no toolkit.
|
|
43
|
+
*/
|
|
44
|
+
export interface ResolvedFile {
|
|
45
|
+
/** Which node of the plan the property is on. */
|
|
46
|
+
readonly on: NodeKind;
|
|
47
|
+
/** The GTK property that takes it — `file` on a `Gtk.Picture`. */
|
|
48
|
+
readonly property: string;
|
|
49
|
+
/** `path` → `Gio.File.new_for_path`; `uri` → `Gio.File.new_for_uri`. */
|
|
50
|
+
readonly kind: 'path' | 'uri';
|
|
51
|
+
readonly value: string;
|
|
52
|
+
}
|
|
53
|
+
/** A press this element takes through a `Gtk.GestureClick` rather than a widget signal. */
|
|
54
|
+
export interface ResolvedGesture {
|
|
55
|
+
/** The React Native prop that supplied the callback. */
|
|
56
|
+
readonly prop: string;
|
|
57
|
+
/** The `Gtk.GestureClick` signal — `released` is a completed press. */
|
|
58
|
+
readonly signal: string;
|
|
59
|
+
}
|
|
34
60
|
export interface PrimitivePlan {
|
|
35
61
|
readonly primitive: string;
|
|
36
62
|
/** The node the PARENT adopts. */
|
|
@@ -41,7 +67,17 @@ export interface PrimitivePlan {
|
|
|
41
67
|
readonly slot: string | null;
|
|
42
68
|
/** Where an absolutely positioned CHILD goes: into `node`, under this slot. */
|
|
43
69
|
readonly absoluteSlot: string | null;
|
|
70
|
+
/** A node that takes no children and sits BEHIND them — `ImageBackground`'s picture. */
|
|
71
|
+
readonly backdrop: WidgetNode | null;
|
|
72
|
+
/** The slot `backdrop` declares to `node`, or null for the default slot. */
|
|
73
|
+
readonly backdropSlot: string | null;
|
|
74
|
+
/** The slot `content` declares to `node`, or null for the default slot. */
|
|
75
|
+
readonly contentSlot: string | null;
|
|
44
76
|
readonly events: readonly ResolvedEvent[];
|
|
77
|
+
/** Widget properties whose value is a file the framework layer constructs. */
|
|
78
|
+
readonly files: readonly ResolvedFile[];
|
|
79
|
+
/** Presses that arrive through a gesture controller instead of a signal. */
|
|
80
|
+
readonly gestures: readonly ResolvedGesture[];
|
|
45
81
|
/** Where a text child goes, or null when text under this primitive is refused. */
|
|
46
82
|
readonly textSink: string | null;
|
|
47
83
|
/** What this element publishes to its children. */
|