@gjsify/react-native 0.49.0 → 0.51.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/PROPS.md +59 -59
- package/README.md +17 -0
- package/lib/esm/components.js +1 -1
- package/lib/esm/press.js +1 -1
- package/lib/esm/primitives/accessibility.js +1 -1
- package/lib/esm/primitives/answers.js +1 -1
- package/lib/esm/primitives/errors.js +1 -1
- package/lib/esm/primitives/resolve.js +1 -1
- package/lib/esm/prop-table.js +1 -1
- package/lib/types/press.d.ts +5 -0
- package/lib/types/primitives/accessibility.d.ts +7 -0
- package/lib/types/primitives/answers.d.ts +42 -1
- package/lib/types/primitives/errors.d.ts +58 -2
- package/lib/types/primitives/errors.spec.d.ts +2 -0
- package/lib/types/prop-table.d.ts +23 -5
- package/package.json +10 -10
package/PROPS.md
CHANGED
|
@@ -28,13 +28,13 @@ widget `GtkBox` · takes no text child.
|
|
|
28
28
|
| `accessibilityHint` | accessible | `Gtk.Accessible.update_property(): help-text` | — |
|
|
29
29
|
| `accessibilityLabel` | accessible | `Gtk.Accessible.update_property(): label` | — |
|
|
30
30
|
| `accessibilityLiveRegion` | refused | — | declares that a screen reader should speak this element when its CONTENT changes. GTK has the announcement — `Gtk.Accessible.announce(message, priority)` since 4.14 — but not the watch: it is an imperative call, and this element’s content is a SUBTREE, which GTK emits no signal for. `<Text>` answers this prop, because its content is one property (`Gtk.Label:label`) and so is both the moment and the message. Elsewhere, call `announce()` on the widget through a ref when you change the content |
|
|
31
|
-
| `accessibilityRole` | property | `accessible-role` | refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
32
|
-
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` |
|
|
31
|
+
| `accessibilityRole` | property | `accessible-role` | takes `adjustable`, `alert`, `button`, `checkbox`, `combobox`, `dropdownlist`, `grid`, `header`, `iconmenu`, `image`, `imagebutton`, `link`, `list`, `menu`, `menubar`, `menuitem`, `none`, `progressbar`, `radio`, `radiogroup`, `scrollbar`, `search`, `spinbutton`, `switch`, `tab`, `tabbar`, `tablist`, `text`, `timer`, `togglebutton`, `toolbar`, `viewgroup`, `webview`; refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
32
|
+
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` | takes `busy`, `checked`, `disabled`, `expanded`, `selected` |
|
|
33
33
|
| `accessible` | ignored | — | asks for two things, and GTK already answers one: every GTK widget is in the accessibility tree, so “this element is an accessibility element” is the desktop default rather than an opt-in. The other thing it asks — merge my whole subtree into ONE accessible node, which is what `accessible={true}` does on iOS — GTK has no mechanism for, and a desktop screen reader navigates the widget tree it is given. To take an element OUT of that tree, set `accessibilityRole="none"`: it is the one prop that writes `Gtk.Accessible:accessible-role`, and two props writing one property is the silent-drop shape this table refuses by name |
|
|
34
34
|
| `id` | refused | — | 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` |
|
|
35
35
|
| `nativeID` | refused | — | 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` |
|
|
36
36
|
| `onLayout` | refused | — | 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 |
|
|
37
|
-
| `pointerEvents` | property | `can-target` |
|
|
37
|
+
| `pointerEvents` | property | `can-target` | takes `auto`, `none` |
|
|
38
38
|
| `testID` | property | `name` | — |
|
|
39
39
|
|
|
40
40
|
`accessibilityRole` is answered for every other value, and these are refused by name:
|
|
@@ -55,13 +55,13 @@ widget `GtkLabel` · a text child writes `label`.
|
|
|
55
55
|
|---|---|---|---|
|
|
56
56
|
| `accessibilityHint` | accessible | `Gtk.Accessible.update_property(): help-text` | — |
|
|
57
57
|
| `accessibilityLabel` | accessible | `Gtk.Accessible.update_property(): label` | — |
|
|
58
|
-
| `accessibilityLiveRegion` | announcement | `notify::label`, `Gtk.Accessible.announce()` |
|
|
59
|
-
| `accessibilityRole` | property | `accessible-role` | refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
60
|
-
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` |
|
|
58
|
+
| `accessibilityLiveRegion` | announcement | `notify::label`, `Gtk.Accessible.announce()` | takes `assertive`, `none`, `polite` |
|
|
59
|
+
| `accessibilityRole` | property | `accessible-role` | takes `adjustable`, `alert`, `button`, `checkbox`, `combobox`, `dropdownlist`, `grid`, `header`, `iconmenu`, `image`, `imagebutton`, `link`, `list`, `menu`, `menubar`, `menuitem`, `none`, `progressbar`, `radio`, `radiogroup`, `scrollbar`, `search`, `spinbutton`, `switch`, `tab`, `tabbar`, `tablist`, `text`, `timer`, `togglebutton`, `toolbar`, `viewgroup`, `webview`; refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
60
|
+
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` | takes `busy`, `checked`, `disabled`, `expanded`, `selected` |
|
|
61
61
|
| `accessible` | ignored | — | asks for two things, and GTK already answers one: every GTK widget is in the accessibility tree, so “this element is an accessibility element” is the desktop default rather than an opt-in. The other thing it asks — merge my whole subtree into ONE accessible node, which is what `accessible={true}` does on iOS — GTK has no mechanism for, and a desktop screen reader navigates the widget tree it is given. To take an element OUT of that tree, set `accessibilityRole="none"`: it is the one prop that writes `Gtk.Accessible:accessible-role`, and two props writing one property is the silent-drop shape this table refuses by name |
|
|
62
62
|
| `adjustsFontSizeToFit` | refused | — | GTK has no shrink-to-fit text; a label ellipsizes or wraps. Use `numberOfLines` with `ellipsizeMode` |
|
|
63
63
|
| `allowFontScaling` | ignored | — | text scaling is a desktop-wide GNOME setting, not a per-label opt-in |
|
|
64
|
-
| `ellipsizeMode` | property | `ellipsize` |
|
|
64
|
+
| `ellipsizeMode` | property | `ellipsize` | takes `head`, `middle`, `tail` |
|
|
65
65
|
| `id` | refused | — | 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` |
|
|
66
66
|
| `maxFontSizeMultiplier` | ignored | — | see `allowFontScaling` |
|
|
67
67
|
| `nativeID` | refused | — | 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` |
|
|
@@ -90,8 +90,8 @@ widget `GtkButton` · a text child writes `label`.
|
|
|
90
90
|
| `accessibilityHint` | accessible | `Gtk.Accessible.update_property(): help-text` | — |
|
|
91
91
|
| `accessibilityLabel` | accessible | `Gtk.Accessible.update_property(): label` | — |
|
|
92
92
|
| `accessibilityLiveRegion` | refused | — | declares that a screen reader should speak this element when its CONTENT changes. GTK has the announcement — `Gtk.Accessible.announce(message, priority)` since 4.14 — but not the watch: it is an imperative call, and this element’s content is a SUBTREE, which GTK emits no signal for. `<Text>` answers this prop, because its content is one property (`Gtk.Label:label`) and so is both the moment and the message. Elsewhere, call `announce()` on the widget through a ref when you change the content |
|
|
93
|
-
| `accessibilityRole` | property | `accessible-role` | refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
94
|
-
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` |
|
|
93
|
+
| `accessibilityRole` | property | `accessible-role` | takes `adjustable`, `alert`, `button`, `checkbox`, `combobox`, `dropdownlist`, `grid`, `header`, `iconmenu`, `image`, `imagebutton`, `link`, `list`, `menu`, `menubar`, `menuitem`, `none`, `progressbar`, `radio`, `radiogroup`, `scrollbar`, `search`, `spinbutton`, `switch`, `tab`, `tabbar`, `tablist`, `text`, `timer`, `togglebutton`, `toolbar`, `viewgroup`, `webview`; refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
94
|
+
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` | takes `busy`, `checked`, `disabled`, `expanded`, `selected` |
|
|
95
95
|
| `accessible` | ignored | — | asks for two things, and GTK already answers one: every GTK widget is in the accessibility tree, so “this element is an accessibility element” is the desktop default rather than an opt-in. The other thing it asks — merge my whole subtree into ONE accessible node, which is what `accessible={true}` does on iOS — GTK has no mechanism for, and a desktop screen reader navigates the widget tree it is given. To take an element OUT of that tree, set `accessibilityRole="none"`: it is the one prop that writes `Gtk.Accessible:accessible-role`, and two props writing one property is the silent-drop shape this table refuses by name |
|
|
96
96
|
| `android_ripple` | ignored | — | an Android-only ripple; Adwaita has its own press feedback |
|
|
97
97
|
| `delayLongPress` | refused | — | see `onLongPress` |
|
|
@@ -104,7 +104,7 @@ widget `GtkButton` · a text child writes `label`.
|
|
|
104
104
|
| `onPress` | event | `clicked` | — |
|
|
105
105
|
| `onPressIn` | refused | — | 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 |
|
|
106
106
|
| `onPressOut` | refused | — | see `onPressIn` — `active:` is the mechanism |
|
|
107
|
-
| `pointerEvents` | property | `can-target` |
|
|
107
|
+
| `pointerEvents` | property | `can-target` | takes `auto`, `none` |
|
|
108
108
|
| `testID` | property | `name` | — |
|
|
109
109
|
|
|
110
110
|
`accessibilityRole` is answered for every other value, and these are refused by name:
|
|
@@ -126,12 +126,12 @@ widget `GtkScrolledWindow` · children go into `GtkBox` · takes no text child.
|
|
|
126
126
|
| `accessibilityHint` | accessible | `Gtk.Accessible.update_property(): help-text` | — |
|
|
127
127
|
| `accessibilityLabel` | accessible | `Gtk.Accessible.update_property(): label` | — |
|
|
128
128
|
| `accessibilityLiveRegion` | refused | — | declares that a screen reader should speak this element when its CONTENT changes. GTK has the announcement — `Gtk.Accessible.announce(message, priority)` since 4.14 — but not the watch: it is an imperative call, and this element’s content is a SUBTREE, which GTK emits no signal for. `<Text>` answers this prop, because its content is one property (`Gtk.Label:label`) and so is both the moment and the message. Elsewhere, call `announce()` on the widget through a ref when you change the content |
|
|
129
|
-
| `accessibilityRole` | property | `accessible-role` | refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
130
|
-
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` |
|
|
129
|
+
| `accessibilityRole` | property | `accessible-role` | takes `adjustable`, `alert`, `button`, `checkbox`, `combobox`, `dropdownlist`, `grid`, `header`, `iconmenu`, `image`, `imagebutton`, `link`, `list`, `menu`, `menubar`, `menuitem`, `none`, `progressbar`, `radio`, `radiogroup`, `scrollbar`, `search`, `spinbutton`, `switch`, `tab`, `tabbar`, `tablist`, `text`, `timer`, `togglebutton`, `toolbar`, `viewgroup`, `webview`; refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
130
|
+
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` | takes `busy`, `checked`, `disabled`, `expanded`, `selected` |
|
|
131
131
|
| `accessible` | ignored | — | asks for two things, and GTK already answers one: every GTK widget is in the accessibility tree, so “this element is an accessibility element” is the desktop default rather than an opt-in. The other thing it asks — merge my whole subtree into ONE accessible node, which is what `accessible={true}` does on iOS — GTK has no mechanism for, and a desktop screen reader navigates the widget tree it is given. To take an element OUT of that tree, set `accessibilityRole="none"`: it is the one prop that writes `Gtk.Accessible:accessible-role`, and two props writing one property is the silent-drop shape this table refuses by name |
|
|
132
132
|
| `contentContainerClassName` | ignored | — | read directly as the content node’s class list |
|
|
133
133
|
| `contentContainerStyle` | ignored | — | read directly as the content node’s style set |
|
|
134
|
-
| `horizontal` | property | `orientation`, `hscrollbar-policy`, `vscrollbar-policy` |
|
|
134
|
+
| `horizontal` | property | `orientation`, `hscrollbar-policy`, `vscrollbar-policy` | takes `false`, `true` |
|
|
135
135
|
| `id` | refused | — | 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` |
|
|
136
136
|
| `keyboardDismissMode` | ignored | — | see `keyboardShouldPersistTaps` |
|
|
137
137
|
| `keyboardShouldPersistTaps` | ignored | — | there is no on-screen keyboard to dismiss |
|
|
@@ -141,8 +141,8 @@ widget `GtkScrolledWindow` · children go into `GtkBox` · takes no text child.
|
|
|
141
141
|
| `refreshControl` | refused | — | 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 |
|
|
142
142
|
| `scrollEnabled` | refused | — | 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 |
|
|
143
143
|
| `scrollEventThrottle` | refused | — | see `onScroll` |
|
|
144
|
-
| `showsHorizontalScrollIndicator` | property | `hscrollbar-policy` |
|
|
145
|
-
| `showsVerticalScrollIndicator` | property | `vscrollbar-policy` |
|
|
144
|
+
| `showsHorizontalScrollIndicator` | property | `hscrollbar-policy` | takes `false`, `true` |
|
|
145
|
+
| `showsVerticalScrollIndicator` | property | `vscrollbar-policy` | takes `false`, `true` |
|
|
146
146
|
| `testID` | property | `name` | — |
|
|
147
147
|
|
|
148
148
|
`accessibilityRole` is answered for every other value, and these are refused by name:
|
|
@@ -164,8 +164,8 @@ widget `AdwSpinner` · takes no text child.
|
|
|
164
164
|
| `accessibilityHint` | accessible | `Gtk.Accessible.update_property(): help-text` | — |
|
|
165
165
|
| `accessibilityLabel` | accessible | `Gtk.Accessible.update_property(): label` | — |
|
|
166
166
|
| `accessibilityLiveRegion` | refused | — | declares that a screen reader should speak this element when its CONTENT changes. GTK has the announcement — `Gtk.Accessible.announce(message, priority)` since 4.14 — but not the watch: it is an imperative call, and this element’s content is a SUBTREE, which GTK emits no signal for. `<Text>` answers this prop, because its content is one property (`Gtk.Label:label`) and so is both the moment and the message. Elsewhere, call `announce()` on the widget through a ref when you change the content |
|
|
167
|
-
| `accessibilityRole` | property | `accessible-role` | refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
168
|
-
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` |
|
|
167
|
+
| `accessibilityRole` | property | `accessible-role` | takes `adjustable`, `alert`, `button`, `checkbox`, `combobox`, `dropdownlist`, `grid`, `header`, `iconmenu`, `image`, `imagebutton`, `link`, `list`, `menu`, `menubar`, `menuitem`, `none`, `progressbar`, `radio`, `radiogroup`, `scrollbar`, `search`, `spinbutton`, `switch`, `tab`, `tabbar`, `tablist`, `text`, `timer`, `togglebutton`, `toolbar`, `viewgroup`, `webview`; refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
168
|
+
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` | takes `busy`, `checked`, `disabled`, `expanded`, `selected` |
|
|
169
169
|
| `accessible` | ignored | — | asks for two things, and GTK already answers one: every GTK widget is in the accessibility tree, so “this element is an accessibility element” is the desktop default rather than an opt-in. The other thing it asks — merge my whole subtree into ONE accessible node, which is what `accessible={true}` does on iOS — GTK has no mechanism for, and a desktop screen reader navigates the widget tree it is given. To take an element OUT of that tree, set `accessibilityRole="none"`: it is the one prop that writes `Gtk.Accessible:accessible-role`, and two props writing one property is the silent-drop shape this table refuses by name |
|
|
170
170
|
| `animating` | property | `visible` | — |
|
|
171
171
|
| `color` | style | `style: color` | — |
|
|
@@ -173,7 +173,7 @@ widget `AdwSpinner` · takes no text child.
|
|
|
173
173
|
| `id` | refused | — | 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` |
|
|
174
174
|
| `nativeID` | refused | — | 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` |
|
|
175
175
|
| `onLayout` | refused | — | 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 |
|
|
176
|
-
| `size` | property | `width-request`, `height-request` |
|
|
176
|
+
| `size` | property | `width-request`, `height-request` | takes `large`, `small`, or a number of pixels |
|
|
177
177
|
| `testID` | property | `name` | — |
|
|
178
178
|
|
|
179
179
|
`accessibilityRole` is answered for every other value, and these are refused by name:
|
|
@@ -195,8 +195,8 @@ widget `GtkEntry` · a text child writes `text` · a `ref` receives the `text-in
|
|
|
195
195
|
| `accessibilityHint` | accessible | `Gtk.Accessible.update_property(): help-text` | — |
|
|
196
196
|
| `accessibilityLabel` | accessible | `Gtk.Accessible.update_property(): label` | — |
|
|
197
197
|
| `accessibilityLiveRegion` | refused | — | declares that a screen reader should speak this element when its CONTENT changes. GTK has the announcement — `Gtk.Accessible.announce(message, priority)` since 4.14 — but not the watch: it is an imperative call, and this element’s content is a SUBTREE, which GTK emits no signal for. `<Text>` answers this prop, because its content is one property (`Gtk.Label:label`) and so is both the moment and the message. Elsewhere, call `announce()` on the widget through a ref when you change the content |
|
|
198
|
-
| `accessibilityRole` | property | `accessible-role` | refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
199
|
-
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` |
|
|
198
|
+
| `accessibilityRole` | property | `accessible-role` | takes `adjustable`, `alert`, `button`, `checkbox`, `combobox`, `dropdownlist`, `grid`, `header`, `iconmenu`, `image`, `imagebutton`, `link`, `list`, `menu`, `menubar`, `menuitem`, `none`, `progressbar`, `radio`, `radiogroup`, `scrollbar`, `search`, `spinbutton`, `switch`, `tab`, `tabbar`, `tablist`, `text`, `timer`, `togglebutton`, `toolbar`, `viewgroup`, `webview`; refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
199
|
+
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` | takes `busy`, `checked`, `disabled`, `expanded`, `selected` |
|
|
200
200
|
| `accessible` | ignored | — | asks for two things, and GTK already answers one: every GTK widget is in the accessibility tree, so “this element is an accessibility element” is the desktop default rather than an opt-in. The other thing it asks — merge my whole subtree into ONE accessible node, which is what `accessible={true}` does on iOS — GTK has no mechanism for, and a desktop screen reader navigates the widget tree it is given. To take an element OUT of that tree, set `accessibilityRole="none"`: it is the one prop that writes `Gtk.Accessible:accessible-role`, and two props writing one property is the silent-drop shape this table refuses by name |
|
|
201
201
|
| `autoCapitalize` | ignored | — | an on-screen keyboard behaviour; a hardware keyboard has no shift state to preset |
|
|
202
202
|
| `autoComplete` | ignored | — | is Android’s autofill hint, and there is no autofill service on a GTK desktop to hint to — a password manager fills a field through the accessibility bus or a paste, neither of which the widget declares anything for. `keyboardType` is the one hint that does land: it writes `Gtk.Entry:input-purpose`, which an input method reads |
|
|
@@ -206,7 +206,7 @@ widget `GtkEntry` · a text child writes `text` · a `ref` receives the `text-in
|
|
|
206
206
|
| `editable` | property | `editable` | — |
|
|
207
207
|
| `id` | refused | — | 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` |
|
|
208
208
|
| `keyboardAppearance` | ignored | — | there is no on-screen keyboard to theme |
|
|
209
|
-
| `keyboardType` | property | `input-purpose` |
|
|
209
|
+
| `keyboardType` | property | `input-purpose` | takes `decimal-pad`, `default`, `email-address`, `number-pad`, `numeric`, `phone-pad`, `url` |
|
|
210
210
|
| `maxLength` | property | `max-length` | — |
|
|
211
211
|
| `multiline` | ignored | — | it chose the widget; it is not also a property |
|
|
212
212
|
| `nativeID` | refused | — | 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` |
|
|
@@ -244,8 +244,8 @@ One React Native prop, two GTK widgets: `multiline` selects this row instead of
|
|
|
244
244
|
| `accessibilityHint` | accessible | `Gtk.Accessible.update_property(): help-text` | — |
|
|
245
245
|
| `accessibilityLabel` | accessible | `Gtk.Accessible.update_property(): label` | — |
|
|
246
246
|
| `accessibilityLiveRegion` | refused | — | declares that a screen reader should speak this element when its CONTENT changes. GTK has the announcement — `Gtk.Accessible.announce(message, priority)` since 4.14 — but not the watch: it is an imperative call, and this element’s content is a SUBTREE, which GTK emits no signal for. `<Text>` answers this prop, because its content is one property (`Gtk.Label:label`) and so is both the moment and the message. Elsewhere, call `announce()` on the widget through a ref when you change the content |
|
|
247
|
-
| `accessibilityRole` | property | `accessible-role` | refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
248
|
-
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` |
|
|
247
|
+
| `accessibilityRole` | property | `accessible-role` | takes `adjustable`, `alert`, `button`, `checkbox`, `combobox`, `dropdownlist`, `grid`, `header`, `iconmenu`, `image`, `imagebutton`, `link`, `list`, `menu`, `menubar`, `menuitem`, `none`, `progressbar`, `radio`, `radiogroup`, `scrollbar`, `search`, `spinbutton`, `switch`, `tab`, `tabbar`, `tablist`, `text`, `timer`, `togglebutton`, `toolbar`, `viewgroup`, `webview`; refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
248
|
+
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` | takes `busy`, `checked`, `disabled`, `expanded`, `selected` |
|
|
249
249
|
| `accessible` | ignored | — | asks for two things, and GTK already answers one: every GTK widget is in the accessibility tree, so “this element is an accessibility element” is the desktop default rather than an opt-in. The other thing it asks — merge my whole subtree into ONE accessible node, which is what `accessible={true}` does on iOS — GTK has no mechanism for, and a desktop screen reader navigates the widget tree it is given. To take an element OUT of that tree, set `accessibilityRole="none"`: it is the one prop that writes `Gtk.Accessible:accessible-role`, and two props writing one property is the silent-drop shape this table refuses by name |
|
|
250
250
|
| `autoCapitalize` | ignored | — | an on-screen keyboard behaviour; a hardware keyboard has no shift state to preset |
|
|
251
251
|
| `autoComplete` | ignored | — | is Android’s autofill hint, and there is no autofill service on a GTK desktop to hint to — a password manager fills a field through the accessibility bus or a paste, neither of which the widget declares anything for. `keyboardType` is the one hint that does land: it writes `Gtk.Entry:input-purpose`, which an input method reads |
|
|
@@ -255,7 +255,7 @@ One React Native prop, two GTK widgets: `multiline` selects this row instead of
|
|
|
255
255
|
| `editable` | property | `editable` | — |
|
|
256
256
|
| `id` | refused | — | 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` |
|
|
257
257
|
| `keyboardAppearance` | ignored | — | there is no on-screen keyboard to theme |
|
|
258
|
-
| `keyboardType` | property | `input-purpose` |
|
|
258
|
+
| `keyboardType` | property | `input-purpose` | takes `decimal-pad`, `default`, `email-address`, `number-pad`, `numeric`, `phone-pad`, `url` |
|
|
259
259
|
| `maxLength` | refused | — | `Gtk.TextView` installs no `max-length` (measured) — the limit belongs to the buffer |
|
|
260
260
|
| `multiline` | ignored | — | it chose the widget; it is not also a property |
|
|
261
261
|
| `nativeID` | refused | — | 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` |
|
|
@@ -291,8 +291,8 @@ widget `GtkSwitch` · takes no text child.
|
|
|
291
291
|
| `accessibilityHint` | accessible | `Gtk.Accessible.update_property(): help-text` | — |
|
|
292
292
|
| `accessibilityLabel` | accessible | `Gtk.Accessible.update_property(): label` | — |
|
|
293
293
|
| `accessibilityLiveRegion` | refused | — | declares that a screen reader should speak this element when its CONTENT changes. GTK has the announcement — `Gtk.Accessible.announce(message, priority)` since 4.14 — but not the watch: it is an imperative call, and this element’s content is a SUBTREE, which GTK emits no signal for. `<Text>` answers this prop, because its content is one property (`Gtk.Label:label`) and so is both the moment and the message. Elsewhere, call `announce()` on the widget through a ref when you change the content |
|
|
294
|
-
| `accessibilityRole` | property | `accessible-role` | refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
295
|
-
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` |
|
|
294
|
+
| `accessibilityRole` | property | `accessible-role` | takes `adjustable`, `alert`, `button`, `checkbox`, `combobox`, `dropdownlist`, `grid`, `header`, `iconmenu`, `image`, `imagebutton`, `link`, `list`, `menu`, `menubar`, `menuitem`, `none`, `progressbar`, `radio`, `radiogroup`, `scrollbar`, `search`, `spinbutton`, `switch`, `tab`, `tabbar`, `tablist`, `text`, `timer`, `togglebutton`, `toolbar`, `viewgroup`, `webview`; refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
295
|
+
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` | takes `busy`, `checked`, `disabled`, `expanded`, `selected` |
|
|
296
296
|
| `accessible` | ignored | — | asks for two things, and GTK already answers one: every GTK widget is in the accessibility tree, so “this element is an accessibility element” is the desktop default rather than an opt-in. The other thing it asks — merge my whole subtree into ONE accessible node, which is what `accessible={true}` does on iOS — GTK has no mechanism for, and a desktop screen reader navigates the widget tree it is given. To take an element OUT of that tree, set `accessibilityRole="none"`: it is the one prop that writes `Gtk.Accessible:accessible-role`, and two props writing one property is the silent-drop shape this table refuses by name |
|
|
297
297
|
| `disabled` | property | `sensitive` | — |
|
|
298
298
|
| `id` | refused | — | 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` |
|
|
@@ -324,8 +324,8 @@ widget `GtkPicture` · takes no text child.
|
|
|
324
324
|
| `accessibilityHint` | accessible | `Gtk.Accessible.update_property(): help-text` | — |
|
|
325
325
|
| `accessibilityLabel` | accessible | `Gtk.Accessible.update_property(): label` | — |
|
|
326
326
|
| `accessibilityLiveRegion` | refused | — | declares that a screen reader should speak this element when its CONTENT changes. GTK has the announcement — `Gtk.Accessible.announce(message, priority)` since 4.14 — but not the watch: it is an imperative call, and this element’s content is a SUBTREE, which GTK emits no signal for. `<Text>` answers this prop, because its content is one property (`Gtk.Label:label`) and so is both the moment and the message. Elsewhere, call `announce()` on the widget through a ref when you change the content |
|
|
327
|
-
| `accessibilityRole` | property | `accessible-role` | refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
328
|
-
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` |
|
|
327
|
+
| `accessibilityRole` | property | `accessible-role` | takes `adjustable`, `alert`, `button`, `checkbox`, `combobox`, `dropdownlist`, `grid`, `header`, `iconmenu`, `image`, `imagebutton`, `link`, `list`, `menu`, `menubar`, `menuitem`, `none`, `progressbar`, `radio`, `radiogroup`, `scrollbar`, `search`, `spinbutton`, `switch`, `tab`, `tabbar`, `tablist`, `text`, `timer`, `togglebutton`, `toolbar`, `viewgroup`, `webview`; refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
328
|
+
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` | takes `busy`, `checked`, `disabled`, `expanded`, `selected` |
|
|
329
329
|
| `accessible` | ignored | — | asks for two things, and GTK already answers one: every GTK widget is in the accessibility tree, so “this element is an accessibility element” is the desktop default rather than an opt-in. The other thing it asks — merge my whole subtree into ONE accessible node, which is what `accessible={true}` does on iOS — GTK has no mechanism for, and a desktop screen reader navigates the widget tree it is given. To take an element OUT of that tree, set `accessibilityRole="none"`: it is the one prop that writes `Gtk.Accessible:accessible-role`, and two props writing one property is the silent-drop shape this table refuses by name |
|
|
330
330
|
| `alt` | property | `alternative-text` | — |
|
|
331
331
|
| `blurRadius` | refused | — | 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 |
|
|
@@ -343,7 +343,7 @@ widget `GtkPicture` · takes no text child.
|
|
|
343
343
|
| `onProgress` | refused | — | 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 |
|
|
344
344
|
| `progressiveRenderingEnabled` | ignored | — | GTK decodes an image in one pass |
|
|
345
345
|
| `resizeMethod` | ignored | — | an Android decoder hint |
|
|
346
|
-
| `resizeMode` | property | `content-fit` |
|
|
346
|
+
| `resizeMode` | property | `content-fit` | takes `center`, `contain`, `cover`, `stretch` |
|
|
347
347
|
| `resizeMultiplier` | ignored | — | an Android decoder hint |
|
|
348
348
|
| `source` | file | `file` | — |
|
|
349
349
|
| `testID` | property | `name` | — |
|
|
@@ -368,8 +368,8 @@ widget `GtkOverlay` · children go into `GtkBox` · backdrop `GtkPicture` · tak
|
|
|
368
368
|
| `accessibilityHint` | accessible | `Gtk.Accessible.update_property(): help-text` | — |
|
|
369
369
|
| `accessibilityLabel` | accessible | `Gtk.Accessible.update_property(): label` | — |
|
|
370
370
|
| `accessibilityLiveRegion` | refused | — | declares that a screen reader should speak this element when its CONTENT changes. GTK has the announcement — `Gtk.Accessible.announce(message, priority)` since 4.14 — but not the watch: it is an imperative call, and this element’s content is a SUBTREE, which GTK emits no signal for. `<Text>` answers this prop, because its content is one property (`Gtk.Label:label`) and so is both the moment and the message. Elsewhere, call `announce()` on the widget through a ref when you change the content |
|
|
371
|
-
| `accessibilityRole` | property | `accessible-role` | refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
372
|
-
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` |
|
|
371
|
+
| `accessibilityRole` | property | `accessible-role` | takes `adjustable`, `alert`, `button`, `checkbox`, `combobox`, `dropdownlist`, `grid`, `header`, `iconmenu`, `image`, `imagebutton`, `link`, `list`, `menu`, `menubar`, `menuitem`, `none`, `progressbar`, `radio`, `radiogroup`, `scrollbar`, `search`, `spinbutton`, `switch`, `tab`, `tabbar`, `tablist`, `text`, `timer`, `togglebutton`, `toolbar`, `viewgroup`, `webview`; refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
372
|
+
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` | takes `busy`, `checked`, `disabled`, `expanded`, `selected` |
|
|
373
373
|
| `accessible` | ignored | — | asks for two things, and GTK already answers one: every GTK widget is in the accessibility tree, so “this element is an accessibility element” is the desktop default rather than an opt-in. The other thing it asks — merge my whole subtree into ONE accessible node, which is what `accessible={true}` does on iOS — GTK has no mechanism for, and a desktop screen reader navigates the widget tree it is given. To take an element OUT of that tree, set `accessibilityRole="none"`: it is the one prop that writes `Gtk.Accessible:accessible-role`, and two props writing one property is the silent-drop shape this table refuses by name |
|
|
374
374
|
| `alt` | property | `alternative-text` | — |
|
|
375
375
|
| `id` | refused | — | 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` |
|
|
@@ -377,8 +377,8 @@ widget `GtkOverlay` · children go into `GtkBox` · backdrop `GtkPicture` · tak
|
|
|
377
377
|
| `imageStyle` | ignored | — | read directly as the picture node’s style set |
|
|
378
378
|
| `nativeID` | refused | — | 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` |
|
|
379
379
|
| `onLayout` | refused | — | 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 |
|
|
380
|
-
| `pointerEvents` | property | `can-target` |
|
|
381
|
-
| `resizeMode` | property | `content-fit` |
|
|
380
|
+
| `pointerEvents` | property | `can-target` | takes `auto`, `none` |
|
|
381
|
+
| `resizeMode` | property | `content-fit` | takes `center`, `contain`, `cover`, `stretch` |
|
|
382
382
|
| `source` | file | `file` | — |
|
|
383
383
|
| `testID` | property | `name` | — |
|
|
384
384
|
|
|
@@ -401,8 +401,8 @@ widget `GtkButton` · a text child writes `label`.
|
|
|
401
401
|
| `accessibilityHint` | accessible | `Gtk.Accessible.update_property(): help-text` | — |
|
|
402
402
|
| `accessibilityLabel` | accessible | `Gtk.Accessible.update_property(): label` | — |
|
|
403
403
|
| `accessibilityLiveRegion` | refused | — | declares that a screen reader should speak this element when its CONTENT changes. GTK has the announcement — `Gtk.Accessible.announce(message, priority)` since 4.14 — but not the watch: it is an imperative call, and this element’s content is a SUBTREE, which GTK emits no signal for. `<Text>` answers this prop, because its content is one property (`Gtk.Label:label`) and so is both the moment and the message. Elsewhere, call `announce()` on the widget through a ref when you change the content |
|
|
404
|
-
| `accessibilityRole` | property | `accessible-role` | refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
405
|
-
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` |
|
|
404
|
+
| `accessibilityRole` | property | `accessible-role` | takes `adjustable`, `alert`, `button`, `checkbox`, `combobox`, `dropdownlist`, `grid`, `header`, `iconmenu`, `image`, `imagebutton`, `link`, `list`, `menu`, `menubar`, `menuitem`, `none`, `progressbar`, `radio`, `radiogroup`, `scrollbar`, `search`, `spinbutton`, `switch`, `tab`, `tabbar`, `tablist`, `text`, `timer`, `togglebutton`, `toolbar`, `viewgroup`, `webview`; refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
405
|
+
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` | takes `busy`, `checked`, `disabled`, `expanded`, `selected` |
|
|
406
406
|
| `accessible` | ignored | — | asks for two things, and GTK already answers one: every GTK widget is in the accessibility tree, so “this element is an accessibility element” is the desktop default rather than an opt-in. The other thing it asks — merge my whole subtree into ONE accessible node, which is what `accessible={true}` does on iOS — GTK has no mechanism for, and a desktop screen reader navigates the widget tree it is given. To take an element OUT of that tree, set `accessibilityRole="none"`: it is the one prop that writes `Gtk.Accessible:accessible-role`, and two props writing one property is the silent-drop shape this table refuses by name |
|
|
407
407
|
| `activeOpacity` | refused | — | sets the pressed appearance, which on GTK is the CSS `:active` pseudo-class rather than a prop (ADR 0032 § 7). Write `active:opacity-70` — 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 |
|
|
408
408
|
| `delayLongPress` | refused | — | see `onLongPress` |
|
|
@@ -417,7 +417,7 @@ widget `GtkButton` · a text child writes `label`.
|
|
|
417
417
|
| `onPress` | event | `clicked` | — |
|
|
418
418
|
| `onPressIn` | refused | — | 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 |
|
|
419
419
|
| `onPressOut` | refused | — | see `onPressIn` — `active:` is the mechanism |
|
|
420
|
-
| `pointerEvents` | property | `can-target` |
|
|
420
|
+
| `pointerEvents` | property | `can-target` | takes `auto`, `none` |
|
|
421
421
|
| `pressRetentionOffset` | refused | — | see `hitSlop` — GTK hit-tests the allocation and nothing around it |
|
|
422
422
|
| `testID` | property | `name` | — |
|
|
423
423
|
| `touchSoundDisabled` | ignored | — | an Android touch sound; a desktop button makes none |
|
|
@@ -441,8 +441,8 @@ widget `GtkButton` · a text child writes `label`.
|
|
|
441
441
|
| `accessibilityHint` | accessible | `Gtk.Accessible.update_property(): help-text` | — |
|
|
442
442
|
| `accessibilityLabel` | accessible | `Gtk.Accessible.update_property(): label` | — |
|
|
443
443
|
| `accessibilityLiveRegion` | refused | — | declares that a screen reader should speak this element when its CONTENT changes. GTK has the announcement — `Gtk.Accessible.announce(message, priority)` since 4.14 — but not the watch: it is an imperative call, and this element’s content is a SUBTREE, which GTK emits no signal for. `<Text>` answers this prop, because its content is one property (`Gtk.Label:label`) and so is both the moment and the message. Elsewhere, call `announce()` on the widget through a ref when you change the content |
|
|
444
|
-
| `accessibilityRole` | property | `accessible-role` | refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
445
|
-
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` |
|
|
444
|
+
| `accessibilityRole` | property | `accessible-role` | takes `adjustable`, `alert`, `button`, `checkbox`, `combobox`, `dropdownlist`, `grid`, `header`, `iconmenu`, `image`, `imagebutton`, `link`, `list`, `menu`, `menubar`, `menuitem`, `none`, `progressbar`, `radio`, `radiogroup`, `scrollbar`, `search`, `spinbutton`, `switch`, `tab`, `tabbar`, `tablist`, `text`, `timer`, `togglebutton`, `toolbar`, `viewgroup`, `webview`; refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
445
|
+
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` | takes `busy`, `checked`, `disabled`, `expanded`, `selected` |
|
|
446
446
|
| `accessible` | ignored | — | asks for two things, and GTK already answers one: every GTK widget is in the accessibility tree, so “this element is an accessibility element” is the desktop default rather than an opt-in. The other thing it asks — merge my whole subtree into ONE accessible node, which is what `accessible={true}` does on iOS — GTK has no mechanism for, and a desktop screen reader navigates the widget tree it is given. To take an element OUT of that tree, set `accessibilityRole="none"`: it is the one prop that writes `Gtk.Accessible:accessible-role`, and two props writing one property is the silent-drop shape this table refuses by name |
|
|
447
447
|
| `activeOpacity` | refused | — | sets the pressed appearance, which on GTK is the CSS `:active` pseudo-class rather than a prop (ADR 0032 § 7). Write `active:opacity-70` — 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 |
|
|
448
448
|
| `delayLongPress` | refused | — | see `onLongPress` |
|
|
@@ -459,7 +459,7 @@ widget `GtkButton` · a text child writes `label`.
|
|
|
459
459
|
| `onPressIn` | refused | — | 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 |
|
|
460
460
|
| `onPressOut` | refused | — | see `onPressIn` — `active:` is the mechanism |
|
|
461
461
|
| `onShowUnderlay` | refused | — | see `underlayColor` — there is no underlay to show |
|
|
462
|
-
| `pointerEvents` | property | `can-target` |
|
|
462
|
+
| `pointerEvents` | property | `can-target` | takes `auto`, `none` |
|
|
463
463
|
| `pressRetentionOffset` | refused | — | see `hitSlop` — GTK hit-tests the allocation and nothing around it |
|
|
464
464
|
| `testID` | property | `name` | — |
|
|
465
465
|
| `touchSoundDisabled` | ignored | — | an Android touch sound; a desktop button makes none |
|
|
@@ -484,8 +484,8 @@ widget `GtkBox` · takes no text child.
|
|
|
484
484
|
| `accessibilityHint` | accessible | `Gtk.Accessible.update_property(): help-text` | — |
|
|
485
485
|
| `accessibilityLabel` | accessible | `Gtk.Accessible.update_property(): label` | — |
|
|
486
486
|
| `accessibilityLiveRegion` | refused | — | declares that a screen reader should speak this element when its CONTENT changes. GTK has the announcement — `Gtk.Accessible.announce(message, priority)` since 4.14 — but not the watch: it is an imperative call, and this element’s content is a SUBTREE, which GTK emits no signal for. `<Text>` answers this prop, because its content is one property (`Gtk.Label:label`) and so is both the moment and the message. Elsewhere, call `announce()` on the widget through a ref when you change the content |
|
|
487
|
-
| `accessibilityRole` | property | `accessible-role` | refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
488
|
-
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` |
|
|
487
|
+
| `accessibilityRole` | property | `accessible-role` | takes `adjustable`, `alert`, `button`, `checkbox`, `combobox`, `dropdownlist`, `grid`, `header`, `iconmenu`, `image`, `imagebutton`, `link`, `list`, `menu`, `menubar`, `menuitem`, `none`, `progressbar`, `radio`, `radiogroup`, `scrollbar`, `search`, `spinbutton`, `switch`, `tab`, `tabbar`, `tablist`, `text`, `timer`, `togglebutton`, `toolbar`, `viewgroup`, `webview`; refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
488
|
+
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` | takes `busy`, `checked`, `disabled`, `expanded`, `selected` |
|
|
489
489
|
| `accessible` | ignored | — | asks for two things, and GTK already answers one: every GTK widget is in the accessibility tree, so “this element is an accessibility element” is the desktop default rather than an opt-in. The other thing it asks — merge my whole subtree into ONE accessible node, which is what `accessible={true}` does on iOS — GTK has no mechanism for, and a desktop screen reader navigates the widget tree it is given. To take an element OUT of that tree, set `accessibilityRole="none"`: it is the one prop that writes `Gtk.Accessible:accessible-role`, and two props writing one property is the silent-drop shape this table refuses by name |
|
|
490
490
|
| `delayLongPress` | refused | — | see `onLongPress` |
|
|
491
491
|
| `delayPressIn` | refused | — | see `onPressIn` — there is no press-in event to delay |
|
|
@@ -499,7 +499,7 @@ widget `GtkBox` · takes no text child.
|
|
|
499
499
|
| `onPress` | gesture | `Gtk.GestureClick::released` | — |
|
|
500
500
|
| `onPressIn` | refused | — | 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 |
|
|
501
501
|
| `onPressOut` | refused | — | see `onPressIn` — `active:` is the mechanism |
|
|
502
|
-
| `pointerEvents` | property | `can-target` |
|
|
502
|
+
| `pointerEvents` | property | `can-target` | takes `auto`, `none` |
|
|
503
503
|
| `pressRetentionOffset` | refused | — | see `hitSlop` — GTK hit-tests the allocation and nothing around it |
|
|
504
504
|
| `testID` | property | `name` | — |
|
|
505
505
|
| `touchSoundDisabled` | ignored | — | an Android touch sound; a desktop button makes none |
|
|
@@ -523,8 +523,8 @@ widget `GtkButton` · takes no text child.
|
|
|
523
523
|
| `accessibilityHint` | accessible | `Gtk.Accessible.update_property(): help-text` | — |
|
|
524
524
|
| `accessibilityLabel` | accessible | `Gtk.Accessible.update_property(): label` | — |
|
|
525
525
|
| `accessibilityLiveRegion` | refused | — | declares that a screen reader should speak this element when its CONTENT changes. GTK has the announcement — `Gtk.Accessible.announce(message, priority)` since 4.14 — but not the watch: it is an imperative call, and this element’s content is a SUBTREE, which GTK emits no signal for. `<Text>` answers this prop, because its content is one property (`Gtk.Label:label`) and so is both the moment and the message. Elsewhere, call `announce()` on the widget through a ref when you change the content |
|
|
526
|
-
| `accessibilityRole` | property | `accessible-role` | refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
527
|
-
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` |
|
|
526
|
+
| `accessibilityRole` | property | `accessible-role` | takes `adjustable`, `alert`, `button`, `checkbox`, `combobox`, `dropdownlist`, `grid`, `header`, `iconmenu`, `image`, `imagebutton`, `link`, `list`, `menu`, `menubar`, `menuitem`, `none`, `progressbar`, `radio`, `radiogroup`, `scrollbar`, `search`, `spinbutton`, `switch`, `tab`, `tabbar`, `tablist`, `text`, `timer`, `togglebutton`, `toolbar`, `viewgroup`, `webview`; refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
527
|
+
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` | takes `busy`, `checked`, `disabled`, `expanded`, `selected` |
|
|
528
528
|
| `accessible` | ignored | — | asks for two things, and GTK already answers one: every GTK widget is in the accessibility tree, so “this element is an accessibility element” is the desktop default rather than an opt-in. The other thing it asks — merge my whole subtree into ONE accessible node, which is what `accessible={true}` does on iOS — GTK has no mechanism for, and a desktop screen reader navigates the widget tree it is given. To take an element OUT of that tree, set `accessibilityRole="none"`: it is the one prop that writes `Gtk.Accessible:accessible-role`, and two props writing one property is the silent-drop shape this table refuses by name |
|
|
529
529
|
| `color` | refused | — | 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>` |
|
|
530
530
|
| `disabled` | property | `sensitive` | — |
|
|
@@ -561,13 +561,13 @@ widget `GtkBox` · takes no text child.
|
|
|
561
561
|
| `accessibilityHint` | accessible | `Gtk.Accessible.update_property(): help-text` | — |
|
|
562
562
|
| `accessibilityLabel` | accessible | `Gtk.Accessible.update_property(): label` | — |
|
|
563
563
|
| `accessibilityLiveRegion` | refused | — | declares that a screen reader should speak this element when its CONTENT changes. GTK has the announcement — `Gtk.Accessible.announce(message, priority)` since 4.14 — but not the watch: it is an imperative call, and this element’s content is a SUBTREE, which GTK emits no signal for. `<Text>` answers this prop, because its content is one property (`Gtk.Label:label`) and so is both the moment and the message. Elsewhere, call `announce()` on the widget through a ref when you change the content |
|
|
564
|
-
| `accessibilityRole` | property | `accessible-role` | refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
565
|
-
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` |
|
|
564
|
+
| `accessibilityRole` | property | `accessible-role` | takes `adjustable`, `alert`, `button`, `checkbox`, `combobox`, `dropdownlist`, `grid`, `header`, `iconmenu`, `image`, `imagebutton`, `link`, `list`, `menu`, `menubar`, `menuitem`, `none`, `progressbar`, `radio`, `radiogroup`, `scrollbar`, `search`, `spinbutton`, `switch`, `tab`, `tabbar`, `tablist`, `text`, `timer`, `togglebutton`, `toolbar`, `viewgroup`, `webview`; refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
565
|
+
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` | takes `busy`, `checked`, `disabled`, `expanded`, `selected` |
|
|
566
566
|
| `accessible` | ignored | — | asks for two things, and GTK already answers one: every GTK widget is in the accessibility tree, so “this element is an accessibility element” is the desktop default rather than an opt-in. The other thing it asks — merge my whole subtree into ONE accessible node, which is what `accessible={true}` does on iOS — GTK has no mechanism for, and a desktop screen reader navigates the widget tree it is given. To take an element OUT of that tree, set `accessibilityRole="none"`: it is the one prop that writes `Gtk.Accessible:accessible-role`, and two props writing one property is the silent-drop shape this table refuses by name |
|
|
567
567
|
| `id` | refused | — | 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` |
|
|
568
568
|
| `nativeID` | refused | — | 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` |
|
|
569
569
|
| `onLayout` | refused | — | 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 |
|
|
570
|
-
| `pointerEvents` | property | `can-target` |
|
|
570
|
+
| `pointerEvents` | property | `can-target` | takes `auto`, `none` |
|
|
571
571
|
| `testID` | property | `name` | — |
|
|
572
572
|
|
|
573
573
|
`accessibilityRole` is answered for every other value, and these are refused by name:
|
|
@@ -589,8 +589,8 @@ widget `AdwDialog` · children go into `GtkBox` · takes no text child.
|
|
|
589
589
|
| `accessibilityHint` | accessible | `Gtk.Accessible.update_property(): help-text` | — |
|
|
590
590
|
| `accessibilityLabel` | accessible | `Gtk.Accessible.update_property(): label` | — |
|
|
591
591
|
| `accessibilityLiveRegion` | refused | — | declares that a screen reader should speak this element when its CONTENT changes. GTK has the announcement — `Gtk.Accessible.announce(message, priority)` since 4.14 — but not the watch: it is an imperative call, and this element’s content is a SUBTREE, which GTK emits no signal for. `<Text>` answers this prop, because its content is one property (`Gtk.Label:label`) and so is both the moment and the message. Elsewhere, call `announce()` on the widget through a ref when you change the content |
|
|
592
|
-
| `accessibilityRole` | property | `accessible-role` | refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
593
|
-
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` |
|
|
592
|
+
| `accessibilityRole` | property | `accessible-role` | takes `adjustable`, `alert`, `button`, `checkbox`, `combobox`, `dropdownlist`, `grid`, `header`, `iconmenu`, `image`, `imagebutton`, `link`, `list`, `menu`, `menubar`, `menuitem`, `none`, `progressbar`, `radio`, `radiogroup`, `scrollbar`, `search`, `spinbutton`, `switch`, `tab`, `tabbar`, `tablist`, `text`, `timer`, `togglebutton`, `toolbar`, `viewgroup`, `webview`; refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
593
|
+
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` | takes `busy`, `checked`, `disabled`, `expanded`, `selected` |
|
|
594
594
|
| `accessible` | ignored | — | asks for two things, and GTK already answers one: every GTK widget is in the accessibility tree, so “this element is an accessibility element” is the desktop default rather than an opt-in. The other thing it asks — merge my whole subtree into ONE accessible node, which is what `accessible={true}` does on iOS — GTK has no mechanism for, and a desktop screen reader navigates the widget tree it is given. To take an element OUT of that tree, set `accessibilityRole="none"`: it is the one prop that writes `Gtk.Accessible:accessible-role`, and two props writing one property is the silent-drop shape this table refuses by name |
|
|
595
595
|
| `allowSwipeDismissal` | refused | — | swipe-to-dismiss is a touch gesture; the desktop dismissal is Escape or a click on the backdrop, and `onRequestClose` already reports both |
|
|
596
596
|
| `animationType` | refused | — | libadwaita animates the presentation itself and picks the animation from `Adw.Dialog:presentation-mode` — a floating sheet fades and scales, a bottom sheet slides up — so there is no property that selects one. Reach the dialog through a `ref` and set `presentation-mode` if the sheet should arrive from the bottom |
|
|
@@ -631,8 +631,8 @@ widget `GtkImage` · takes no text child.
|
|
|
631
631
|
| `accessibilityHint` | accessible | `Gtk.Accessible.update_property(): help-text` | — |
|
|
632
632
|
| `accessibilityLabel` | accessible | `Gtk.Accessible.update_property(): label` | — |
|
|
633
633
|
| `accessibilityLiveRegion` | refused | — | declares that a screen reader should speak this element when its CONTENT changes. GTK has the announcement — `Gtk.Accessible.announce(message, priority)` since 4.14 — but not the watch: it is an imperative call, and this element’s content is a SUBTREE, which GTK emits no signal for. `<Text>` answers this prop, because its content is one property (`Gtk.Label:label`) and so is both the moment and the message. Elsewhere, call `announce()` on the widget through a ref when you change the content |
|
|
634
|
-
| `accessibilityRole` | property | `accessible-role` | refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
635
|
-
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` |
|
|
634
|
+
| `accessibilityRole` | property | `accessible-role` | takes `adjustable`, `alert`, `button`, `checkbox`, `combobox`, `dropdownlist`, `grid`, `header`, `iconmenu`, `image`, `imagebutton`, `link`, `list`, `menu`, `menubar`, `menuitem`, `none`, `progressbar`, `radio`, `radiogroup`, `scrollbar`, `search`, `spinbutton`, `switch`, `tab`, `tabbar`, `tablist`, `text`, `timer`, `togglebutton`, `toolbar`, `viewgroup`, `webview`; refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
635
|
+
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` | takes `busy`, `checked`, `disabled`, `expanded`, `selected` |
|
|
636
636
|
| `accessible` | ignored | — | asks for two things, and GTK already answers one: every GTK widget is in the accessibility tree, so “this element is an accessibility element” is the desktop default rather than an opt-in. The other thing it asks — merge my whole subtree into ONE accessible node, which is what `accessible={true}` does on iOS — GTK has no mechanism for, and a desktop screen reader navigates the widget tree it is given. To take an element OUT of that tree, set `accessibilityRole="none"`: it is the one prop that writes `Gtk.Accessible:accessible-role`, and two props writing one property is the silent-drop shape this table refuses by name |
|
|
637
637
|
| `color` | style | `style: color` | — |
|
|
638
638
|
| `id` | refused | — | 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` |
|
|
@@ -661,8 +661,8 @@ widget `GtkBox` · takes no text child.
|
|
|
661
661
|
| `accessibilityHint` | accessible | `Gtk.Accessible.update_property(): help-text` | — |
|
|
662
662
|
| `accessibilityLabel` | accessible | `Gtk.Accessible.update_property(): label` | — |
|
|
663
663
|
| `accessibilityLiveRegion` | refused | — | declares that a screen reader should speak this element when its CONTENT changes. GTK has the announcement — `Gtk.Accessible.announce(message, priority)` since 4.14 — but not the watch: it is an imperative call, and this element’s content is a SUBTREE, which GTK emits no signal for. `<Text>` answers this prop, because its content is one property (`Gtk.Label:label`) and so is both the moment and the message. Elsewhere, call `announce()` on the widget through a ref when you change the content |
|
|
664
|
-
| `accessibilityRole` | property | `accessible-role` | refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
665
|
-
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` |
|
|
664
|
+
| `accessibilityRole` | property | `accessible-role` | takes `adjustable`, `alert`, `button`, `checkbox`, `combobox`, `dropdownlist`, `grid`, `header`, `iconmenu`, `image`, `imagebutton`, `link`, `list`, `menu`, `menubar`, `menuitem`, `none`, `progressbar`, `radio`, `radiogroup`, `scrollbar`, `search`, `spinbutton`, `switch`, `tab`, `tabbar`, `tablist`, `text`, `timer`, `togglebutton`, `toolbar`, `viewgroup`, `webview`; refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
665
|
+
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` | takes `busy`, `checked`, `disabled`, `expanded`, `selected` |
|
|
666
666
|
| `accessible` | ignored | — | asks for two things, and GTK already answers one: every GTK widget is in the accessibility tree, so “this element is an accessibility element” is the desktop default rather than an opt-in. The other thing it asks — merge my whole subtree into ONE accessible node, which is what `accessible={true}` does on iOS — GTK has no mechanism for, and a desktop screen reader navigates the widget tree it is given. To take an element OUT of that tree, set `accessibilityRole="none"`: it is the one prop that writes `Gtk.Accessible:accessible-role`, and two props writing one property is the silent-drop shape this table refuses by name |
|
|
667
667
|
| `behavior` | ignored | — | describes how to move out of an on-screen keyboard’s way, and none appears |
|
|
668
668
|
| `contentContainerStyle` | refused | — | 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 |
|
|
@@ -671,7 +671,7 @@ widget `GtkBox` · takes no text child.
|
|
|
671
671
|
| `keyboardVerticalOffset` | ignored | — | see `behavior` |
|
|
672
672
|
| `nativeID` | refused | — | 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` |
|
|
673
673
|
| `onLayout` | refused | — | 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 |
|
|
674
|
-
| `pointerEvents` | property | `can-target` |
|
|
674
|
+
| `pointerEvents` | property | `can-target` | takes `auto`, `none` |
|
|
675
675
|
| `testID` | property | `name` | — |
|
|
676
676
|
|
|
677
677
|
`accessibilityRole` is answered for every other value, and these are refused by name:
|
|
@@ -697,8 +697,8 @@ widget `GtkBox` · children go into `GtkScrolledWindow` · takes no text child.
|
|
|
697
697
|
| `accessibilityHint` | accessible | `Gtk.Accessible.update_property(): help-text` | — |
|
|
698
698
|
| `accessibilityLabel` | accessible | `Gtk.Accessible.update_property(): label` | — |
|
|
699
699
|
| `accessibilityLiveRegion` | refused | — | declares that a screen reader should speak this element when its CONTENT changes. GTK has the announcement — `Gtk.Accessible.announce(message, priority)` since 4.14 — but not the watch: it is an imperative call, and this element’s content is a SUBTREE, which GTK emits no signal for. `<Text>` answers this prop, because its content is one property (`Gtk.Label:label`) and so is both the moment and the message. Elsewhere, call `announce()` on the widget through a ref when you change the content |
|
|
700
|
-
| `accessibilityRole` | property | `accessible-role` | refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
701
|
-
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` |
|
|
700
|
+
| `accessibilityRole` | property | `accessible-role` | takes `adjustable`, `alert`, `button`, `checkbox`, `combobox`, `dropdownlist`, `grid`, `header`, `iconmenu`, `image`, `imagebutton`, `link`, `list`, `menu`, `menubar`, `menuitem`, `none`, `progressbar`, `radio`, `radiogroup`, `scrollbar`, `search`, `spinbutton`, `switch`, `tab`, `tabbar`, `tablist`, `text`, `timer`, `togglebutton`, `toolbar`, `viewgroup`, `webview`; refuses `drawerlayout`, `horizontalscrollview`, `keyboardkey`, `pager`, `scrollview`, `slidingdrawer`, `summary` — see below |
|
|
701
|
+
| `accessibilityState` | accessible | `busy → Gtk.Accessible.update_state(): busy`, `checked → Gtk.Accessible.update_state(): checked`, `disabled → Gtk.Accessible.update_state(): disabled`, `expanded → Gtk.Accessible.update_state(): expanded`, `selected → Gtk.Accessible.update_state(): selected` | takes `busy`, `checked`, `disabled`, `expanded`, `selected` |
|
|
702
702
|
| `accessible` | ignored | — | asks for two things, and GTK already answers one: every GTK widget is in the accessibility tree, so “this element is an accessibility element” is the desktop default rather than an opt-in. The other thing it asks — merge my whole subtree into ONE accessible node, which is what `accessible={true}` does on iOS — GTK has no mechanism for, and a desktop screen reader navigates the widget tree it is given. To take an element OUT of that tree, set `accessibilityRole="none"`: it is the one prop that writes `Gtk.Accessible:accessible-role`, and two props writing one property is the silent-drop shape this table refuses by name |
|
|
703
703
|
| `columnWrapperStyle` | refused | — | see `numColumns` |
|
|
704
704
|
| `contentContainerStyle` | refused | — | 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` |
|
|
@@ -707,7 +707,7 @@ widget `GtkBox` · children go into `GtkScrolledWindow` · takes no text child.
|
|
|
707
707
|
| `getItem` | ignored | — | read by the component — VirtualizedList’s accessor form of `data` |
|
|
708
708
|
| `getItemCount` | ignored | — | see `getItem` |
|
|
709
709
|
| `getItemLayout` | refused | — | 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 |
|
|
710
|
-
| `horizontal` | property | `orientation`, `hscrollbar-policy`, `vscrollbar-policy` |
|
|
710
|
+
| `horizontal` | property | `orientation`, `hscrollbar-policy`, `vscrollbar-policy` | takes `false`, `true` |
|
|
711
711
|
| `id` | refused | — | 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` |
|
|
712
712
|
| `initialNumToRender` | refused | — | 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 |
|
|
713
713
|
| `initialScrollIndex` | refused | — | 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 |
|
|
@@ -732,8 +732,8 @@ widget `GtkBox` · children go into `GtkScrolledWindow` · takes no text child.
|
|
|
732
732
|
| `renderSectionHeader` | ignored | — | read by the item factory |
|
|
733
733
|
| `scrollEventThrottle` | refused | — | see `onScroll` |
|
|
734
734
|
| `sections` | ignored | — | read by the component — SectionList’s form of `data` |
|
|
735
|
-
| `showsHorizontalScrollIndicator` | property | `hscrollbar-policy` |
|
|
736
|
-
| `showsVerticalScrollIndicator` | property | `vscrollbar-policy` |
|
|
735
|
+
| `showsHorizontalScrollIndicator` | property | `hscrollbar-policy` | takes `false`, `true` |
|
|
736
|
+
| `showsVerticalScrollIndicator` | property | `vscrollbar-policy` | takes `false`, `true` |
|
|
737
737
|
| `stickySectionHeadersEnabled` | refused | — | 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 |
|
|
738
738
|
| `testID` | property | `name` | — |
|
|
739
739
|
| `updateCellsBatchingPeriod` | refused | — | 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 |
|
package/README.md
CHANGED
|
@@ -78,6 +78,23 @@ expect(explainProp('Text', 'onPress')).toContain('Wrap it in a `<Pressable>`');
|
|
|
78
78
|
runtime one. [PROPS.md](PROPS.md) is the generated document, one section per
|
|
79
79
|
primitive, held byte for byte by `check-rn-surface.mjs`.
|
|
80
80
|
|
|
81
|
+
**A prop can be answered and still refuse a VALUE, and the table says so at both
|
|
82
|
+
grains** — `propRefusedValues` lists the spellings with a reason of their own,
|
|
83
|
+
`propAllowedValues` lists the ones a mapped prop takes at all, and
|
|
84
|
+
`acceptsPropValue`/`explainPropValue` answer for one value:
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
acceptsPropValue('View', 'pointerEvents', 'box-none'); // false — GTK's `can-target`
|
|
88
|
+
propAllowedValues('View', 'pointerEvents'); // ['auto', 'none']
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Both halves are needed because they are different facts: a value can be refused by
|
|
92
|
+
NAME, with its own sentence, or by being absent from the list its route maps. Reading
|
|
93
|
+
only the first answered ACCEPTED for `box-none` until #1648 (ADR 0039 § Amendment).
|
|
94
|
+
What is still not answered is the TYPE grain — `acceptsPropValue('Text',
|
|
95
|
+
'selectable', 'yes')` is `true` while a render refuses the string — because that is a
|
|
96
|
+
predicate rather than a list; `status/open-todos.md` carries what it would take.
|
|
97
|
+
|
|
81
98
|
## `<TextInput>`'s ref is a handle, not the widget
|
|
82
99
|
|
|
83
100
|
React Native's `TextInput` is a class, so `useRef<TextInput>(null)` and
|
package/lib/esm/components.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./_virtual/_rolldown/runtime.js";import{applyAccessibility as e}from"./accessibility.js";import{accessor as t}from"./accessor.js";import{PrimitiveError as n}from"./primitives/errors.js";import{onLiveRegion as
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import{applyAccessibility as e}from"./accessibility.js";import{accessor as t}from"./accessor.js";import{PrimitiveError as n,describeElement as r}from"./primitives/errors.js";import{onLiveRegion as i}from"./announce.js";import{splitAnimatedStyle as a}from"./primitives/style.js";import{resolvePrimitive as o}from"./primitives/resolve.js";import{childFacts as s,childNodes as c,isAbsoluteChild as l,isTextNode as u}from"./child-facts.js";import{ParentContext as d,ParentProvider as f}from"./parent-context.js";import{onGesture as p,onPressStateChange as m}from"./press.js";import{createHandle as h}from"./primitives/handles.js";import{animatedProperty as g,assertNoStaticClash as _}from"./animated/properties.js";import{styleConfig as v}from"./style-config.js";import y from"gi://GObject?version=2.0";import b from"gi://Gtk?version=4.0";import x from"gi://Gio?version=2.0";import S from"gi://GLib?version=2.0";import{createElement as C,useCallback as w,useContext as T,useEffect as E,useMemo as D,useRef as O,useState as k}from"react";function useSignals(e,n){let r=O(null),i=O(n);return i.current=n,{props:D(()=>{let n={};for(let a of e)n[`on:${a.signal}`]=()=>{let e=i.current[a.prop];if(typeof e!=`function`)return;if(a.read===null){e();return}let n=r.current;e(n===null?void 0:n[t(a.read)])};return n},[e.map(e=>`${e.prop}>${e.signal}>${e.read??``}`).join(`|`)]),widgetRef:r}}function nodeProps(e,t,n){let r={...t,...e.props,...n};return e.cssClasses.length>0&&(r[`css-classes`]=[...e.cssClasses]),r}function usePlan(e,t){let i=t,a=T(d),l=v(),u=c(i.children),f=o(e,i,{tokens:l.tokens,sheet:l.sheet,...a===null?{}:{parent:a},children:s(u,l.tokens)}),p=Object.keys(f.intent);if(p.length>0)throw new n(e,p.join(`, `),"carries layout that only a parent can resolve — `flex-1` and `self-*` need the parent orientation, `absolute` needs the parent to be an overlay — and no parent context was published above this element: either it is the root of its React tree, or it was built outside its parent’s provider. Wrap it in a <View>, or move the utility to a child.",r(i));let m=useSignals(f.events,i),g=i.ref,_=f.handle,y=f.node.tag,b=D(()=>e=>{m.widgetRef.current=e;let t=e==null?e:h(_,e,y);typeof g==`function`?g(t):g!=null&&(g.current=t)},[g,m.widgetRef,_,y]);useGestures(f.gestures,i,m.widgetRef),useLiveRegions(f.announcements,m.widgetRef),useAccessibility(f.accessibility,m.widgetRef);let x=useFiles(f.files),S={...m.props,ref:b,...x.outer};f.slot!==null&&(S.slot=f.slot);let C={...x.content};f.contentSlot!==null&&(C.slot=f.contentSlot);let w={...x.backdrop};f.backdropSlot!==null&&(w.slot=f.backdropSlot);let E=D(()=>f.childContext,[JSON.stringify(f.childContext),f.childContext]);return{plan:f,children:u,inherited:a?.props??{},extra:S,contentExtra:C,backdropExtra:w,published:E,tokens:l.tokens,widgetRef:m.widgetRef}}function useFiles(e){return D(()=>{let t={outer:{},content:{},backdrop:{}};for(let n of e)t[n.on][n.property]=n.kind===`path`?x.File.new_for_path(n.value):x.File.new_for_uri(n.value);return t},[e.map(e=>`${e.on}>${e.property}>${e.kind}>${e.value}`).join(`|`)])}function useGestures(e,t,n){let r=O(t);r.current=t;let i=e.map(e=>`${e.prop}>${e.signal}`).join(`|`);E(()=>{let e=n.current;if(i===``||e==null)return;let t=i.split(`|`).map(t=>{let[n,i]=t.split(`>`);return p(e,i,()=>{let e=r.current[n];typeof e==`function`&&e()})});return()=>{for(let e of t)e()}},[i,n])}function useLiveRegions(e,t){let n=e.map(e=>`${e.signal}>${e.read}>${e.priority}`).join(`|`);E(()=>{let e=t.current;if(n===``||e==null)return;let r=n.split(`|`).map(t=>{let[n,r,a]=t.split(`>`);return i(e,{prop:`accessibilityLiveRegion`,signal:n,read:r,priority:a})});return()=>{for(let e of r)e()}},[n,t])}function useAccessibility(t,n){let r=t.length===0?``:JSON.stringify(t);E(()=>{let t=n.current;if(!(r===``||t==null))return e(t,JSON.parse(r))},[r,n])}function render(e){let{plan:t,children:n,inherited:r,extra:i,contentExtra:a,backdropExtra:o,published:s,tokens:c}=e,wrap=e=>C(f,{value:s},...e);if(t.content===null){let e=t.textSink!==null&&n.every(u)?n:[wrap(n)];return C(t.node.tag,nodeProps(t.node,r,i),...e)}let d=t.absoluteSlot===null?[]:n.filter(e=>l(e,c)),p=t.absoluteSlot===null?n:n.filter(e=>!l(e,c)),m=C(t.content.tag,nodeProps(t.content,{},a),wrap(p)),h=t.backdrop===null?[]:[C(t.backdrop.tag,nodeProps(t.backdrop,{},o))];return C(t.node.tag,nodeProps(t.node,r,i),...h,m,...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]=k(!1),i=usePlan(`Pressable`,t===null?e:{...e,children:t({pressed:n})}),a=i.widgetRef;return E(()=>{if(t===null)return;let e=a.current;if(e!=null)return m(e,r)},[t===null,a]),render(i)}const A=y.registerClass({GTypeName:`GjsifyReactNativeRailLayout`},class RailLayout extends b.BoxLayout{vfunc_measure(e,t,n){let plain=n=>super.vfunc_measure(e,t,n);if(t!==b.Orientation.VERTICAL||n>=0||this.get_orientation()!==b.Orientation.HORIZONTAL)return plain(n);let r=super.vfunc_measure(e,b.Orientation.HORIZONTAL,-1)[0],i=e.get_ancestor(b.ScrolledWindow.$gtype),a=i===null?0:Math.round(i.get_hadjustment().get_page_size()),o=Math.max(a,r);if(o<=0)return plain(n);let[,s,,c]=super.vfunc_measure(e,b.Orientation.VERTICAL,o);return[s,s,c,c]}});let j=0;const railWatchCount=()=>j;function useIntrinsicContentHeight(e){let t=O(null),n=O(null);return w(r=>{let i=t.current;i!==null&&(i.adjustment.disconnect(i.id),t.current=null,--j),n.current!==null&&(S.source_remove(n.current),n.current=null);let a=r??null;if(a===null||!e)return;let o=a.get_layout_manager();if(!(o instanceof A)){let e=new A({orientation:b.Orientation.HORIZONTAL});o instanceof b.BoxLayout&&e.set_spacing(o.get_spacing()),a.set_layout_manager(e)}let s=a.get_ancestor(b.ScrolledWindow.$gtype);if(s===null)return;let c=s.get_hadjustment(),l=c.connect(`notify::page-size`,()=>{n.current===null&&(n.current=S.idle_add(S.PRIORITY_DEFAULT_IDLE,()=>(n.current=null,a.queue_resize(),S.SOURCE_REMOVE)))});t.current={adjustment:c,id:l},j+=1},[e])}function ScrollView(e){let t=usePlan(`ScrollView`,e),n=useIntrinsicContentHeight(e.horizontal===!0);return render({...t,contentExtra:{...t.contentExtra,ref:n}})}function ActivityIndicator(e){return render(usePlan(`ActivityIndicator`,e))}function TextInput(e){return render(usePlan(`TextInput`,e))}function Switch(e){return render(usePlan(`Switch`,e))}function Image(e){return render(usePlan(`Image`,e))}function ImageBackground(e){return render(usePlan(`ImageBackground`,e))}function TouchableOpacity(e){return render(usePlan(`TouchableOpacity`,e))}function TouchableHighlight(e){return render(usePlan(`TouchableHighlight`,e))}function TouchableWithoutFeedback(e){return render(usePlan(`TouchableWithoutFeedback`,e))}function Button(e){return render(usePlan(`Button`,e))}function SafeAreaView(e){return render(usePlan(`SafeAreaView`,e))}function Modal(e){let t=usePlan(`Modal`,e);return e.visible===!1?null:render(t)}function KeyboardAvoidingView(e){return render(usePlan(`KeyboardAvoidingView`,e))}function StatusBar(e){return null}const M="configures the status bar above a phone screen, and a desktop window has none — the space above it belongs to the compositor and the header bar inside it is `Adw.HeaderBar`, an ordinary widget you render. This refuses rather than accepting the call, because a setter that appears to work is indistinguishable from one that does";Object.defineProperties(StatusBar,Object.getOwnPropertyDescriptors({setBarStyle:()=>{throw new n(`StatusBar`,`setBarStyle`,M)},setHidden:()=>{throw new n(`StatusBar`,`setHidden`,M)},setBackgroundColor:()=>{throw new n(`StatusBar`,`setBackgroundColor`,M)},setTranslucent:()=>{throw new n(`StatusBar`,`setTranslucent`,M)},setNetworkActivityIndicatorVisible:()=>{throw new n(`StatusBar`,`setNetworkActivityIndicatorVisible`,M)},pushStackEntry:()=>{throw new n(`StatusBar`,`pushStackEntry`,M)},popStackEntry:()=>{throw new n(`StatusBar`,`popStackEntry`,M)},replaceStackEntry:()=>{throw new n(`StatusBar`,`replaceStackEntry`,M)},get currentHeight(){throw new n(`StatusBar`,`currentHeight`,"is the height of a phone’s status bar, and code reads it straight into a layout (`paddingTop: StatusBar.currentHeight`). A desktop window has no such bar, so any number here would inset every ported screen by a bar that is not there. Use 0 explicitly if that is what you mean")}}));function animatedBindings(e,t){let{plain:n,animated:r}=a(t),i=[];for(let[t,n]of Object.entries(r))g(e,t),i.push({key:t,value:n});return{plain:n,bindings:i}}function AnimatedView(e){let n=v(),{plain:r,bindings:i}=animatedBindings(`Animated.View`,e.style),a={...e,style:r};_(`Animated.View`,a,i.map(e=>e.key),n.tokens);let o=usePlan(`View`,a),s=o.widgetRef,c=i.map(e=>`${e.key}#${e.value.id}`).join(`|`),l=O(i);l.current=i,E(()=>{let e=s.current;if(c===``||e==null)return;let n=e,r=l.current.map(r=>{let i=t(g(`Animated.View`,r.key).property);return r.value.__attach({widget:e,write:e=>{n[i]=e}})});return()=>{for(let e of r)e()}},[c,s]);let u={};for(let e of i)u[t(g(`Animated.View`,e.key).property)]=e.value.__getValue();return render({...o,extra:{...o.extra,...u}})}function Icon(e){return render(usePlan(`Icon`,e))}export{ActivityIndicator,AnimatedView,Button,Icon,Image,ImageBackground,KeyboardAvoidingView,Modal,Pressable,SafeAreaView,ScrollView,StatusBar,Switch,Text,TextInput,TouchableHighlight,TouchableOpacity,TouchableWithoutFeedback,View,nodeProps,railWatchCount,usePlan};
|
package/lib/esm/press.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./_virtual/_rolldown/runtime.js";import e from"gi://Gtk?version=4.0";let
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import e from"gi://GObject?version=2.0";import t from"gi://Gtk?version=4.0";let n=0;const pressWatchCount=()=>n,isPressed=e=>(e.get_state_flags()&t.StateFlags.ACTIVE)!==0;function onPressStateChange(e,t){let r=isPressed(e),i=e.connect(`state-flags-changed`,()=>{let n=isPressed(e);n!==r&&(r=n,t(n))});return n+=1,t(r),()=>{e.disconnect(i),--n}}function onGesture(n,r,i){let a=new t.GestureClick,o=e.signal_connect(a,r,()=>i());return n.add_controller(a),()=>{n.remove_controller(a),a.disconnect(o)}}export{onGesture,onPressStateChange,pressWatchCount};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"../_virtual/_rolldown/runtime.js";const
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import{describeValue as e,unknownAccessibleKeyDetail as t}from"./errors.js";const n={false:0,true:1,mixed:2};function coerceAttribute(e,t){switch(e.as){case`string`:return typeof t==`string`?t:null;case`boolean`:return typeof t==`boolean`?t:null;case`tristate`:return typeof t==`boolean`?t?n.true:n.false:t===`mixed`?n.mixed:null}}const r={string:`a string`,boolean:`true or false`,tristate:`true, false or "mixed" — GTK reads it as a Gtk.AccessibleTristate`};function resolveAccessible(n,i,a){if(n.from===`value`){let t=coerceAttribute(n.attribute,a);return t===null?{entries:[],problem:`writes the GTK accessible ${n.attribute.set} "${n.attribute.name}" and needs ${r[n.attribute.as]}; got ${e(a)}`}:{entries:[{prop:i,set:n.attribute.set,name:n.attribute.name,value:t}],problem:null}}if(typeof a!=`object`||!a||Array.isArray(a))return{entries:[],problem:`is a record of accessibility states and needs an object — its keys are ${Object.keys(n.members).sort().join(`, `)}; got ${e(a)}`};let o=[];for(let[s,c]of Object.entries(a)){if(c===void 0)continue;let a=n.refuses[s];if(a!==void 0)return{entries:[],problem:`carries "${s}", which ${a}`};let l=n.members[s];if(l===void 0)return{entries:[],problem:t(s,Object.keys(n.members))};let u=coerceAttribute(l,c);if(u===null)return{entries:[],problem:`carries "${s}", which needs ${r[l.as]}; got ${e(c)}`};o.push({prop:i,set:l.set,name:l.name,value:u})}return{entries:o,problem:null}}export{resolveAccessible};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"../_virtual/_rolldown/runtime.js";function accessibleReach(e){let call=e=>e===`property`?`Gtk.Accessible.update_property()`:`Gtk.Accessible.update_state()`;return e.from===`value`?[`${call(e.attribute.set)}: ${e.attribute.name}`]:Object.keys(e.members).sort().map(t=>{let n=e.members[t];return`${t} → ${call(n.set)}: ${n.name}`})}const isAccepted=e=>e!==`refused`&&e!==`unknown`,unknownPropDetail=e=>`is not a prop this primitive answers for. It takes: ${Object.keys(e.props).sort().join(`, `)}. An unlisted prop is refused rather than dropped: a prop that silently does nothing is indistinguishable from a bug in the application, forever`,unknownPrimitiveDetail=e=>`is not a primitive this layer answers for. Known: ${[...e].sort().join(`, `)}`,e={};function answerForRoute(t){switch(t.to){case`property`:return{status:`property`,why:``,gtk:t.names,refuses:t.refuses??e};case`style-property`:return{status:`style`,why:``,gtk:[`style: ${t.name}`],refuses:e};case`event`:return{status:`event`,why:``,gtk:[t.signal],refuses:e};case`file`:return{status:`file`,why:``,gtk:[t.property],refuses:e};case`gesture`:return{status:`gesture`,why:``,gtk:[`Gtk.GestureClick::${t.signal}`],refuses:e};case`announce`:return{status:`announcement`,why:``,gtk:[t.signal,`Gtk.Accessible.announce()`],refuses:e};case`accessible`:return{status:`accessible`,why:``,gtk:accessibleReach(t),refuses:t.from===`members`?t.refuses:e};case`ignored`:return{status:`ignored`,why:t.why,gtk:[],refuses:e};case`refused`:return{status:`refused`,why:t.why,gtk:[],refuses:e}}}function answerFor(t,n,r,i){if(n.refusesStyle!==void 0&&(r===`style`||r===`className`))return{primitive:t,prop:r,status:`refused`,why:n.refusesStyle,gtk:[],refuses:e};if(i.has(r))return{primitive:t,prop:r,status:`framework`,why:``,gtk:[],refuses:e};let a=n.props[r];if(a===void 0)return{primitive:t,prop:r,status:`unknown`,why:unknownPropDetail(n),gtk:[],refuses:e};let o=(Array.isArray(a)?a:[a]).map(answerForRoute),s=o[0];return{primitive:t,prop:r,status:s.status,why:s.why,gtk:o.flatMap(e=>e.gtk),refuses:Object.assign({},...o.map(e=>e.refuses))}}function propNamesOf(e){return Object.keys(e.props).sort()}export{answerFor,isAccepted,propNamesOf,unknownPrimitiveDetail,unknownPropDetail};
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";function accessibleReach(e){let call=e=>e===`property`?`Gtk.Accessible.update_property()`:`Gtk.Accessible.update_state()`;return e.from===`value`?[`${call(e.attribute.set)}: ${e.attribute.name}`]:Object.keys(e.members).sort().map(t=>{let n=e.members[t];return`${t} → ${call(n.set)}: ${n.name}`})}const isAccepted=e=>e!==`refused`&&e!==`unknown`,unknownPropDetail=e=>`is not a prop this primitive answers for. It takes: ${Object.keys(e.props).sort().join(`, `)}. An unlisted prop is refused rather than dropped: a prop that silently does nothing is indistinguishable from a bug in the application, forever`,unknownPrimitiveDetail=e=>`is not a primitive this layer answers for. Known: ${[...e].sort().join(`, `)}`,e={},named=e=>({values:e,numbers:!1});function coercionVocabulary(e){switch(e.as){case`map`:return named(Object.keys(e.map??{}));case`pixels-or-map`:return{values:Object.keys(e.map??{}),numbers:!0};case`string`:case`boolean`:case`not`:case`int`:return null}}function routeValueVocabulary(e){switch(e.to){case`property`:return coercionVocabulary(e);case`announce`:return named(Object.keys(e.map));case`accessible`:return e.from===`members`?named(Object.keys(e.members)):null;case`style-property`:case`event`:case`file`:case`gesture`:case`ignored`:case`refused`:return null}}function intersectVocabularies(e){let t=e.filter(e=>e!==null);return t.length===0?null:{values:t[0].values.filter(e=>t.every(t=>t.values.includes(e))),numbers:t.every(e=>e.numbers)}}function answerForRoute(t){let n=routeValueVocabulary(t);switch(t.to){case`property`:return{status:`property`,why:``,gtk:t.names,refuses:t.refuses??e,allows:n};case`style-property`:return{status:`style`,why:``,gtk:[`style: ${t.name}`],refuses:e,allows:n};case`event`:return{status:`event`,why:``,gtk:[t.signal],refuses:e,allows:n};case`file`:return{status:`file`,why:``,gtk:[t.property],refuses:e,allows:n};case`gesture`:return{status:`gesture`,why:``,gtk:[`Gtk.GestureClick::${t.signal}`],refuses:e,allows:n};case`announce`:return{status:`announcement`,why:``,gtk:[t.signal,`Gtk.Accessible.announce()`],refuses:e,allows:n};case`accessible`:return{status:`accessible`,why:``,gtk:accessibleReach(t),refuses:t.from===`members`?t.refuses:e,allows:n};case`ignored`:return{status:`ignored`,why:t.why,gtk:[],refuses:e,allows:n};case`refused`:return{status:`refused`,why:t.why,gtk:[],refuses:e,allows:n}}}function answerFor(t,n,r,i){if(n.refusesStyle!==void 0&&(r===`style`||r===`className`))return{primitive:t,prop:r,status:`refused`,why:n.refusesStyle,gtk:[],refuses:e,allows:null};if(i.has(r))return{primitive:t,prop:r,status:`framework`,why:``,gtk:[],refuses:e,allows:null};let a=n.props[r];if(a===void 0)return{primitive:t,prop:r,status:`unknown`,why:unknownPropDetail(n),gtk:[],refuses:e,allows:null};let o=(Array.isArray(a)?a:[a]).map(answerForRoute),s=o[0];return{primitive:t,prop:r,status:s.status,why:s.why,gtk:o.flatMap(e=>e.gtk),refuses:Object.assign({},...o.map(e=>e.refuses)),allows:intersectVocabularies(o.map(e=>e.allows))}}function propNamesOf(e){return Object.keys(e.props).sort()}export{answerFor,isAccepted,propNamesOf,routeValueVocabulary,unknownPrimitiveDetail,unknownPropDetail};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"../_virtual/_rolldown/runtime.js";const primitiveErrorMessage=(e,t,n)=>`@gjsify/react-native: <${e}>${t===``?``:` ${t}`} — ${n}`,describeValue=e=>typeof e==`string`?`"${e}"`:typeof e==`object`&&e?Object.prototype.toString.call(e):String(e)
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";const primitiveErrorMessage=(e,t,n,r=``)=>`@gjsify/react-native: <${e}>${t===``?``:` ${t}`} — ${n}${r===``?``:` ${r}`}`,describeElement=e=>{let t=[],n=(Array.isArray(e.className)?e.className.filter(e=>typeof e==`string`).join(` `):typeof e.className==`string`?e.className:``).trim().replace(/\s+/gu,` `);return n!==``&&t.push(`className="${n.length>120?`${n.slice(0,117)}…`:n}"`),typeof e.testID==`string`&&e.testID!==``&&t.push(`testID="${e.testID}"`),t.length===0?``:`[${t.join(` `)}]`},describeValue=e=>typeof e==`string`?`"${e}"`:typeof e==`object`&&e?Object.prototype.toString.call(e):String(e),unknownMappedValueDetail=(e,t)=>`has no GTK equivalent for ${e}. Known: ${[...t].sort().join(`, `)}. A value absent from that list is absent because GTK has no member for it, not because the table is short`,unknownAccessibleKeyDetail=(e,t)=>`carries "${e}", which is not a state this layer answers for. It takes: ${[...t].sort().join(`, `)}`;var PrimitiveError=class extends Error{constructor(e,t,n,r=``){super(primitiveErrorMessage(e,t,n,r)),this.name=`PrimitiveError`,this.primitive=e,this.subject=t,this.where=r}};export{PrimitiveError,describeElement,describeValue,primitiveErrorMessage,unknownAccessibleKeyDetail,unknownMappedValueDetail};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"../_virtual/_rolldown/runtime.js";import{PrimitiveError as e,describeValue as t}from"./errors.js";import{resolveAccessible as
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import{PrimitiveError as e,describeValue as t,unknownMappedValueDetail as n}from"./errors.js";import{resolveAccessible as r}from"./accessibility.js";import{unknownPrimitiveDetail as i,unknownPropDetail as a}from"./answers.js";import{resolveIntent as o}from"./intents.js";import{mintClass as s,normalise as c,partition as l,variantDeclarations as u}from"./style.js";import{FRAMEWORK_PROPS as d,PRIMITIVES as f,PRIMITIVE_NAMES as p}from"./table.js";const m=[`orientation`,`spacing`],withOrientationClass=(e,t)=>{if(t.length===0)return t;let n=e.orientation;return typeof n==`string`?[n,...t]:t},wrapped=(e,t,n)=>{if(n===null)return{tag:e,props:t};let{spacing:r,...i}=t;return{tag:n.tag,props:{...i,...n.props}}};function declaresAbsolute(e,t,n=`View`){let{props:r}=c(e,t,n);return l(r).intent.overlay?.role===`child`}function resolvePrimitive(t,n,r){let h=f[t];if(h===void 0)throw new e(t,``,i(p));let g=h.switchOn!==void 0&&n[h.switchOn.prop]===!0?h.switchOn.whenTrue:h,_=g.content,v={...g.widgetProps},y={..._?.widgetProps},b={...g.backdrop?.widgetProps},x={},S=[],C=[],w=[],T=[],E=[],D=new Set([_?.styleProp,_?.classNameProp,g.backdrop?.styleProp,g.backdrop?.classNameProp].filter(e=>typeof e==`string`));if(g.refusesStyle!==void 0&&(n.className!==void 0||n.style!==void 0))throw new e(t,n.className===void 0?`prop "style"`:`prop "className"`,g.refusesStyle);for(let r of Object.keys(n)){if(d.has(r)||D.has(r))continue;let i=n[r];if(i===void 0)continue;let o=g.props[r];if(o===void 0)throw new e(t,`prop "${r}"`,a(g));for(let e of Array.isArray(o)?o:[o])applyRoute(e,r,i,{primitive:t,spec:g,outerProps:v,contentProps:y,backdropProps:b,styleExtra:x,events:S,files:C,gestures:w,announcements:T,accessibility:E})}let O=c(n,r.tokens,t),k=l({...O.props,...x}),A=orientationOf(k.props.orientation??v.orientation,g.orientation),j=_===void 0?A:orientationOf(y.orientation,_.orientation),M=o({primitive:t,intent:k.intent,orientation:j,widget:g.widget,...r.parent===void 0?{}:{parent:r.parent},...r.children===void 0?{}:{children:r.children},emittedProps:k.props}),N=s(r.sheet,[...k.css,...M.css],u(O.groups,r.tokens,t));Object.assign(v,k.props,M.props),assertOneTextAuthority(t,g,v,r.children);let P=[...g.cssClasses,...N===null?[]:[N]],F=g.overlayOnAbsoluteChild;if(F!==void 0&&(r.children?.absolute??0)>0){let e={...g.widgetProps};for(let t of m)v[t]!==void 0&&(e[t]=v[t],delete v[t]);let n=wrapped(g.tag,e,M.wrapping);return{primitive:t,node:{tag:F.tag,props:v,cssClasses:withOrientationClass(v,P)},content:{tag:n.tag,props:n.props,cssClasses:[]},backdrop:null,backdropSlot:null,contentSlot:null,slot:M.slot,absoluteSlot:F.slot,events:S,files:C,gestures:w,announcements:T,accessibility:E,handle:g.handle??null,textSink:g.textSink,childContext:{...M.childContext,orientation:j,overlay:!0},intent:M.remaining}}let I=_===void 0?null:resolveNode(_,n,y,r,t),L=g.backdrop===void 0?null:resolveNode(g.backdrop,n,b,r,t),R=wrapped(g.tag,v,M.wrapping);return{primitive:t,node:{tag:R.tag,props:R.props,cssClasses:withOrientationClass(R.props,P)},content:I===null?null:I.node,backdrop:L===null?null:L.node,backdropSlot:g.backdrop?.slot??null,contentSlot:_?.slot??null,slot:M.slot,absoluteSlot:null,events:S,files:C,gestures:w,announcements:T,accessibility:E,handle:g.handle??null,textSink:g.textSink,childContext:I===null?{...M.childContext,overlay:!1}:{...I.childContext,...I.childContext.textAlign===void 0&&M.childContext.textAlign!==void 0?{textAlign:M.childContext.textAlign}:{},overlay:!1},intent:M.remaining}}function resolveNode(e,t,n,r,i){let a=`${i} ${e.styleProp??`content`}`,d=c({...e.classNameProp===null?{}:{className:t[e.classNameProp]},...e.styleProp===null?{}:{style:t[e.styleProp]}},r.tokens,a),f=l(d.props),p=orientationOf(f.props.orientation??n.orientation,e.orientation),m=o({primitive:a,intent:f.intent,orientation:p,widget:e.widget,parent:{orientation:p,props:{},overlay:!1},emittedProps:f.props}),h=s(r.sheet,[...f.css,...m.css],u(d.groups,r.tokens,a));Object.assign(n,f.props,m.props);let g=wrapped(e.tag,n,m.wrapping);return{node:{tag:g.tag,props:g.props,cssClasses:withOrientationClass(g.props,h===null?[]:[h])},childContext:{...m.childContext,orientation:p}}}function applyRoute(i,a,o,s){switch(i.to){case`refused`:throw new e(s.primitive,`prop "${a}"`,i.why);case`ignored`:return;case`style-property`:s.styleExtra[i.name]=o;return;case`event`:if(typeof o!=`function`)throw new e(s.primitive,`prop "${a}"`,`binds the GTK signal "${i.signal}" and needs a function; got ${t(o)}`);s.events.push({prop:a,signal:i.signal,read:i.read??null});return;case`file`:s.files.push({on:nodeOf(i.on,s,a),property:i.property,...normaliseSource(s.primitive,a,o)});return;case`gesture`:if(typeof o!=`function`)throw new e(s.primitive,`prop "${a}"`,`binds a Gtk.GestureClick's "${i.signal}" and needs a function; got ${t(o)}`);s.gestures.push({prop:a,signal:i.signal});return;case`announce`:{let r=i.map[String(o)];if(r===void 0)throw new e(s.primitive,`prop "${a}"`,n(t(o),Object.keys(i.map)));if(r===null)return;s.announcements.push({prop:a,signal:i.signal,read:i.read,priority:r});return}case`accessible`:{let{entries:t,problem:n}=r(i,a,o);if(n!==null)throw new e(s.primitive,`prop "${a}"`,n);s.accessibility.push(...t);return}case`property`:{let e=nodeOf(i.on,s,a),t=e===`content`?s.contentProps:e===`backdrop`?s.backdropProps:s.outerProps,n=coerce(i,a,o,s.primitive);for(let e of i.names)t[e]=n;i.also!==void 0&&Object.assign(t,i.also);return}}}function nodeOf(t,n,r){if(t===`content`&&n.spec.content===void 0)throw new e(n.primitive,`prop "${r}"`,`is routed to a content node this primitive does not declare — the table is wrong, not the call`);if(t===`backdrop`&&n.spec.backdrop===void 0)throw new e(n.primitive,`prop "${r}"`,`is routed to a backdrop node this primitive does not declare — the table is wrong, not the call`);return t??`outer`}function normaliseSource(n,r,i){let refuse=t=>{throw new e(n,`prop "${r}"`,t)};if(typeof i==`number`)return refuse("is a number, which is what `require('./image.png')` returns: an opaque id into React Native’s own asset registry. This build chain has no such registry (ADR 0032 § 12 leaves the build to the consumer), so there is nothing to resolve it against. Use `{ uri: '/path/to/image.png' }`, or ship the image in a GResource and use `{ uri: 'resource:///…' }`");if(Array.isArray(i))return refuse("is an array, which is React Native’s per-device-scale picker (`@2x`, `@3x`). GTK draws ONE texture and scales it by the surface’s own scale factor, so there is no candidate to choose between. Give one source");if(typeof i==`string`)return refuse("is a bare string. React Native’s own type is `{ uri }`, and accepting both spellings here would make one string ambiguous between a path and a URI at exactly the layer that has to decide. Write `{ uri: … }`");if(typeof i!=`object`||!i)return refuse(`expects { uri }; got ${t(i)}`);let a=i,o=Object.keys(a).filter(e=>e!==`uri`);if(o.length>0)return refuse(`carries ${o.join(`, `)} beside \`uri\`. Those describe a remote image React Native measures before it arrives (\`width\`/\`height\`) or fetches with headers, and neither reaches a \`Gtk.Picture\` — it takes a file and draws it. Keep \`uri\` alone`);let s=a.uri;if(typeof s!=`string`||s===``)return refuse(`expects { uri: string }; got uri = ${t(s)}`);let c=/^([a-zA-Z][a-zA-Z0-9+.-]+):/.exec(s)?.[1]?.toLowerCase();return c===void 0?{kind:`path`,value:s}:c===`file`||c===`resource`?{kind:`uri`,value:s}:refuse(c===`http`||c===`https`||c===`data`?`is a \`${c}:\` URI, and loading one needs a fetch, a decoder and a cache — an asynchronous pipeline this layer does not own. Handing a non-native \`Gio.File\` to \`Gtk.Picture:file\` would decode on the main loop instead. Fetch the bytes yourself, build a \`Gdk.Texture\`, and set \`paintable\` through a ref`:`is a \`${c}:\` URI, and this layer only opens what GTK can read synchronously: a local path, \`file:\` and \`resource:\` (measured). Anything else needs a loader that is not here`)}function coerce(n,r,i,a){let bad=n=>{throw new e(a,`prop "${r}"`,`expects ${n}; got ${t(i)}`)};switch(n.as){case`string`:return typeof i==`string`?i:typeof i==`number`||typeof i==`boolean`?String(i):bad(`a string`);case`boolean`:return typeof i==`boolean`?i:bad(`a boolean`);case`not`:return typeof i==`boolean`?!i:bad(`a boolean`);case`int`:return typeof i==`number`&&Number.isFinite(i)?Math.trunc(i):bad(`a number`);case`map`:return lookup(n,r,i,a);case`pixels-or-map`:return typeof i==`number`&&Number.isFinite(i)?Math.trunc(i):lookup(n,r,i,a)}}function lookup(r,i,a,o){let s=r.map??{},c=s[String(a)];if(c!==void 0)return c;let l=r.refuses?.[String(a)];throw l===void 0?new e(o,`prop "${i}"`,n(t(a),Object.keys(s))):new e(o,`prop "${i}" = ${t(a)}`,l)}function assertOneTextAuthority(t,n,r,i){if(!(n.textSink===null||i?.text!==!0)&&r[n.textSink]!==void 0)throw new e(t,`prop → "${n.textSink}"`,`is the same widget property a text CHILD writes, and both were given. Whichever the reconciler applied last would win, possibly differently on a first render and on an update — so it is refused. Keep one`)}const orientationOf=(e,t)=>e===`horizontal`||e===`vertical`?e:t;export{declaresAbsolute,resolvePrimitive};
|
package/lib/esm/prop-table.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./_virtual/_rolldown/runtime.js";import{PrimitiveError as e,describeValue as t,primitiveErrorMessage as n}from"./primitives/errors.js";import{answerFor as
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import{PrimitiveError as e,describeValue as t,primitiveErrorMessage as n,unknownAccessibleKeyDetail as r,unknownMappedValueDetail as i}from"./primitives/errors.js";import{answerFor as a,isAccepted as o,propNamesOf as s,unknownPrimitiveDetail as c}from"./primitives/answers.js";import{FRAMEWORK_PROPS as l,PRIMITIVES as u,PRIMITIVE_NAMES as d}from"./primitives/table.js";const f=Object.fromEntries(Object.entries(u).filter(([,e])=>e.switchOn!==void 0).map(([e,t])=>[e,t.switchOn.prop]));function specFor(t,n){let r=u[t];if(r===void 0)throw new e(t,``,c(d));let i=r.switchOn;return i===void 0||n===void 0||n[i.prop]!==!0?r:i.whenTrue}function propAnswer(e,t,n){return a(e,specFor(e,n),t,l)}function acceptsProp(e,t,n){return o(propAnswer(e,t,n).status)}function explainProp(e,t,r){let i=propAnswer(e,t,r);return o(i.status)?null:n(e,`prop "${t}"`,i.why)}function propRefusedValues(e,t,n){return Object.keys(propAnswer(e,t,n).refuses).sort()}function acceptsPropValue(e,t,n,r){return explainPropValue(e,t,n,r)===null}function vocabularyAccepts(e,t){return e.numbers&&typeof t==`number`&&Number.isFinite(t)?!0:e.values.includes(String(t))}function explainPropValue(e,a,s,c){let l=propAnswer(e,a,c);if(!o(l.status))return explainProp(e,a,c);let u=l.refuses[String(s)];return u===void 0?l.allows!==null&&!vocabularyAccepts(l.allows,s)?l.status===`accessible`?n(e,`prop "${a}"`,r(String(s),l.allows.values)):n(e,`prop "${a}"`,i(t(s),l.allows.values)):null:l.status===`accessible`?n(e,`prop "${a}"`,`carries "${String(s)}", which ${u}`):n(e,`prop "${a}" = ${t(s)}`,u)}function propAllowedValues(e,t,n){let r=propAnswer(e,t,n).allows;return r===null?null:[...r.values].sort()}function propNames(e,t){return s(specFor(e,t))}function propTable(e){return d.flatMap(t=>propNames(t,e).map(n=>propAnswer(t,n,e)))}export{d as PRIMITIVE_NAMES,f as PRIMITIVE_VARIANTS,acceptsProp,acceptsPropValue,explainProp,explainPropValue,propAllowedValues,propAnswer,propNames,propRefusedValues,propTable};
|
package/lib/types/press.d.ts
CHANGED
|
@@ -23,5 +23,10 @@ export declare function onPressStateChange(widget: Gtk.Widget, listener: (presse
|
|
|
23
23
|
* The controller is REMOVED and the handler disconnected, in that order: a controller
|
|
24
24
|
* left on a widget outlives every JS reference to it, and its handler is then one of
|
|
25
25
|
* the callbacks GJS blocks during GC.
|
|
26
|
+
*
|
|
27
|
+
* `GObject.signal_connect` rather than `gesture.connect`: `ResolvedGesture.signal` is a
|
|
28
|
+
* `string` that `components.ts` joins into one key and splits back out, so the name is
|
|
29
|
+
* DATA by the time it arrives here — and since `@girs` 5.0.0 `connect` takes only the
|
|
30
|
+
* names `Gtk.GestureClick` itself declares. Same connection, same id.
|
|
26
31
|
*/
|
|
27
32
|
export declare function onGesture(widget: Gtk.Widget, signal: string, listener: () => void): () => void;
|
|
@@ -105,6 +105,13 @@ export interface AccessibilityProps {
|
|
|
105
105
|
*
|
|
106
106
|
* Throws nothing itself: it reports a bad value as a `problem` so the caller raises
|
|
107
107
|
* the one `PrimitiveError` this layer raises, with the primitive's own name in it.
|
|
108
|
+
*
|
|
109
|
+
* A `problem` is the COMPLETE detail, `got …` included where a value is worth
|
|
110
|
+
* showing. The caller used to append `; got <the whole prop value>` to all of them,
|
|
111
|
+
* which printed `[object Object]` for every record-level refusal — the fact the
|
|
112
|
+
* message already named the key made the tail noise, and for a bad MEMBER it named
|
|
113
|
+
* the wrong thing entirely. It also made the key-level sentences unreproducible by
|
|
114
|
+
* `prop-table.ts`, which is handed the KEY and never the record (#1648, ADR 0039 § 1).
|
|
108
115
|
*/
|
|
109
116
|
export declare function resolveAccessible(route: AccessibleRoute, prop: string, value: unknown): {
|
|
110
117
|
entries: readonly ResolvedAccessible[];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PrimitiveSpec } from './table.js';
|
|
1
|
+
import type { PrimitiveSpec, PropRoute } from './table.js';
|
|
2
2
|
/**
|
|
3
3
|
* What this layer does about a prop.
|
|
4
4
|
*
|
|
@@ -62,6 +62,31 @@ export interface PropAnswer {
|
|
|
62
62
|
* stay one string (ADR 0039 § 2).
|
|
63
63
|
*/
|
|
64
64
|
readonly refuses: Readonly<Record<string, string>>;
|
|
65
|
+
/**
|
|
66
|
+
* The values this prop ACCEPTS by name, when the table enumerates them — the
|
|
67
|
+
* inverse grain of {@link refuses}, and `null` when there is no such list.
|
|
68
|
+
*
|
|
69
|
+
* THE TWO GRAINS ARE NOT THE SAME FACT, and reading only one is how #1648
|
|
70
|
+
* happened. `refuses` enumerates what is forbidden; a `map` enumerates what is
|
|
71
|
+
* allowed, and a value outside it is refused BY OMISSION. `pointerEvents` is
|
|
72
|
+
* `{ auto, none }` with no `refuses` at all, so the oracle answered ACCEPTED for
|
|
73
|
+
* `box-none` — a real React Native spelling that a render throws on — and a
|
|
74
|
+
* consumer deleted their own working mapping on the strength of it.
|
|
75
|
+
*/
|
|
76
|
+
readonly allows: ValueVocabulary | null;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* The values one route accepts by name, for the routes whose table row says.
|
|
80
|
+
*
|
|
81
|
+
* `numbers` is not a special case bolted on: `pixels-or-map` accepts a pixel COUNT
|
|
82
|
+
* beside its two named steps, and a vocabulary that could not say so would make
|
|
83
|
+
* `<ActivityIndicator size={24}>` read as refused.
|
|
84
|
+
*/
|
|
85
|
+
export interface ValueVocabulary {
|
|
86
|
+
/** Accepted spellings, in the table's own keys. Compared against `String(value)`. */
|
|
87
|
+
readonly values: readonly string[];
|
|
88
|
+
/** A finite number is accepted without appearing in {@link values}. */
|
|
89
|
+
readonly numbers: boolean;
|
|
65
90
|
}
|
|
66
91
|
/** Does this status let a render proceed? `ignored` counts — it is a declared no-op, not a refusal. */
|
|
67
92
|
export declare const isAccepted: (status: PropStatus) => boolean;
|
|
@@ -69,6 +94,22 @@ export declare const isAccepted: (status: PropStatus) => boolean;
|
|
|
69
94
|
export declare const unknownPropDetail: (spec: PrimitiveSpec) => string;
|
|
70
95
|
/** The detail of the refusal an unknown PRIMITIVE gets. `resolve.ts` throws exactly this. */
|
|
71
96
|
export declare const unknownPrimitiveDetail: (names: readonly string[]) => string;
|
|
97
|
+
/**
|
|
98
|
+
* One route → the values it accepts by name, or `null` when it enumerates none.
|
|
99
|
+
*
|
|
100
|
+
* THE COMPLETENESS QUESTION, asked of every route kind in one place (#1648). A route
|
|
101
|
+
* that refuses a value by OMISSION from a list is invisible to {@link PropAnswer.refuses},
|
|
102
|
+
* and three kinds do it — a mapped property, an `announce` map, and an accessible
|
|
103
|
+
* record's member keys. Before this function each of them was a separate oversight
|
|
104
|
+
* waiting to be reported; now the switch has no `default`, so the next route kind
|
|
105
|
+
* cannot be added without answering the question for it.
|
|
106
|
+
*
|
|
107
|
+
* `file` is the deliberate `null` worth naming: its refusals ARE value-level
|
|
108
|
+
* (`http:` has no synchronous loader, a `require()` id has no asset registry) but
|
|
109
|
+
* they are computed from the value's shape rather than drawn from a list, so no
|
|
110
|
+
* vocabulary can express them and the oracle must not pretend otherwise.
|
|
111
|
+
*/
|
|
112
|
+
export declare function routeValueVocabulary(route: PropRoute): ValueVocabulary | null;
|
|
72
113
|
/**
|
|
73
114
|
* What `primitive` does about `prop`.
|
|
74
115
|
*
|
|
@@ -6,7 +6,32 @@
|
|
|
6
6
|
* Two template literals that happen to agree are not that: the format is here once and
|
|
7
7
|
* both the throw and the static answer are built from it.
|
|
8
8
|
*/
|
|
9
|
-
export declare const primitiveErrorMessage: (primitive: string, subject: string, detail: string) => string;
|
|
9
|
+
export declare const primitiveErrorMessage: (primitive: string, subject: string, detail: string, where?: string) => string;
|
|
10
|
+
/**
|
|
11
|
+
* Which element, as far as the author's own words can say it.
|
|
12
|
+
*
|
|
13
|
+
* A refusal names a PRIMITIVE, and an application has many elements per primitive: a
|
|
14
|
+
* consumer with twenty-five `<View className="flex-1 bg-canvas">` sites gets a message
|
|
15
|
+
* that identifies none of them, and the stack is this package's own frames
|
|
16
|
+
* (`usePlan`, `View`, `renderWithHooks`) with no component names in a bundle. Finding
|
|
17
|
+
* the element took patching the built `lib/` to print `props.className`, which is not
|
|
18
|
+
* a thing a consumer should have to do.
|
|
19
|
+
*
|
|
20
|
+
* TWO FIELDS, NOT A PROPS DUMP, and each is a deliberate choice. `className` is what
|
|
21
|
+
* the author wrote and is how they will search for it; `testID` is the other thing
|
|
22
|
+
* they chose the value of. `children` is a React tree, `style` can be a large object,
|
|
23
|
+
* and `nativeID` is refused by name (`primitives/table.ts`) so it can never be
|
|
24
|
+
* present.
|
|
25
|
+
*
|
|
26
|
+
* CAPPED, because a computed class list is ordinary authoring — 24 of the measured
|
|
27
|
+
* application's `className=` sites are arrays or joins — and a refusal that scrolls is
|
|
28
|
+
* a refusal nobody reads. An array is flattened the way `splitVariants` flattens one,
|
|
29
|
+
* so the message shows what the element resolved to rather than the expression.
|
|
30
|
+
*/
|
|
31
|
+
export declare const describeElement: (props: {
|
|
32
|
+
className?: string | readonly (string | false | null | undefined)[] | null;
|
|
33
|
+
testID?: unknown;
|
|
34
|
+
}) => string;
|
|
10
35
|
/**
|
|
11
36
|
* How a VALUE reads inside a subject — `prop "accessibilityRole" = "keyboardkey"`.
|
|
12
37
|
*
|
|
@@ -16,6 +41,29 @@ export declare const primitiveErrorMessage: (primitive: string, subject: string,
|
|
|
16
41
|
* not one string.
|
|
17
42
|
*/
|
|
18
43
|
export declare const describeValue: (value: unknown) => string;
|
|
44
|
+
/**
|
|
45
|
+
* The refusal a value gets for being ABSENT from the list its route maps.
|
|
46
|
+
*
|
|
47
|
+
* ONE FORMATTER FOR THREE READERS, which is the whole point: `resolve.ts` throws it
|
|
48
|
+
* for a mapped property and for an `announce` route, and `prop-table.ts` returns it
|
|
49
|
+
* as the static answer. It was written out twice in `resolve.ts` and not at all in
|
|
50
|
+
* `prop-table.ts` — and the missing third copy is #1648, an oracle that answered
|
|
51
|
+
* ACCEPTED for `pointerEvents="box-none"` while the render threw this very sentence.
|
|
52
|
+
*
|
|
53
|
+
* `described` arrives already rendered rather than as the value, because the two
|
|
54
|
+
* modules that build this reach `describeValue` and the one that classifies routes
|
|
55
|
+
* may hold no relative value import (ADR 0039 § 2).
|
|
56
|
+
*/
|
|
57
|
+
export declare const unknownMappedValueDetail: (described: string, known: readonly string[]) => string;
|
|
58
|
+
/**
|
|
59
|
+
* The refusal a KEY gets for not being a member of an accessible record.
|
|
60
|
+
*
|
|
61
|
+
* The same fact as {@link unknownMappedValueDetail} at the other grain the table has
|
|
62
|
+
* — `accessibilityState` enumerates its members rather than its values — so it is
|
|
63
|
+
* shared for the same reason: `accessibility.ts` decides it and `prop-table.ts` has
|
|
64
|
+
* to answer with it.
|
|
65
|
+
*/
|
|
66
|
+
export declare const unknownAccessibleKeyDetail: (key: string, known: readonly string[]) => string;
|
|
19
67
|
/** A primitive, prop or combination this layer cannot answer for, and why. */
|
|
20
68
|
export declare class PrimitiveError extends Error {
|
|
21
69
|
readonly name = "PrimitiveError";
|
|
@@ -23,5 +71,13 @@ export declare class PrimitiveError extends Error {
|
|
|
23
71
|
readonly primitive: string;
|
|
24
72
|
/** The prop, utility or combination that caused it. Empty when it is the primitive itself. */
|
|
25
73
|
readonly subject: string;
|
|
26
|
-
|
|
74
|
+
/**
|
|
75
|
+
* The author's own handle on the element — `[className="…"]` — or empty.
|
|
76
|
+
*
|
|
77
|
+
* Optional, so every existing throw and `prop-table`'s static answers produce the
|
|
78
|
+
* same string they did before. ADR 0039 § 1 asks that the static answer and the
|
|
79
|
+
* thrown message be one string, and an optional argument is how both stay one.
|
|
80
|
+
*/
|
|
81
|
+
readonly where: string;
|
|
82
|
+
constructor(primitive: string, subject: string, detail: string, where?: string);
|
|
27
83
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { type PropAnswer, type PropStatus } from './primitives/answers.js';
|
|
1
|
+
import { type PropAnswer, type PropStatus, type ValueVocabulary } from './primitives/answers.js';
|
|
2
2
|
import { PRIMITIVE_NAMES } from './primitives/table.js';
|
|
3
|
-
export type { PropAnswer, PropStatus };
|
|
3
|
+
export type { PropAnswer, PropStatus, ValueVocabulary };
|
|
4
4
|
/**
|
|
5
5
|
* Every primitive this layer answers for.
|
|
6
6
|
*
|
|
@@ -68,11 +68,29 @@ export declare function acceptsPropValue(primitive: string, prop: string, value:
|
|
|
68
68
|
* under Node type stripping is why) — so the formatter the throw uses lives in
|
|
69
69
|
* `errors.ts` and both call it.
|
|
70
70
|
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
71
|
+
* TWO GRAINS OF REFUSAL, AND THE SECOND ONE WAS MISSING (#1648). A prop can refuse a
|
|
72
|
+
* value by NAME — `answer.refuses`, a deny-list with a reason per entry — and it can
|
|
73
|
+
* refuse one by OMISSION from the list its route maps: `pointerEvents` is
|
|
74
|
+
* `{ auto, none }`, `box-none` is a real React Native spelling with no GTK
|
|
75
|
+
* expression, and a render throws on it. Reading only the deny-list answered ACCEPTED
|
|
76
|
+
* for the second kind on every mapped property, every `announce` route and every
|
|
77
|
+
* accessible record — and a consumer deleted a working `box-none` mapping of their
|
|
78
|
+
* own because a green test said the layer had caught up.
|
|
79
|
+
*
|
|
80
|
+
* What is still NOT answered here is the TYPE grain: `coerce` refuses a non-boolean
|
|
81
|
+
* for `editable` and a non-function for `onPress`, and neither is a list this table
|
|
82
|
+
* can publish. `acceptsPropValue` is an oracle for the vocabulary, not for the type.
|
|
74
83
|
*/
|
|
75
84
|
export declare function explainPropValue(primitive: string, prop: string, value: unknown, variant?: PropVariant): string | null;
|
|
85
|
+
/**
|
|
86
|
+
* The values this prop accepts by name, or `null` when the table enumerates none.
|
|
87
|
+
*
|
|
88
|
+
* The reader for {@link PropAnswer.allows}, beside `propRefusedValues` because they
|
|
89
|
+
* are the two halves of one question and a consumer holding a ledger of "which props
|
|
90
|
+
* has the layer caught up on" needs both: a deny-list says which spellings have a
|
|
91
|
+
* reason, an allow-list says which ones exist at all.
|
|
92
|
+
*/
|
|
93
|
+
export declare function propAllowedValues(primitive: string, prop: string, variant?: PropVariant): readonly string[] | null;
|
|
76
94
|
/** Every prop name this primitive's table row carries, sorted. Framework props are not among them. */
|
|
77
95
|
export declare function propNames(primitive: string, variant?: PropVariant): readonly string[];
|
|
78
96
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/react-native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.51.0",
|
|
4
4
|
"description": "The React Native view vocabulary rendered onto GTK4/Adwaita, over @gjsify/gtk-host",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "lib/esm/index.js",
|
|
@@ -120,8 +120,8 @@
|
|
|
120
120
|
"react-native"
|
|
121
121
|
],
|
|
122
122
|
"dependencies": {
|
|
123
|
-
"@gjsify/adwaita-app": "^0.
|
|
124
|
-
"@gjsify/gtk-host": "^0.
|
|
123
|
+
"@gjsify/adwaita-app": "^0.51.0",
|
|
124
|
+
"@gjsify/gtk-host": "^0.51.0"
|
|
125
125
|
},
|
|
126
126
|
"peerDependencies": {
|
|
127
127
|
"@react-navigation/core": "^7.21.13",
|
|
@@ -148,13 +148,13 @@
|
|
|
148
148
|
}
|
|
149
149
|
},
|
|
150
150
|
"devDependencies": {
|
|
151
|
-
"@girs/adw-1": "
|
|
152
|
-
"@girs/gdk-4.0": "
|
|
153
|
-
"@girs/gjs": "
|
|
154
|
-
"@girs/gtk-4.0": "
|
|
155
|
-
"@gjsify/cli": "^0.
|
|
156
|
-
"@gjsify/rolldown-plugin-gjsify": "^0.
|
|
157
|
-
"@gjsify/unit": "^0.
|
|
151
|
+
"@girs/adw-1": "5.0.0",
|
|
152
|
+
"@girs/gdk-4.0": "5.0.0",
|
|
153
|
+
"@girs/gjs": "5.0.0",
|
|
154
|
+
"@girs/gtk-4.0": "5.0.0",
|
|
155
|
+
"@gjsify/cli": "^0.51.0",
|
|
156
|
+
"@gjsify/rolldown-plugin-gjsify": "^0.51.0",
|
|
157
|
+
"@gjsify/unit": "^0.51.0",
|
|
158
158
|
"@react-navigation/core": "^7.21.13",
|
|
159
159
|
"@react-navigation/routers": "^7.6.4",
|
|
160
160
|
"@types/node": "^25.9.2",
|