@gjsify/react-native 0.46.0 → 0.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/PROPS.md +319 -92
- package/README.md +94 -0
- package/SUPPORT.md +14 -9
- package/lib/esm/accessibility.js +1 -0
- package/lib/esm/apis/alert.js +1 -1
- package/lib/esm/app-registry.js +1 -1
- package/lib/esm/child-facts.js +1 -0
- package/lib/esm/components.js +1 -1
- package/lib/esm/generated/own-exports.js +1 -1
- package/lib/esm/generated/unsupported-react-native.js +1 -1
- package/lib/esm/index.js +1 -1
- package/lib/esm/lists/controller.js +1 -1
- package/lib/esm/primitives/accessibility.js +1 -0
- package/lib/esm/primitives/answers.js +1 -1
- package/lib/esm/primitives/defaults.js +1 -1
- package/lib/esm/primitives/errors.js +1 -1
- package/lib/esm/primitives/index.js +1 -1
- package/lib/esm/primitives/resolve.js +1 -1
- package/lib/esm/primitives/style.js +1 -1
- package/lib/esm/primitives/table.js +1 -1
- package/lib/esm/prop-table.js +1 -1
- package/lib/esm/router/chrome.js +1 -0
- package/lib/esm/router/navigation.js +1 -1
- package/lib/esm/router/per-route-cache.js +1 -0
- package/lib/esm/router/stack.js +1 -1
- package/lib/esm/router/tabs.js +1 -1
- package/lib/esm/solid/index.js +1 -1
- package/lib/esm/support-table.js +1 -1
- package/lib/esm/window-chrome.js +1 -0
- package/lib/types/accessibility.d.ts +10 -0
- package/lib/types/app-registry.d.ts +95 -5
- package/lib/types/app-registry.spec.d.ts +2 -0
- package/lib/types/child-facts.d.ts +45 -0
- package/lib/types/child-facts.spec.d.ts +2 -0
- package/lib/types/components.d.ts +34 -1
- package/lib/types/generated/unsupported-react-native.d.ts +8 -4
- package/lib/types/index.d.ts +3 -3
- package/lib/types/primitives/accessibility.d.ts +112 -0
- package/lib/types/primitives/answers.d.ts +18 -0
- package/lib/types/primitives/errors.d.ts +9 -0
- package/lib/types/primitives/resolve.d.ts +10 -0
- package/lib/types/primitives/style.d.ts +23 -0
- package/lib/types/primitives/table.d.ts +13 -1
- package/lib/types/prop-table.d.ts +29 -0
- package/lib/types/router/chrome.d.ts +106 -0
- package/lib/types/router/errors.d.ts +3 -1
- package/lib/types/router/per-route-cache.d.ts +21 -0
- package/lib/types/router/stack.d.ts +6 -1
- package/lib/types/solid/index.d.ts +2 -1
- package/lib/types/support-table.d.ts +1 -1
- package/lib/types/window-chrome.d.ts +39 -0
- package/package.json +7 -7
- package/react-native-surface.json +18 -9
|
@@ -1 +1 @@
|
|
|
1
|
-
import"../_virtual/_rolldown/runtime.js";const e={box:!0,alignsText:!1,wrapsInto:{tag:`GtkFlowBox`,widgetProps:{"max-children-per-line":65535,"selection-mode":`none`}}},t={box:!1,alignsText:!1,wrapsInto:null},n={box:!1,alignsText:!0,wrapsInto:null},r="GTK carries accessibility through `Gtk.Accessible.update_property()`, an imperative call, not through a widget property — so there is nothing for this layer to set as data. `AccessibilityInfo` (tier P3) is the entry that owns this, and GTK’s model maps onto the props well once it exists",i="would write `Gtk.Widget:name`, and so does `testID`. Two props for one property is the silent-drop shape the host refuses by name (`signalTaken`), so this layer picks one: use `testID`",a={testID:{to:`property`,names:[`name`],as:`string`},id:{to:`refused`,why:i},nativeID:{to:`refused`,why:i},onLayout:{to:`refused`,why:"GTK reports its allocation through `Gtk.Widget.vfunc_size_allocate`, a SUBCLASS override rather than a signal, so there is no handler to bind. `useWindowDimensions` (tier P2) is the window-level answer"},accessible:{to:`refused`,why:r},accessibilityLabel:{to:`refused`,why:r},accessibilityRole:{to:`refused`,why:r},accessibilityHint:{to:`refused`,why:r},accessibilityState:{to:`refused`,why:r},accessibilityLiveRegion:{to:`refused`,why:"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"}},o={to:`property`,names:[`can-target`],as:`map`,map:{auto:!0,none:!1}},s={...a,multiline:{to:`ignored`,why:`it chose the widget; it is not also a property`},editable:{to:`property`,names:[`editable`],as:`boolean`},keyboardType:{to:`property`,names:[`input-purpose`],as:`map`,map:{default:`free-form`,"email-address":`email`,"phone-pad":`phone`,"number-pad":`digits`,numeric:`number`,"decimal-pad":`number`,url:`url`}},autoFocus:{to:`refused`,why:"focus is `Gtk.Widget.grab_focus()`, which only works once the widget is mapped — an imperative call at a moment this layer does not own. Call it from a ref in an effect"},onFocus:{to:`refused`,why:"focus arrives through a `Gtk.EventControllerFocus`, a controller rather than a signal on the widget, so it is not a prop this layer can route"},onBlur:{to:`refused`,why:"see `onFocus` — the same controller"},returnKeyType:{to:`ignored`,why:`a desktop keyboard has one Return key and no label to change`},autoCapitalize:{to:`ignored`,why:`an on-screen keyboard behaviour; a hardware keyboard has no shift state to preset`},autoCorrect:{to:`ignored`,why:`an on-screen keyboard behaviour`},keyboardAppearance:{to:`ignored`,why:`there is no on-screen keyboard to theme`},autoComplete:{to:`ignored`,why:"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"},textContentType:{to:`ignored`,why:"is `autoComplete`’s iOS spelling and has the same absent addressee. Note `Gtk.Accessible` does carry an `autocomplete` PROPERTY, and it is a different thing: it describes a widget that completes its own text (a combo box), not a system that fills it in"},submitBehavior:{to:`ignored`,why:"chooses what the Return key does, and each GTK widget has exactly one answer with nothing to select between: a `Gtk.Entry` always emits `activate` (which is `onSubmitEditing`) and can never insert a newline, and a `Gtk.TextView` always inserts a newline and never submits — which is why `onSubmitEditing` is refused on a multiline input. `multiline` is the prop that picks the behaviour, because it picks the widget"}},c="`Gtk.TextView` keeps its content in a `Gtk.TextBuffer` rather than in a property (measured: 61 properties, no `text`), so there is nothing for this layer to set as data. Drop `multiline` for a `Gtk.Entry`, or reach the buffer through a ref",l={tag:`GtkTextView`,widgetProps:{"wrap-mode":`word-char`},cssClasses:[],orientation:`vertical`,widget:t,textSink:null,handle:`text-input`,props:{...s,value:{to:`refused`,why:c},defaultValue:{to:`refused`,why:c},onChangeText:{to:`refused`,why:c},placeholder:{to:`refused`,why:"`Gtk.TextView` installs no `placeholder-text` (measured); the Adwaita idiom is a label above the field"},maxLength:{to:`refused`,why:"`Gtk.TextView` installs no `max-length` (measured) — the limit belongs to the buffer"},secureTextEntry:{to:`refused`,why:"`Gtk.TextView` installs no `visibility` (measured), and a multiline password field is not a thing a desktop offers"},onSubmitEditing:{to:`refused`,why:`Return inserts a newline in a multiline field; there is nothing to submit`}}},u={cover:`cover`,contain:`contain`,stretch:`fill`,center:`scale-down`},d="is a load event, and `Gtk.Picture` emits NO signals at all (measured: its GType lists none) — it is handed a file or a paintable and draws it, reporting neither progress nor failure. A missing file leaves `paintable` null with no diagnostic, so a callback that never fires would hide exactly the case it exists to report. Load the bytes yourself and set `paintable` through a ref",f="is a per-pixel effect. GTK composites a `Gdk.Paintable` and has no filter property on the widget that draws it — the counterpart is a `Gsk` render node or a `Gtk.Snapshot` subclass, which is a widget of its own rather than a prop on this one",PRESSED_STYLE_IS_CSS=e=>`sets the pressed appearance, which on GTK is the CSS \`:active\` pseudo-class rather than a prop (ADR 0032 § 7). Write \`${e}\` — it resolves through the same variant mechanism as every other utility, reads the project's own token scale, and GTK animates it with no re-render at all`,p="tunes React Native’s own virtualisation, and `Gtk.ListView` does that job itself — it creates and recycles rows through the factory as the viewport moves (measured: 205 of 500 rows set up in a 400×300 window) and installs no property that changes the batching. There is nothing for this to set",m="is pull-to-refresh, which GTK has no idiom for and should not grow one — `RefreshControl` is `refused` in the support table for the same reason. Give the desktop build a refresh action in the header bar",h={...a,disabled:{to:`property`,names:[`sensitive`],as:`not`},onPressIn:{to:`refused`,why:"press state is the GTK CSS `:active` pseudo-class, not React state (ADR 0032 § 7) — write `active:opacity-70` and GTK animates it with no re-render at all"},onPressOut:{to:`refused`,why:"see `onPressIn` — `active:` is the mechanism"},onLongPress:{to:`refused`,why:"a long press is a `Gtk.GestureLongPress` controller added to the widget, not a property or a signal on it, so it is not something this layer can route as data"},delayLongPress:{to:`refused`,why:"see `onLongPress`"},delayPressIn:{to:`refused`,why:"see `onPressIn` — there is no press-in event to delay"},delayPressOut:{to:`refused`,why:"see `onPressIn`"},hitSlop:{to:`refused`,why:"GTK hit-tests the allocation and has no way to grow it past the widget. Pad the element (`p-*`), which enlarges the real target"},pressRetentionOffset:{to:`refused`,why:"see `hitSlop` — GTK hit-tests the allocation and nothing around it"},touchSoundDisabled:{to:`ignored`,why:`an Android touch sound; a desktop button makes none`}},g={View:{tag:`GtkBox`,widgetProps:{orientation:`vertical`},cssClasses:[],orientation:`vertical`,widget:e,textSink:null,overlayOnAbsoluteChild:{tag:`GtkOverlay`,slot:`overlay`},props:{...a,pointerEvents:o}},Text:{tag:`GtkLabel`,widgetProps:{wrap:!0,xalign:0,yalign:0},cssClasses:[],orientation:`vertical`,widget:n,textSink:`label`,props:{...a,numberOfLines:{to:`property`,names:[`lines`],as:`int`,also:{ellipsize:`end`,wrap:!0}},ellipsizeMode:{to:`property`,names:[`ellipsize`],as:`map`,map:{head:`start`,middle:`middle`,tail:`end`}},selectable:{to:`property`,names:[`selectable`],as:`boolean`},accessibilityLiveRegion:{to:`announce`,signal:`notify::label`,read:`label`,map:{none:null,polite:`medium`,assertive:`high`}},onPress:{to:`refused`,why:"a `Gtk.Label` emits no `clicked` (measured: `activate-current-link`, `activate-link`, `copy-clipboard`, `move-cursor` and nothing else). Wrap it in a `<Pressable>`, which is a real `Gtk.Button`"},allowFontScaling:{to:`ignored`,why:`text scaling is a desktop-wide GNOME setting, not a per-label opt-in`},maxFontSizeMultiplier:{to:`ignored`,why:"see `allowFontScaling`"},adjustsFontSizeToFit:{to:`refused`,why:"GTK has no shrink-to-fit text; a label ellipsizes or wraps. Use `numberOfLines` with `ellipsizeMode`"}}},Pressable:{tag:`GtkButton`,widgetProps:{},cssClasses:[`flat`],orientation:`vertical`,widget:t,textSink:`label`,props:{...a,pointerEvents:o,onPress:{to:`event`,signal:`clicked`},onPressIn:{to:`refused`,why:"press state is the GTK CSS `:active` pseudo-class, not React state (ADR 0032 § 7) — write `active:opacity-70` and GTK animates it with no re-render at all"},onPressOut:{to:`refused`,why:"see `onPressIn` — `active:` is the mechanism"},onLongPress:{to:`refused`,why:"a long press is a `Gtk.GestureLongPress` controller added to the widget, not a property or a signal on it, so it is not something this layer can route as data"},delayLongPress:{to:`refused`,why:"see `onLongPress`"},hitSlop:{to:`refused`,why:"GTK hit-tests the allocation and has no way to grow it past the widget. Pad the button (`p-*`), which enlarges the real target"},android_ripple:{to:`ignored`,why:`an Android-only ripple; Adwaita has its own press feedback`},disabled:{to:`property`,names:[`sensitive`],as:`not`}}},ScrollView:{tag:`GtkScrolledWindow`,widgetProps:{"hscrollbar-policy":`never`},cssClasses:[],orientation:`vertical`,widget:t,textSink:null,content:{tag:`GtkBox`,widgetProps:{orientation:`vertical`},orientation:`vertical`,widget:e,styleProp:`contentContainerStyle`,classNameProp:`contentContainerClassName`},props:{...a,horizontal:[{to:`property`,on:`content`,names:[`orientation`],as:`map`,map:{true:`horizontal`,false:`vertical`}},{to:`property`,on:`outer`,names:[`hscrollbar-policy`],as:`map`,map:{true:`automatic`,false:`never`}},{to:`property`,on:`outer`,names:[`vscrollbar-policy`],as:`map`,map:{true:`never`,false:`automatic`}}],showsVerticalScrollIndicator:{to:`property`,names:[`vscrollbar-policy`],as:`map`,map:{true:`automatic`,false:`external`}},showsHorizontalScrollIndicator:{to:`property`,names:[`hscrollbar-policy`],as:`map`,map:{true:`automatic`,false:`external`}},scrollEnabled:{to:`refused`,why:"a `Gtk.ScrolledWindow` has no switch that stops scrolling — setting both policies to `never` hides the bars AND clamps the child, which is a different thing. Render the content without the ScrollView when it must not scroll"},onScroll:{to:`refused`,why:"GTK reports scroll position through the `Gtk.Adjustment` objects behind `hadjustment`/`vadjustment` — `notify::value` on an adjustment, not a signal on the scrolled window — so there is no prop to route. Reach the adjustment through a ref"},scrollEventThrottle:{to:`refused`,why:"see `onScroll`"},refreshControl:{to:`refused`,why:"GTK has no pull-to-refresh idiom and `RefreshControl` is `refused` in the support table for that reason. Give the desktop build a refresh action"},keyboardShouldPersistTaps:{to:`ignored`,why:`there is no on-screen keyboard to dismiss`},keyboardDismissMode:{to:`ignored`,why:"see `keyboardShouldPersistTaps`"},contentContainerStyle:{to:`ignored`,why:`read directly as the content node’s style set`},contentContainerClassName:{to:`ignored`,why:`read directly as the content node’s class list`}}},ActivityIndicator:{tag:`AdwSpinner`,widgetProps:{},cssClasses:[],orientation:`vertical`,widget:t,textSink:null,props:{...a,animating:{to:`property`,names:[`visible`],as:`boolean`},hidesWhenStopped:{to:`ignored`,why:"a stopped `Adw.Spinner` is a hidden one here — there is no property that stops it while it is on screen (measured), so this is already the behaviour"},size:{to:`property`,names:[`width-request`,`height-request`],as:`pixels-or-map`,map:{small:16,large:32}},color:{to:`style-property`,name:`color`}}},TextInput:{tag:`GtkEntry`,widgetProps:{},cssClasses:[],orientation:`vertical`,widget:t,textSink:`text`,handle:`text-input`,switchOn:{prop:`multiline`,whenTrue:l},props:{...s,value:{to:`property`,names:[`text`],as:`string`},defaultValue:{to:`property`,names:[`text`],as:`string`},placeholder:{to:`property`,names:[`placeholder-text`],as:`string`},maxLength:{to:`property`,names:[`max-length`],as:`int`},secureTextEntry:{to:`property`,names:[`visibility`],as:`not`},onChangeText:{to:`event`,signal:`notify::text`,read:`text`},onSubmitEditing:{to:`event`,signal:`activate`}}},Switch:{tag:`GtkSwitch`,widgetProps:{},cssClasses:[],orientation:`vertical`,widget:t,textSink:null,props:{...a,value:{to:`property`,names:[`active`],as:`boolean`},onValueChange:{to:`event`,signal:`notify::active`,read:`active`},disabled:{to:`property`,names:[`sensitive`],as:`not`},trackColor:{to:`refused`,why:"Adwaita paints the switch from the theme’s accent colour, and its track is a CSS `slider`/`trough` subnode rather than a property. Style it from the application stylesheet"},thumbColor:{to:`refused`,why:"see `trackColor`"},ios_backgroundColor:{to:`ignored`,why:`an iOS-only fallback colour`}}},Image:{tag:`GtkPicture`,widgetProps:{"content-fit":`cover`},cssClasses:[],orientation:`vertical`,widget:t,textSink:null,props:{...a,source:{to:`file`,property:`file`},resizeMode:{to:`property`,names:[`content-fit`],as:`map`,map:u},alt:{to:`property`,names:[`alternative-text`],as:`string`},onLoad:{to:`refused`,why:d},onLoadStart:{to:`refused`,why:d},onLoadEnd:{to:`refused`,why:d},onError:{to:`refused`,why:d},onProgress:{to:`refused`,why:d},blurRadius:{to:`refused`,why:f},tintColor:{to:`refused`,why:f},capInsets:{to:`refused`,why:"is iOS nine-part stretching. GTK’s counterpart is a CSS `border-image` on a widget’s background, which is a different widget and a different property set"},defaultSource:{to:`refused`,why:"is the placeholder shown while the real image loads, and `Gtk.Picture` has one file at a time with no load event to swap on (measured: it emits no signals). Render a placeholder widget beside it and remove it yourself"},loadingIndicatorSource:{to:`refused`,why:"see `defaultSource`"},progressiveRenderingEnabled:{to:`ignored`,why:`GTK decodes an image in one pass`},fadeDuration:{to:`ignored`,why:`an Android cross-fade on load; there is no load event here to fade from (measured)`},resizeMethod:{to:`ignored`,why:`an Android decoder hint`},resizeMultiplier:{to:`ignored`,why:`an Android decoder hint`}}},ImageBackground:{tag:`GtkOverlay`,widgetProps:{},cssClasses:[],orientation:`vertical`,widget:t,textSink:null,backdrop:{tag:`GtkPicture`,widgetProps:{"content-fit":`cover`},orientation:`vertical`,widget:t,styleProp:`imageStyle`,classNameProp:null,slot:`child`},content:{tag:`GtkBox`,widgetProps:{orientation:`vertical`},orientation:`vertical`,widget:e,styleProp:null,classNameProp:null,slot:`overlay`},props:{...a,pointerEvents:o,source:{to:`file`,on:`backdrop`,property:`file`},resizeMode:{to:`property`,on:`backdrop`,names:[`content-fit`],as:`map`,map:u},alt:{to:`property`,on:`backdrop`,names:[`alternative-text`],as:`string`},imageStyle:{to:`ignored`,why:`read directly as the picture node’s style set`},imageRef:{to:`refused`,why:"hands back the inner `Image`’s instance. This element’s `ref` is the `Gtk.Overlay`; the picture is its main child and `overlay.get_child()` reaches it, so a second ref would be a second way to say the same thing"}}},TouchableOpacity:{tag:`GtkButton`,cssClasses:[`flat`],widgetProps:{},orientation:`vertical`,widget:t,textSink:`label`,props:{...h,pointerEvents:o,onPress:{to:`event`,signal:`clicked`},activeOpacity:{to:`refused`,why:PRESSED_STYLE_IS_CSS(`active:opacity-70`)}}},TouchableHighlight:{tag:`GtkButton`,cssClasses:[`flat`],widgetProps:{},orientation:`vertical`,widget:t,textSink:`label`,props:{...h,pointerEvents:o,onPress:{to:`event`,signal:`clicked`},activeOpacity:{to:`refused`,why:PRESSED_STYLE_IS_CSS(`active:opacity-70`)},underlayColor:{to:`refused`,why:PRESSED_STYLE_IS_CSS(`active:bg-<token>`)},onShowUnderlay:{to:`refused`,why:"see `underlayColor` — there is no underlay to show"},onHideUnderlay:{to:`refused`,why:"see `underlayColor`"}}},TouchableWithoutFeedback:{tag:`GtkBox`,widgetProps:{orientation:`vertical`},cssClasses:[],orientation:`vertical`,widget:e,textSink:null,overlayOnAbsoluteChild:{tag:`GtkOverlay`,slot:`overlay`},props:{...h,pointerEvents:o,onPress:{to:`gesture`,signal:`released`},disabled:{to:`property`,names:[`can-target`],as:`not`}}},Button:{tag:`GtkButton`,widgetProps:{},cssClasses:[],orientation:`vertical`,widget:t,textSink:null,refusesStyle:"takes no `style` and no `className`. React Native’s own `Button` takes neither — its documented styling story is that you cannot, and you use `Pressable` when you need to — and GTK agrees: an Adwaita button is painted by the theme and by its own classes (`suggested-action`, `destructive-action`), which an application stylesheet sets. Use `<Pressable>`",props:{...a,title:{to:`property`,names:[`label`],as:`string`},onPress:{to:`event`,signal:`clicked`},disabled:{to:`property`,names:[`sensitive`],as:`not`},color:{to:`refused`,why:"is the button’s background on Android and its text colour on iOS — one prop, two meanings, and GTK has a third answer: `suggested-action` and `destructive-action` are Adwaita’s own classes for the two cases a colour is usually asking for. Set them from the application stylesheet, or use `<Pressable>`"},touchSoundDisabled:{to:`ignored`,why:`an Android touch sound; a desktop button makes none`},hasTVPreferredFocus:{to:`ignored`,why:`an Android TV focus hint`},nextFocusDown:{to:`ignored`,why:`an Android TV focus hint`},nextFocusForward:{to:`ignored`,why:`an Android TV focus hint`},nextFocusLeft:{to:`ignored`,why:`an Android TV focus hint`},nextFocusRight:{to:`ignored`,why:`an Android TV focus hint`},nextFocusUp:{to:`ignored`,why:`an Android TV focus hint`}}},SafeAreaView:{tag:`GtkBox`,widgetProps:{orientation:`vertical`},cssClasses:[],orientation:`vertical`,widget:e,textSink:null,overlayOnAbsoluteChild:{tag:`GtkOverlay`,slot:`overlay`},props:{...a,pointerEvents:o}},Icon:{tag:`GtkImage`,widgetProps:{},cssClasses:[],orientation:`vertical`,widget:t,textSink:null,props:{...a,name:{to:`property`,names:[`icon-name`],as:`string`},size:{to:`property`,names:[`pixel-size`],as:`int`},color:{to:`style-property`,name:`color`}}},KeyboardAvoidingView:{tag:`GtkBox`,widgetProps:{orientation:`vertical`},cssClasses:[],orientation:`vertical`,widget:e,textSink:null,overlayOnAbsoluteChild:{tag:`GtkOverlay`,slot:`overlay`},props:{...a,pointerEvents:o,behavior:{to:`ignored`,why:`describes how to move out of an on-screen keyboard’s way, and none appears`},keyboardVerticalOffset:{to:`ignored`,why:"see `behavior`"},enabled:{to:`ignored`,why:"see `behavior` — the avoidance is already off"},contentContainerStyle:{to:`refused`,why:"styles the inner view React Native adds to do the avoiding, and there is no avoiding here — so there is no second node to style. Put it on `style`, which lands on the one box this element is"}}},FlatList:{tag:`GtkBox`,widgetProps:{orientation:`vertical`},cssClasses:[],orientation:`vertical`,widget:e,textSink:null,content:{tag:`GtkScrolledWindow`,widgetProps:{"hscrollbar-policy":`never`,vexpand:!0,hexpand:!0},orientation:`vertical`,widget:t,styleProp:null,classNameProp:null},props:{...a,horizontal:[{to:`property`,on:`outer`,names:[`orientation`],as:`map`,map:{true:`horizontal`,false:`vertical`}},{to:`property`,on:`content`,names:[`hscrollbar-policy`],as:`map`,map:{true:`automatic`,false:`never`}},{to:`property`,on:`content`,names:[`vscrollbar-policy`],as:`map`,map:{true:`never`,false:`automatic`}}],showsVerticalScrollIndicator:{to:`property`,on:`content`,names:[`vscrollbar-policy`],as:`map`,map:{true:`automatic`,false:`external`}},showsHorizontalScrollIndicator:{to:`property`,on:`content`,names:[`hscrollbar-policy`],as:`map`,map:{true:`automatic`,false:`external`}},data:{to:`ignored`,why:`read by the component, which drives the Gio.ListStore from it`},renderItem:{to:`ignored`,why:`read by the item factory`},keyExtractor:{to:`ignored`,why:`read by the component, to key the model rows`},getItem:{to:`ignored`,why:"read by the component — VirtualizedList’s accessor form of `data`"},getItemCount:{to:`ignored`,why:"see `getItem`"},sections:{to:`ignored`,why:"read by the component — SectionList’s form of `data`"},renderSectionHeader:{to:`ignored`,why:`read by the item factory`},ListEmptyComponent:{to:`ignored`,why:`rendered by the component instead of the scroller`},ListHeaderComponent:{to:`ignored`,why:`rendered by the component, before the scroller`},ListFooterComponent:{to:`ignored`,why:`rendered by the component, after the scroller`},onEndReached:{to:`ignored`,why:`bound by the component to the scroller’s own Gtk.Adjustment`},onEndReachedThreshold:{to:`ignored`,why:"see `onEndReached`"},extraData:{to:`ignored`,why:`read by the component; a change re-renders every bound row`},onRowError:{to:`ignored`,why:`read by the component, and handed to each row’s own React root`},initialNumToRender:{to:`refused`,why:p},maxToRenderPerBatch:{to:`refused`,why:p},updateCellsBatchingPeriod:{to:`refused`,why:p},windowSize:{to:`refused`,why:p},removeClippedSubviews:{to:`refused`,why:p},getItemLayout:{to:`refused`,why:p},initialScrollIndex:{to:`refused`,why:"scrolls to a row before the first paint. `Gtk.ListView.scroll_to(position, flags, scroll_info)` is the counterpart and it is an imperative call on a realised view, not a property — reach the view through a ref and call it"},onViewableItemsChanged:{to:`refused`,why:"reports which rows are on screen. `Gtk.ListView` binds and unbinds rows itself and exposes no viewport range — the closest fact is `Gtk.ListItem:position` inside the factory, which is per row rather than a set, so a faithful answer would be a guess assembled from bind order"},viewabilityConfig:{to:`refused`,why:"see `onViewableItemsChanged`"},viewabilityConfigCallbackPairs:{to:`refused`,why:"see `onViewableItemsChanged`"},onScroll:{to:`refused`,why:"GTK reports scroll position through the `Gtk.Adjustment` objects behind the scroller’s `hadjustment`/`vadjustment` — `notify::value` on an adjustment, not a signal on the widget. `onEndReached` is the one question this layer answers from it; reach the adjustment through a ref for the rest"},scrollEventThrottle:{to:`refused`,why:"see `onScroll`"},numColumns:{to:`refused`,why:"lays the rows out in a grid, and a `Gtk.ListView` is one column of rows by construction. `Gtk.GridView` is the widget that does this and it is a different tag with a different model contract, so it is a primitive of its own rather than a prop on this one"},columnWrapperStyle:{to:`refused`,why:"see `numColumns`"},inverted:{to:`refused`,why:"draws the list bottom-up. GTK has no reversed list view; the honest equivalent is to reverse `data` yourself, which is one line and visible in the code"},refreshing:{to:`refused`,why:m},onRefresh:{to:`refused`,why:m},refreshControl:{to:`refused`,why:m},ItemSeparatorComponent:{to:`refused`,why:"puts a widget BETWEEN rows, and a `Gtk.ListView` has no between — it has rows. `Gtk.ListView:show-separators` draws the Adwaita separator itself; set it through a ref, or give the row its own bottom border with `border-b`"},stickySectionHeadersEnabled:{to:`refused`,why:"GTK’s own sticky headers are a `Gtk.ListView:header-factory` over a model that implements `Gtk.SectionModel` (MEASURED: `Gio.ListStore` does not, every selection model and `Gtk.FlattenListModel` do). This layer flattens the sections into one model with header ROWS instead, so a header scrolls with its section — which is what `stickySectionHeadersEnabled={false}` asks for and the only thing it can deliver"},keyboardShouldPersistTaps:{to:`ignored`,why:`there is no on-screen keyboard to dismiss`},keyboardDismissMode:{to:`ignored`,why:"see `keyboardShouldPersistTaps`"},contentContainerStyle:{to:`refused`,why:"styles the box React Native puts the rows in, and there is no such box: `Gtk.ListView` builds each row from the factory and owns the space between them. Style the row inside `renderItem`, or the list itself through `style`"}}}},_=Object.keys(g),v=new Set([`children`,`key`,`ref`,`className`,`style`]);export{v as FRAMEWORK_PROPS,g as PRIMITIVES,_ as PRIMITIVE_NAMES};
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";const e={box:!0,alignsText:!1,wrapsInto:{tag:`GtkFlowBox`,widgetProps:{"max-children-per-line":65535,"selection-mode":`none`,"accessible-role":`generic`}}},t={box:!1,alignsText:!1,wrapsInto:null},n={box:!1,alignsText:!0,wrapsInto:null},r={set:`property`,name:`label`,as:`string`},i={set:`property`,name:`help-text`,as:`string`},a={disabled:{set:`state`,name:`disabled`,as:`boolean`},busy:{set:`state`,name:`busy`,as:`boolean`},checked:{set:`state`,name:`checked`,as:`tristate`},selected:{set:`state`,name:`selected`,as:`tristate`},expanded:{set:`state`,name:`expanded`,as:`tristate`}},o={none:`none`,button:`button`,togglebutton:`toggle-button`,link:`link`,search:`search-box`,image:`img`,imagebutton:`button`,text:`label`,adjustable:`slider`,header:`heading`,alert:`alert`,checkbox:`checkbox`,combobox:`combo-box`,dropdownlist:`combo-box`,menu:`menu`,menubar:`menu-bar`,menuitem:`menu-item`,iconmenu:`menu`,progressbar:`progress-bar`,radio:`radio`,radiogroup:`radio-group`,scrollbar:`scrollbar`,spinbutton:`spin-button`,switch:`switch`,tab:`tab`,tablist:`tab-list`,tabbar:`tab-list`,timer:`timer`,list:`list`,toolbar:`toolbar`,grid:`grid`,viewgroup:`generic`,webview:`document`},s={keyboardkey:'describes a key of an on-screen keyboard, and neither GTK nor ARIA has a role for one — a desktop keyboard is the input method, not a widget in your tree. If you are building a keypad, the keys are `accessibilityRole="button"`; the container needs no role, because React Native has no spelling for ARIA’s `group` and a plain `<View>` is already the `generic` a screen reader walks through',summary:"is an iOS trait for the one element VoiceOver reads first when an app launches, and GTK has no counterpart because a desktop screen reader announces the focused widget instead. Put the text in the window title, or carry it as `accessibilityLabel` on the element it summarises — React Native’s role list has no `status`, so there is no role to give it here",scrollview:"names Android’s ScrollView class rather than a role, and this layer already answers the idea: `<ScrollView>` becomes a `Gtk.ScrolledWindow`, whose accessibility a screen reader reads from the widget itself. Drop the prop",horizontalscrollview:"names an Android class, like `scrollview` — use `<ScrollView horizontal>` and drop the prop",drawerlayout:"names Android’s DrawerLayout. The desktop pattern survives the component (`Adw.OverlaySplitView`), but it is a widget rather than a role — drop the prop and give the drawer an `accessibilityLabel`; React Native’s role list has no `navigation`, and the widget carries the rest",slidingdrawer:"names a deprecated Android class — see `drawerlayout`",pager:"names Android’s ViewPager. GTK’s counterpart is a `Gtk.Stack`, and the role a screen reader wants on it is `tablist` when it has visible switchers and nothing at all when it does not"},c="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`",l={testID:{to:`property`,names:[`name`],as:`string`},id:{to:`refused`,why:c},nativeID:{to:`refused`,why:c},onLayout:{to:`refused`,why:"GTK reports its allocation through `Gtk.Widget.vfunc_size_allocate`, a SUBCLASS override rather than a signal, so there is no handler to bind. `useWindowDimensions` (tier P2) is the window-level answer"},accessible:{to:`ignored`,why:'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'},accessibilityLabel:{to:`accessible`,from:`value`,attribute:r},accessibilityRole:{to:`property`,names:[`accessible-role`],as:`map`,map:o,refuses:s},accessibilityHint:{to:`accessible`,from:`value`,attribute:i},accessibilityState:{to:`accessible`,from:`members`,members:a,refuses:{}},accessibilityLiveRegion:{to:`refused`,why:"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"}},u={to:`property`,names:[`can-target`],as:`map`,map:{auto:!0,none:!1}},d={...l,multiline:{to:`ignored`,why:`it chose the widget; it is not also a property`},editable:{to:`property`,names:[`editable`],as:`boolean`},keyboardType:{to:`property`,names:[`input-purpose`],as:`map`,map:{default:`free-form`,"email-address":`email`,"phone-pad":`phone`,"number-pad":`digits`,numeric:`number`,"decimal-pad":`number`,url:`url`}},autoFocus:{to:`refused`,why:"focus is `Gtk.Widget.grab_focus()`, which only works once the widget is mapped — an imperative call at a moment this layer does not own. Call it from a ref in an effect"},onFocus:{to:`refused`,why:"focus arrives through a `Gtk.EventControllerFocus`, a controller rather than a signal on the widget, so it is not a prop this layer can route"},onBlur:{to:`refused`,why:"see `onFocus` — the same controller"},returnKeyType:{to:`ignored`,why:`a desktop keyboard has one Return key and no label to change`},autoCapitalize:{to:`ignored`,why:`an on-screen keyboard behaviour; a hardware keyboard has no shift state to preset`},autoCorrect:{to:`ignored`,why:`an on-screen keyboard behaviour`},keyboardAppearance:{to:`ignored`,why:`there is no on-screen keyboard to theme`},autoComplete:{to:`ignored`,why:"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"},textContentType:{to:`ignored`,why:"is `autoComplete`’s iOS spelling and has the same absent addressee. Note `Gtk.Accessible` does carry an `autocomplete` PROPERTY, and it is a different thing: it describes a widget that completes its own text (a combo box), not a system that fills it in"},submitBehavior:{to:`ignored`,why:"chooses what the Return key does, and each GTK widget has exactly one answer with nothing to select between: a `Gtk.Entry` always emits `activate` (which is `onSubmitEditing`) and can never insert a newline, and a `Gtk.TextView` always inserts a newline and never submits — which is why `onSubmitEditing` is refused on a multiline input. `multiline` is the prop that picks the behaviour, because it picks the widget"}},f="`Gtk.TextView` keeps its content in a `Gtk.TextBuffer` rather than in a property (measured: 61 properties, no `text`), so there is nothing for this layer to set as data. Drop `multiline` for a `Gtk.Entry`, or reach the buffer through a ref",p={tag:`GtkTextView`,widgetProps:{"wrap-mode":`word-char`},cssClasses:[],orientation:`vertical`,widget:t,textSink:null,handle:`text-input`,props:{...d,value:{to:`refused`,why:f},defaultValue:{to:`refused`,why:f},onChangeText:{to:`refused`,why:f},placeholder:{to:`refused`,why:"`Gtk.TextView` installs no `placeholder-text` (measured); the Adwaita idiom is a label above the field"},maxLength:{to:`refused`,why:"`Gtk.TextView` installs no `max-length` (measured) — the limit belongs to the buffer"},secureTextEntry:{to:`refused`,why:"`Gtk.TextView` installs no `visibility` (measured), and a multiline password field is not a thing a desktop offers"},onSubmitEditing:{to:`refused`,why:`Return inserts a newline in a multiline field; there is nothing to submit`}}},m={cover:`cover`,contain:`contain`,stretch:`fill`,center:`scale-down`},h="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",g="is a per-pixel effect. GTK composites a `Gdk.Paintable` and has no filter property on the widget that draws it — the counterpart is a `Gsk` render node or a `Gtk.Snapshot` subclass, which is a widget of its own rather than a prop on this one",PRESSED_STYLE_IS_CSS=e=>`sets the pressed appearance, which on GTK is the CSS \`:active\` pseudo-class rather than a prop (ADR 0032 § 7). Write \`${e}\` — it resolves through the same variant mechanism as every other utility, reads the project's own token scale, and GTK animates it with no re-render at all`,_="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",v="is pull-to-refresh, which GTK has no idiom for and should not grow one — `RefreshControl` is `refused` in the support table for the same reason. Give the desktop build a refresh action in the header bar",y={...l,disabled:{to:`property`,names:[`sensitive`],as:`not`},onPressIn:{to:`refused`,why:"press state is the GTK CSS `:active` pseudo-class, not React state (ADR 0032 § 7) — write `active:opacity-70` and GTK animates it with no re-render at all"},onPressOut:{to:`refused`,why:"see `onPressIn` — `active:` is the mechanism"},onLongPress:{to:`refused`,why:"a long press is a `Gtk.GestureLongPress` controller added to the widget, not a property or a signal on it, so it is not something this layer can route as data"},delayLongPress:{to:`refused`,why:"see `onLongPress`"},delayPressIn:{to:`refused`,why:"see `onPressIn` — there is no press-in event to delay"},delayPressOut:{to:`refused`,why:"see `onPressIn`"},hitSlop:{to:`refused`,why:"GTK hit-tests the allocation and has no way to grow it past the widget. Pad the element (`p-*`), which enlarges the real target"},pressRetentionOffset:{to:`refused`,why:"see `hitSlop` — GTK hit-tests the allocation and nothing around it"},touchSoundDisabled:{to:`ignored`,why:`an Android touch sound; a desktop button makes none`}},b={View:{tag:`GtkBox`,widgetProps:{orientation:`vertical`},cssClasses:[],orientation:`vertical`,widget:e,textSink:null,overlayOnAbsoluteChild:{tag:`GtkOverlay`,slot:`overlay`},props:{...l,pointerEvents:u}},Text:{tag:`GtkLabel`,widgetProps:{wrap:!0,xalign:0,yalign:0},cssClasses:[],orientation:`vertical`,widget:n,textSink:`label`,props:{...l,numberOfLines:{to:`property`,names:[`lines`],as:`int`,also:{ellipsize:`end`,wrap:!0}},ellipsizeMode:{to:`property`,names:[`ellipsize`],as:`map`,map:{head:`start`,middle:`middle`,tail:`end`}},selectable:{to:`property`,names:[`selectable`],as:`boolean`},accessibilityLiveRegion:{to:`announce`,signal:`notify::label`,read:`label`,map:{none:null,polite:`medium`,assertive:`high`}},onPress:{to:`refused`,why:"a `Gtk.Label` emits no `clicked` (measured: `activate-current-link`, `activate-link`, `copy-clipboard`, `move-cursor` and nothing else). Wrap it in a `<Pressable>`, which is a real `Gtk.Button`"},allowFontScaling:{to:`ignored`,why:`text scaling is a desktop-wide GNOME setting, not a per-label opt-in`},maxFontSizeMultiplier:{to:`ignored`,why:"see `allowFontScaling`"},adjustsFontSizeToFit:{to:`refused`,why:"GTK has no shrink-to-fit text; a label ellipsizes or wraps. Use `numberOfLines` with `ellipsizeMode`"}}},Pressable:{tag:`GtkButton`,widgetProps:{},cssClasses:[`flat`],orientation:`vertical`,widget:t,textSink:`label`,props:{...l,pointerEvents:u,onPress:{to:`event`,signal:`clicked`},onPressIn:{to:`refused`,why:"press state is the GTK CSS `:active` pseudo-class, not React state (ADR 0032 § 7) — write `active:opacity-70` and GTK animates it with no re-render at all"},onPressOut:{to:`refused`,why:"see `onPressIn` — `active:` is the mechanism"},onLongPress:{to:`refused`,why:"a long press is a `Gtk.GestureLongPress` controller added to the widget, not a property or a signal on it, so it is not something this layer can route as data"},delayLongPress:{to:`refused`,why:"see `onLongPress`"},hitSlop:{to:`refused`,why:"GTK hit-tests the allocation and has no way to grow it past the widget. Pad the button (`p-*`), which enlarges the real target"},android_ripple:{to:`ignored`,why:`an Android-only ripple; Adwaita has its own press feedback`},disabled:{to:`property`,names:[`sensitive`],as:`not`}}},ScrollView:{tag:`GtkScrolledWindow`,widgetProps:{"hscrollbar-policy":`never`},cssClasses:[],orientation:`vertical`,widget:t,textSink:null,content:{tag:`GtkBox`,widgetProps:{orientation:`vertical`},orientation:`vertical`,widget:e,styleProp:`contentContainerStyle`,classNameProp:`contentContainerClassName`},props:{...l,horizontal:[{to:`property`,on:`content`,names:[`orientation`],as:`map`,map:{true:`horizontal`,false:`vertical`}},{to:`property`,on:`outer`,names:[`hscrollbar-policy`],as:`map`,map:{true:`automatic`,false:`never`}},{to:`property`,on:`outer`,names:[`vscrollbar-policy`],as:`map`,map:{true:`never`,false:`automatic`}}],showsVerticalScrollIndicator:{to:`property`,names:[`vscrollbar-policy`],as:`map`,map:{true:`automatic`,false:`external`}},showsHorizontalScrollIndicator:{to:`property`,names:[`hscrollbar-policy`],as:`map`,map:{true:`automatic`,false:`external`}},scrollEnabled:{to:`refused`,why:"a `Gtk.ScrolledWindow` has no switch that stops scrolling — setting both policies to `never` hides the bars AND clamps the child, which is a different thing. Render the content without the ScrollView when it must not scroll"},onScroll:{to:`refused`,why:"GTK reports scroll position through the `Gtk.Adjustment` objects behind `hadjustment`/`vadjustment` — `notify::value` on an adjustment, not a signal on the scrolled window — so there is no prop to route. Reach the adjustment through a ref"},scrollEventThrottle:{to:`refused`,why:"see `onScroll`"},refreshControl:{to:`refused`,why:"GTK has no pull-to-refresh idiom and `RefreshControl` is `refused` in the support table for that reason. Give the desktop build a refresh action"},keyboardShouldPersistTaps:{to:`ignored`,why:`there is no on-screen keyboard to dismiss`},keyboardDismissMode:{to:`ignored`,why:"see `keyboardShouldPersistTaps`"},contentContainerStyle:{to:`ignored`,why:`read directly as the content node’s style set`},contentContainerClassName:{to:`ignored`,why:`read directly as the content node’s class list`}}},ActivityIndicator:{tag:`AdwSpinner`,widgetProps:{},cssClasses:[],orientation:`vertical`,widget:t,textSink:null,props:{...l,animating:{to:`property`,names:[`visible`],as:`boolean`},hidesWhenStopped:{to:`ignored`,why:"a stopped `Adw.Spinner` is a hidden one here — there is no property that stops it while it is on screen (measured), so this is already the behaviour"},size:{to:`property`,names:[`width-request`,`height-request`],as:`pixels-or-map`,map:{small:16,large:32}},color:{to:`style-property`,name:`color`}}},TextInput:{tag:`GtkEntry`,widgetProps:{},cssClasses:[],orientation:`vertical`,widget:t,textSink:`text`,handle:`text-input`,switchOn:{prop:`multiline`,whenTrue:p},props:{...d,value:{to:`property`,names:[`text`],as:`string`},defaultValue:{to:`property`,names:[`text`],as:`string`},placeholder:{to:`property`,names:[`placeholder-text`],as:`string`},maxLength:{to:`property`,names:[`max-length`],as:`int`},secureTextEntry:{to:`property`,names:[`visibility`],as:`not`},onChangeText:{to:`event`,signal:`notify::text`,read:`text`},onSubmitEditing:{to:`event`,signal:`activate`}}},Switch:{tag:`GtkSwitch`,widgetProps:{},cssClasses:[],orientation:`vertical`,widget:t,textSink:null,props:{...l,value:{to:`property`,names:[`active`],as:`boolean`},onValueChange:{to:`event`,signal:`notify::active`,read:`active`},disabled:{to:`property`,names:[`sensitive`],as:`not`},trackColor:{to:`refused`,why:"Adwaita paints the switch from the theme’s accent colour, and its track is a CSS `slider`/`trough` subnode rather than a property. Style it from the application stylesheet"},thumbColor:{to:`refused`,why:"see `trackColor`"},ios_backgroundColor:{to:`ignored`,why:`an iOS-only fallback colour`}}},Image:{tag:`GtkPicture`,widgetProps:{"content-fit":`cover`},cssClasses:[],orientation:`vertical`,widget:t,textSink:null,props:{...l,source:{to:`file`,property:`file`},resizeMode:{to:`property`,names:[`content-fit`],as:`map`,map:m},alt:{to:`property`,names:[`alternative-text`],as:`string`},onLoad:{to:`refused`,why:h},onLoadStart:{to:`refused`,why:h},onLoadEnd:{to:`refused`,why:h},onError:{to:`refused`,why:h},onProgress:{to:`refused`,why:h},blurRadius:{to:`refused`,why:g},tintColor:{to:`refused`,why:g},capInsets:{to:`refused`,why:"is iOS nine-part stretching. GTK’s counterpart is a CSS `border-image` on a widget’s background, which is a different widget and a different property set"},defaultSource:{to:`refused`,why:"is the placeholder shown while the real image loads, and `Gtk.Picture` has one file at a time with no load event to swap on (measured: it emits no signals). Render a placeholder widget beside it and remove it yourself"},loadingIndicatorSource:{to:`refused`,why:"see `defaultSource`"},progressiveRenderingEnabled:{to:`ignored`,why:`GTK decodes an image in one pass`},fadeDuration:{to:`ignored`,why:`an Android cross-fade on load; there is no load event here to fade from (measured)`},resizeMethod:{to:`ignored`,why:`an Android decoder hint`},resizeMultiplier:{to:`ignored`,why:`an Android decoder hint`}}},ImageBackground:{tag:`GtkOverlay`,widgetProps:{},cssClasses:[],orientation:`vertical`,widget:t,textSink:null,backdrop:{tag:`GtkPicture`,widgetProps:{"content-fit":`cover`},orientation:`vertical`,widget:t,styleProp:`imageStyle`,classNameProp:null,slot:`child`},content:{tag:`GtkBox`,widgetProps:{orientation:`vertical`},orientation:`vertical`,widget:e,styleProp:null,classNameProp:null,slot:`overlay`},props:{...l,pointerEvents:u,source:{to:`file`,on:`backdrop`,property:`file`},resizeMode:{to:`property`,on:`backdrop`,names:[`content-fit`],as:`map`,map:m},alt:{to:`property`,on:`backdrop`,names:[`alternative-text`],as:`string`},imageStyle:{to:`ignored`,why:`read directly as the picture node’s style set`},imageRef:{to:`refused`,why:"hands back the inner `Image`’s instance. This element’s `ref` is the `Gtk.Overlay`; the picture is its main child and `overlay.get_child()` reaches it, so a second ref would be a second way to say the same thing"}}},TouchableOpacity:{tag:`GtkButton`,cssClasses:[`flat`],widgetProps:{},orientation:`vertical`,widget:t,textSink:`label`,props:{...y,pointerEvents:u,onPress:{to:`event`,signal:`clicked`},activeOpacity:{to:`refused`,why:PRESSED_STYLE_IS_CSS(`active:opacity-70`)}}},TouchableHighlight:{tag:`GtkButton`,cssClasses:[`flat`],widgetProps:{},orientation:`vertical`,widget:t,textSink:`label`,props:{...y,pointerEvents:u,onPress:{to:`event`,signal:`clicked`},activeOpacity:{to:`refused`,why:PRESSED_STYLE_IS_CSS(`active:opacity-70`)},underlayColor:{to:`refused`,why:PRESSED_STYLE_IS_CSS(`active:bg-<token>`)},onShowUnderlay:{to:`refused`,why:"see `underlayColor` — there is no underlay to show"},onHideUnderlay:{to:`refused`,why:"see `underlayColor`"}}},TouchableWithoutFeedback:{tag:`GtkBox`,widgetProps:{orientation:`vertical`},cssClasses:[],orientation:`vertical`,widget:e,textSink:null,overlayOnAbsoluteChild:{tag:`GtkOverlay`,slot:`overlay`},props:{...y,pointerEvents:u,onPress:{to:`gesture`,signal:`released`},disabled:{to:`property`,names:[`can-target`],as:`not`}}},Button:{tag:`GtkButton`,widgetProps:{},cssClasses:[],orientation:`vertical`,widget:t,textSink:null,refusesStyle:"takes no `style` and no `className`. React Native’s own `Button` takes neither — its documented styling story is that you cannot, and you use `Pressable` when you need to — and GTK agrees: an Adwaita button is painted by the theme and by its own classes (`suggested-action`, `destructive-action`), which an application stylesheet sets. Use `<Pressable>`",props:{...l,title:{to:`property`,names:[`label`],as:`string`},onPress:{to:`event`,signal:`clicked`},disabled:{to:`property`,names:[`sensitive`],as:`not`},color:{to:`refused`,why:"is the button’s background on Android and its text colour on iOS — one prop, two meanings, and GTK has a third answer: `suggested-action` and `destructive-action` are Adwaita’s own classes for the two cases a colour is usually asking for. Set them from the application stylesheet, or use `<Pressable>`"},touchSoundDisabled:{to:`ignored`,why:`an Android touch sound; a desktop button makes none`},hasTVPreferredFocus:{to:`ignored`,why:`an Android TV focus hint`},nextFocusDown:{to:`ignored`,why:`an Android TV focus hint`},nextFocusForward:{to:`ignored`,why:`an Android TV focus hint`},nextFocusLeft:{to:`ignored`,why:`an Android TV focus hint`},nextFocusRight:{to:`ignored`,why:`an Android TV focus hint`},nextFocusUp:{to:`ignored`,why:`an Android TV focus hint`}}},SafeAreaView:{tag:`GtkBox`,widgetProps:{orientation:`vertical`},cssClasses:[],orientation:`vertical`,widget:e,textSink:null,overlayOnAbsoluteChild:{tag:`GtkOverlay`,slot:`overlay`},props:{...l,pointerEvents:u}},Modal:{tag:`AdwDialog`,widgetProps:{"can-close":!1},cssClasses:[],orientation:`vertical`,widget:t,textSink:null,content:{tag:`GtkBox`,widgetProps:{orientation:`vertical`},orientation:`vertical`,widget:e,styleProp:null,classNameProp:null},props:{...l,visible:{to:`ignored`,why:`read directly by the binding: the element is rendered only while it is true`},onRequestClose:{to:`event`,signal:`close-attempt`},onShow:{to:`event`,signal:`map`},onDismiss:{to:`refused`,why:"would never fire. The only thing that dismisses a dialog here is the element being unrendered, and the host disconnects a node’s handlers BEFORE it retracts the node — so `Adw.Dialog::closed` is emitted with the handler already gone. A callback that fires for no dismissal at all is worse than one that says so. Do the work in the effect cleanup of whatever renders the `<Modal>`"},animationType:{to:`refused`,why:"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"},transparent:{to:`refused`,why:"an `Adw.Dialog` is always a sheet over libadwaita’s own dimmed backdrop; there is no full-bleed transparent mode, and faking one would be a sheet with no chrome that still dims. For an overlay you paint yourself, put an absolutely positioned `<View>` in a `<View>` — that becomes a `Gtk.Overlay` — instead of a `<Modal>`"},backdropColor:{to:`refused`,why:"see `transparent` — the dim layer is libadwaita’s and is painted from the theme"},presentationStyle:{to:`refused`,why:"iOS presentation vocabulary. The GTK axis is `Adw.Dialog:presentation-mode` (auto / floating / bottom-sheet), which says WHERE the sheet sits rather than how much it covers, so no member of this maps onto one. Set that property through a `ref`"},allowSwipeDismissal:{to:`refused`,why:"swipe-to-dismiss is a touch gesture; the desktop dismissal is Escape or a click on the backdrop, and `onRequestClose` already reports both"},supportedOrientations:{to:`refused`,why:`a desktop window has no orientation to lock`},onOrientationChange:{to:`refused`,why:"see `supportedOrientations` — nothing rotates"},modalRef:{to:`refused`,why:"React Native’s second ref, to the native modal host view. There is one node here and `ref` already hands back its `Gtk.Widget`; two refs to one widget would be two names for the same thing"},hardwareAccelerated:{to:`ignored`,why:`an Android window flag; GTK4 renders through GSK either way`},statusBarTranslucent:{to:`ignored`,why:`a desktop window has no status bar to go under`},navigationBarTranslucent:{to:`ignored`,why:"see `statusBarTranslucent`"}}},Icon:{tag:`GtkImage`,widgetProps:{},cssClasses:[],orientation:`vertical`,widget:t,textSink:null,props:{...l,name:{to:`property`,names:[`icon-name`],as:`string`},size:{to:`property`,names:[`pixel-size`],as:`int`},color:{to:`style-property`,name:`color`}}},KeyboardAvoidingView:{tag:`GtkBox`,widgetProps:{orientation:`vertical`},cssClasses:[],orientation:`vertical`,widget:e,textSink:null,overlayOnAbsoluteChild:{tag:`GtkOverlay`,slot:`overlay`},props:{...l,pointerEvents:u,behavior:{to:`ignored`,why:`describes how to move out of an on-screen keyboard’s way, and none appears`},keyboardVerticalOffset:{to:`ignored`,why:"see `behavior`"},enabled:{to:`ignored`,why:"see `behavior` — the avoidance is already off"},contentContainerStyle:{to:`refused`,why:"styles the inner view React Native adds to do the avoiding, and there is no avoiding here — so there is no second node to style. Put it on `style`, which lands on the one box this element is"}}},FlatList:{tag:`GtkBox`,widgetProps:{orientation:`vertical`},cssClasses:[],orientation:`vertical`,widget:e,textSink:null,content:{tag:`GtkScrolledWindow`,widgetProps:{"hscrollbar-policy":`never`,vexpand:!0,hexpand:!0},orientation:`vertical`,widget:t,styleProp:null,classNameProp:null},props:{...l,horizontal:[{to:`property`,on:`outer`,names:[`orientation`],as:`map`,map:{true:`horizontal`,false:`vertical`}},{to:`property`,on:`content`,names:[`hscrollbar-policy`],as:`map`,map:{true:`automatic`,false:`never`}},{to:`property`,on:`content`,names:[`vscrollbar-policy`],as:`map`,map:{true:`never`,false:`automatic`}}],showsVerticalScrollIndicator:{to:`property`,on:`content`,names:[`vscrollbar-policy`],as:`map`,map:{true:`automatic`,false:`external`}},showsHorizontalScrollIndicator:{to:`property`,on:`content`,names:[`hscrollbar-policy`],as:`map`,map:{true:`automatic`,false:`external`}},data:{to:`ignored`,why:`read by the component, which drives the Gio.ListStore from it`},renderItem:{to:`ignored`,why:`read by the item factory`},keyExtractor:{to:`ignored`,why:`read by the component, to key the model rows`},getItem:{to:`ignored`,why:"read by the component — VirtualizedList’s accessor form of `data`"},getItemCount:{to:`ignored`,why:"see `getItem`"},sections:{to:`ignored`,why:"read by the component — SectionList’s form of `data`"},renderSectionHeader:{to:`ignored`,why:`read by the item factory`},ListEmptyComponent:{to:`ignored`,why:`rendered by the component instead of the scroller`},ListHeaderComponent:{to:`ignored`,why:`rendered by the component, before the scroller`},ListFooterComponent:{to:`ignored`,why:`rendered by the component, after the scroller`},onEndReached:{to:`ignored`,why:`bound by the component to the scroller’s own Gtk.Adjustment`},onEndReachedThreshold:{to:`ignored`,why:"see `onEndReached`"},extraData:{to:`ignored`,why:`read by the component; a change re-renders every bound row`},onRowError:{to:`ignored`,why:`read by the component, and handed to each row’s own React root`},initialNumToRender:{to:`refused`,why:_},maxToRenderPerBatch:{to:`refused`,why:_},updateCellsBatchingPeriod:{to:`refused`,why:_},windowSize:{to:`refused`,why:_},removeClippedSubviews:{to:`refused`,why:_},getItemLayout:{to:`refused`,why:_},initialScrollIndex:{to:`refused`,why:"scrolls to a row before the first paint. `Gtk.ListView.scroll_to(position, flags, scroll_info)` is the counterpart and it is an imperative call on a realised view, not a property — reach the view through a ref and call it"},onViewableItemsChanged:{to:`refused`,why:"reports which rows are on screen. `Gtk.ListView` binds and unbinds rows itself and exposes no viewport range — the closest fact is `Gtk.ListItem:position` inside the factory, which is per row rather than a set, so a faithful answer would be a guess assembled from bind order"},viewabilityConfig:{to:`refused`,why:"see `onViewableItemsChanged`"},viewabilityConfigCallbackPairs:{to:`refused`,why:"see `onViewableItemsChanged`"},onScroll:{to:`refused`,why:"GTK reports scroll position through the `Gtk.Adjustment` objects behind the scroller’s `hadjustment`/`vadjustment` — `notify::value` on an adjustment, not a signal on the widget. `onEndReached` is the one question this layer answers from it; reach the adjustment through a ref for the rest"},scrollEventThrottle:{to:`refused`,why:"see `onScroll`"},numColumns:{to:`refused`,why:"lays the rows out in a grid, and a `Gtk.ListView` is one column of rows by construction. `Gtk.GridView` is the widget that does this and it is a different tag with a different model contract, so it is a primitive of its own rather than a prop on this one"},columnWrapperStyle:{to:`refused`,why:"see `numColumns`"},inverted:{to:`refused`,why:"draws the list bottom-up. GTK has no reversed list view; the honest equivalent is to reverse `data` yourself, which is one line and visible in the code"},refreshing:{to:`refused`,why:v},onRefresh:{to:`refused`,why:v},refreshControl:{to:`refused`,why:v},ItemSeparatorComponent:{to:`refused`,why:"puts a widget BETWEEN rows, and a `Gtk.ListView` has no between — it has rows. `Gtk.ListView:show-separators` draws the Adwaita separator itself; set it through a ref, or give the row its own bottom border with `border-b`"},stickySectionHeadersEnabled:{to:`refused`,why:"GTK’s own sticky headers are a `Gtk.ListView:header-factory` over a model that implements `Gtk.SectionModel` (MEASURED: `Gio.ListStore` does not, every selection model and `Gtk.FlattenListModel` do). This layer flattens the sections into one model with header ROWS instead, so a header scrolls with its section — which is what `stickySectionHeadersEnabled={false}` asks for and the only thing it can deliver"},keyboardShouldPersistTaps:{to:`ignored`,why:`there is no on-screen keyboard to dismiss`},keyboardDismissMode:{to:`ignored`,why:"see `keyboardShouldPersistTaps`"},contentContainerStyle:{to:`refused`,why:"styles the box React Native puts the rows in, and there is no such box: `Gtk.ListView` builds each row from the factory and owns the space between them. Style the row inside `renderItem`, or the list itself through `style`"}}}},x=Object.keys(b),S=new Set([`children`,`key`,`ref`,`className`,`style`]);export{S as FRAMEWORK_PROPS,b as PRIMITIVES,x as PRIMITIVE_NAMES};
|
package/lib/esm/prop-table.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./_virtual/_rolldown/runtime.js";import{PrimitiveError as e,primitiveErrorMessage as
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import{PrimitiveError as e,describeValue as t,primitiveErrorMessage as n}from"./primitives/errors.js";import{answerFor as r,isAccepted as i,propNamesOf as a,unknownPrimitiveDetail as o}from"./primitives/answers.js";import{FRAMEWORK_PROPS as s,PRIMITIVES as c,PRIMITIVE_NAMES as l}from"./primitives/table.js";const u=Object.fromEntries(Object.entries(c).filter(([,e])=>e.switchOn!==void 0).map(([e,t])=>[e,t.switchOn.prop]));function specFor(t,n){let r=c[t];if(r===void 0)throw new e(t,``,o(l));let i=r.switchOn;return i===void 0||n===void 0||n[i.prop]!==!0?r:i.whenTrue}function propAnswer(e,t,n){return r(e,specFor(e,n),t,s)}function acceptsProp(e,t,n){return i(propAnswer(e,t,n).status)}function explainProp(e,t,r){let a=propAnswer(e,t,r);return i(a.status)?null:n(e,`prop "${t}"`,a.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 explainPropValue(e,r,a,o){let s=propAnswer(e,r,o);if(!i(s.status))return explainProp(e,r,o);let c=s.refuses[String(a)];return c===void 0?null:s.status===`accessible`?n(e,`prop "${r}"`,`carries "${String(a)}", which ${c}`):n(e,`prop "${r}" = ${t(a)}`,c)}function propNames(e,t){return a(specFor(e,t))}function propTable(e){return l.flatMap(t=>propNames(t,e).map(n=>propAnswer(t,n,e)))}export{l as PRIMITIVE_NAMES,u as PRIMITIVE_VARIANTS,acceptsProp,acceptsPropValue,explainProp,explainPropValue,propAnswer,propNames,propRefusedValues,propTable};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import{useWindowChrome as e}from"../window-chrome.js";import{RouterError as t}from"./errors.js";import{PerRouteCache as n}from"./per-route-cache.js";import{createContext as r,createElement as i,useCallback as a,useContext as o,useEffect as s,useLayoutEffect as c,useRef as l,useState as u}from"react";const d=r({taken:!1,decorated:!1,titleSlot:null}),provideChromeLevel=(e,t)=>i(d.Provider,{value:e},t),underHeaderBar=e=>({taken:!0,decorated:!0,titleSlot:e}),withoutHeaderBar=e=>({taken:!0,decorated:e,titleSlot:null});function useChrome(t,n){let r=o(d),i=e(),a=!r.taken,s=a&&n;c(()=>{if(!(!s||i===null))return i.claim(`<${t}>`)},[s,i,t]);let l=a&&!s&&i!==null;return{decorated:r.decorated||l,titleSlot:r.titleSlot}}function useTitleSlots(e){let[r,i]=u({}),o=l(new Map),c=l(new n),d=a(n=>c.current.getOrCreate(n,()=>({setTitleWidget(r){let a=o.current.get(n);if(r===null){if(a===void 0)return;o.current.delete(n),i(e=>{let{[n]:t,...r}=e;return r});return}if(a!==r){if(a!==void 0)throw new t(`chrome-taken`,`<${e}>`,`was asked for a second title widget for one header bar. A window has one header bar per level and that bar has one title, so two navigators inside the same screen cannot both put their switcher in it — give one of them its own route group`);o.current.set(n,r),i(e=>({...e,[n]:r}))}}})),[e]),f=c.current;s(()=>()=>f.clear(),[f]);let p=a(e=>c.current.retain(e),[]);return{titleWidgetFor:a(e=>r[e]??null,[r]),slotFor:d,retain:p}}export{provideChromeLevel,underHeaderBar,useChrome,useTitleSlots,withoutHeaderBar};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"../_virtual/_rolldown/runtime.js";import{RouterError as e}from"./errors.js";import{hrefFrom as t,paramsSeenBy as n}from"./href.js";import{pathConfigOf as r,screenUrls as i}from"./routes.js";import{useSyncExternalStore as a}from"react";import{CommonActions as o,StackActions as s,createNavigationContainerRef as c,getActionFromState as l,getPathFromState as u,getStateFromPath as d,useRoute as f}from"@react-navigation/core";const p=c(),upstream=e=>e;let m=null;const h=new Set,liveRootState=()=>p.isReady()?p.getRootState():void 0;function installRouter(t){if(m!==null)throw new e(`no-router-mounted`,`RouterRoot`,"is already mounted. `router` is a module-level object — the shape of the name being reproduced — so one process routes one tree. Render one RouterRoot and nest navigators inside it");m={tree:t,config:r(t)}}function uninstallRouter(){m=null,notifyStateChanged()}function notifyStateChanged(){for(let e of h)e()}function required(t){if(m===null)throw new e(`no-router-mounted`,`router.${t}()`,`was called with no router mounted. Render <RouterRoot manifest={…}> above the tree that calls it — the manifest is the bundler plugin’s virtual module`);return m}function readyContainer(t){if(required(t),!p.isReady())throw new e(`no-router-mounted`,`router.${t}()`,`was called before the navigation container was ready. A container becomes ready during the first commit, so this is a call from a module body or from a render — move it into an effect or an event handler`);return p}function resolve(t,n){let{tree:r,config:a}=required(t),o=d(n,upstream(a));if(o===void 0)throw new e(`unresolved-href`,n,`matches no route. The manifest holds: ${i(r).join(`, `)}. A \`+not-found.tsx\` catches everything else`);return o}function focusChain(e){let t=[],n=e;for(;n!==void 0;){let e=n.index??n.routes.length-1,r=n.routes[e];if(r===void 0)break;t.push({name:r.name,...r.params===void 0?{}:{params:r.params}}),n=r.state}return t}function targetFor(e){let t=liveRootState();for(let[n,r]of e.entries()){if(t===void 0)return null;if(n===e.length-1)return t.routeNames.includes(r.name)?{key:t.key,type:t.type}:null;let i=t.routes.find(e=>e.name===r.name);if(i===void 0)return null;t=i.state}return null}function pushOrReplace(e,n){let r=t(e,n),i=readyContainer(e),{config:a}=required(e),c=resolve(e,r),u=focusChain(c),d=u[u.length-1],f=targetFor(u);if(d!==void 0&&f!==null&&f.type===`stack`){let t=e===`push`?s.push(d.name,d.params):s.replace(d.name,d.params);i.dispatch({...t,target:f.key});return}let p=l(c,upstream(a));i.dispatch(p??o.reset(c))}const g={push(e){pushOrReplace(`push`,e)},navigate(e){let n=readyContainer(`navigate`),{config:r}=required(`navigate`),i=resolve(`navigate`,t(`navigate`,e)),a=l(i,upstream(r));n.dispatch(a??o.reset(i))},replace(e){pushOrReplace(`replace`,e)},back(){let t=readyContainer(`back`);if(!t.canGoBack())throw new e(`unresolved-href`,`router.back()`,`has nothing to go back to — this is the first screen in the history. Guard the call, or use router.replace() to leave a screen that cannot be popped`);t.dispatch(o.goBack())},canGoBack(){return m===null||!p.isReady()?!1:p.canGoBack()},dismiss(){throw dismissRefusal(`dismiss`)},dismissAll(){throw dismissRefusal(`dismissAll`)},dismissTo(){throw dismissRefusal(`dismissTo`)},setParams(){throw new e(`unresolved-href`,`router.setParams()`,"edits the current route’s params in place, so the URL stops describing the screen — `usePathname()` would answer for a path whose params are no longer the route’s. Navigate with `router.replace({ pathname, params })` instead, which changes both together")}},dismissRefusal=t=>new e(`unresolved-href`,`router.${t}()`,"dismisses a MODAL, and this layer has no modal stack to dismiss from
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import{RouterError as e}from"./errors.js";import{hrefFrom as t,paramsSeenBy as n}from"./href.js";import{pathConfigOf as r,screenUrls as i}from"./routes.js";import{useSyncExternalStore as a}from"react";import{CommonActions as o,StackActions as s,createNavigationContainerRef as c,getActionFromState as l,getPathFromState as u,getStateFromPath as d,useRoute as f}from"@react-navigation/core";const p=c(),upstream=e=>e;let m=null;const h=new Set,liveRootState=()=>p.isReady()?p.getRootState():void 0;function installRouter(t){if(m!==null)throw new e(`no-router-mounted`,`RouterRoot`,"is already mounted. `router` is a module-level object — the shape of the name being reproduced — so one process routes one tree. Render one RouterRoot and nest navigators inside it");m={tree:t,config:r(t)}}function uninstallRouter(){m=null,notifyStateChanged()}function notifyStateChanged(){for(let e of h)e()}function required(t){if(m===null)throw new e(`no-router-mounted`,`router.${t}()`,`was called with no router mounted. Render <RouterRoot manifest={…}> above the tree that calls it — the manifest is the bundler plugin’s virtual module`);return m}function readyContainer(t){if(required(t),!p.isReady())throw new e(`no-router-mounted`,`router.${t}()`,`was called before the navigation container was ready. A container becomes ready during the first commit, so this is a call from a module body or from a render — move it into an effect or an event handler`);return p}function resolve(t,n){let{tree:r,config:a}=required(t),o=d(n,upstream(a));if(o===void 0)throw new e(`unresolved-href`,n,`matches no route. The manifest holds: ${i(r).join(`, `)}. A \`+not-found.tsx\` catches everything else`);return o}function focusChain(e){let t=[],n=e;for(;n!==void 0;){let e=n.index??n.routes.length-1,r=n.routes[e];if(r===void 0)break;t.push({name:r.name,...r.params===void 0?{}:{params:r.params}}),n=r.state}return t}function targetFor(e){let t=liveRootState();for(let[n,r]of e.entries()){if(t===void 0)return null;if(n===e.length-1)return t.routeNames.includes(r.name)?{key:t.key,type:t.type}:null;let i=t.routes.find(e=>e.name===r.name);if(i===void 0)return null;t=i.state}return null}function pushOrReplace(e,n){let r=t(e,n),i=readyContainer(e),{config:a}=required(e),c=resolve(e,r),u=focusChain(c),d=u[u.length-1],f=targetFor(u);if(d!==void 0&&f!==null&&f.type===`stack`){let t=e===`push`?s.push(d.name,d.params):s.replace(d.name,d.params);i.dispatch({...t,target:f.key});return}let p=l(c,upstream(a));i.dispatch(p??o.reset(c))}const g={push(e){pushOrReplace(`push`,e)},navigate(e){let n=readyContainer(`navigate`),{config:r}=required(`navigate`),i=resolve(`navigate`,t(`navigate`,e)),a=l(i,upstream(r));n.dispatch(a??o.reset(i))},replace(e){pushOrReplace(`replace`,e)},back(){let t=readyContainer(`back`);if(!t.canGoBack())throw new e(`unresolved-href`,`router.back()`,`has nothing to go back to — this is the first screen in the history. Guard the call, or use router.replace() to leave a screen that cannot be popped`);t.dispatch(o.goBack())},canGoBack(){return m===null||!p.isReady()?!1:p.canGoBack()},dismiss(){throw dismissRefusal(`dismiss`)},dismissAll(){throw dismissRefusal(`dismissAll`)},dismissTo(){throw dismissRefusal(`dismissTo`)},setParams(){throw new e(`unresolved-href`,`router.setParams()`,"edits the current route’s params in place, so the URL stops describing the screen — `usePathname()` would answer for a path whose params are no longer the route’s. Navigate with `router.replace({ pathname, params })` instead, which changes both together")}},dismissRefusal=t=>new e(`unresolved-href`,`router.${t}()`,"dismisses a MODAL, and this layer has no modal stack to dismiss from. `<Modal>` itself is buildable now — the host places an `Adw.Dialog` by PRESENTING it against a parent rather than parenting it (ADR 0045) — but a modal STACK is a routing concept this layer has not decided: which presented dialogs count as entries, and what `dismissTo` names. `router.back()` pops the navigation stack"),subscribe=e=>(h.add(e),()=>{h.delete(e)}),currentPathname=()=>{let e=liveRootState();if(m===null||e===void 0)return`/`;let t=u(e,upstream(m.config)),n=t.indexOf(`?`);return n===-1?t:t.slice(0,n)};function usePathname(){return a(subscribe,currentPathname,currentPathname)}function useLocalSearchParams(){return n(f().params)}export{installRouter,p as navigationRef,notifyStateChanged,g as router,uninstallRouter,useLocalSearchParams,usePathname};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";let e=0;const perRouteCacheEntries=()=>e;var PerRouteCache=class{constructor(){this.held=new Map}getOrCreate(t,n){let r=this.held.get(t);if(r!==void 0)return r;let i=n();return this.held.set(t,i),e++,i}set(t,n){this.held.has(t)||e++,this.held.set(t,n)}get(e){return this.held.get(e)}retain(t){for(let n of this.held.keys())t.has(n)||(this.held.delete(n),e--)}clear(){e-=this.held.size,this.held.clear()}get size(){return this.held.size}};export{PerRouteCache,perRouteCacheEntries};
|
package/lib/esm/router/stack.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"../_virtual/_rolldown/runtime.js";import{RouterError as e}from"./errors.js";import{
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import{RouterError as e}from"./errors.js";import{PerRouteCache as t}from"./per-route-cache.js";import{provideChromeLevel as n,underHeaderBar as r,useChrome as i,useTitleSlots as a,withoutHeaderBar as o}from"./chrome.js";import{navigationPair as s,screenOptionsFrom as c,useRouteNode as l,useSynthesisedScreens as u}from"./screens.js";import{createElement as d,useCallback as f,useEffect as p,useLayoutEffect as m,useMemo as h,useRef as g,useState as _}from"react";import{StackActions as v,StackRouter as y,useNavigationBuilder as b}from"@react-navigation/core";const x=[`title`,`headerShown`,`animation`];function widgetStack(e){let t=e.get_navigation_stack(),n=t.get_n_items(),r=[];for(let e=0;e<n;e++){let n=t.get_item(e),i=n===null?null:n.get_tag();if(i===null)break;r.push(i)}return r}const same=(e,t)=>e.length===t.length&&e.every((e,n)=>t[n]===e),isStrictPrefix=(e,t)=>e.length<t.length&&e.every((e,n)=>t[n]===e);function applyStack(e,t,n,r){if(same(t,n))return`none`;let i=n[n.length-1];if(i!==void 0&&isStrictPrefix(n,t))return e.set_animate_transitions(r(t[t.length-1])),e.pop_to_tag(i),`pop`;if(i!==void 0&&isStrictPrefix(t,n)){let a=n.slice(0,-1);return same(a,t)||e.replace_with_tags([...a]),e.set_animate_transitions(r(i)),e.push_by_tag(i),`push`}return e.replace_with_tags([...n]),`replace`}const initialTracking=(e,t)=>({order:[...e],focused:t,closing:{}}),sameMembers=(e,t)=>e.length===t.length&&e.every(e=>t.includes(e)),neededKeys=(e,t)=>[...t,...Object.keys(e.closing).filter(e=>!t.includes(e))],needsAdvance=(e,t,n)=>!sameMembers(e.order,neededKeys(e,t))||e.focused!==n;function advanceTracking(e,t,n,r){let i={};for(let[n,r]of Object.entries(e.closing))t.includes(n)||(i[n]=r);let a=e.focused;if(a!==void 0&&!t.includes(a)){let e=r[a];e!==void 0&&(i[a]=e)}let o=[...t,...Object.keys(i).filter(e=>!t.includes(e))];return{order:[...e.order.filter(e=>o.includes(e)),...o.filter(t=>!e.order.includes(t))],focused:n,closing:i}}function releaseFrom(e,t){return e.closing[t]===void 0?e:{order:e.order.filter(e=>e!==t),focused:e.focused,closing:Object.fromEntries(Object.entries(e.closing).filter(([e])=>e!==t))}}function coalesce(e){let t=!1;return()=>{t||(t=!0,Promise.resolve().then(()=>{t=!1,e()}))}}const focusedKeyOf=e=>e.routes[e.index]?.key;function useStackPages(e,t){let n=e.routes.map(e=>e.key),r=focusedKeyOf(e),i=g(t),a=g(initialTracking(n,r)),[,o]=_(0);needsAdvance(a.current,n,r)&&(a.current=advanceTracking(a.current,n,r,i.current)),m(()=>{i.current=t});let s=f(e=>{let t=releaseFrom(a.current,e);t!==a.current&&(a.current=t,o(e=>e+1))},[]);return{pages:a.current.order.map(e=>t[e]??a.current.closing[e]).filter(e=>e!==void 0),release:s}}function usePageBindings(e){let n=g(new Map),r=g(new t),i=f(t=>r.current.getOrCreate(t,()=>({ref:e=>{e==null?n.current.delete(t):n.current.set(t,e)},onHidden:()=>e(t)})),[e]),a=r.current;p(()=>()=>a.clear(),[a]);let o=f(e=>r.current.retain(e),[]);return{bindingsFor:i,widgets:n.current,retain:o}}function pageElement(e,t,i){let{route:a,options:s}=e,c=s.headerShown===!1?n(o(i.decorated),e.render()):d(`AdwToolbarView`,null,d(`AdwHeaderBar`,{slot:`top`,showStartTitleButtons:!i.decorated,showEndTitleButtons:!i.decorated},i.titleWidget),n(r(i.titleSlot),e.render()));return d(`AdwNavigationPage`,{key:a.key,tag:a.key,title:s.title??a.name,"on:hidden":t.onHidden,ref:t.ref},c)}function StackView(e){let{state:n,descriptors:r,navigation:o,NavigationContent:s}=b(y,e),c=g(null),{pages:l,release:u}=useStackPages(n,r),{bindingsFor:_,widgets:x,retain:S}=usePageBindings(u),C=n.routes.map(e=>e.key),w=focusedKeyOf(n),T=i(`Stack`,l.filter(e=>e.route.key===w||!C.includes(e.route.key)).some(e=>e.options.headerShown!==!1)),{titleWidgetFor:E,slotFor:D,retain:O}=a(`Stack`),k=g(new t);for(let e of l)k.current.set(e.route.key,e.options);let A=k.current;p(()=>()=>A.clear(),[A]),m(()=>{let e=new Set(l.map(e=>e.route.key));k.current.retain(e),O(e),S(e)});let j=f(e=>e===void 0?!0:k.current.get(e)?.animation!==`none`,[]),M=f(()=>{let e=c.current;if(e===null)return;let t=o.getState(),n=widgetStack(e),r=t.routes.map(e=>e.key);isStrictPrefix(n,r)&&o.dispatch({...v.pop(r.length-n.length),target:t.key});let i=o.getState();applyStack(e,widgetStack(e),i.routes.map(e=>e.key),j)},[o,j]),N=h(()=>coalesce(M),[M]),P=g(!0);return m(()=>{let e=c.current;if(e===null)return;let t=n.routes.map(e=>e.key);if(P.current){P.current=!1,e.set_animate_transitions(!1),same(widgetStack(e),t)||e.replace_with_tags([...t]),e.set_animate_transitions(!0);return}applyStack(e,widgetStack(e),t,j)}),m(()=>{for(let e of l){let t=e.route.key;if(n.routes.some(e=>e.key===t))continue;let r=x.get(t);r!==void 0&&!r.get_mapped()&&u(t)}}),d(s,null,d(`AdwNavigationView`,{ref:c,popOnEscape:!0,"on:popped":N},...l.map(e=>pageElement(e,_(e.route.key),{decorated:T.decorated,titleWidget:E(e.route.key),titleSlot:D(e.route.key)}))))}StackView.displayName=`GjsifyStackView`;const S=s(StackView);function StackScreen(t){throw new e(`not-a-screen-child`,`<Stack.Screen>`,"was rendered instead of being read. It is a declaration: `<Stack>` collects its `name` and `options` and never renders it, so it only belongs as a direct child of `<Stack>`")}StackScreen.displayName=`Stack.Screen`;function Stack(e){let t=l(`Stack`),n=c(`Stack`,StackScreen,x,e.children),r=u(t,S.Screen,n),i=e.screenOptions===void 0?{}:{screenOptions:e.screenOptions};return d(S.Navigator,i,...r)}Stack.Screen=StackScreen;export{Stack,advanceTracking,applyStack,coalesce,initialTracking,neededKeys,needsAdvance,releaseFrom};
|
package/lib/esm/router/tabs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"../_virtual/_rolldown/runtime.js";import{RouterError as e}from"./errors.js";import{
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import{RouterError as e}from"./errors.js";import{provideChromeLevel as t,underHeaderBar as n,useChrome as r,withoutHeaderBar as i}from"./chrome.js";import{navigationPair as a,screenOptionsFrom as o,useRouteNode as s,useSynthesisedScreens as c}from"./screens.js";import{createElement as l,useCallback as u,useLayoutEffect as d,useMemo as f,useRef as p}from"react";import{TabActions as m,TabRouter as h,useNavigationBuilder as g}from"@react-navigation/core";const _=[`title`];function showFocusedPage(e,t){if(e.get_visible_child_name()===t)return!0;let n=e.get_child_by_name(t);return n===null||!n.get_visible()?!1:(e.set_visible_child_name(t),!0)}function TabsView(a){let{state:o,descriptors:s,navigation:c,NavigationContent:_}=g(h,a),v=p(null),y=p(null),b=o.routes[o.index]?.key,x=r(`Tabs`,a.headerShown!==!1),S=u(()=>{let e=y.current,t=v.current;e!==null&&t!==null&&e.get_stack()!==t&&e.set_stack(t)},[]);d(S);let C=u(e=>{v.current=e??null,S()},[S]),w=u(e=>{y.current=e??null,S()},[S]),T=f(()=>l(`AdwViewSwitcher`,{slot:`title`,ref:w,policy:`wide`}),[w]),E=x.titleSlot,D=E!==null&&a.headerShown!==!1;d(()=>{if(!(E===null||a.headerShown===!1))return E.setTitleWidget(T),()=>E.setTitleWidget(null)},[E,a.headerShown,T]);let O=p(null);d(()=>{let e=v.current;e===null||b===void 0||(O.current=b,showFocusedPage(e,b))});let k=u(()=>{let t=v.current;if(t===null)return;let n=t.get_visible_child_name();if(n===null||O.current===null||n===O.current)return;let r=c.getState();if(n===r.routes[r.index]?.key)return;let i=r.routes.find(e=>e.key===n);if(i===void 0)throw new e(`no-route-node`,`<Tabs> page "${n}"`,`became visible and belongs to no route in this navigator. Every page is added under its route key, so this means something outside the router added a child to the Adw.ViewStack`);if(c.emit({type:`tabPress`,target:i.key,canPreventDefault:!0}).defaultPrevented){let e=r.routes[r.index]?.key??n;O.current=e,showFocusedPage(t,e);return}c.dispatch({...m.jumpTo(i.name,i.params),target:r.key})},[c]),A=D||a.headerShown===!1?i(x.decorated):n(null),j=o.routes.map(n=>{let r=s[n.key];if(r===void 0)throw new e(`no-route-node`,`<Tabs> route "${n.name}"`,`has no descriptor. React Navigation builds one per screen, so this is a route the navigator never received a <Screen> for`);return l(`AdwBin`,{key:n.key,layout:{name:n.key,title:r.options.title??n.name}},t(A,r.render()))}),M=l(`AdwViewStack`,{ref:C,"on:notify::visible-child-name":k},...j);return a.headerShown===!1||D?l(_,null,M):l(_,null,l(`AdwToolbarView`,null,l(`AdwHeaderBar`,{slot:`top`,showStartTitleButtons:!x.decorated,showEndTitleButtons:!x.decorated},T),M))}TabsView.displayName=`GjsifyTabsView`;const v=a(TabsView);function TabsScreen(t){throw new e(`not-a-screen-child`,`<Tabs.Screen>`,"was rendered instead of being read. It is a declaration: `<Tabs>` collects its `name` and `options` and never renders it, so it only belongs as a direct child of `<Tabs>`")}TabsScreen.displayName=`Tabs.Screen`;function Tabs(e){let t=s(`Tabs`),n=o(`Tabs`,TabsScreen,_,e.children),r=c(t,v.Screen,n);return l(v.Navigator,{...e.screenOptions===void 0?{}:{screenOptions:e.screenOptions},...e.headerShown===void 0?{}:{headerShown:e.headerShown}},...r)}Tabs.Screen=TabsScreen;export{Tabs,showFocusedPage};
|
package/lib/esm/solid/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"../_virtual/_rolldown/runtime.js";import{
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import{applyAccessibility as e}from"../accessibility.js";import{accessor as t}from"../accessor.js";import{PrimitiveError as n}from"../primitives/errors.js";import{onLiveRegion as r}from"../announce.js";import{resolvePrimitive as i}from"../primitives/resolve.js";import{createHandle as a}from"../primitives/handles.js";import{styleConfig as o}from"../style-config.js";import{createContext as s,createMemo as c,createSignal as l,onCleanup as u,onMount as d,untrack as f,useContext as p}from"solid-js";import{createComponent as m,createElement as h,effect as g,insert as _,insertNode as v,mount as y,setProp as b,widgetOf as x}from"@gjsify/gtk-host/solid";const S=s(()=>null),C=new WeakSet,w=new WeakMap,T={absolute:1,count:1,text:!1},sameContext=(e,t)=>JSON.stringify(e)===JSON.stringify(t),sameValue=(e,t)=>Array.isArray(e)&&Array.isArray(t)?e.length===t.length&&e.every((e,n)=>e===t[n]):e===t;function element(t,n){let s=n,m=o(),y=p(S),[E,D]=l(null),O=c(()=>{let e=y();return i(t,s,{tokens:m.tokens,sheet:m.sheet,...e===null?{}:{parent:e},children:E()??T})}),k=f(O).childContext.overlay,A=c(()=>({...O().childContext,overlay:k}),void 0,{equals:sameContext}),j=childrenUnder(s,A);assertOwnChildren(t,j(),A),D(factsOf(t,j()));let M=f(O),N=h(M.node.tag),P=M.content===null?null:h(M.content.tag);M.slot!==null&&C.add(N),w.set(N,y);for(let[e,t]of Object.entries(dispatchers(M.events,s,N)))b(N,e,t);M.announcements.length>0&&d(()=>{let e=x(N),t=M.announcements.map(t=>r(e,t));u(()=>{for(let e of t)e()})}),d(()=>{let t=x(N);g(()=>{let n=O().accessibility;n.length!==0&&u(e(t,n))})});let F={},I={};g(()=>{let e=O();assertStableShape(t,M,e),writeProps(N,F,{...y()?.props,...e.node.props,...e.slot===null?{}:{slot:e.slot},...classProp(e.node)}),P!==null&&e.content!==null&&writeProps(P,I,{...e.content.props,...classProp(e.content)})});let L=s.ref;typeof L==`function`&&d(()=>L(a(M.handle,x(N),M.node.tag))),P!==null&&v(N,P);let R=P??N;if(M.absoluteSlot===null)_(R,j);else{_(R,()=>split(j()).ordinary);for(let e of split(f(j)).slotted)v(N,e)}return N}function childrenUnder(e,t){let n=S.Provider;return m(n,{value:t,get children(){return e.children}})}function assertOwnChildren(e,t,r){for(let i of Array.isArray(t)?t:[t]){if(typeof i!=`object`||!i)continue;let t=w.get(i);if(!(t===void 0||t===r))throw new n(e,`children`,"contains an element that was built BEFORE this one, so it resolved outside this element's context: it never learned this parent's orientation or its inherited alignment, and the loss is silent — `flex-1` stays unresolved and `items-center` never reaches it. Pass children lazily, `get children() { return … }`, which is what every Solid JSX compiler emits and the reason Solid's context works at all")}}function factsOf(e,t){let r=(Array.isArray(t)?t:[t]).filter(e=>e!=null&&typeof e!=`boolean`),i=0,a=!1;for(let t of r)if(typeof t==`string`||typeof t==`number`)a=!0;else if(typeof t==`function`)throw new n(e,`children`,"was given a function that takes an argument. Children-as-a-function-of-`{ pressed }` is implemented in the REACT binding and not in this one, and the difference is Solid's own: a component body runs once, so the press state would have to arrive as a SIGNAL the child reads rather than as a value the parent re-renders with — a different design, not a port of the React one. Write `className=\"active:opacity-70\"`, which is the GTK CSS `:active` pseudo-class (ADR 0032 § 7) and what nearly every use of the function form is asking for. A zero-argument accessor is Solid's own dynamic child and never reaches this refusal");else typeof t==`object`&&t&&C.has(t)&&i++;return{absolute:i,count:r.length,text:a}}function split(e){let t=Array.isArray(e)?e:[e],n=[],r=[];for(let e of t)typeof e==`object`&&e&&C.has(e)?r.push(e):n.push(e);return{ordinary:n,slotted:r}}function dispatchers(e,n,r){let i={};for(let a of e)i[`on:${a.signal}`]=()=>{let e=n[a.prop];if(typeof e==`function`){if(a.read===null){e();return}e(x(r)[t(a.read)])}};return i}function writeProps(e,t,n){for(let r of Object.keys(t))r in n||(b(e,r,void 0),delete t[r]);for(let[r,i]of Object.entries(n))sameValue(t[r],i)||(b(e,r,i),t[r]=i)}const classProp=e=>e.cssClasses.length===0?{}:{"css-classes":[...e.cssClasses]};function assertStableShape(e,t,r){let shape=e=>[e.node.tag,e.content?.tag??`-`,e.events.map(e=>`${e.prop}>${e.signal}`).join(`,`),e.announcements.map(e=>`${e.signal}>${e.priority}`).join(`,`)].join(`|`),i=shape(t),a=shape(r);if(i!==a)throw new n(e,`reactive update`,`would change the element from ${i} to ${a}, and a Solid element is created once — there is no reconciler pass that could swap the widget. Split the branches into two elements under a <Show>, where each one is created for its own shape`)}function View(e){return element(`View`,e)}function Text(e){return element(`Text`,e)}function Pressable(e){return element(`Pressable`,e)}function ScrollView(e){return element(`ScrollView`,e)}function ActivityIndicator(e){return element(`ActivityIndicator`,e)}function TextInput(e){return element(`TextInput`,e)}function Switch(e){return element(`Switch`,e)}export{ActivityIndicator,Pressable,ScrollView,Switch,Text,TextInput,View,y as mount};
|