@symbiote-native/solid 3.1.0 → 3.3.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 (74) hide show
  1. package/build/components/checkbox-props.d.ts +6 -0
  2. package/build/components/checkbox-props.js +1 -0
  3. package/build/components/flat-list/index.d.ts +3 -2
  4. package/build/components/flat-list/index.jsx +8 -10
  5. package/build/components/input-accessory-view-props.d.ts +4 -4
  6. package/build/components/keyboard-avoiding-view.d.ts +2 -2
  7. package/build/components/keyboard-avoiding-view.jsx +34 -114
  8. package/build/components/layout-conformance-props.d.ts +6 -0
  9. package/build/components/layout-conformance-props.js +1 -0
  10. package/build/components/modal.d.ts +4 -4
  11. package/build/components/modal.jsx +11 -11
  12. package/build/components/refresh-control-props.d.ts +7 -7
  13. package/build/components/scroll-view-props.d.ts +8 -5
  14. package/build/components/text-input-props.d.ts +2 -1
  15. package/build/components/text-props.d.ts +3 -3
  16. package/build/components/touchable-props.d.ts +6 -6
  17. package/build/components/virtualized-list/index.android.d.ts +2 -2
  18. package/build/components/virtualized-list/index.ios.d.ts +2 -2
  19. package/build/components/virtualized-list/item-content.d.ts +6 -0
  20. package/build/components/virtualized-list/item-content.jsx +9 -0
  21. package/build/components/virtualized-list/list-body.d.ts +15 -0
  22. package/build/components/virtualized-list/list-body.jsx +20 -0
  23. package/build/components/virtualized-list/list-parts.d.ts +14 -0
  24. package/build/components/virtualized-list/list-parts.js +27 -0
  25. package/build/components/virtualized-list/list-rows.d.ts +18 -0
  26. package/build/components/virtualized-list/list-rows.jsx +91 -0
  27. package/build/components/virtualized-list/list-window.d.ts +11 -0
  28. package/build/components/virtualized-list/list-window.js +29 -0
  29. package/build/components/virtualized-list/nested-scope.d.ts +7 -0
  30. package/build/components/virtualized-list/nested-scope.js +21 -0
  31. package/build/components/virtualized-list/scroll-handlers.d.ts +12 -0
  32. package/build/components/virtualized-list/scroll-handlers.js +31 -0
  33. package/build/components/virtualized-list/scroll-tree.d.ts +18 -0
  34. package/build/components/virtualized-list/scroll-tree.jsx +143 -0
  35. package/build/components/virtualized-list/shared.d.ts +3 -74
  36. package/build/components/virtualized-list/shared.jsx +53 -752
  37. package/build/components/virtualized-list/sticky-binding.d.ts +13 -0
  38. package/build/components/virtualized-list/sticky-binding.js +111 -0
  39. package/build/components/virtualized-list/sticky-header.d.ts +1 -0
  40. package/build/components/virtualized-list/sticky-header.jsx +11 -159
  41. package/build/components/virtualized-list/sticky-state.d.ts +14 -0
  42. package/build/components/virtualized-list/sticky-state.js +54 -0
  43. package/build/components/virtualized-list/use-list-driver.d.ts +22 -0
  44. package/build/components/virtualized-list/use-list-driver.js +128 -0
  45. package/build/components/virtualized-list/use-separators.d.ts +7 -0
  46. package/build/components/virtualized-list/use-separators.js +22 -0
  47. package/build/components/virtualized-list/virtualized-list-props.d.ts +86 -0
  48. package/build/components/virtualized-list/virtualized-list-props.js +53 -0
  49. package/build/components/virtualized-section-list/index.d.ts +22 -9
  50. package/build/components/virtualized-section-list/index.jsx +87 -115
  51. package/build/components/virtualized-section-list/section-item-cell.d.ts +18 -0
  52. package/build/components/virtualized-section-list/section-item-cell.jsx +37 -0
  53. package/build/components.d.ts +6 -1
  54. package/build/components.js +1 -0
  55. package/build/define-descriptor-component.d.ts +6 -0
  56. package/build/define-descriptor-component.js +10 -0
  57. package/build/define-optional-descriptor-component.d.ts +3 -0
  58. package/build/define-optional-descriptor-component.js +12 -0
  59. package/build/descriptor-to-solid.d.ts +2 -1
  60. package/build/descriptor-to-solid.js +7 -3
  61. package/build/index.d.ts +13 -4
  62. package/build/index.js +24 -37
  63. package/build/jsx-runtime.d.ts +2 -0
  64. package/build/modules/animated/index.d.ts +54 -41
  65. package/build/modules/animated/index.js +2 -26
  66. package/build/modules/app-registry/index.d.ts +3 -3
  67. package/build/modules/app-registry/index.js +2 -2
  68. package/build/modules/status-bar.js +14 -27
  69. package/build/primitives/create-color-scheme.d.ts +1 -1
  70. package/build/primitives/define-native-view-component.d.ts +5 -0
  71. package/build/primitives/define-native-view-component.js +22 -0
  72. package/build/primitives/use-event.d.ts +6 -0
  73. package/build/primitives/use-event.js +18 -0
  74. package/package.json +6 -6
