@symbiote-native/svelte 1.0.0 → 3.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.
- package/README.md +11 -13
- package/build/components/{activity-indicator/activity-indicator-props.d.ts → activity-indicator-props.d.ts} +1 -1
- package/build/components/flat-list/index.svelte +9 -5
- package/build/components/{image-background/image-background-props.d.ts → image-background-props.d.ts} +1 -1
- package/build/components/index.d.ts +6 -24
- package/build/components/index.js +0 -18
- package/build/components/keyboard-avoiding-view/index.svelte +16 -7
- package/build/components/modal/index.svelte +7 -7
- package/build/components/pressable/pressable-props.d.ts +3 -0
- package/build/components/refresh-control-props.d.ts +1 -0
- package/build/components/text-props.d.ts +1 -0
- package/build/components/touchable-highlight/touchable-highlight-props.d.ts +2 -0
- package/build/components/touchable-native-feedback/touchable-native-feedback-props.d.ts +1 -0
- package/build/components/touchable-without-feedback/touchable-without-feedback-props.d.ts +3 -1
- package/build/components/virtualized-list/index.svelte +79 -257
- package/build/components/virtualized-list/virtualized-list-props.d.ts +2 -2
- package/build/components/virtualized-list/virtualized-list-props.js +24 -4
- package/build/create-portal/index.js +2 -2
- package/build/dom-shim/canonical-prop-names.d.ts +2 -0
- package/build/dom-shim/canonical-prop-names.js +323 -0
- package/build/dom-shim/document.js +1 -1
- package/build/dom-shim/element.d.ts +10 -3
- package/build/dom-shim/element.js +233 -31
- package/build/dom-shim/patch-globals.js +31 -5
- package/build/dom-shim/shim-node.d.ts +6 -0
- package/build/dom-shim/shim-node.js +48 -1
- package/build/dom-shim/style-cache.d.ts +1 -0
- package/build/dom-shim/style-cache.js +27 -0
- package/build/dom-shim/text.js +5 -4
- package/build/host-instance.d.ts +2 -3
- package/build/host-instance.js +9 -3
- package/build/index.d.ts +7 -4
- package/build/index.js +17 -5
- package/build/intrinsic-elements.d.ts +63 -0
- package/build/modules/animated/index.d.ts +30 -46
- package/build/modules/animated/index.js +24 -34
- package/build/modules/image/index.d.ts +3 -0
- package/build/modules/image/index.js +15 -0
- package/build/preprocessor/scoped-styles.js +1 -1
- package/build/register.d.ts +1 -1
- package/build/register.js +13 -31
- package/build/root-element.js +1 -1
- package/metro-css-parser.cjs +2 -1
- package/metro-svelte-transformer.cjs +1 -17
- package/package.json +8 -16
- package/build/components/RefreshControl.svelte +0 -40
- package/build/components/RefreshControl.svelte.d.ts +0 -5
- package/build/components/SafeAreaView.svelte +0 -34
- package/build/components/SafeAreaView.svelte.d.ts +0 -5
- package/build/components/Text.svelte +0 -34
- package/build/components/Text.svelte.d.ts +0 -5
- package/build/components/View.svelte +0 -43
- package/build/components/View.svelte.d.ts +0 -5
- package/build/components/activity-indicator/activity-indicator-platform.android.d.ts +0 -3
- package/build/components/activity-indicator/activity-indicator-platform.android.js +0 -5
- package/build/components/activity-indicator/activity-indicator-platform.d.ts +0 -1
- package/build/components/activity-indicator/activity-indicator-platform.ios.d.ts +0 -3
- package/build/components/activity-indicator/activity-indicator-platform.ios.js +0 -6
- package/build/components/activity-indicator/activity-indicator-platform.js +0 -5
- package/build/components/activity-indicator/index.svelte +0 -63
- package/build/components/activity-indicator/index.svelte.d.ts +0 -5
- package/build/components/button.svelte +0 -76
- package/build/components/button.svelte.d.ts +0 -5
- package/build/components/image/image-logic.d.ts +0 -2
- package/build/components/image/image-logic.js +0 -135
- package/build/components/image/index.d.ts +0 -3
- package/build/components/image/index.js +0 -10
- package/build/components/image/index.svelte +0 -66
- package/build/components/image/index.svelte.d.ts +0 -5
- package/build/components/image-background/index.svelte +0 -87
- package/build/components/image-background/index.svelte.d.ts +0 -5
- package/build/components/input-accessory-view/index.svelte +0 -51
- package/build/components/input-accessory-view/index.svelte.d.ts +0 -5
- package/build/components/pressable/index.svelte +0 -185
- package/build/components/pressable/index.svelte.d.ts +0 -9
- package/build/components/scroll-view/index.svelte +0 -331
- package/build/components/scroll-view/index.svelte.d.ts +0 -18
- package/build/components/scroll-view/scroll-view-platform-types.d.ts +0 -3
- package/build/components/scroll-view/scroll-view-platform.android.d.ts +0 -3
- package/build/components/scroll-view/scroll-view-platform.android.js +0 -3
- package/build/components/scroll-view/scroll-view-platform.d.ts +0 -1
- package/build/components/scroll-view/scroll-view-platform.ios.d.ts +0 -3
- package/build/components/scroll-view/scroll-view-platform.ios.js +0 -3
- package/build/components/scroll-view/scroll-view-platform.js +0 -4
- package/build/components/scroll-view/scroll-view-sticky-context.d.ts +0 -7
- package/build/components/scroll-view/scroll-view-sticky-context.js +0 -1
- package/build/components/scroll-view/sticky-header-props.d.ts +0 -10
- package/build/components/scroll-view/sticky-header-props.js +0 -1
- package/build/components/scroll-view/sticky-header.svelte +0 -287
- package/build/components/scroll-view/sticky-header.svelte.d.ts +0 -5
- package/build/components/switch/index.svelte +0 -134
- package/build/components/switch/index.svelte.d.ts +0 -5
- package/build/components/text-input/index.svelte +0 -372
- package/build/components/text-input/index.svelte.d.ts +0 -17
- package/build/components/touchable-highlight/index.svelte +0 -139
- package/build/components/touchable-highlight/index.svelte.d.ts +0 -5
- package/build/components/touchable-native-feedback/index.d.ts +0 -9
- package/build/components/touchable-native-feedback/index.js +0 -14
- package/build/components/touchable-native-feedback/touchable-native-feedback.svelte +0 -49
- package/build/components/touchable-native-feedback/touchable-native-feedback.svelte.d.ts +0 -5
- package/build/components/touchable-opacity/index.svelte +0 -181
- package/build/components/touchable-opacity/index.svelte.d.ts +0 -5
- package/build/components/touchable-without-feedback/index.svelte +0 -75
- package/build/components/touchable-without-feedback/index.svelte.d.ts +0 -5
- package/build/dom-shim/fold-host-bag.d.ts +0 -1
- package/build/dom-shim/fold-host-bag.js +0 -7
- package/build/modules/animated/animated-component-props.d.ts +0 -7
- package/build/modules/animated/animated-component-props.js +0 -1
- package/build/modules/animated/create-animated-component.d.ts +0 -5
- package/build/modules/animated/create-animated-component.js +0 -131
- package/build/preprocessor/lower-host-primitives.d.ts +0 -10
- package/build/preprocessor/lower-host-primitives.js +0 -455
- package/build/state-style.d.ts +0 -1
- package/build/state-style.js +0 -8
- /package/build/components/{activity-indicator/activity-indicator-props.js → activity-indicator-props.js} +0 -0
- /package/build/components/{image-background/image-background-props.js → image-background-props.js} +0 -0
- /package/build/{components/scroll-view/scroll-view-platform-types.js → intrinsic-elements.js} +0 -0
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
<script lang="ts" module>
|
|
2
|
-
// See View.svelte's header comment — same object-bag design (svelte-adapter-dom-shim
|
|
3
|
-
// skill §3g(c)). No IResponderProps here, matching every other adapter's ITextProps.
|
|
4
|
-
import type { ITextProps } from './text-props';
|
|
5
|
-
|
|
6
|
-
export type { ITextProps };
|
|
7
|
-
</script>
|
|
8
|
-
|
|
9
|
-
<script lang="ts">
|
|
10
|
-
import { resolveTextProps } from '@symbiote-native/components';
|
|
11
|
-
import { createAttachmentsSync } from '../runes/attachments';
|
|
12
|
-
import type { ShimElement } from '../dom-shim';
|
|
13
|
-
|
|
14
|
-
let { children, ...rest }: ITextProps = $props();
|
|
15
|
-
|
|
16
|
-
// See View.svelte's note: `{@attach}` arrives as a symbol-keyed entry in the same rest object.
|
|
17
|
-
let hostShim = $state.raw<ShimElement | null>(null);
|
|
18
|
-
const syncAttachments = createAttachmentsSync();
|
|
19
|
-
$effect(() => {
|
|
20
|
-
syncAttachments(hostShim, rest);
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
// A FRESH object per pass, exactly as View.svelte builds its own: ShimElement's `p` setter
|
|
24
|
-
// diffs the incoming bag against the one it stored last time, so handing it the SAME live rest
|
|
25
|
-
// proxy twice compares that object with itself and applies nothing — every prop update after
|
|
26
|
-
// mount was silently dropped.
|
|
27
|
-
// resolveTextProps carries RN's Text.js defaults (ellipsizeMode 'tail', allowFontScaling
|
|
28
|
-
// true); without them native falls back to `clip` and a clamped Text cuts mid-word.
|
|
29
|
-
const bag = $derived(resolveTextProps({ ...rest }));
|
|
30
|
-
</script>
|
|
31
|
-
|
|
32
|
-
<symbiote-text p={bag} bind:this={hostShim}>
|
|
33
|
-
{@render children?.()}
|
|
34
|
-
</symbiote-text>
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
<script lang="ts" module>
|
|
2
|
-
// Host primitive for app code. Per svelte-adapter-dom-shim skill §3g(c): Symbiote's
|
|
3
|
-
// custom-element codegen path stringifies individual attributes, so unlike Vue's View
|
|
4
|
-
// (which spreads props onto the intrinsic tag and lets patchProp route each one), this
|
|
5
|
-
// component assembles every prop into ONE object bag and hands it to `<symbiote-view p={bag}>`
|
|
6
|
-
// — the shim element's `p` setter diffs it per key into routeProp. `children` is pulled out
|
|
7
|
-
// first: it is a Svelte-specific field (a Snippet), never forwarded into the bag, mirroring
|
|
8
|
-
// why every adapter's IViewProps is declared per-adapter (CLAUDE.md
|
|
9
|
-
// <prop_types_split_agnostic_vs_per_adapter>) rather than shared verbatim.
|
|
10
|
-
import type { IViewProps } from './view-props';
|
|
11
|
-
|
|
12
|
-
export type { IViewProps };
|
|
13
|
-
</script>
|
|
14
|
-
|
|
15
|
-
<script lang="ts">
|
|
16
|
-
import { createAttachmentsSync } from '../runes/attachments';
|
|
17
|
-
import type { ShimElement } from '../dom-shim';
|
|
18
|
-
|
|
19
|
-
let { children, id, nativeID, ...rest }: IViewProps = $props();
|
|
20
|
-
|
|
21
|
-
// `{@attach fn}` on a component lands as a SYMBOL-keyed prop, so it rides in `rest` alongside
|
|
22
|
-
// the ordinary bag keys and never reaches the engine (routeProp only walks string keys). This
|
|
23
|
-
// is the one directive-shaped Svelte feature that IS legal on a component, hence the only way
|
|
24
|
-
// an author reaches the committed host node — see runes/attachments.ts.
|
|
25
|
-
let hostShim = $state.raw<ShimElement | null>(null);
|
|
26
|
-
const syncAttachments = createAttachmentsSync();
|
|
27
|
-
$effect(() => {
|
|
28
|
-
syncAttachments(hostShim, rest);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
// RN's modern `id` is just a W3C-named alias for `nativeID`: View.js copies it over
|
|
32
|
-
// (`processedProps.nativeID = id`), so `id` wins when both are set. Fold it here and drop
|
|
33
|
-
// the raw `id` key so it never reaches Fabric (every non-function prop in the bag otherwise
|
|
34
|
-
// passes through to the slot as-is) — mirrors React's `resolveId` in
|
|
35
|
-
// `adapters/react/src/components.ts`, adapted to the object-bag idiom.
|
|
36
|
-
const bag = $derived(
|
|
37
|
-
id === undefined ? { ...rest, nativeID } : { ...rest, nativeID: id },
|
|
38
|
-
);
|
|
39
|
-
</script>
|
|
40
|
-
|
|
41
|
-
<symbiote-view p={bag} bind:this={hostShim}>
|
|
42
|
-
{@render children?.()}
|
|
43
|
-
</symbiote-view>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './activity-indicator-platform.ios';
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
// Base / default: re-exports the iOS build. Metro overrides this with
|
|
2
|
-
// activity-indicator-platform.ios.ts / .android.ts on a real host; under tsc/vitest the host
|
|
3
|
-
// config resolves here. Filename is the selector, no Platform.OS read — same convention as
|
|
4
|
-
// switch/switch-platform.ts.
|
|
5
|
-
export * from './activity-indicator-platform.ios.js';
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
<script lang="ts" module>
|
|
2
|
-
// ActivityIndicator: render-only (no state). Calls the shared renderActivityIndicator()
|
|
3
|
-
// straight from core/components — the size translation, platform default-color fold, and
|
|
4
|
-
// native-extras all live there, once, for every adapter. The root stays a literal template
|
|
5
|
-
// tag (`bind:this` needs a known tag), but its child (the spinner) is materialized and kept
|
|
6
|
-
// in sync via the generic descriptorToSvelte bridge (createDescriptorChildrenSync) instead of
|
|
7
|
-
// a hand-written child tag — see svelte-adapter-dom-shim skill §19 for why this is safe and
|
|
8
|
-
// cheap (create once, update by position, never recreate).
|
|
9
|
-
import type { IActivityIndicatorProps } from './activity-indicator-props';
|
|
10
|
-
|
|
11
|
-
export type { IActivityIndicatorProps };
|
|
12
|
-
</script>
|
|
13
|
-
|
|
14
|
-
<script lang="ts">
|
|
15
|
-
import {
|
|
16
|
-
renderActivityIndicator,
|
|
17
|
-
resolveAccessibilityProps,
|
|
18
|
-
} from '@symbiote-native/components';
|
|
19
|
-
import { PLATFORM } from './activity-indicator-platform';
|
|
20
|
-
import { createDescriptorChildrenSync } from '../../descriptor-to-svelte';
|
|
21
|
-
import { createAttachmentsSync } from '../../runes/attachments';
|
|
22
|
-
import type { ShimElement } from '../../dom-shim';
|
|
23
|
-
|
|
24
|
-
let {
|
|
25
|
-
animating = true,
|
|
26
|
-
color,
|
|
27
|
-
hidesWhenStopped = true,
|
|
28
|
-
size = 'small',
|
|
29
|
-
style,
|
|
30
|
-
class: className,
|
|
31
|
-
...passthrough
|
|
32
|
-
}: IActivityIndicatorProps = $props();
|
|
33
|
-
|
|
34
|
-
const descriptor = $derived(
|
|
35
|
-
renderActivityIndicator(
|
|
36
|
-
{
|
|
37
|
-
animating,
|
|
38
|
-
hidesWhenStopped,
|
|
39
|
-
size,
|
|
40
|
-
color,
|
|
41
|
-
style,
|
|
42
|
-
passthrough: {
|
|
43
|
-
...resolveAccessibilityProps(passthrough),
|
|
44
|
-
class: className,
|
|
45
|
-
},
|
|
46
|
-
},
|
|
47
|
-
PLATFORM,
|
|
48
|
-
),
|
|
49
|
-
);
|
|
50
|
-
let hostShim = $state.raw<ShimElement | null>(null);
|
|
51
|
-
const syncChildren = createDescriptorChildrenSync();
|
|
52
|
-
|
|
53
|
-
$effect(() => {
|
|
54
|
-
syncChildren(hostShim, descriptor.children);
|
|
55
|
-
});
|
|
56
|
-
// See View.svelte's note on `{@attach}`.
|
|
57
|
-
const syncAttachments = createAttachmentsSync();
|
|
58
|
-
$effect(() => {
|
|
59
|
-
syncAttachments(hostShim, passthrough);
|
|
60
|
-
});
|
|
61
|
-
</script>
|
|
62
|
-
|
|
63
|
-
<symbiote-view p={descriptor.props} bind:this={hostShim} />
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
<script lang="ts" module>
|
|
2
|
-
// Button: the minimal cross-platform button, rendered in RN's iOS shape (Button.js): a
|
|
3
|
-
// TouchableOpacity wrapping a Text. The base text style, the role constant, and the color fold
|
|
4
|
-
// (caller color tints the label; disabled greys it) are shared in
|
|
5
|
-
// @symbiote-native/components/view/render-button — this component only composes its
|
|
6
|
-
// TouchableOpacity + a raw `symbiote-text` host and forwards the native-only props, the Svelte
|
|
7
|
-
// twin of React's/Vue's Button.
|
|
8
|
-
import type { IButtonProps } from './button-props';
|
|
9
|
-
|
|
10
|
-
export type { IButtonProps };
|
|
11
|
-
</script>
|
|
12
|
-
|
|
13
|
-
<script lang="ts">
|
|
14
|
-
import {
|
|
15
|
-
BUTTON_ACCESSIBILITY_ROLE,
|
|
16
|
-
resolveButtonTextStyle,
|
|
17
|
-
} from '@symbiote-native/components';
|
|
18
|
-
import TouchableOpacity from './touchable-opacity/index.svelte';
|
|
19
|
-
|
|
20
|
-
let {
|
|
21
|
-
title,
|
|
22
|
-
onPress,
|
|
23
|
-
color,
|
|
24
|
-
disabled,
|
|
25
|
-
touchSoundDisabled,
|
|
26
|
-
testID,
|
|
27
|
-
hasTVPreferredFocus,
|
|
28
|
-
nextFocusDown,
|
|
29
|
-
nextFocusForward,
|
|
30
|
-
nextFocusLeft,
|
|
31
|
-
nextFocusRight,
|
|
32
|
-
nextFocusUp,
|
|
33
|
-
class: className,
|
|
34
|
-
...accessibilityRest
|
|
35
|
-
}: IButtonProps = $props();
|
|
36
|
-
|
|
37
|
-
const textStyle = $derived(resolveButtonTextStyle(color, disabled));
|
|
38
|
-
|
|
39
|
-
// The native-only props TouchableOpacity does not type but forwards to Fabric (testID +
|
|
40
|
-
// TV-focus). Carried as a plain record (the pass-through idiom Image/React's Button use) so
|
|
41
|
-
// excess-property typing does not reject the native-only keys. TV-focus is inert on a phone.
|
|
42
|
-
const nativeForward = $derived.by(() => {
|
|
43
|
-
const forward: Record<string, unknown> = { testID };
|
|
44
|
-
if (hasTVPreferredFocus !== undefined)
|
|
45
|
-
forward.hasTVPreferredFocus = hasTVPreferredFocus;
|
|
46
|
-
if (nextFocusDown !== undefined) forward.nextFocusDown = nextFocusDown;
|
|
47
|
-
if (nextFocusForward !== undefined)
|
|
48
|
-
forward.nextFocusForward = nextFocusForward;
|
|
49
|
-
if (nextFocusLeft !== undefined) forward.nextFocusLeft = nextFocusLeft;
|
|
50
|
-
if (nextFocusRight !== undefined) forward.nextFocusRight = nextFocusRight;
|
|
51
|
-
if (nextFocusUp !== undefined) forward.nextFocusUp = nextFocusUp;
|
|
52
|
-
return forward;
|
|
53
|
-
});
|
|
54
|
-
</script>
|
|
55
|
-
|
|
56
|
-
<!--
|
|
57
|
-
RN's Button sets role=button, is accessible, and propagates the disabled accessibility state.
|
|
58
|
-
The caller's accessibility props pass through via {...accessibilityRest}, but Button's fixed
|
|
59
|
-
role/accessible/disabled-state win, applied after the spread. touchSoundDisabled maps to the
|
|
60
|
-
pressable's android_disableSound.
|
|
61
|
-
-->
|
|
62
|
-
<TouchableOpacity
|
|
63
|
-
{...accessibilityRest}
|
|
64
|
-
{...nativeForward}
|
|
65
|
-
{onPress}
|
|
66
|
-
{disabled}
|
|
67
|
-
class={className}
|
|
68
|
-
android_disableSound={touchSoundDisabled}
|
|
69
|
-
accessibilityRole={BUTTON_ACCESSIBILITY_ROLE}
|
|
70
|
-
accessible={true}
|
|
71
|
-
accessibilityState={{ disabled }}
|
|
72
|
-
>
|
|
73
|
-
{#snippet children()}
|
|
74
|
-
<symbiote-text p={{ style: textStyle }}>{title}</symbiote-text>
|
|
75
|
-
{/snippet}
|
|
76
|
-
</TouchableOpacity>
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
// Svelte-side duplicate of core/components/src/view/render-image/index.ts's private prop-mapping
|
|
2
|
-
// helpers (normalizeSource / headersFromAliases / expandSrcSet / readStyleString / readSourceUri /
|
|
3
|
-
// resolveSourceArray). None of them are exported — not even from that file — so per the
|
|
4
|
-
// svelte-adapter-dom-shim skill's §15 ("skip consuming a render-*.ts function's Descriptor output
|
|
5
|
-
// programmatically; hand-author the equivalent markup, reusing only EXPORTED pure helpers"), this
|
|
6
|
-
// module reproduces the mapping directly rather than calling renderImage() and reading its
|
|
7
|
-
// returned Descriptor's `.props`.
|
|
8
|
-
//
|
|
9
|
-
// GENUINE GAP (see the Svelte-components work report): these helpers should be exported from
|
|
10
|
-
// core/components/src/view/render-image/index.ts so no adapter needs this duplication. Until
|
|
11
|
-
// then, this file is kept byte-for-byte equivalent to that source and reuses every primitive that
|
|
12
|
-
// IS already exported (resolveImageSource, flattenStyle, dlog) — only the mid-level composition
|
|
13
|
-
// is duplicated.
|
|
14
|
-
import { dlog, flattenStyle, resolveImageSource, } from '@symbiote-native/engine';
|
|
15
|
-
function normalizeSource(source) {
|
|
16
|
-
const resolved = resolveImageSource(source);
|
|
17
|
-
const sources = Array.isArray(resolved) ? resolved : [resolved];
|
|
18
|
-
dlog(`Image source resolved to ${JSON.stringify(sources)}`);
|
|
19
|
-
return sources;
|
|
20
|
-
}
|
|
21
|
-
function headersFromAliases(view) {
|
|
22
|
-
const headers = {};
|
|
23
|
-
if (view.crossOrigin === 'use-credentials') {
|
|
24
|
-
headers['Access-Control-Allow-Credentials'] = 'true';
|
|
25
|
-
}
|
|
26
|
-
if (view.referrerPolicy !== undefined) {
|
|
27
|
-
headers['Referrer-Policy'] = view.referrerPolicy;
|
|
28
|
-
}
|
|
29
|
-
return headers;
|
|
30
|
-
}
|
|
31
|
-
function expandSrcSet(srcSet, view, headers) {
|
|
32
|
-
const sources = [];
|
|
33
|
-
let useSrcForDefaultScale = true;
|
|
34
|
-
for (const entry of srcSet.split(', ')) {
|
|
35
|
-
const [uri, xScale = '1x'] = entry.split(' ');
|
|
36
|
-
if (!xScale.endsWith('x')) {
|
|
37
|
-
dlog(`Image srcSet: unsupported scale token "${xScale}", skipping`);
|
|
38
|
-
continue;
|
|
39
|
-
}
|
|
40
|
-
const scale = parseInt(xScale.slice(0, -1), 10);
|
|
41
|
-
if (Number.isNaN(scale))
|
|
42
|
-
continue;
|
|
43
|
-
if (scale === 1)
|
|
44
|
-
useSrcForDefaultScale = false;
|
|
45
|
-
sources.push({
|
|
46
|
-
uri,
|
|
47
|
-
scale,
|
|
48
|
-
width: view.width,
|
|
49
|
-
height: view.height,
|
|
50
|
-
...{ headers },
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
if (useSrcForDefaultScale && view.src !== undefined) {
|
|
54
|
-
sources.push({
|
|
55
|
-
uri: view.src,
|
|
56
|
-
scale: 1,
|
|
57
|
-
width: view.width,
|
|
58
|
-
height: view.height,
|
|
59
|
-
...{ headers },
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
if (sources.length === 0)
|
|
63
|
-
dlog('Image srcSet: produced no valid sources');
|
|
64
|
-
return sources;
|
|
65
|
-
}
|
|
66
|
-
function resolveSourceArray(view) {
|
|
67
|
-
const headers = headersFromAliases(view);
|
|
68
|
-
if (view.srcSet !== undefined) {
|
|
69
|
-
return expandSrcSet(view.srcSet, view, headers);
|
|
70
|
-
}
|
|
71
|
-
if (view.src !== undefined) {
|
|
72
|
-
return [
|
|
73
|
-
{ uri: view.src, width: view.width, height: view.height, ...{ headers } },
|
|
74
|
-
];
|
|
75
|
-
}
|
|
76
|
-
if (view.source === undefined) {
|
|
77
|
-
dlog('Image: no source / src / srcSet provided');
|
|
78
|
-
return [];
|
|
79
|
-
}
|
|
80
|
-
const sources = normalizeSource(view.source);
|
|
81
|
-
if (Object.keys(headers).length > 0 && sources.length === 1) {
|
|
82
|
-
const [only] = sources;
|
|
83
|
-
if (typeof only === 'object' &&
|
|
84
|
-
only !== null &&
|
|
85
|
-
typeof Reflect.get(only, 'uri') === 'string') {
|
|
86
|
-
return [{ ...only, headers }];
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
return sources;
|
|
90
|
-
}
|
|
91
|
-
function readStyleString(style, key) {
|
|
92
|
-
if (style === undefined)
|
|
93
|
-
return undefined;
|
|
94
|
-
const flat = flattenStyle(style);
|
|
95
|
-
const value = Object.hasOwn(flat, key) ? flat[key] : undefined;
|
|
96
|
-
return typeof value === 'string' ? value : undefined;
|
|
97
|
-
}
|
|
98
|
-
function readSourceUri(source) {
|
|
99
|
-
const [resolved] = normalizeSource(source);
|
|
100
|
-
if (typeof resolved === 'object' && resolved !== null) {
|
|
101
|
-
const uri = Reflect.get(resolved, 'uri');
|
|
102
|
-
if (typeof uri === 'string')
|
|
103
|
-
return uri;
|
|
104
|
-
}
|
|
105
|
-
return undefined;
|
|
106
|
-
}
|
|
107
|
-
// Builds the exact prop bag renderImage's `mapped` produces, minus the final `el()` wrap — the
|
|
108
|
-
// caller hands the result straight to `<symbiote-image p={bag}>`.
|
|
109
|
-
export function buildImageBag(view) {
|
|
110
|
-
// `width` / `height` aliases fold into style; explicit style keys win.
|
|
111
|
-
const foldedStyle = view.width === undefined && view.height === undefined
|
|
112
|
-
? view.style
|
|
113
|
-
: [{ width: view.width, height: view.height }, view.style];
|
|
114
|
-
const mapped = {
|
|
115
|
-
...view.passthrough,
|
|
116
|
-
style: foldedStyle,
|
|
117
|
-
source: resolveSourceArray(view),
|
|
118
|
-
resizeMode: view.resizeMode ?? readStyleString(view.style, 'resizeMode'),
|
|
119
|
-
tintColor: view.tintColor ?? readStyleString(view.style, 'tintColor'),
|
|
120
|
-
};
|
|
121
|
-
// `alt` is the accessibility text: it sets accessibilityLabel and marks the image accessible.
|
|
122
|
-
// An explicit accessibilityLabel (already folded into passthrough) still wins.
|
|
123
|
-
if (view.alt !== undefined) {
|
|
124
|
-
if (mapped.accessibilityLabel === undefined)
|
|
125
|
-
mapped.accessibilityLabel = view.alt;
|
|
126
|
-
mapped.accessible = true;
|
|
127
|
-
}
|
|
128
|
-
if (view.defaultSource !== undefined)
|
|
129
|
-
mapped.defaultSource = normalizeSource(view.defaultSource);
|
|
130
|
-
if (view.loadingIndicatorSource !== undefined) {
|
|
131
|
-
mapped.loadingIndicatorSrc = readSourceUri(view.loadingIndicatorSource);
|
|
132
|
-
}
|
|
133
|
-
dlog('Image -> RCTImageView');
|
|
134
|
-
return mapped;
|
|
135
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
// Image statics (getSize / prefetch / queryCache / abortPrefetch / resolveAssetSource) attach onto
|
|
2
|
-
// the component value, mirroring RN's `Image.getSize` static surface — shared verbatim via
|
|
3
|
-
// @symbiote-native/engine's imageStatics, the same source React's and Vue's Image use. A `.svelte`
|
|
4
|
-
// file's own module type resolves through svelte's ambient `declare module '*.svelte'` fallback (a
|
|
5
|
-
// bare value export, not props-parameterized — see view-props.ts's header comment for the general
|
|
6
|
-
// reason), so the statics are attached here in a plain sibling `.ts` file rather than inside
|
|
7
|
-
// `index.svelte` itself.
|
|
8
|
-
import ImageComponent from './index.svelte';
|
|
9
|
-
import { imageStatics } from '@symbiote-native/components';
|
|
10
|
-
export const Image = Object.assign(ImageComponent, imageStatics);
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
<script lang="ts" module>
|
|
2
|
-
// Image: render-only (no state). Source resolution / width-height fold / resizeMode & tintColor
|
|
3
|
-
// style-read / alt->accessibility fold mirror core/components/src/view/render-image/index.ts's
|
|
4
|
-
// renderImage() exactly, via image-logic.ts's buildImageBag (see that file's header for why the
|
|
5
|
-
// logic is duplicated rather than the Descriptor consumed). renderImage always produces a
|
|
6
|
-
// SINGLE symbiote-image node, so the markup here is just that one host tag.
|
|
7
|
-
//
|
|
8
|
-
// Statics (getSize/prefetch/queryCache/…) are attached in the sibling `index.ts`, not here — a
|
|
9
|
-
// `.svelte` file's default export resolves through svelte's ambient module fallback (a bare
|
|
10
|
-
// value, not something `Object.assign` can usefully augment from inside the component itself).
|
|
11
|
-
import type { IImageProps } from './image-props';
|
|
12
|
-
|
|
13
|
-
export type { IImageProps };
|
|
14
|
-
</script>
|
|
15
|
-
|
|
16
|
-
<script lang="ts">
|
|
17
|
-
import { resolveAccessibilityProps } from '@symbiote-native/components';
|
|
18
|
-
import { buildImageBag } from './image-logic';
|
|
19
|
-
import { createAttachmentsSync } from '../../runes/attachments';
|
|
20
|
-
import type { ShimElement } from '../../dom-shim';
|
|
21
|
-
|
|
22
|
-
let {
|
|
23
|
-
source,
|
|
24
|
-
defaultSource,
|
|
25
|
-
loadingIndicatorSource,
|
|
26
|
-
style,
|
|
27
|
-
resizeMode,
|
|
28
|
-
tintColor,
|
|
29
|
-
src,
|
|
30
|
-
srcSet,
|
|
31
|
-
alt,
|
|
32
|
-
width,
|
|
33
|
-
height,
|
|
34
|
-
crossOrigin,
|
|
35
|
-
referrerPolicy,
|
|
36
|
-
...passthrough
|
|
37
|
-
}: IImageProps = $props();
|
|
38
|
-
|
|
39
|
-
const bag = $derived(
|
|
40
|
-
buildImageBag({
|
|
41
|
-
source,
|
|
42
|
-
defaultSource,
|
|
43
|
-
loadingIndicatorSource,
|
|
44
|
-
style,
|
|
45
|
-
resizeMode,
|
|
46
|
-
tintColor,
|
|
47
|
-
src,
|
|
48
|
-
srcSet,
|
|
49
|
-
alt,
|
|
50
|
-
width,
|
|
51
|
-
height,
|
|
52
|
-
crossOrigin,
|
|
53
|
-
referrerPolicy,
|
|
54
|
-
passthrough: resolveAccessibilityProps(passthrough),
|
|
55
|
-
}),
|
|
56
|
-
);
|
|
57
|
-
|
|
58
|
-
// See View.svelte's note on `{@attach}`.
|
|
59
|
-
let hostShim = $state.raw<ShimElement | null>(null);
|
|
60
|
-
const syncAttachments = createAttachmentsSync();
|
|
61
|
-
$effect(() => {
|
|
62
|
-
syncAttachments(hostShim, passthrough);
|
|
63
|
-
});
|
|
64
|
-
</script>
|
|
65
|
-
|
|
66
|
-
<symbiote-image p={bag} bind:this={hostShim} />
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
<script lang="ts" module>
|
|
2
|
-
// ImageBackground: render-only composition (absolute-fill Image behind, children on top).
|
|
3
|
-
// Calls renderImageBackground() straight from core/components for the absolute-fill
|
|
4
|
-
// positioning + wrapper-dimension proxy onto the inner Image — both tags stay literal (the
|
|
5
|
-
// wrapper hosts `{@render children?.()}` as a live sibling after the image, which the
|
|
6
|
-
// generic descriptorToSvelte bridge can't safely own: appending the image inside an $effect
|
|
7
|
-
// would race Svelte's own placement of the live children and could reorder them — see
|
|
8
|
-
// svelte-adapter-dom-shim skill §19), so `.props`/`.children[0].props` are destructured onto
|
|
9
|
-
// the two known host tags, same pattern as Modal/index.svelte.
|
|
10
|
-
import type { IImageBackgroundProps } from './image-background-props';
|
|
11
|
-
|
|
12
|
-
export type { IImageBackgroundProps };
|
|
13
|
-
</script>
|
|
14
|
-
|
|
15
|
-
<script lang="ts">
|
|
16
|
-
import {
|
|
17
|
-
renderImageBackground,
|
|
18
|
-
resolveAccessibilityProps,
|
|
19
|
-
} from '@symbiote-native/components';
|
|
20
|
-
import { resolveClassName } from '@symbiote-native/engine';
|
|
21
|
-
import { createAttachmentsSync } from '../../runes/attachments';
|
|
22
|
-
import type { ShimElement } from '../../dom-shim';
|
|
23
|
-
|
|
24
|
-
let {
|
|
25
|
-
children,
|
|
26
|
-
style,
|
|
27
|
-
imageStyle,
|
|
28
|
-
class: className,
|
|
29
|
-
source,
|
|
30
|
-
defaultSource,
|
|
31
|
-
loadingIndicatorSource,
|
|
32
|
-
resizeMode,
|
|
33
|
-
tintColor,
|
|
34
|
-
src,
|
|
35
|
-
srcSet,
|
|
36
|
-
alt,
|
|
37
|
-
width,
|
|
38
|
-
height,
|
|
39
|
-
crossOrigin,
|
|
40
|
-
referrerPolicy,
|
|
41
|
-
...passthrough
|
|
42
|
-
}: IImageBackgroundProps = $props();
|
|
43
|
-
|
|
44
|
-
const resolvedImageStyle = $derived(
|
|
45
|
-
typeof imageStyle === 'string' ? resolveClassName(imageStyle) : imageStyle,
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
const descriptor = $derived(
|
|
49
|
-
renderImageBackground({
|
|
50
|
-
style,
|
|
51
|
-
imageStyle: resolvedImageStyle,
|
|
52
|
-
image: {
|
|
53
|
-
source,
|
|
54
|
-
defaultSource,
|
|
55
|
-
loadingIndicatorSource,
|
|
56
|
-
resizeMode,
|
|
57
|
-
tintColor,
|
|
58
|
-
src,
|
|
59
|
-
srcSet,
|
|
60
|
-
alt,
|
|
61
|
-
width,
|
|
62
|
-
height,
|
|
63
|
-
crossOrigin,
|
|
64
|
-
referrerPolicy,
|
|
65
|
-
passthrough: resolveAccessibilityProps(passthrough),
|
|
66
|
-
},
|
|
67
|
-
}),
|
|
68
|
-
);
|
|
69
|
-
const imageBag = $derived.by(() => {
|
|
70
|
-
const child = descriptor.children[0];
|
|
71
|
-
return typeof child === 'string' ? {} : child.props;
|
|
72
|
-
});
|
|
73
|
-
const wrapperBag = $derived({ ...descriptor.props, class: className });
|
|
74
|
-
|
|
75
|
-
// See View.svelte's note on `{@attach}` — the attachment binds to the OUTER wrapper, the node
|
|
76
|
-
// this component's own `class`/`style` land on and the one a caller means by "this component".
|
|
77
|
-
let hostShim = $state.raw<ShimElement | null>(null);
|
|
78
|
-
const syncAttachments = createAttachmentsSync();
|
|
79
|
-
$effect(() => {
|
|
80
|
-
syncAttachments(hostShim, passthrough);
|
|
81
|
-
});
|
|
82
|
-
</script>
|
|
83
|
-
|
|
84
|
-
<symbiote-view p={wrapperBag} bind:this={hostShim}>
|
|
85
|
-
<symbiote-image p={imageBag} />
|
|
86
|
-
{@render children?.()}
|
|
87
|
-
</symbiote-view>
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
<script lang="ts" module>
|
|
2
|
-
// InputAccessoryView: render-only host assembly (iOS). Calls the shared
|
|
3
|
-
// core/components/src/view/render-input-accessory-view.ts's renderInputAccessoryView()
|
|
4
|
-
// directly (nativeID/backgroundColor/style -> the host node, everything else passthrough) —
|
|
5
|
-
// the same calling convention as keyboard-avoiding-view/index.svelte's shared-render-fn call,
|
|
6
|
-
// rather than hand-duplicating its prop-assembly logic (per the svelte-adapter-dom-shim
|
|
7
|
-
// skill's §15/§19 correction: a fixed-shape Descriptor still has to be CALLED, not
|
|
8
|
-
// re-derived). The root tag stays literal below since renderInputAccessoryView always paints
|
|
9
|
-
// the same 'symbiote-input-accessory-view' host — no dynamic <svelte:element> needed. The
|
|
10
|
-
// host has no structural children of its own; the user's children nest directly under it.
|
|
11
|
-
import type { IInputAccessoryViewProps } from './input-accessory-view-props';
|
|
12
|
-
|
|
13
|
-
export type { IInputAccessoryViewProps };
|
|
14
|
-
</script>
|
|
15
|
-
|
|
16
|
-
<script lang="ts">
|
|
17
|
-
import {
|
|
18
|
-
renderInputAccessoryView,
|
|
19
|
-
resolveAccessibilityProps,
|
|
20
|
-
} from '@symbiote-native/components';
|
|
21
|
-
import { createAttachmentsSync } from '../../runes/attachments';
|
|
22
|
-
import type { ShimElement } from '../../dom-shim';
|
|
23
|
-
|
|
24
|
-
let {
|
|
25
|
-
nativeID,
|
|
26
|
-
backgroundColor,
|
|
27
|
-
style,
|
|
28
|
-
children,
|
|
29
|
-
...passthrough
|
|
30
|
-
}: IInputAccessoryViewProps = $props();
|
|
31
|
-
|
|
32
|
-
const descriptor = $derived(
|
|
33
|
-
renderInputAccessoryView({
|
|
34
|
-
nativeID,
|
|
35
|
-
backgroundColor,
|
|
36
|
-
style,
|
|
37
|
-
passthrough: resolveAccessibilityProps(passthrough),
|
|
38
|
-
}),
|
|
39
|
-
);
|
|
40
|
-
|
|
41
|
-
// See View.svelte's note on `{@attach}`.
|
|
42
|
-
let hostShim = $state.raw<ShimElement | null>(null);
|
|
43
|
-
const syncAttachments = createAttachmentsSync();
|
|
44
|
-
$effect(() => {
|
|
45
|
-
syncAttachments(hostShim, passthrough);
|
|
46
|
-
});
|
|
47
|
-
</script>
|
|
48
|
-
|
|
49
|
-
<symbiote-input-accessory-view p={descriptor.props} bind:this={hostShim}>
|
|
50
|
-
{@render children?.()}
|
|
51
|
-
</symbiote-input-accessory-view>
|