@symbiote-native/solid 0.0.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/README.md +25 -14
  2. package/babel-lower-host-primitives.cjs +323 -0
  3. package/babel-preset.cjs +5 -0
  4. package/build/bootstrap.d.ts +7 -0
  5. package/build/bootstrap.js +18 -0
  6. package/build/components/activity-indicator/index.android.d.ts +2 -0
  7. package/build/components/activity-indicator/index.android.js +11 -0
  8. package/build/components/activity-indicator/index.d.ts +1 -0
  9. package/build/components/activity-indicator/index.ios.d.ts +2 -0
  10. package/build/components/activity-indicator/index.ios.js +10 -0
  11. package/build/components/activity-indicator/index.js +4 -0
  12. package/build/components/activity-indicator/shared.d.ts +8 -0
  13. package/build/components/activity-indicator/shared.js +51 -0
  14. package/build/components/button.d.ts +7 -0
  15. package/build/components/button.jsx +45 -0
  16. package/build/components/flat-list/index.d.ts +10 -0
  17. package/build/components/flat-list/index.jsx +118 -0
  18. package/build/components/image-background.d.ts +10 -0
  19. package/build/components/image-background.jsx +74 -0
  20. package/build/components/image.d.ts +9 -0
  21. package/build/components/image.js +75 -0
  22. package/build/components/input-accessory-view.d.ts +11 -0
  23. package/build/components/input-accessory-view.jsx +39 -0
  24. package/build/components/keyboard-avoiding-view.d.ts +15 -0
  25. package/build/components/keyboard-avoiding-view.jsx +152 -0
  26. package/build/components/modal.d.ts +24 -0
  27. package/build/components/modal.jsx +125 -0
  28. package/build/components/pressable.d.ts +31 -0
  29. package/build/components/pressable.jsx +211 -0
  30. package/build/components/refresh-control.d.ts +18 -0
  31. package/build/components/refresh-control.jsx +36 -0
  32. package/build/components/safe-area-view.d.ts +11 -0
  33. package/build/components/safe-area-view.jsx +24 -0
  34. package/build/components/scroll-view/index.android.d.ts +2 -0
  35. package/build/components/scroll-view/index.android.js +11 -0
  36. package/build/components/scroll-view/index.d.ts +2 -0
  37. package/build/components/scroll-view/index.ios.d.ts +2 -0
  38. package/build/components/scroll-view/index.ios.js +8 -0
  39. package/build/components/scroll-view/index.js +9 -0
  40. package/build/components/scroll-view/shared.d.ts +85 -0
  41. package/build/components/scroll-view/shared.jsx +334 -0
  42. package/build/components/scroll-view/sticky-header.d.ts +18 -0
  43. package/build/components/scroll-view/sticky-header.jsx +182 -0
  44. package/build/components/section-list/index.d.ts +6 -0
  45. package/build/components/section-list/index.jsx +8 -0
  46. package/build/components/switch/index.android.d.ts +2 -0
  47. package/build/components/switch/index.android.js +12 -0
  48. package/build/components/switch/index.d.ts +1 -0
  49. package/build/components/switch/index.ios.d.ts +2 -0
  50. package/build/components/switch/index.ios.js +11 -0
  51. package/build/components/switch/index.js +4 -0
  52. package/build/components/switch/shared.d.ts +11 -0
  53. package/build/components/switch/shared.js +87 -0
  54. package/build/components/text-input.d.ts +10 -0
  55. package/build/components/text-input.js +290 -0
  56. package/build/components/text.d.ts +26 -0
  57. package/build/components/text.jsx +27 -0
  58. package/build/components/touchable/index.d.ts +22 -0
  59. package/build/components/touchable/index.jsx +247 -0
  60. package/build/components/touchable-native-feedback/index.d.ts +16 -0
  61. package/build/components/touchable-native-feedback/index.jsx +68 -0
  62. package/build/components/view.d.ts +32 -0
  63. package/build/components/view.jsx +49 -0
  64. package/build/components/virtualized-list/index.android.d.ts +2 -0
  65. package/build/components/virtualized-list/index.android.js +9 -0
  66. package/build/components/virtualized-list/index.d.ts +1 -0
  67. package/build/components/virtualized-list/index.ios.d.ts +2 -0
  68. package/build/components/virtualized-list/index.ios.js +9 -0
  69. package/build/components/virtualized-list/index.js +4 -0
  70. package/build/components/virtualized-list/shared.d.ts +75 -0
  71. package/build/components/virtualized-list/shared.jsx +782 -0
  72. package/build/components/virtualized-section-list/index.d.ts +62 -0
  73. package/build/components/virtualized-section-list/index.jsx +145 -0
  74. package/build/components.d.ts +43 -0
  75. package/build/components.js +54 -0
  76. package/build/create-portal/index.d.ts +11 -0
  77. package/build/create-portal/index.jsx +88 -0
  78. package/build/create-tunnel/index.d.ts +13 -0
  79. package/build/create-tunnel/index.jsx +53 -0
  80. package/build/descriptor-to-solid.d.ts +3 -0
  81. package/build/descriptor-to-solid.js +91 -0
  82. package/build/host-instance.d.ts +2 -0
  83. package/build/host-instance.js +36 -0
  84. package/build/index.d.ts +31 -0
  85. package/build/index.js +98 -0
  86. package/build/jsx-runtime.d.ts +26 -0
  87. package/build/jsx-runtime.js +46 -0
  88. package/build/modules/animated/create-animated-component.d.ts +10 -0
  89. package/build/modules/animated/create-animated-component.jsx +127 -0
  90. package/build/modules/animated/index.d.ts +54 -0
  91. package/build/modules/animated/index.js +78 -0
  92. package/build/modules/app-registry/index.d.ts +7 -0
  93. package/build/modules/app-registry/index.js +37 -0
  94. package/build/modules/status-bar.d.ts +7 -0
  95. package/build/modules/status-bar.js +45 -0
  96. package/build/primitives/create-color-scheme.d.ts +3 -0
  97. package/build/primitives/create-color-scheme.js +33 -0
  98. package/build/primitives/create-window-dimensions.d.ts +3 -0
  99. package/build/primitives/create-window-dimensions.js +34 -0
  100. package/build/register.d.ts +1 -0
  101. package/build/register.js +31 -0
  102. package/build/render.d.ts +7 -0
  103. package/build/render.js +91 -0
  104. package/build/renderer.d.ts +8 -0
  105. package/build/renderer.js +259 -0
  106. package/build/state-style.d.ts +1 -0
  107. package/build/state-style.js +13 -0
  108. package/build/utils/host-ref.d.ts +3 -0
  109. package/build/utils/host-ref.js +22 -0
  110. package/build/utils/stable-keys.d.ts +1 -0
  111. package/build/utils/stable-keys.js +31 -0
  112. package/package.json +24 -8