package/build/index.js CHANGED
@@ -4,13 +4,9 @@
4
4
  // uses. All Fabric clone-on-write lives in the engine, shared cross-adapter. App code imports
5
5
  // @symbiote-native/solid, never react-native.
6
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.
7
+ // Layer status (symbiote-new-adapter §7): L4 in progress, the barrel grows a layer at a time
8
+ // Primitives, touch components, lists and the engine runtime modules are at full parity with React
9
+ // `Portal` (same-surface) and `createTunnel` (cross-surface) sit on the universal renderer
14
10
  //
15
11
  // The two lifecycle primitives are spelled `createColorScheme` / `createWindowDimensions`, not
16
12
  // `use*`: in Solid `use*` means consuming something that already exists (useContext,
@@ -33,16 +29,14 @@ export { setImageSourceResolver } from '@symbiote-native/components';
33
29
  // the same reason React exports descriptorToReact — an external wrapper package over a third-party
34
30
  // native view maps its shared render fn's Descriptor through the SAME bridge the adapter uses.
35
31
  export { descriptorToSolid } from './descriptor-to-solid.js';
32
+ export { defineDescriptorComponent } from './define-descriptor-component.js';
33
+ export { defineOptionalDescriptorComponent } from './define-optional-descriptor-component.js';
36
34
  // Safe in the barrel (unlike ./bootstrap, which imports react-native): the registry seam itself
37
35
  // only reaches the engine and solid-js.
38
- export { AppRegistry, setHostRegistrar } from './modules/app-registry/index.js';
39
- // Animated: the three list/scroll components that are still components, over the engine's
40
- // framework-agnostic value graph. There is no `Animated.View` / `Animated.Text` / `Animated.Image`
41
- // — those primitives are tags, and `<view style={{ opacity: someAnimatedValue }}>` is the whole
42
- // API (.claude/rules/animated-values-resolve-in-the-engine.md). Solid's JSX takes the dotted form
43
- // of what remains directly — `<Animated.ScrollView/>` compiles to
44
- // createComponent(Animated.ScrollView, …) — so no local alias is needed, unlike Angular, whose AOT
45
- // compiler cannot trace a class through property access (.claude/rules/dotted-component-tags.md).
36
+ export { AppRegistry, HeadlessJsTaskError, setHostRegistrar, } from './modules/app-registry/index.js';
37
+ // Animated keeps only the list and scroll components, over the engine's value graph
38
+ // The primitives are tags: `<view style={{ opacity: someAnimatedValue }}>` is the whole API
39
+ // Solid's JSX takes `<Animated.ScrollView/>` directly, unlike Angular (dotted-component-tags.md)
46
40
  export { StatusBar } from './modules/status-bar.js';
47
41
  // What survives of `Image` once the primitive is the `<image>` tag: RN's statics namespace, no
48
42
  // view. Grouped with the runtime modules rather than the components for exactly that reason.
@@ -62,9 +56,12 @@ export { createTunnel } from './create-tunnel/index.jsx';
62
56
  // the subscription logic; these add only the Solid lifecycle (signal + onCleanup).
63
57
  export { createColorScheme } from './primitives/create-color-scheme.js';
64
58
  export { createWindowDimensions } from './primitives/create-window-dimensions.js';
59
+ export { createAnimatedColor, createAnimatedValue, createAnimatedValueXY, } from '@symbiote-native/engine';
65
60
  export { createPermissionHook } from './primitives/create-permission-hook.js';
66
61
  export { createResourceHook } from './primitives/create-resource-hook.js';
