@symbiote-native/components 0.2.0 → 0.2.1

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.
@@ -6,7 +6,7 @@
6
6
  // importing it directly must stay unreachable from the tested main index.ts.
7
7
  import { processColor, DeviceEventEmitter, Image } from 'react-native';
8
8
  import { setColorProcessor, setDeviceEventSource, setNativeViewConfigSource, } from '@symbiote-native/engine';
9
- import { setImageSourceResolver } from './view/render-image';
9
+ import { setImageSourceResolver } from './view/render-image.js';
10
10
  // @ts-expect-error react-native ships no types for this internal path (plain .js) — the
11
11
  // try/catch below is what actually proves the shape, not TS.
12
12
  import * as ReactNativeViewConfigRegistry from 'react-native/Libraries/Renderer/shims/ReactNativeViewConfigRegistry';
@@ -2,7 +2,7 @@
2
2
  // Each name is the ViewManager's REACT_CLASS in react-native/ReactAndroid/.../views/**.
3
3
  // device-verify-pending: source-confirmed from RN's Android ViewManagers, proven on a
4
4
  // real host by the absence of a "Can't find ViewManager '<name>'" red box.
5
- import { buildDescriptors, makeDescriptorFor } from './shared';
5
+ import { buildDescriptors, makeDescriptorFor } from './shared.js';
6
6
  const ANDROID_NAMES = {
7
7
  'symbiote-view': 'RCTView',
8
8
  'symbiote-text': 'RCTText',
@@ -2,7 +2,7 @@
2
2
  // (component-names.ts re-exports it) for headless tsx / tsc / web fallback. See ADR 0020.
3
3
  // Fabric names are the codegen spec's registered name (the new-arch name), not the legacy
4
4
  // paperComponentName (RCTSwitch, …).
5
- import { buildDescriptors, makeDescriptorFor } from './shared';
5
+ import { buildDescriptors, makeDescriptorFor } from './shared.js';
6
6
  const IOS_NAMES = {
7
7
  'symbiote-view': 'RCTView',
8
8
  'symbiote-text': 'RCTText',
@@ -2,4 +2,4 @@
2
2
  // with component-names.ios.ts / component-names.android.ts on a real host; under tsx /
3
3
  // tsc / web (no Metro) the host config resolves here. Filename is the selector, no
4
4
  // Platform.OS read. See ADR 0020.
5
- export * from './index.ios';
5
+ export * from './index.ios.js';
package/build/index.js CHANGED
@@ -2,62 +2,62 @@
2
2
  // (`state/`) and render functions (`view/`) that paint `Descriptor` trees; every adapter
3
3
  // wires state→render with ITS lifecycle (React hooks / Vue reactivity) and maps the
4
4
  // Descriptor onto its own element. See CLAUDE.md <components_split_logic_view_lifecycle>.
5
- export { el, txt } from './descriptor';
5
+ export { el, txt } from './descriptor.js';
6
6
  // Accessibility folding: the web-alias (aria-*/role) → canonical accessibility* transform
7
7
  // and its types. Framework-agnostic (ADR 0024), so React, Vue, and the next adapter all fold
8
8
  // identically; moved here from @symbiote-native/react. RefreshControl/SafeAreaView/ScrollView consume it.
9
- export { resolveAccessibilityProps } from './accessibility-props';
9
+ export { resolveAccessibilityProps } from './accessibility-props.js';
10
10
  // Intrinsic (`symbiote-*`) → Fabric view-name resolution. Shared by every adapter so the
11
11
  // names CANNOT drift between them (one engine, one Fabric). The name tables are
12
12
  // Metro-split (.ios/.android, filename selects, no Platform.OS read, ADR 0020); the base
13
13
  // re-exports iOS for headless. descriptorFor is the per-platform-bound resolver.
14
- export { descriptorFor, COMPONENT_DESCRIPTORS } from './component-names';
15
- export { buildDescriptors, makeDescriptorFor } from './component-names/shared';
16
- export { renderActivityIndicator } from './view/render-activity-indicator';
17
- export { renderSwitch } from './view/render-switch';
14
+ export { descriptorFor, COMPONENT_DESCRIPTORS } from './component-names/index.js';
15
+ export { buildDescriptors, makeDescriptorFor } from './component-names/shared.js';
16
+ export { renderActivityIndicator } from './view/render-activity-indicator.js';
17
+ export { renderSwitch } from './view/render-switch.js';
18
18
  // Switch is the first STATE machine off this layer (ActivityIndicator was render-only):
19
19
  // the reducer + the two pure predicates are the logic half, the adapter supplies the hook.
20
- export { switchReducer, createInitialSwitchState, shouldSnapBack, valueFromChange, } from './state/switch';
20
+ export { switchReducer, createInitialSwitchState, shouldSnapBack, valueFromChange, } from './state/switch.js';
21
21
  // ScrollView: pure render/command helpers (no state machine, no 3-layer split). The adapter
22
22
  // owns the refs/effects/element assembly and the sticky-header component; these supply the
23
23
  // platform-invariant math and plumbing every adapter shares (ADR 0024).
24
- export { resolveDecelerationRate, selectScrollIntrinsics, readLayoutDimension, didContentSizeChange, SCROLL_VIEW_BASE_HORIZONTAL, SCROLL_VIEW_BASE_VERTICAL, } from './view/render-scroll-view';
25
- export { buildScrollViewHandle, splitLayoutProps, attachStickyScroll, isSymbioteEvent, forwardScrollEvent, } from './scroll-view-commands';
26
- export { computeStickyInterpolation, nextStickyHeaderY, stickyDebounceMs, readLayoutNumber, STICKY_HEADER_Z_INDEX, } from './view/render-scroll-sticky';
27
- export { renderImage, imageStatics, setImageSourceResolver } from './view/render-image';
24
+ export { resolveDecelerationRate, selectScrollIntrinsics, readLayoutDimension, didContentSizeChange, SCROLL_VIEW_BASE_HORIZONTAL, SCROLL_VIEW_BASE_VERTICAL, } from './view/render-scroll-view.js';
25
+ export { buildScrollViewHandle, splitLayoutProps, attachStickyScroll, isSymbioteEvent, forwardScrollEvent, } from './scroll-view-commands.js';
26
+ export { computeStickyInterpolation, nextStickyHeaderY, stickyDebounceMs, readLayoutNumber, STICKY_HEADER_Z_INDEX, } from './view/render-scroll-sticky.js';
27
+ export { renderImage, imageStatics, setImageSourceResolver } from './view/render-image.js';
28
28
  // ImageBackground: render-only composition (absolute-fill image behind, children on top).
29
- export { renderImageBackground } from './view/render-image-background';
29
+ export { renderImageBackground } from './view/render-image-background.js';
30
30
  // InputAccessoryView: render-only host assembly (nativeID/backgroundColor).
31
- export { renderInputAccessoryView } from './view/render-input-accessory-view';
31
+ export { renderInputAccessoryView } from './view/render-input-accessory-view.js';
32
32
  // Modal: full 3-layer split (state machine gates the iOS keep-alive frame).
33
- export { renderModal } from './view/render-modal';
34
- export { modalReducer, createInitialModalState, shouldRenderModal } from './state/modal';
33
+ export { renderModal } from './view/render-modal.js';
34
+ export { modalReducer, createInitialModalState, shouldRenderModal } from './state/modal.js';
35
35
  // KeyboardAvoidingView: pure inset/behavior math; the adapter owns the Keyboard subscription.
36
- export { computeInset, readKeyboardFrame, readLayoutFrame, resolveKeyboardAvoidingLayout, DEFAULT_VERTICAL_OFFSET, } from './view/render-keyboard-avoiding-view';
36
+ export { computeInset, readKeyboardFrame, readLayoutFrame, resolveKeyboardAvoidingLayout, DEFAULT_VERTICAL_OFFSET, } from './view/render-keyboard-avoiding-view.js';
37
37
  // Pressable: the press state machine (logic) + render decisions. The pure lifecycle (timers,
38
38
  // geometry, drift test, suppression flags) lives in state/pressable; the responder-listener +
39
39
  // accessibilityState + ripple render decisions in view/render-pressable. Every adapter supplies
40
40
  // only its reactive `pressed` cell + the View's measure handle (see the 3-layer split).
41
- export { createPressHandlers, createPressRuntime, normalizeRect, maxEdge, isTouchWithinRegion, readPoint, computeRegion, rippleProps, DEFAULT_DELAY_LONG_PRESS_MS, DEFAULT_PRESS_RECT_OFFSETS, } from './state/pressable';
42
- export { buildPressableListeners, resolveDisabledAccessibilityState, noteHoverNoop, } from './view/render-pressable';
41
+ export { createPressHandlers, createPressRuntime, normalizeRect, maxEdge, isTouchWithinRegion, readPoint, computeRegion, rippleProps, DEFAULT_DELAY_LONG_PRESS_MS, DEFAULT_PRESS_RECT_OFFSETS, } from './state/pressable.js';
42
+ export { buildPressableListeners, resolveDisabledAccessibilityState, noteHoverNoop, } from './view/render-pressable.js';
43
43
  // Touchable*: shared press-timing constants + the deactivation-floor math (the Animated feedback
44
44
  // itself stays per-adapter), and TouchableNativeFeedback's pure static factories + background map.
45
- export { computePressOutWait, DEFAULT_ACTIVE_OPACITY, OPACITY_ACTIVE_DURATION_MS, OPACITY_INACTIVE_DURATION_MS, RESTING_OPACITY, DEFAULT_HIGHLIGHT_CHILD_OPACITY, DEFAULT_UNDERLAY_COLOR, DEFAULT_MIN_PRESS_DURATION_MS, } from './state/touchable';
46
- export { backgroundProps, canUseNativeForeground, selectableBackground, selectableBackgroundBorderless, rippleBackground, } from './view/render-touchable-native-feedback';
45
+ export { computePressOutWait, DEFAULT_ACTIVE_OPACITY, OPACITY_ACTIVE_DURATION_MS, OPACITY_INACTIVE_DURATION_MS, RESTING_OPACITY, DEFAULT_HIGHLIGHT_CHILD_OPACITY, DEFAULT_UNDERLAY_COLOR, DEFAULT_MIN_PRESS_DURATION_MS, } from './state/touchable.js';
46
+ export { backgroundProps, canUseNativeForeground, selectableBackground, selectableBackgroundBorderless, rippleBackground, } from './view/render-touchable-native-feedback.js';
47
47
  // Button: shared base text style, role constant, and color fold (the adapter composes its own
48
48
  // TouchableOpacity + Text).
49
- export { BUTTON_ACCESSIBILITY_ROLE, buttonTextStyle, resolveButtonTextStyle, } from './view/render-button';
49
+ export { BUTTON_ACCESSIBILITY_ROLE, buttonTextStyle, resolveButtonTextStyle, } from './view/render-button.js';
50
50
  // TextInput: the controlled-value / event-count handshake. The logic half is the pure
51
51
  // folds/maps + the controlled-write predicate (not a single reducer: count must re-render the
52
52
  // imperative handle, lastNativeText must not); the view half picks the intrinsic and maps the
53
53
  // resolved native props. Both shared verbatim across React and Vue; the adapter owns only the
54
54
  // hooks/reactivity + the imperative handle.
55
- export { resolveTextInputProps, foldText, foldAutoComplete, foldSubmitBehavior, mapAutoComplete, textFromChange, eventCountFromChange, shouldCommandText, INITIAL_EVENT_COUNT, SELECTION_NONE, } from './state/text-input';
56
- export { renderTextInput } from './view/render-text-input';
55
+ export { resolveTextInputProps, foldText, foldAutoComplete, foldSubmitBehavior, mapAutoComplete, textFromChange, eventCountFromChange, shouldCommandText, INITIAL_EVENT_COUNT, SELECTION_NONE, } from './state/text-input.js';
56
+ export { renderTextInput } from './view/render-text-input.js';
57
57
  // VirtualizedList family: the framework-agnostic windowing engine + data shapes. Lists
58
58
  // have NO view/render-*.ts (the cell content is the framework's own children, so there is
59
59
  // no Descriptor render fn) — the shared layer for lists is this STATE/logic, reused
60
60
  // verbatim by React and Vue. See core/components/.docs-note-lists.md.
61
- export { DEFAULT_WINDOW_SIZE, DEFAULT_INITIAL_NUM_TO_RENDER, DEFAULT_END_REACHED_THRESHOLD, DEFAULT_MAX_TO_RENDER_PER_BATCH, DEFAULT_UPDATE_CELLS_BATCHING_PERIOD, DEFAULT_VIEW_AREA_COVERAGE_PERCENT_THRESHOLD, DEFAULT_START_REACHED_THRESHOLD, FIRST_INDEX, EMPTY_OFFSET, NO_INDEX, NO_CONTENT_LENGTH_SENT, INVERTED_Y_STYLE, INVERTED_X_STYLE, readScrollOffset, readLayoutLength, buildOffsets, computeWindow, throttleWindow, visiblePercent, isCellViewable, offsetForIndex, averageMeasuredLength, highestMeasuredIndex, computeEndReached, computeStartReached, buildViewabilityPairs, computeViewableSet, diffViewable, maxMinimumViewTime, buildListPlan, } from './state/virtualized-list';
62
- export { SINGLE_COLUMN, chunkIntoRows, rowKeyExtractor, expandRowToken, expandRowViewability, lastItemOfRow, firstItemOfRow, } from './state/flat-list';
63
- export { flattenSections, unwrapEntryItem, sectionEntryKey, scrollLocationToFlatIndex, } from './state/section-list';
61
+ export { DEFAULT_WINDOW_SIZE, DEFAULT_INITIAL_NUM_TO_RENDER, DEFAULT_END_REACHED_THRESHOLD, DEFAULT_MAX_TO_RENDER_PER_BATCH, DEFAULT_UPDATE_CELLS_BATCHING_PERIOD, DEFAULT_VIEW_AREA_COVERAGE_PERCENT_THRESHOLD, DEFAULT_START_REACHED_THRESHOLD, FIRST_INDEX, EMPTY_OFFSET, NO_INDEX, NO_CONTENT_LENGTH_SENT, INVERTED_Y_STYLE, INVERTED_X_STYLE, readScrollOffset, readLayoutLength, buildOffsets, computeWindow, throttleWindow, visiblePercent, isCellViewable, offsetForIndex, averageMeasuredLength, highestMeasuredIndex, computeEndReached, computeStartReached, buildViewabilityPairs, computeViewableSet, diffViewable, maxMinimumViewTime, buildListPlan, } from './state/virtualized-list.js';
62
+ export { SINGLE_COLUMN, chunkIntoRows, rowKeyExtractor, expandRowToken, expandRowViewability, lastItemOfRow, firstItemOfRow, } from './state/flat-list.js';
63
+ export { flattenSections, unwrapEntryItem, sectionEntryKey, scrollLocationToFlatIndex, } from './state/section-list.js';
@@ -9,7 +9,7 @@
9
9
  // iOS's ActivityIndicatorView takes neither and defaults to GRAY. The adapter's per-host
10
10
  // file supplies those bits via `platform`.
11
11
  import { dlog } from '@symbiote-native/engine';
12
- import { el } from '../descriptor';
12
+ import { el } from '../descriptor.js';
13
13
  // Fixed pixel boxes RN gives the two named sizes (styles.sizeSmall/sizeLarge).
14
14
  const SIZE_SMALL_PX = 20;
15
15
  const SIZE_LARGE_PX = 36;
@@ -9,8 +9,8 @@
9
9
  // fight the wrapper's explicit dimensions, so we proxy them back onto the Image so it fills
10
10
  // the box. `imageStyle` wins last.
11
11
  import { dlog, flattenStyle, } from '@symbiote-native/engine';
12
- import { el } from '../descriptor';
13
- import { renderImage } from './render-image';
12
+ import { el } from '../descriptor.js';
13
+ import { renderImage } from './render-image.js';
14
14
  // The inner Image's positioning: absolute-fill behind the wrapper's children.
15
15
  const IMAGE_BACKGROUND_ABSOLUTE_FILL = {
16
16
  position: 'absolute',
@@ -1,5 +1,5 @@
1
1
  import { dlog, flattenStyle, getNativeModule, Platform, } from '@symbiote-native/engine';
2
- import { el } from '../descriptor';
2
+ import { el } from '../descriptor.js';
3
3
  // Default resolver: identity. RN's resolveAssetSource (which turns a require()
4
4
  // number into {uri, scale, width, height}) is wired in by the app at startup.
5
5
  let resolveSource = source => source;
@@ -5,7 +5,7 @@
5
5
  // onto the intrinsic and the user children (injected by the adapter) nest under it. Shared
6
6
  // verbatim across adapters: React and Vue both bridge this Descriptor.
7
7
  import { dlog } from '@symbiote-native/engine';
8
- import { el } from '../descriptor';
8
+ import { el } from '../descriptor.js';
9
9
  export function renderInputAccessoryView(view) {
10
10
  const props = { ...view.passthrough, style: view.style };
11
11
  if (view.nativeID !== undefined)
@@ -6,7 +6,7 @@
6
6
  // full-screen container View that holds the user children (injected by the adapter). Shared
7
7
  // verbatim: React and Vue both bridge this Descriptor; the keep-alive state lives in state/modal.ts.
8
8
  import { dlog } from '@symbiote-native/engine';
9
- import { el } from '../descriptor';
9
+ import { el } from '../descriptor.js';
10
10
  // The full-screen box RN anchors the modal content in (Modal.js styles.container: [side]:0,
11
11
  // top:0, flex:1, backgroundColor:'white'). It is NOT position:absolute, it is a flex child that
12
12
  // fills the ModalHostView, whose shadow node self-sizes to the screen
@@ -5,7 +5,7 @@
5
5
  // ios_backgroundColor folds into the style as the pill that shows through the shrunken track.
6
6
  // Pure and prop-driven; no hooks, no events. The adapter owns those.
7
7
  import { dlog } from '@symbiote-native/engine';
8
- import { el } from '../descriptor';
8
+ import { el } from '../descriptor.js';
9
9
  // RN rounds the iOS background pill to this radius when ios_backgroundColor is set.
10
10
  const IOS_BACKGROUND_BORDER_RADIUS = 16;
11
11
  // Fold ios_backgroundColor into the style, matching RN's iOS branch: it paints the
@@ -5,7 +5,7 @@
5
5
  // remaining native events) arrive folded into `passthrough` and land on the host untouched.
6
6
  // Pure and prop-driven; no hooks, no events. The adapter owns those.
7
7
  import { dlog } from '@symbiote-native/engine';
8
- import { el } from '../descriptor';
8
+ import { el } from '../descriptor.js';
9
9
  // One host element per native input class. Text carries the only non-trivial nesting elsewhere;
10
10
  // here the choice is binary and runtime (the `multiline` prop), so the module stays flat.
11
11
  const SINGLELINE_INTRINSIC = 'symbiote-text-input';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@symbiote-native/components",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Framework-agnostic component logic (state machines + render functions) for SymbioteNative — written once, inherited by every adapter (React, Vue, Angular, ...).",
5
5
  "repository": {
6
6
  "type": "git",
@@ -33,7 +33,7 @@
33
33
  "access": "public"
34
34
  },
35
35
  "dependencies": {
36
- "@symbiote-native/engine": "0.1.1"
36
+ "@symbiote-native/engine": "0.1.2"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "react-native": ">=0.86"