@@ -0,0 +1,31 @@
1
+ import './register';
2
+ export { mount, unmount } from './render';
3
+ export { findNodeHandle } from './host-instance';
4
+ export type { IHostInstance } from './host-instance';
5
+ export * from './components';
6
+ export type { IAccessibilityProps, IAriaProps, IAccessibilityRole, IRole, IAccessibilityStateValue, IAccessibilityValue, IAccessibilityActionInfo, IResponderProps, IImageSource, IImageSourceProp, IResizeMode, IImageSize, IImageCacheStatus, IEnterKeyHint, IInputMode, ISubmitBehavior, } from '@symbiote-native/components';
7
+ export { setImageSourceResolver } from '@symbiote-native/components';
8
+ export { descriptorToSolid } from './descriptor-to-solid';
9
+ export { AppRegistry, setHostRegistrar } from './modules/app-registry';
10
+ export type { IComponentProvider, IWrapperComponentProvider, IAppParameters, IRunnable, IHostRegistrar, IRegistry, IHeadlessTask, ITaskProvider, ITaskCanceller, ITaskCancelProvider, } from './modules/app-registry';
11
+ export { StatusBar } from './modules/status-bar';
12
+ export type { IStatusBarProps, IStatusBarStyle } from './modules/status-bar';
13
+ export { Portal } from './create-portal';
14
+ export type { IPortalProps, IPortalTarget } from './create-portal';
15
+ export { createTunnel } from './create-tunnel';
16
+ export type { ITunnel, ITunnelInProps } from './create-tunnel';
17
+ export { createColorScheme } from './primitives/create-color-scheme';
18
+ export { createWindowDimensions } from './primitives/create-window-dimensions';
19
+ export { Animated, createAnimatedComponent } from './modules/animated';
20
+ export type { IAnimatedComponentProps } from './modules/animated';
21
+ export { Platform, StyleSheet, PixelRatio, PlatformColor, DynamicColorIOS, processColor, } from '@symbiote-native/engine';
22
+ export { setNativeViewConfigSource, setColorProcessor, setDeviceEventSource, } from '@symbiote-native/engine';
23
+ export { dlog, isDebug } from '@symbiote-native/engine';
24
+ export type { IViewStyle, ITextStyle, IFlexAlign, IFlexJustify, ISymbioteEvent, ISymbioteNode, IRootTag, INativeViewConfig, INativeViewConfigSource, IColorValue, IOpaqueColorValue, IDynamicColorIOSTuple, IPixelRatioStatic, IPlatformStatic, IPlatformOSType, IPlatformConstantsIOS, IPlatformConstantsAndroid, IPlatformSelectSpec, } from '@symbiote-native/engine';
25
+ export { Alert, Share, ActionSheetIOS, Linking, Vibration, ToastAndroid, Settings, I18nManager, Dimensions, Appearance, AppState, Keyboard, KEYBOARD_EVENT, BackHandler, PermissionsAndroid, PERMISSIONS, RESULTS, LayoutAnimation, InteractionManager, } from '@symbiote-native/engine';
26
+ export type { IAlertType, IAlertButtonStyle, IAlertButton, IAlertButtons, IAlertOptions, IShareContent, IShareOptions, IShareAction, IActionSheetIOSOptions, IShareActionSheetIOSOptions, IShareActionSheetError, IUrlEvent, II18nManagerConstants, IDisplayMetrics, IDisplayMetricsAndroid, IDimensionsPayload, IDimensionsSet, IDimensionsKey, IDimensionsChangeListener, IDimensionsStatic, IColorSchemeName, IColorSchemePreference, IAppStateStatus, IAppStateEvent, IKeyboardEventName, IKeyboardEvent, IKeyboardMetrics, IBackPressEventName, IBackPressHandler, IPermission, IPermissionStatus, IRationale, ILayoutAnimationType, ILayoutAnimationProperty, ILayoutAnimationConfig, ILayoutAnimationAnim, IInteractionEvent, ISimpleTask, IPromiseTask, ITask, IHandle, } from '@symbiote-native/engine';
27
+ export { PanResponder } from '@symbiote-native/engine';
28
+ export type { IPanResponderGestureState, IPanResponderCallbacks, IGestureResponderHandlers, IPanResponderInstance, } from '@symbiote-native/engine';
29
+ export { AccessibilityInfo } from '@symbiote-native/engine';
30
+ export type { IAccessibilityChangeEvent, IAccessibilityChangeEventName, IAccessibilityChangeEventHandler, IAccessibilityAnnouncementFinishedEvent, IAnnounceForAccessibilityOptions, IAccessibilityEventType, } from '@symbiote-native/engine';
31
+ export { For, Index, Show, ErrorBoundary, Suspense, SuspenseList, } from 'solid-js';
package/build/index.js ADDED
@@ -0,0 +1,98 @@
1
+ // @symbiote-native/solid: a Solid adapter over @symbiote-native/engine, built on Solid's own
2
+ // universal custom-renderer API (solid-js/universal). Compiled Solid JSX drives real native
3
+ // iOS/Android views; underneath, every call routes into the same mutation API every other adapter
4
+ // uses. All Fabric clone-on-write lives in the engine, shared cross-adapter. App code imports
5
+ // @symbiote-native/solid, never react-native.
6
+ //
7
+ // Layer status (symbiote-new-adapter §7): L4 in progress. The primitives, the stateful touch
8
+ // components, the Touchable family, Button / ImageBackground / InputAccessoryView, StatusBar and
9
+ // the list family are done at full parity with the React reference, and the engine-owned runtime
10
+ // modules are re-exported below. Content relocation is in too: `Portal` (same-surface, React's
11
+ // createPortal twin) and `createTunnel` (cross-surface), both written over the universal renderer
12
+ // — solid-js/web's DOM-bound Portal was never the route to either. This barrel grows a layer at a
13
+ // time on purpose, so a break localizes to the layer that introduced it.
14
+ //
15
+ // The two lifecycle primitives are spelled `createColorScheme` / `createWindowDimensions`, not
16
+ // `use*`: in Solid `use*` means consuming something that already exists (useContext,
17
+ // useTransition) while a function that creates its own state and owns a subscription is `createX`.
18
+ // Angular spells the same pair as services for the same idiom reason — this is a naming
19
+ // divergence <adapter_src_follows_framework_idioms> asks for, not a parity gap.
20
+ // No JSX augmentation is imported here. The host tags live in this package's own JSX namespace at
21
+ // ./jsx-runtime, which an app reaches by config rather than by import:
22
+ // `"jsxImportSource": "@symbiote-native/solid"` (see that file). The earlier
23
+ // `declare module 'solid-js'` shim is gone with it — one mechanism, not two.
24
+ // Bare, side-effect only, and deliberately NOT `export * from './register'` — see that file.
25
+ import './register.js';
26
+ export { mount, unmount } from './render.js';
27
+ export { findNodeHandle } from './host-instance.js';
28
+ export * from './components.js';
29
+ // The app-entry seam that hands Image RN's own source resolver; grouped with the Image types it
30
+ // serves rather than with the engine seams below, matching React's and Svelte's barrels.
31
+ export { setImageSourceResolver } from '@symbiote-native/components';
32
+ // descriptorToSolid: the @symbiote-native/components Descriptor → engine-node bridge. Exported for
33
+ // the same reason React exports descriptorToReact — an external wrapper package over a third-party
34
+ // native view maps its shared render fn's Descriptor through the SAME bridge the adapter uses.
35
+ export { descriptorToSolid } from './descriptor-to-solid.js';
36
+ // Safe in the barrel (unlike ./bootstrap, which imports react-native): the registry seam itself
37
+ // only reaches the engine and solid-js.
38
+ export { AppRegistry, setHostRegistrar } from './modules/app-registry/index.js';
39
+ // Animated: the six animated components RN exposes, over the engine's framework-agnostic value
40
+ // graph. Solid's JSX takes the dotted form directly — `<Animated.View/>` compiles to
41
+ // createComponent(Animated.View, …) — so no local alias is needed, unlike Angular, whose AOT
42
+ // compiler cannot trace a class through property access (.claude/rules/dotted-component-tags.md).
43
+ export { StatusBar } from './modules/status-bar.js';
44
+ // Portal: same-surface content relocation, the twin of React's createPortal and Angular's
45
+ // PortalDirective/PortalOutletDirective. `mount` takes an already-mounted host node in THIS
46
+ // surface (a ref off a rendered component) or the surface itself; reaching a second, separately
47
+ // mounted surface is a different mechanism by design — see ./create-portal's header.
48
+ export { Portal } from './create-portal/index.jsx';
49
+ // createTunnel: cross-surface content sharing, the case Portal deliberately does not cover. A
50
+ // shared store, never a reach into a foreign surface's tree — `Out` paints from whichever surface
51
+ // renders it. Same name and same In/Out shape as the React, Vue, Svelte and Angular versions.
52
+ export { createTunnel } from './create-tunnel/index.jsx';
53
+ // Reactive wrappers over the engine's own Appearance / Dimensions event sources. The engine keeps
54
+ // the subscription logic; these add only the Solid lifecycle (signal + onCleanup).
55
+ export { createColorScheme } from './primitives/create-color-scheme.js';
56
+ export { createWindowDimensions } from './primitives/create-window-dimensions.js';
57
+ export { Animated, createAnimatedComponent } from './modules/animated/index.js';
58
+ // Everything below is re-exported VERBATIM from the shared packages — no Solid half exists or is
59
+ // wanted, so a passthrough stub file would only add a hop (.claude/rules/barrel-passthrough.md).
60
+ // The app names @symbiote-native/solid and gets RN's single import root.
61
+ // Pure utilities and the color surface: no native event, no lifecycle, so they live in the engine
62
+ // per <runtime_modules_layering>.
63
+ export { Platform, StyleSheet, PixelRatio, PlatformColor, DynamicColorIOS, processColor, } from '@symbiote-native/engine';
64
+ // The three app-entry seams, wired once on a real host. setNativeViewConfigSource is how a
65
+ // third-party Fabric view auto-derives its metadata:
66
+ // setNativeViewConfigSource(name => ReactNativeViewConfigRegistry.get(name))
67
+ export { setNativeViewConfigSource, setColorProcessor, setDeviceEventSource, } from '@symbiote-native/engine';
68
+ // Diagnostics gated by DEBUG (<keep_logs_gate_behind_DEBUG>): app code logs through the same seam
69
+ // the engine does, never a bare console.log.
70
+ export { dlog, isDebug } from '@symbiote-native/engine';
71
+ // Imperative runtime modules: thin JS over getNativeModule + device events, no Fabric component
72
+ // of their own, so there is nothing per-framework to write.
73
+ export { Alert, Share, ActionSheetIOS, Linking, Vibration, ToastAndroid, Settings, I18nManager, Dimensions, Appearance, AppState, Keyboard, KEYBOARD_EVENT, BackHandler, PermissionsAndroid, PERMISSIONS, RESULTS, LayoutAnimation, InteractionManager, } from '@symbiote-native/engine';
74
+ // PanResponder: the gesture recognizer over the engine's responder events, shared by every adapter.
75
+ export { PanResponder } from '@symbiote-native/engine';
76
+ // AccessibilityInfo comes STRAIGHT from the engine, which owns the iOS/Android split
77
+ // (core/engine/src/accessibility-info/). React routes it through an adapter folder of the same
78
+ // name, but that folder is a pure passthrough of these exact names — matching it means matching
79
+ // the engine module, not growing a second one here.
80
+ export { AccessibilityInfo } from '@symbiote-native/engine';
81
+ // Solid's control flow is pure reactivity with no DOM dependency, so it works verbatim over the
82
+ // universal renderer and is re-exported here to keep an app on one import. solid-js/web's own
83
+ // `Portal` is NOT among them and cannot be — it allocates its container with
84
+ // `document.createElement` — but the CAPABILITY is not missing: this package ships its own
85
+ // `Portal` over the universal renderer (./create-portal, exported above), at the same
86
+ // same-surface scope React and Angular chose for theirs. `Dynamic` is the one member of that DOM-bound pair still absent.
87
+ // It is absent on its own terms, not as fallout from Portal: nothing here needed it (a tunnel
88
+ // renders stored content by calling a thunk inside <For>, no dynamic component involved), and no
89
+ // other adapter ships a twin of it for parity to require one.
90
+ //
91
+ // Solid's own control-flow `Switch`/`Match` pair is ABSENT for a different reason: `Switch` collides
92
+ // head-on with RN's Switch component, which every other adapter exports under exactly that name and
93
+ // which P0 parity (<adapters_reach_full_feature_parity>) pins here too. The RN component wins the
94
+ // name; the control-flow pair keeps its canonical home, `import { Switch, Match } from 'solid-js'`
95
+ // (alias it there if both are needed in one file). `Match` is withheld ALONGSIDE it deliberately —
96
+ // re-exporting a lone `Match` while `Switch` means something else would compile fine and then fail
97
+ // at runtime, which is worse than a missing export.
98
+ export { For, Index, Show, ErrorBoundary, Suspense, SuspenseList, } from 'solid-js';
@@ -0,0 +1,26 @@
1
+ import type { ISymbioteIntrinsic } from '@symbiote-native/components';
2
+ import type { ISymbioteNode } from '@symbiote-native/engine';
3
+ type ISymbioteHostAttributes = {
4
+ readonly children?: JSX.Element;
5
+ readonly [attribute: string]: unknown;
6
+ };
7
+ export declare namespace JSX {
8
+ type Element = ISymbioteNode | IArrayElement | IFunctionElement | (string & {}) | number | boolean | null | undefined;
9
+ interface IArrayElement extends Array<Element> {
10
+ }
11
+ interface IFunctionElement {
12
+ (): Element;
13
+ }
14
+ interface ElementClass {
15
+ }
16
+ interface ElementAttributesProperty {
17
+ }
18
+ interface ElementChildrenAttribute {
19
+ children: {};
20
+ }
21
+ interface IntrinsicAttributes {
22
+ }
23
+ interface IntrinsicElements extends Record<ISymbioteIntrinsic, ISymbioteHostAttributes> {
24
+ }
25
+ }
26
+ export {};
@@ -0,0 +1,46 @@
1
+ // The package's own JSX namespace — what an app points `jsxImportSource` at:
2
+ //
3
+ // // tsconfig.json
4
+ // "jsx": "preserve",
5
+ // "jsxImportSource": "@symbiote-native/solid"
6
+ //
7
+ // TypeScript resolves the namespace from `<jsxImportSource>/jsx-runtime` and NOTHING ELSE. That
8
+ // holds under `jsx: "preserve"` too, which is easy to doubt — the flag is documented as naming the
9
+ // module the `jsx`/`jsxs` factories are imported from, and `preserve` imports nothing. Measured:
10
+ // pointing jsxImportSource at a package that does not exist fails with
11
+ // `TS2875: This JSX tag requires the module path '<source>/jsx-runtime' to exist`, on a config
12
+ // whose `jsx` is `preserve`. So the entry is type-only by nature — the emitted build/jsx-runtime.js
13
+ // is empty and never imported by anything, because babel-preset-solid rewrites JSX into calls on
14
+ // ./renderer instead (that is the `moduleName` option, a separate mechanism from this one).
15
+ //
16
+ // WHY OUR OWN NAMESPACE AND NOT AN AUGMENTATION OF SOLID'S. `@lightningtv/solid` (3.2.5), the
17
+ // most widely used universal renderer on a non-DOM host, ships exactly
18
+ // `declare module 'solid-js' { namespace JSX { interface IntrinsicElements { … } } }` plus
19
+ // `export type { JSX } from 'solid-js'`. That re-export is genuinely all it takes to make the
20
+ // entry resolvable, and it is what this package's own src/jsx.ts did before this file replaced it.
21
+ // It buys one thing: an app stops needing a `/// <reference types="@symbiote-native/solid" />` line
22
+ // to pull the augmentation into its program. It does NOT buy the other two, and both matter more:
23
+ //
24
+ // 1. Augmenting MERGES into solid-js's own IntrinsicElements, which lists every HTML and SVG
25
+ // tag. `<div>` stays valid JSX in a React Native app and fails at runtime, not at compile
26
+ // time. Declaring the interface fresh here is what makes an unknown tag an error.
27
+ // 2. solid-js's `JSX.Element` is `Node | ArrayElement | (string & {}) | number | boolean | null
28
+ // | undefined`, and `Node` is a DOM type. A React Native program has no DOM lib (this repo:
29
+ // `lib: ["ES2022"]`; the canary: RN's own config, equally DOM-less), so the name does not
30
+ // resolve — and `skipLibCheck: true` SUPPRESSES that error inside solid-js's .d.ts rather
31
+ // than surfacing it, leaving `Node` as `any`. One `any` in a union collapses the whole union,
32
+ // so `JSX.Element` is `any` and every JSX child position in every consuming app goes
33
+ // unchecked. Measured two ways: `const bogus: JSX.Element = { definitelyNotAnElement: true }`
34
+ // compiles, and `const node: Node = …` in a first-party file (not skipLibCheck'd) reports
35
+ // `TS2304: Cannot find name 'Node'`.
36
+ //
37
+ // The risk this trades against — recorded when the swap was deferred — is that our `Element` has
38
+ // to line up with what solid-js's own `<Show>` / `<For>` return. It does, for a reason that only
39
+ // holds because of point 2 above: those return solid's `JSX.Element`, which IS `any` in exactly the
40
+ // DOM-less programs we target, so it is assignable to anything of ours. jsx-runtime.test.tsx pins
41
+ // the runtime half (both compose through this renderer and re-render on a signal); the type half is
42
+ // carried by examples/solid's own `tsc --noEmit`. The one configuration that would break the
43
+ // alignment is an app that pulls in the DOM lib, giving solid's `Element` a real `Node` — recorded
44
+ // in `.claude/rules/solid-jsx-namespace.md`.
45
+ export {};
46
+ /* eslint-enable @typescript-eslint/no-namespace, @typescript-eslint/no-empty-object-type */
@@ -0,0 +1,10 @@
1
+ import { type Component, type Ref } from 'solid-js';
2
+ import type { JSX } from '../../jsx-runtime';
3
+ export interface IAnimatedComponentProps {
4
+ style?: unknown;
5
+ ref?: Ref<unknown>;
6
+ passthroughAnimatedPropExplicitValues?: unknown;
7
+ children?: JSX.Element;
8
+ [key: string]: unknown;
9
+ }
10
+ export declare function createAnimatedComponent(Base: Component<any> | string): (props: IAnimatedComponentProps) => JSX.Element;
@@ -0,0 +1,127 @@
1
+ // createAnimatedComponent for @symbiote-native/solid: wraps a base component so its props may
2
+ // carry AnimatedNodes. The Solid twin of adapters/{react,vue}/src/modules/animated/
3
+ // create-animated-component; grown from components/scroll-view/animated-host.tsx, which was the
4
+ // same body pinned to `symbiote-view` and is absorbed by this file.
5
+ //
6
+ // A GENERIC WRAP IS POSSIBLE HERE, unlike Svelte. A Solid component is a plain function and
7
+ // `createComponent(Comp, props)` is an ordinary runtime call over any component reference — the
8
+ // same call compiled JSX itself emits. Svelte's four hand-authored .svelte files exist because a
9
+ // compiled Svelte component is not invocable that way; Angular's six explicit @Components exist
10
+ // because AOT-under-Metro ships no JIT. Neither constraint applies.
11
+ //
12
+ // The per-FRAME path never comes through here: value.setValue / animation -> flushValue ->
13
+ // AnimatedProps.update() -> setNativeProps(node). Under the native driver not even that runs — the
14
+ // UI thread owns the props once the leaf is connected to the view tag. This wrap only supplies the
15
+ // DECLARATIVE bag (animated nodes replaced by their current values) so first paint and every
16
+ // non-animated recompute carry concrete numbers.
17
+ //
18
+ // THE COMMIT-TIMING TRAP IS LIVE HERE. This adapter commits through `requestCommit()`, which is
19
+ // microtask-coalesced, so a mount-time effect runs BEFORE the node has a Fabric tag and the native
20
+ // half of the reconcile would silently no-op. `whenCommitted` is the retry seam (Angular passes the
21
+ // same thing for the same reason). Only the NATIVE half is deferred — the leaf is always built and
22
+ // attached to the value graph synchronously, because a deferred build sits behind a canceller the
23
+ // next reconcile drops.
24
+ import { createEffect, mergeProps, onCleanup, splitProps, } from 'solid-js';
25
+ import { createAnimatedLeafLifecycle, isNativeAnimatedAvailable, isSymbioteNode, readPassthroughStyle, reduceProps, resolveHostNode, whenCommitted, } from '@symbiote-native/engine';
26
+ import { createElement, spread } from '../../renderer.js';
27
+ import { withStableKeys } from '../../utils/stable-keys.js';
28
+ // RN's prop carrying already-rasterized values that OVERRIDE the animated prop in the committed
29
+ // props, so the ShadowTree (hit-testing) stays current while the native driver animates.
30
+ const PASSTHROUGH_PROP = 'passthroughAnimatedPropExplicitValues';
31
+ // `Component<any>` is solid-js's own shape for "any component" (it is what ValidComponent is built
32
+ // from). A precise generic cannot work: the bag handed to the base is assembled at RUNTIME from a
33
+ // key set that grows, so no static prop type describes it. The RETURN type stays precise, so a
34
+ // caller of Animated.View still gets a real prop type.
35
+ // `Base` accepts a TAG as well as a component, and the string branch is not symmetry — it is the
36
+ // only shape that works once a primitive becomes a public intrinsic. `<Base {...props} />` on a
37
+ // capitalized identifier compiles to `createComponent(Base, …)`, which is `untrack(() => Comp(props))`
38
+ // in solid-js, so a string base is a `TypeError: Comp is not a function` at first paint. There is
39
+ // nothing to widen INTO either: `createRenderer()` from solid-js/universal returns twelve names and
40
+ // `Dynamic` is not among them (solid-js/web's Dynamic is DOM-only), so the element has to be built
41
+ // through this renderer's own createElement + spread — the same two calls solid's own Dynamic makes
42
+ // on its string branch. `spread` handles `ref` and `children` itself (universal's spreadExpression
43
+ // skips both in its prop loop and drives them separately), which is why nothing is threaded by hand.
44
+ export function createAnimatedComponent(Base) {
45
+ return function AnimatedComponent(props) {
46
+ // The passthrough is CONSUMED (it only overrides the committed style below); `children` and
47
+ // `ref` are pulled out so the bag accessor depends on neither the child subtree nor the ref.
48
+ const [local, rest] = splitProps(props, [
49
+ 'ref',
50
+ 'children',
51
+ PASSTHROUGH_PROP,
52
+ ]);
53
+ // Held by IDENTITY in a plain variable — never a signal, never a store. The engine's commit
54
+ // mirror is a WeakMap keyed on the raw node, so any proxy wrapper becomes a different key and
55
+ // every native bind silently misses (symbiote-engine-core §3).
56
+ let node = null;
57
+ const lifecycle = createAnimatedLeafLifecycle('solid');
58
+ // NOT the native-driver switch. A useNativeDriver animation promotes the graph itself
59
+ // (animations/base.ts -> value.__startNativeAnimation -> graph.__makeNative) and the leaf
60
+ // follows through __addChild, with or without this. This is only RN's EAGER promotion for the
61
+ // sticky-header passthrough, and it still needs a real native module to mean anything.
62
+ const wantsNative = () => {
63
+ const passthrough = local[PASSTHROUGH_PROP];
64
+ return (passthrough !== undefined &&
65
+ passthrough !== null &&
66
+ isNativeAnimatedAvailable());
67
+ };
68
+ // withStableKeys: reduceProps' key set follows `rest`, which a caller can shrink between runs,
69
+ // and Solid's `spread` has no removal pass — a vanished key would keep its last value on the
70
+ // native view forever (.claude/rules/solid-descriptor-bridge.md §1). The host primitives widen
71
+ // their own bags too, but relying on that would make this wrap correct only by accident.
72
+ const bag = withStableKeys(() => {
73
+ const reduced = reduceProps({ ...rest });
74
+ const passthroughStyle = readPassthroughStyle(local[PASSTHROUGH_PROP]);
75
+ if (passthroughStyle !== undefined) {
76
+ reduced.style =
77
+ reduced.style === undefined
78
+ ? passthroughStyle
79
+ : [reduced.style, passthroughStyle];
80
+ }
81
+ return reduced;
82
+ });
83
+ // Capture the base's public instance, resolve it to the underlying host node for the leaf
84
+ // (unwrapping a scroll handle), and forward the ORIGINAL instance to the caller, who expects
85
+ // the component's own handle. Ref shape rationale: utils/host-ref.ts.
86
+ const captureRef = (instance) => {
87
+ node = resolveHostNode(instance);
88
+ if (typeof local.ref === 'function')
89
+ local.ref(instance);
90
+ };
91
+ // createEffect, not createRenderEffect: the node has to exist first. The ref above fills it
92
+ // while the element is built, which is strictly before any effect runs.
93
+ createEffect(() => {
94
+ const current = { ...rest };
95
+ const wants = wantsNative();
96
+ const target = isSymbioteNode(node) ? node : null;
97
+ lifecycle.reconcile(current, target, wants, target === null ? undefined : bind => whenCommitted(target, bind));
98
+ });
99
+ onCleanup(() => {
100
+ lifecycle.teardown();
101
+ });
102
+ // ONE merge, never a spread followed by an explicit prop: mergeProps takes the first
103
+ // NON-undefined value scanning back-to-front, so a later explicit `undefined` would lose
104
+ // (.claude/rules/solid-descriptor-bridge.md §6). Safe here because the second source carries
105
+ // only `ref` and `children`, neither of which is the vanishing kind. The getter keeps children
106
+ // lazy so reading the bag never walks the child subtree.
107
+ const childProps = mergeProps(bag, {
108
+ ref: captureRef,
109
+ get children() {
110
+ return local.children;
111
+ },
112
+ });
113
+ // Narrowed HERE and not around the whole factory: `Base` is a parameter captured by this inner
114
+ // function, so a check outside it does not reach the JSX below.
115
+ if (typeof Base === 'string') {
116
+ const element = createElement(Base);
117
+ spread(element, childProps, false);
118
+ // createElement's return type is the renderer's node union, which includes the SURFACE — a
119
+ // root the renderer is handed, never something a tag produces. Narrowed rather than cast, and
120
+ // thrown rather than defaulted: returning null here would paint nothing and stay green.
121
+ if (!isSymbioteNode(element))
122
+ throw new Error(`createAnimatedComponent: <${Base}> did not build a host node`);
123
+ return element;
124
+ }
125
+ return <Base {...childProps}/>;
126
+ };
127
+ }
@@ -0,0 +1,54 @@
1
+ import { AnimatedValue, AnimatedValueXY, AnimatedColor, timing, spring, decay, parallel, sequence, stagger, loop, delay, add, subtract, multiply, divide, modulo, diffClamp, event, forkEvent, unforkEvent } from '@symbiote-native/engine';
2
+ import { createAnimatedComponent } from './create-animated-component';
3
+ export { createAnimatedComponent } from './create-animated-component';
4
+ export type { IAnimatedComponentProps } from './create-animated-component';
5
+ export { AnimatedProps, AnimatedStyle, AnimatedTransform, } from '@symbiote-native/engine';
6
+ type IAnimatedComponent = ReturnType<typeof createAnimatedComponent>;
7
+ export declare const Animated: {
8
+ Value: typeof AnimatedValue;
9
+ ValueXY: typeof AnimatedValueXY;
10
+ Color: typeof AnimatedColor;
11
+ Easing: {
12
+ step0(n: number): number;
13
+ step1(n: number): number;
14
+ linear(t: number): number;
15
+ ease(t: number): number;
16
+ quad(t: number): number;
17
+ cubic(t: number): number;
18
+ poly(n: number): import("@symbiote-native/engine").IEasingFunction;
19
+ sin(t: number): number;
20
+ circle(t: number): number;
21
+ exp(t: number): number;
22
+ elastic(bounciness?: number): import("@symbiote-native/engine").IEasingFunction;
23
+ back(s?: number): import("@symbiote-native/engine").IEasingFunction;
24
+ bounce(t: number): number;
25
+ bezier(x1: number, y1: number, x2: number, y2: number): import("@symbiote-native/engine").IEasingFunction;
26
+ in(easing: import("@symbiote-native/engine").IEasingFunction): import("@symbiote-native/engine").IEasingFunction;
27
+ out(easing: import("@symbiote-native/engine").IEasingFunction): import("@symbiote-native/engine").IEasingFunction;
28
+ inOut(easing: import("@symbiote-native/engine").IEasingFunction): import("@symbiote-native/engine").IEasingFunction;
29
+ };
30
+ timing: typeof timing;
31
+ spring: typeof spring;
32
+ decay: typeof decay;
33
+ parallel: typeof parallel;
34
+ sequence: typeof sequence;
35
+ stagger: typeof stagger;
36
+ loop: typeof loop;
37
+ delay: typeof delay;
38
+ add: typeof add;
39
+ subtract: typeof subtract;
40
+ multiply: typeof multiply;
41
+ divide: typeof divide;
42
+ modulo: typeof modulo;
43
+ diffClamp: typeof diffClamp;
44
+ event: typeof event;
45
+ forkEvent: typeof forkEvent;
46
+ unforkEvent: typeof unforkEvent;
47
+ View: (props: import("./create-animated-component").IAnimatedComponentProps) => import("@symbiote-native/solid/jsx-runtime").JSX.Element;
48
+ Text: (props: import("./create-animated-component").IAnimatedComponentProps) => import("@symbiote-native/solid/jsx-runtime").JSX.Element;
49
+ Image: (props: import("./create-animated-component").IAnimatedComponentProps) => import("@symbiote-native/solid/jsx-runtime").JSX.Element;
50
+ ScrollView: IAnimatedComponent;
51
+ FlatList: IAnimatedComponent;
52
+ SectionList: IAnimatedComponent;
53
+ createAnimatedComponent: typeof createAnimatedComponent;
54
+ };
@@ -0,0 +1,78 @@
1
+ // The Animated namespace for @symbiote-native/solid. createAnimatedComponent applied to this
2
+ // adapter's primitives gives the six animated components RN exposes; the value graph, easing and
3
+ // imperative drivers come from @symbiote-native/engine (framework-agnostic), so both halves meet
4
+ // here in one object and `Animated.timing(new Animated.Value(0), …).start()` reads as it does in
5
+ // RN. Solid's JSX takes the dotted form directly — `<Animated.View/>` compiles to
6
+ // createComponent(Animated.View, …), no local alias needed.
7
+ //
8
+ // The NATIVE DRIVER is not this module's doing and must not be re-derived here. A
9
+ // useNativeDriver animation promotes the value graph itself (animations/base.ts ->
10
+ // value.__startNativeAnimation -> graph.__makeNative), and the props leaf follows automatically
11
+ // through graph.__addChild. This file only assembles the surface.
12
+ import { AnimatedValue, AnimatedValueXY, AnimatedColor, AnimatedMock, Easing, Platform, timing, spring, decay, parallel, sequence, stagger, loop, delay, add, subtract, multiply, divide, modulo, diffClamp, event, forkEvent, unforkEvent, } from '@symbiote-native/engine';
13
+ import { View } from '../../components/view.jsx';
14
+ import { Text } from '../../components/text.jsx';
15
+ import { Image } from '../../components/image.js';
16
+ import { ScrollView } from '../../components/scroll-view';
17
+ import { FlatList } from '../../components/flat-list/index.jsx';
18
+ import { SectionList } from '../../components/section-list/index.jsx';
19
+ import { createAnimatedComponent } from './create-animated-component.jsx';
20
+ export { createAnimatedComponent } from './create-animated-component.jsx';
21
+ // The pure graph leaves live in the engine (they extend AnimatedWithChildren, no framework);
22
+ // re-exported so this adapter's Animated surface matches React's.
23
+ export { AnimatedProps, AnimatedStyle, AnimatedTransform, } from '@symbiote-native/engine';
24
+ // View/Text/Image are pure host primitives with no cycle back to here, so wrap them eagerly.
25
+ const AnimatedView = createAnimatedComponent(View);
26
+ const AnimatedText = createAnimatedComponent(Text);
27
+ const AnimatedImage = createAnimatedComponent(Image);
28
+ let animatedScrollView;
29
+ let animatedFlatList;
30
+ let animatedSectionList;
31
+ // The live, JS-driven driver half. RN's AnimatedImplementation.
32
+ const liveDrivers = {
33
+ Value: AnimatedValue,
34
+ ValueXY: AnimatedValueXY,
35
+ Color: AnimatedColor,
36
+ Easing,
37
+ timing,
38
+ spring,
39
+ decay,
40
+ parallel,
41
+ sequence,
42
+ stagger,
43
+ loop,
44
+ delay,
45
+ add,
46
+ subtract,
47
+ multiply,
48
+ divide,
49
+ modulo,
50
+ diffClamp,
51
+ event,
52
+ forkEvent,
53
+ unforkEvent,
54
+ };
55
+ // RN swaps the WHOLE driver namespace for the mock when the host reports isDisableAnimations
56
+ // (reduced motion / test env): same surface, every animation jumping to its final value with no
57
+ // frames. The COMPONENTS stay live in both branches — only this half is swapped, exactly as RN
58
+ // spreads `...Animated` over the same component getters.
59
+ const drivers = Platform.isDisableAnimations ? AnimatedMock : liveDrivers;
60
+ export const Animated = {
61
+ View: AnimatedView,
62
+ Text: AnimatedText,
63
+ Image: AnimatedImage,
64
+ get ScrollView() {
65
+ animatedScrollView ??= createAnimatedComponent(ScrollView);
66
+ return animatedScrollView;
67
+ },
68
+ get FlatList() {
69
+ animatedFlatList ??= createAnimatedComponent(FlatList);
70
+ return animatedFlatList;
71
+ },
72
+ get SectionList() {
73
+ animatedSectionList ??= createAnimatedComponent(SectionList);
74
+ return animatedSectionList;
75
+ },
76
+ createAnimatedComponent,
77
+ ...drivers,
78
+ };
@@ -0,0 +1,7 @@
1
+ import type { Component } from 'solid-js';
2
+ import { type IAppParameters } from '@symbiote-native/engine';
3
+ export type IComponentProvider = () => Component;
4
+ export type IWrapperComponentProvider = (appParameters: IAppParameters) => Component;
5
+ declare const AppRegistry: import("@symbiote-native/engine").IAppRegistry<IComponentProvider, IWrapperComponentProvider>, setHostRegistrar: (registrar: import("@symbiote-native/engine").IHostRegistrar) => void;
6
+ export { AppRegistry, setHostRegistrar };
7
+ export type { IAppParameters, IRunnable, IHostRegistrar, IRegistry, IHeadlessTask, ITaskProvider, ITaskCanceller, ITaskCancelProvider, } from '@symbiote-native/engine';
@@ -0,0 +1,37 @@
1
+ // AppRegistry: the JS entry point RN apps already use:
2
+ // AppRegistry.registerComponent(appKey, () => App)
3
+ // The registry bookkeeping (sections, host-registrar bridge, headless tasks) is
4
+ // framework-agnostic and lives in @symbiote-native/engine's createAppRegistry, the same one every
5
+ // other adapter uses; this file supplies only the one Solid-specific seam.
6
+ //
7
+ // Unlike the Svelte adapter, `IWrapperComponentProvider` is fully supported here and needs no
8
+ // design pass: a Solid component is an ordinary function value, so wrapping composes exactly the
9
+ // way Vue's `h(wrapper, null, { default: renderRoot })` does — `createComponent(Wrapper, { get
10
+ // children() {…} })`, which is also the literal shape compiled JSX emits for children.
11
+ import { createAppRegistry, dlog, } from '@symbiote-native/engine';
12
+ import { createComponent } from '../../renderer.js';
13
+ import { mount } from '../../render.js';
14
+ function runnableFor(componentProvider, getWrapperComponentProvider) {
15
+ return appParameters => {
16
+ dlog(`AppRegistry: mounting on rootTag ${String(appParameters.rootTag)}`);
17
+ const RootComponent = componentProvider();
18
+ const renderRoot = () => createComponent(RootComponent, appParameters.initialProps ?? {});
19
+ // Read live, so setWrapperComponentProvider affects every runnable's next run rather than only
20
+ // ones registered afterwards — same contract as Vue's.
21
+ const wrapperComponentProvider = getWrapperComponentProvider();
22
+ const mounted = wrapperComponentProvider === undefined
23
+ ? renderRoot
24
+ : () => createComponent(wrapperComponentProvider(appParameters), {
25
+ // A getter, not a value: children must stay lazy so the root is created inside the
26
+ // wrapper's own reactive owner (its context providers, error boundaries and cleanups
27
+ // then actually cover the root). Evaluating it eagerly here would build the root
28
+ // outside that owner and quietly break every one of those.
29
+ get children() {
30
+ return renderRoot();
31
+ },
32
+ });
33
+ mount(appParameters.rootTag, mounted);
34
+ };
35
+ }
36
+ const { AppRegistry, setHostRegistrar } = createAppRegistry(runnableFor);
37
+ export { AppRegistry, setHostRegistrar };
@@ -0,0 +1,7 @@
1
+ import { type IStatusBarProps } from '@symbiote-native/engine';
2
+ export type { IStatusBarProps, IStatusBarStyle, IStatusBarAnimation, } from '@symbiote-native/engine';
3
+ declare function StatusBarComponent(props: IStatusBarProps): null;
4
+ declare const StatusBarWithStatics: typeof StatusBarComponent & import("@symbiote-native/engine").IStatusBarImperative;
5
+ export declare const StatusBar: typeof StatusBarWithStatics & {
6
+ readonly currentHeight?: number;
7
+ };
@@ -0,0 +1,45 @@
1
+ // StatusBar — the Solid lifecycle half, and nothing else. The native StatusBarManager driving
2
+ // (applyStatusBarProps), the imperative statics (statusBarImperative) and the Android bar-height
3
+ // constant all live in @symbiote-native/engine, shared verbatim with React / Vue / Svelte /
4
+ // Angular; Metro selects the engine's index.ios.ts / index.android.ts per host, so the platform
5
+ // divergence never reaches this file. Solid supplies only the declarative shape: a component that
6
+ // renders no Fabric view and re-applies its props from a `createEffect` on mount and on every
7
+ // prop change.
8
+ //
9
+ // FLAT, not a folder: the file-layout rule gives a module its own folder only for real
10
+ // `.ios`/`.android`/`-shared` variants. React needs two files because its useEffect dep array is
11
+ // written by hand per platform; there is no dep array here, so one file covers both hosts —
12
+ // the same shape Svelte's and Angular's StatusBar landed on.
13
+ //
14
+ // Simplification vs RN, inherited from every other adapter: RN keeps a prop-merge stack so nested
15
+ // StatusBars compose (deepest wins); this direct-applies one component's props.
16
+ import { createEffect } from 'solid-js';
17
+ import { applyStatusBarProps, statusBarImperative, statusBarCurrentHeight, } from '@symbiote-native/engine';
18
+ // Renders null: StatusBar owns no host node, it drives a native module.
19
+ function StatusBarComponent(props) {
20
+ createEffect(() => {
21
+ // Every field is read HERE, not inside the engine, so the effect's dependency set is the whole
22
+ // prop surface rather than whichever subset this platform's impl happens to destructure —
23
+ // iOS's applyStatusBarProps never touches backgroundColor/translucent, and a props proxy read
24
+ // only there would silently stop re-applying after a host swap.
25
+ applyStatusBarProps({
26
+ barStyle: props.barStyle,
27
+ hidden: props.hidden,
28
+ animated: props.animated,
29
+ networkActivityIndicatorVisible: props.networkActivityIndicatorVisible,
30
+ backgroundColor: props.backgroundColor,
31
+ translucent: props.translucent,
32
+ });
33
+ });
34
+ return null;
35
+ }
36
+ const StatusBarWithStatics = Object.assign(StatusBarComponent, statusBarImperative);
37
+ // Android exposes the bar height as a native constant; undefined on iOS / when absent. A getter,
38
+ // not a value, so nothing touches native at import time.
39
+ Object.defineProperty(StatusBarWithStatics, 'currentHeight', {
40
+ get: statusBarCurrentHeight,
41
+ enumerable: true,
42
+ });
43
+ // currentHeight is optional, so the defineProperty-added accessor need not appear on the runtime
44
+ // object's inferred type for this assignment to hold (no cast) — same shape as Svelte's.
45
+ export const StatusBar = StatusBarWithStatics;
@@ -0,0 +1,3 @@
1
+ import { type Accessor } from 'solid-js';
2
+ import { type IColorSchemeName } from '@symbiote-native/engine';
3
+ export declare function createColorScheme(): Accessor<IColorSchemeName | null>;
@@ -0,0 +1,33 @@
1
+ // createColorScheme — the Solid twin of React's `useColorScheme` hook, Vue's composable, Svelte's
2
+ // rune and Angular's ColorSchemeService, over the framework-agnostic Appearance module
3
+ // (@symbiote-native/engine). The engine owns the native subscription; this file owns only the
4
+ // reactive lifecycle.
5
+ //
6
+ // `primitives/` and `create*`, not `hooks/` and `use*`: Solid's ecosystem calls a composable
7
+ // reactive function a PRIMITIVE (solid-primitives), and reserves `use*` for consuming something
8
+ // that already exists — `useContext`, `useTransition`, and solid-primitives' shared/singleton
9
+ // variants. A primitive that creates its own state and owns a subscription is `createX`.
10
+ // (CLAUDE.md <adapter_src_follows_framework_idioms>: the lifecycle bucket takes the framework's
11
+ // own term, so a Solid `hooks/` folder would be as wrong as a Vue one.)
12
+ //
13
+ // Returns an ACCESSOR, never a snapshot: a Solid component body runs once, so a returned value
14
+ // would freeze at the scheme the app booted with.
15
+ //
16
+ // Outside a component or `createRoot`, `onCleanup` has no owner to attach to — Solid warns
17
+ // ("cleanups created outside a `createRoot` or `render` will never be run") and the Appearance
18
+ // listener lives for the process. The accessor still tracks correctly; only the teardown is lost.
19
+ import { createSignal, onCleanup } from 'solid-js';
20
+ import { Appearance, } from '@symbiote-native/engine';
21
+ export function createColorScheme() {
22
+ const [colorScheme, setColorScheme] = createSignal(Appearance.getColorScheme());
23
+ // No post-subscribe re-read, unlike React/Vue/Svelte: those subscribe from an effect, a tick
24
+ // after the seed read, so a change can slip between the two. Here both statements run in one
25
+ // synchronous tick and nothing can interleave.
26
+ const subscription = Appearance.addChangeListener(preferences => {
27
+ setColorScheme(preferences.colorScheme);
28
+ });
29
+ onCleanup(() => {
30
+ subscription.remove();
31
+ });
32
+ return colorScheme;
33
+ }
@@ -0,0 +1,3 @@
1
+ import { type Accessor } from 'solid-js';
2
+ import { type IDisplayMetrics } from '@symbiote-native/engine';
3
+ export declare function createWindowDimensions(): Accessor<IDisplayMetrics>;