62
+ export { defineNativeViewComponent } from './primitives/define-native-view-component.js';
67
63
  export { createEventValueHook } from './primitives/create-event-value-hook.js';
64
+ export { useEvent, useEventListener } from './primitives/use-event.js';
68
65
  export { Animated, createAnimatedComponent } from './modules/animated/index.js';
69
66
  // Everything below is re-exported VERBATIM from the shared packages — no Solid half exists or is
70
67
  // wanted, so a passthrough stub file would only add a hop (.claude/rules/barrel-passthrough.md).
@@ -72,16 +69,15 @@ export { Animated, createAnimatedComponent } from './modules/animated/index.js';
72
69
  // Pure utilities and the color surface: no native event, no lifecycle, so they live in the engine
73
70
  // per <runtime_modules_layering>.
74
71
  export { Platform, StyleSheet, PixelRatio, PlatformColor, DynamicColorIOS, processColor, } from '@symbiote-native/engine';
75
- // The three app-entry seams, wired once on a real host. setNativeViewConfigSource is how a
76
- // third-party Fabric view auto-derives its metadata:
77
- // setNativeViewConfigSource(name => ReactNativeViewConfigRegistry.get(name))
78
- export { setNativeViewConfigSource, setColorProcessor, setDeviceEventSource, } from '@symbiote-native/engine';
72
+ // Seams wired once on a real host: `setNativeViewConfigSource` derives third-party view configs
73
+ // `setNativeViewConfigSource(name => ReactNativeViewConfigRegistry.get(name))`
74
+ export { setNativeViewConfigSource, setColorProcessor, } from '@symbiote-native/engine';
79
75
  // Diagnostics gated by DEBUG (<keep_logs_gate_behind_DEBUG>): app code logs through the same seam
80
76
  // the engine does, never a bare console.log.
81
77
  export { dlog, isDebug } from '@symbiote-native/engine';
82
78
  // Imperative runtime modules: thin JS over getNativeModule + device events, no Fabric component
83
79
  // of their own, so there is nothing per-framework to write.
84
- 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';
80
+ export { Alert, Share, ActionSheetIOS, Linking, Vibration, ToastAndroid, Settings, I18nManager, Dimensions, Appearance, AppState, Keyboard, KEYBOARD_EVENT, TextInputState, BackHandler, PermissionsAndroid, PERMISSIONS, RESULTS, LayoutAnimation, InteractionManager, } from '@symbiote-native/engine';
85
81
  // PanResponder: the gesture recognizer over the engine's responder events, shared by every adapter.
86
82
  export { PanResponder } from '@symbiote-native/engine';
87
83
  // AccessibilityInfo comes STRAIGHT from the engine, which owns the iOS/Android split
@@ -89,21 +85,12 @@ export { PanResponder } from '@symbiote-native/engine';
89
85
  // name, but that folder is a pure passthrough of these exact names — matching it means matching
90
86
  // the engine module, not growing a second one here.
91
87
  export { AccessibilityInfo } from '@symbiote-native/engine';
92
- // Solid's control flow is pure reactivity with no DOM dependency, so it works verbatim over the
93
- // universal renderer and is re-exported here to keep an app on one import. solid-js/web's own
94
- // `Portal` is NOT among them and cannot be — it allocates its container with
95
- // `document.createElement` — but the CAPABILITY is not missing: this package ships its own
96
- // `Portal` over the universal renderer (./create-portal, exported above), at the same
97
- // same-surface scope React and Angular chose for theirs. `Dynamic` is the one member of that DOM-bound pair still absent.
98
- // It is absent on its own terms, not as fallout from Portal: nothing here needed it (a tunnel
99
- // renders stored content by calling a thunk inside <For>, no dynamic component involved), and no
100
- // other adapter ships a twin of it for parity to require one.
101
- //
102
- // Solid's own control-flow `Switch`/`Match` pair is ABSENT for a different reason: `Switch` collides
103
- // head-on with RN's Switch component, which every other adapter exports under exactly that name and
104
- // which P0 parity (<adapters_reach_full_feature_parity>) pins here too. The RN component wins the
105
- // name; the control-flow pair keeps its canonical home, `import { Switch, Match } from 'solid-js'`
106
- // (alias it there if both are needed in one file). `Match` is withheld ALONGSIDE it deliberately —
107
- // re-exporting a lone `Match` while `Switch` means something else would compile fine and then fail
108
- // at runtime, which is worse than a missing export.
88
+ // Control flow from `solid-js` works over the universal renderer as is, `Portal` is our own above
89
+ // `Switch` is RN's component here, so the `Switch`/`Match` pair stays in `solid-js`
90
+ // A lone `Match` would compile and then fail at runtime, so it is withheld too
109
91
  export { For, Index, Show, ErrorBoundary, Suspense, SuspenseList, } from 'solid-js';
92
+ // The device event bus and the easing curves, shared verbatim from the engine
93
+ export { DeviceEventEmitter, Easing, EventEmitter, NativeAppEventEmitter, NativeEventEmitter, } from '@symbiote-native/engine';
94
+ // RN's dev and native-module utilities, shared verbatim from the engine. The ones RN owns forward
95
+ // to its own module, which `registerApp` hands over
96
+ export { codegenNativeCommands, codegenNativeComponent, DevMenu, DevSettings, LogBox, NativeComponentRegistry, NativeModules, Networking, PushNotificationIOS, ReactNativeVersion, registerCallableModule, requireNativeComponent, Systrace, Touchable, TurboModuleRegistry, UIManager, UTFSequence, } from '@symbiote-native/engine';
@@ -4,6 +4,7 @@ import type { IViewProps } from './components/view-props';
4
4
  import type { ITextProps } from './components/text-props';
5
5
  import type { IPressableProps } from './components/pressable-props';
6
6
  import type { IButtonProps } from './components/button-props';
7
+ import type { ICheckboxProps } from './components/checkbox-props';
7
8
  import type { IImageProps } from './components/image-props';
8
9
  import type { IImageBackgroundProps } from './components/image-background-props';
9
10
  import type { IInputAccessoryViewProps } from './components/input-accessory-view-props';
@@ -26,6 +27,7 @@ interface ICrossedPrimitiveProps {
26
27
  text: ITextProps;
27
28
  pressable: IPressableProps;
28
29
  button: IButtonProps;
30
+ checkbox: ICheckboxProps;
29
31
  image: IImageProps;
30
32
  'image-background': IImageBackgroundProps;
31
33
  'input-accessory-view': IInputAccessoryViewProps;
@@ -1,56 +1,69 @@
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
1
  import { createAnimatedComponent } from './create-animated-component';
3
2
  export { createAnimatedComponent } from './create-animated-component';
4
3
  export type { IAnimatedComponentProps } from './create-animated-component';
5
4
  export { AnimatedProps, AnimatedStyle, AnimatedTransform, } from '@symbiote-native/engine';
6
5
  type IAnimatedComponent = ReturnType<typeof createAnimatedComponent>;
7
6
  export declare const Animated: {
8
- Value: typeof AnimatedValue;
9
- ValueXY: typeof AnimatedValueXY;
10
- Color: typeof AnimatedColor;
7
+ timing: {
8
+ (value: import("@symbiote-native/engine").AnimatedValue, config: import("@symbiote-native/engine").ITimingConfig): import("@symbiote-native/engine").ICompositeAnimation;
9
+ (value: import("@symbiote-native/engine").IVectorValue, config: import("@symbiote-native/engine").IVectorTimingConfig): import("@symbiote-native/engine").ICompositeAnimation;
10
+ };
11
+ spring: {
12
+ (value: import("@symbiote-native/engine").AnimatedValue, config: import("@symbiote-native/engine").ISpringConfig): import("@symbiote-native/engine").ICompositeAnimation;
13
+ (value: import("@symbiote-native/engine").IVectorValue, config: import("@symbiote-native/engine").IVectorSpringConfig): import("@symbiote-native/engine").ICompositeAnimation;
14
+ };
15
+ decay: (_value: import("@symbiote-native/engine").AnimatedValue, _config: import("@symbiote-native/engine").IDecayConfig) => import("@symbiote-native/engine").ICompositeAnimation;
16
+ parallel: (animations: import("@symbiote-native/engine").ICompositeAnimation[], _config?: import("@symbiote-native/engine").IParallelConfig) => import("@symbiote-native/engine").ICompositeAnimation;
17
+ sequence: (animations: import("@symbiote-native/engine").ICompositeAnimation[]) => import("@symbiote-native/engine").ICompositeAnimation;
18
+ stagger: (_time: number, animations: import("@symbiote-native/engine").ICompositeAnimation[]) => import("@symbiote-native/engine").ICompositeAnimation;
19
+ loop: (_animation: import("@symbiote-native/engine").ICompositeAnimation) => import("@symbiote-native/engine").ICompositeAnimation;
20
+ delay: (_time: number) => import("@symbiote-native/engine").ICompositeAnimation;
21
+ Value: typeof import("@symbiote-native/engine").AnimatedValue;
22
+ ValueXY: typeof import("@symbiote-native/engine").AnimatedValueXY;
23
+ Color: typeof import("@symbiote-native/engine").AnimatedColor;
24
+ Interpolation: typeof import("@symbiote-native/engine").AnimatedInterpolation;
25
+ Node: typeof import("@symbiote-native/engine").AnimatedNode;
11
26
  Easing: import("@symbiote-native/engine").IEasing;
12
- timing: typeof timing;
13
- spring: typeof spring;
14
- decay: typeof decay;
15
- parallel: typeof parallel;
16
- sequence: typeof sequence;
17
- stagger: typeof stagger;
18
- loop: typeof loop;
19
- delay: typeof delay;
20
- add: typeof add;
21
- subtract: typeof subtract;
22
- multiply: typeof multiply;
23
- divide: typeof divide;
24
- modulo: typeof modulo;
25
- diffClamp: typeof diffClamp;
26
- event: typeof event;
27
- forkEvent: typeof forkEvent;
28
- unforkEvent: typeof unforkEvent;
27
+ add: typeof import("@symbiote-native/engine").add;
28
+ subtract: typeof import("@symbiote-native/engine").subtract;
29
+ multiply: typeof import("@symbiote-native/engine").multiply;
30
+ divide: typeof import("@symbiote-native/engine").divide;
31
+ modulo: typeof import("@symbiote-native/engine").modulo;
32
+ diffClamp: typeof import("@symbiote-native/engine").diffClamp;
33
+ event: typeof import("@symbiote-native/engine").event;
34
+ attachNativeEvent: typeof import("@symbiote-native/engine").attachNativeEvent;
35
+ forkEvent: typeof import("@symbiote-native/engine").forkEvent;
36
+ unforkEvent: typeof import("@symbiote-native/engine").unforkEvent;
37
+ Event: typeof import("@symbiote-native/engine").AnimatedEvent;
29
38
  FlatList: IAnimatedComponent;
30
39
  SectionList: IAnimatedComponent;
31
40
  createAnimatedComponent: typeof createAnimatedComponent;
32
41
  } | {
33
- Value: typeof AnimatedValue;
34
- ValueXY: typeof AnimatedValueXY;
35
- Color: typeof AnimatedColor;
42
+ Value: typeof import("@symbiote-native/engine").AnimatedValue;
43
+ ValueXY: typeof import("@symbiote-native/engine").AnimatedValueXY;
44
+ Color: typeof import("@symbiote-native/engine").AnimatedColor;
45
+ Interpolation: typeof import("@symbiote-native/engine").AnimatedInterpolation;
46
+ Node: typeof import("@symbiote-native/engine").AnimatedNode;
36
47
  Easing: import("@symbiote-native/engine").IEasing;
37
- timing: (value: AnimatedValue, config: import("@symbiote-native/engine").ITimingConfig) => import("@symbiote-native/engine").ICompositeAnimation;
38
- spring: (value: AnimatedValue, config: import("@symbiote-native/engine").ISpringConfig) => import("@symbiote-native/engine").ICompositeAnimation;
39
- decay: (_value: AnimatedValue, _config: import("@symbiote-native/engine").IDecayConfig) => import("@symbiote-native/engine").ICompositeAnimation;
40
- parallel: (animations: import("@symbiote-native/engine").ICompositeAnimation[], _config?: import("@symbiote-native/engine").IParallelConfig) => import("@symbiote-native/engine").ICompositeAnimation;
41
- sequence: (animations: import("@symbiote-native/engine").ICompositeAnimation[]) => import("@symbiote-native/engine").ICompositeAnimation;
42
- stagger: (_time: number, animations: import("@symbiote-native/engine").ICompositeAnimation[]) => import("@symbiote-native/engine").ICompositeAnimation;
43
- loop: (_animation: import("@symbiote-native/engine").ICompositeAnimation) => import("@symbiote-native/engine").ICompositeAnimation;
44
- delay: (_time: number) => import("@symbiote-native/engine").ICompositeAnimation;
45
- add: typeof add;
46
- subtract: typeof subtract;
47
- multiply: typeof multiply;
48
- divide: typeof divide;
49
- modulo: typeof modulo;
50
- diffClamp: typeof diffClamp;
51
- event: typeof event;
52
- forkEvent: typeof forkEvent;
53
- unforkEvent: typeof unforkEvent;
48
+ timing: typeof import("@symbiote-native/engine").timing;
49
+ spring: typeof import("@symbiote-native/engine").spring;
50
+ decay: typeof import("@symbiote-native/engine").decay;
51
+ parallel: typeof import("@symbiote-native/engine").parallel;
52
+ sequence: typeof import("@symbiote-native/engine").sequence;
53
+ stagger: typeof import("@symbiote-native/engine").stagger;
54
+ loop: typeof import("@symbiote-native/engine").loop;
55
+ delay: typeof import("@symbiote-native/engine").delay;
56
+ add: typeof import("@symbiote-native/engine").add;
57
+ subtract: typeof import("@symbiote-native/engine").subtract;
58
+ multiply: typeof import("@symbiote-native/engine").multiply;
59
+ divide: typeof import("@symbiote-native/engine").divide;
60
+ modulo: typeof import("@symbiote-native/engine").modulo;
61
+ diffClamp: typeof import("@symbiote-native/engine").diffClamp;
62
+ event: typeof import("@symbiote-native/engine").event;
63
+ attachNativeEvent: typeof import("@symbiote-native/engine").attachNativeEvent;
64
+ forkEvent: typeof import("@symbiote-native/engine").forkEvent;
65
+ unforkEvent: typeof import("@symbiote-native/engine").unforkEvent;
66
+ Event: typeof import("@symbiote-native/engine").AnimatedEvent;
54
67
  FlatList: IAnimatedComponent;
55
68
  SectionList: IAnimatedComponent;
56
69
  createAnimatedComponent: typeof createAnimatedComponent;
@@ -19,7 +19,7 @@
19
19
  // useNativeDriver animation promotes the value graph itself (animations/base.ts ->
20
20
  // value.__startNativeAnimation -> graph.__makeNative), and the props leaf follows automatically
21
21
  // through graph.__addChild. This file only assembles the surface.
22
- 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';
22
+ import { AnimatedDrivers, AnimatedMock, Platform, } from '@symbiote-native/engine';
23
23
  import { FlatList } from '../../components/flat-list/index.jsx';
24
24
  import { SectionList } from '../../components/section-list/index.jsx';
25
25
  import { createAnimatedComponent } from './create-animated-component.jsx';
@@ -29,35 +29,11 @@ export { createAnimatedComponent } from './create-animated-component.jsx';
29
29
  export { AnimatedProps, AnimatedStyle, AnimatedTransform, } from '@symbiote-native/engine';
30
30
  let animatedFlatList;
31
31
  let animatedSectionList;
32
- // The live, JS-driven driver half. RN's AnimatedImplementation.
33
- const liveDrivers = {
34
- Value: AnimatedValue,
35
- ValueXY: AnimatedValueXY,
36
- Color: AnimatedColor,
37
- Easing,
38
- timing,
39
- spring,
40
- decay,
41
- parallel,
42
- sequence,
43
- stagger,
44
- loop,
45
- delay,
46
- add,
47
- subtract,
48
- multiply,
49
- divide,
50
- modulo,
51
- diffClamp,
52
- event,
53
- forkEvent,
54
- unforkEvent,
55
- };
56
32
  // RN swaps the WHOLE driver namespace for the mock when the host reports isDisableAnimations
57
33
  // (reduced motion / test env): same surface, every animation jumping to its final value with no
58
34
  // frames. The COMPONENTS stay live in both branches — only this half is swapped, exactly as RN
59
35
  // spreads `...Animated` over the same component getters.
60
- const drivers = Platform.isDisableAnimations ? AnimatedMock : liveDrivers;
36
+ const drivers = Platform.isDisableAnimations ? AnimatedMock : AnimatedDrivers;
61
37
  export const Animated = {
62
38
  get FlatList() {
63
39
  animatedFlatList ??= createAnimatedComponent(FlatList);
@@ -1,7 +1,7 @@
1
1
  import type { Component } from 'solid-js';
2
- import { type IAppParameters } from '@symbiote-native/engine';
2
+ import { HeadlessJsTaskError, type IAppParameters } from '@symbiote-native/engine';
3
3
  export type IComponentProvider = () => Component;
4
4
  export type IWrapperComponentProvider = (appParameters: IAppParameters) => Component;
5
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';
6
+ export { AppRegistry, HeadlessJsTaskError, setHostRegistrar };
7
+ export type { IAppConfig, IAppParameters, IRunnable, IHostRegistrar, IRegistry, IHeadlessTask, ITaskProvider, ITaskCanceller, ITaskCancelProvider, } from '@symbiote-native/engine';
@@ -8,7 +8,7 @@
8
8
  // design pass: a Solid component is an ordinary function value, so wrapping composes exactly the
9
9
  // way Vue's `h(wrapper, null, { default: renderRoot })` does — `createComponent(Wrapper, { get
10
10
  // children() {…} })`, which is also the literal shape compiled JSX emits for children.
11
- import { createAppRegistry, dlog, } from '@symbiote-native/engine';
11
+ import { createAppRegistry, dlog, HeadlessJsTaskError, } from '@symbiote-native/engine';
12
12
  import { createComponent } from '../../renderer.js';
13
13
  import { mount } from '../../render.js';
14
14
  function runnableFor(componentProvider, getWrapperComponentProvider) {
@@ -34,4 +34,4 @@ function runnableFor(componentProvider, getWrapperComponentProvider) {
34
34
  };
35
35
  }
36
36
  const { AppRegistry, setHostRegistrar } = createAppRegistry(runnableFor);
37
- export { AppRegistry, setHostRegistrar };
37
+ export { AppRegistry, HeadlessJsTaskError, setHostRegistrar };
@@ -1,45 +1,32 @@
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.
1
+ // Solid half of StatusBar, the props stack and statics live in the engine. It renders no Fabric
2
+ // view, applies its props to one stack entry from a `createEffect` and releases it on cleanup
3
+ // FLAT, one file covers both hosts since there is no per-platform dependency array
4
+ import { createEffect, onCleanup } from 'solid-js';
5
+ import { createStatusBarEntry, statusBarImperative, statusBarCurrentHeight, } from '@symbiote-native/engine';
6
+ // Renders null: StatusBar owns no host node, it drives a native module
19
7
  function StatusBarComponent(props) {
8
+ const entry = createStatusBarEntry();
20
9
  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({
10
+ // Every field is read here, so the effect depends on the whole prop surface
11
+ entry.apply({
26
12
  barStyle: props.barStyle,
27
13
  hidden: props.hidden,
28
14
  animated: props.animated,
15
+ showHideTransition: props.showHideTransition,
29
16
  networkActivityIndicatorVisible: props.networkActivityIndicatorVisible,
30
17
  backgroundColor: props.backgroundColor,
31
18
  translucent: props.translucent,
32
19
  });
33
20
  });
21
+ // Popping restores what the stack held below this entry
22
+ onCleanup(() => entry.release());
34
23
  return null;
35
24
  }
36
25
  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.
26
+ // A getter, not a value, so nothing touches native at import time
39
27
  Object.defineProperty(StatusBarWithStatics, 'currentHeight', {
40
28
  get: statusBarCurrentHeight,
41
29
  enumerable: true,
42
30
  });
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.
31
+ // `currentHeight` is optional, so the accessor need not appear on the inferred type (no cast)
45
32
  export const StatusBar = StatusBarWithStatics;
@@ -1,3 +1,3 @@
1
1
  import { type Accessor } from 'solid-js';
2
2
  import { type IColorSchemeName } from '@symbiote-native/engine';
3
- export declare function createColorScheme(): Accessor<IColorSchemeName | null>;
3
+ export declare function createColorScheme(): Accessor<IColorSchemeName | null | undefined>;
@@ -0,0 +1,5 @@
1
+ import type { ICreateNativeViewController } from '@symbiote-native/components';
2
+ import type { ISymbioteNode } from '@symbiote-native/engine';
3
+ export declare function defineNativeViewComponent<THandle, TProps extends object>(createController: ICreateNativeViewController<THandle>): (props: TProps & {
4
+ ref?: (handle: THandle) => void;
5
+ }) => ISymbioteNode | null;
@@ -0,0 +1,22 @@
1
+ import { onCleanup, splitProps } from 'solid-js';
2
+ import { createHostNodeHolder } from '@symbiote-native/components';
3
+ import { descriptorToSolid } from '../descriptor-to-solid.js';
4
+ // A Solid component over a package's native view: the props go to the controller, its handle goes
5
+ // to `ref`. The shape of the descriptor is decided once at mount, only values change afterwards
6
+ export function defineNativeViewComponent(createController) {
7
+ return (props) => {
8
+ const [own, viewProps] = splitProps(props, ['ref']);
9
+ const host = createHostNodeHolder();
10
+ const controller = createController(host.getNode);
11
+ onCleanup(() => controller.dispose?.());
12
+ const render = () => {
13
+ const descriptor = controller.render({ ...viewProps });
14
+ return descriptor && host.capture(descriptor);
15
+ };
16
+ const initial = render();
17
+ if (!initial)
18
+ return null;
19
+ own.ref?.(controller.handle);
20
+ return descriptorToSolid(() => render() ?? initial);
21
+ };
22
+ }
@@ -0,0 +1,6 @@
1
+ import type { Accessor } from 'solid-js';
2
+ import type { IEventEmitterOf, IEventName, IEventPayload, IEventsMap } from '@symbiote-native/engine';
3
+ /** Calls the listener for each event, the latest one, and stops when the owner is disposed */
4
+ export declare function useEventListener<TEventsMap extends IEventsMap, TName extends IEventName<TEventsMap>>(emitter: Accessor<IEventEmitterOf<TEventsMap>>, eventName: Accessor<TName>, listener: Accessor<TEventsMap[TName]>): void;
5
+ /** The payload of the last event, `initialValue` (or `null`) until the first one */
6
+ export declare function useEvent<TEventsMap extends IEventsMap, TName extends IEventName<TEventsMap>>(emitter: Accessor<IEventEmitterOf<TEventsMap>>, eventName: Accessor<TName>, initialValue?: IEventPayload<TEventsMap, TName> | null): Accessor<IEventPayload<TEventsMap, TName> | null>;
@@ -0,0 +1,18 @@
1
+ // Solid twins of `useEvent` and `useEventListener` of the `expo` package, for any emitter
2
+ import { createEffect, createSignal, on, onCleanup } from 'solid-js';
3
+ import { bindEventListener } from '@symbiote-native/engine';
4
+ /** Calls the listener for each event, the latest one, and stops when the owner is disposed */
5
+ export function useEventListener(emitter, eventName, listener) {
6
+ createEffect(on([emitter, eventName], ([source, name]) => {
7
+ // The listener is read at each event, a new one is not a new subscription
8
+ onCleanup(bindEventListener(source, name, listener));
9
+ }));
10
+ }
11
+ /** The payload of the last event, `initialValue` (or `null`) until the first one */
12
+ export function useEvent(emitter, eventName, initialValue = null) {
13
+ const [event, setEvent] = createSignal(initialValue);
14
+ createEffect(on([emitter, eventName], ([source, name]) => {
15
+ onCleanup(bindEventListener(source, name, () => (next) => setEvent(() => next)));
16
+ }));
17
+ return event;
18
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@symbiote-native/solid",
3
- "version": "3.1.0",
3
+ "version": "3.3.0",
4
4
  "description": "SymbioteNative's Solid adapter — a solid-js/universal createRenderer driving real native iOS/Android views through the same engine as every other adapter.",
5
5
  "keywords": [
6
6
  "react-native",
@@ -62,19 +62,19 @@
62
62
  "dependencies": {
63
63
  "babel-preset-solid": "^1.9.12",
64
64
  "typescript": "~6.0.0",
65
- "@symbiote-native/components": "3.1.4",
66
- "@symbiote-native/css-parser": "0.5.3"
65
+ "@symbiote-native/components": "3.3.0",
66
+ "@symbiote-native/css-parser": "0.6.0"
67
67
  },
68
68
  "peerDependencies": {
69
69
  "solid-js": ">=1.9.0",
70
70
  "react-native": ">=0.86",
71
- "@symbiote-native/engine": "^1.5.0"
71
+ "@symbiote-native/engine": "^1.7.0"
72
72
  },
73
73
  "devDependencies": {
74
74
  "@babel/core": "^7.25.2",
75
75
  "solid-js": "^1.9.14",
76
- "@symbiote-native/engine": "1.5.0",
77
- "@symbiote-native/test-utils": "0.4.6"
76
+ "@symbiote-native/engine": "1.7.0",
77
+ "@symbiote-native/test-utils": "0.5.0"
78
78
  },
79
79
  "scripts": {
80
80
  "typecheck": "tsc --build",