@symbiote-native/image 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +260 -2
- package/build/angular/image/index.d.ts +20 -0
- package/build/angular/image/index.js +113 -0
- package/build/angular/image-background/index.d.ts +14 -0
- package/build/angular/image-background/index.js +109 -0
- package/build/angular/index.d.ts +4 -0
- package/build/angular/index.js +6 -0
- package/build/angular/inject-image.d.ts +8 -0
- package/build/angular/inject-image.js +20 -0
- package/build/core/constants.d.ts +3 -0
- package/build/core/constants.js +4 -0
- package/build/core/hash-strings.d.ts +5 -0
- package/build/core/hash-strings.js +22 -0
- package/build/core/image-api.d.ts +18 -0
- package/build/core/image-api.js +30 -0
- package/build/core/image-background.d.ts +11 -0
- package/build/core/image-background.js +29 -0
- package/build/core/image-loader.d.ts +20 -0
- package/build/core/image-loader.js +42 -0
- package/build/core/image-ref-loader.d.ts +4 -0
- package/build/core/image-ref-loader.js +10 -0
- package/build/core/image-view-events.d.ts +9 -0
- package/build/core/image-view-events.js +34 -0
- package/build/core/image-view.d.ts +14 -0
- package/build/core/image-view.js +113 -0
- package/build/core/index.d.ts +10 -0
- package/build/core/index.js +7 -0
- package/build/core/native-module.d.ts +27 -0
- package/build/core/native-module.js +3 -0
- package/build/core/native-style.d.ts +19 -0
- package/build/core/native-style.js +65 -0
- package/build/core/props.d.ts +11 -0
- package/build/core/props.js +87 -0
- package/build/core/sources.d.ts +8 -0
- package/build/core/sources.js +61 -0
- package/build/core/types.d.ts +186 -0
- package/build/core/types.js +1 -0
- package/build/react/image-background.d.ts +7 -0
- package/build/react/image-background.js +7 -0
- package/build/react/image.d.ts +8 -0
- package/build/react/image.js +6 -0
- package/build/react/index.d.ts +6 -0
- package/build/react/index.js +5 -0
- package/build/react/use-image.d.ts +8 -0
- package/build/react/use-image.js +20 -0
- package/build/solid/image-background.d.ts +7 -0
- package/build/solid/image-background.js +4 -0
- package/build/solid/image.d.ts +45 -0
- package/build/solid/image.js +4 -0
- package/build/solid/index.d.ts +5 -0
- package/build/solid/index.js +5 -0
- package/build/solid/use-image.d.ts +8 -0
- package/build/solid/use-image.js +16 -0
- package/build/svelte/image-background-props.d.ts +5 -0
- package/build/svelte/image-background-props.js +1 -0
- package/build/svelte/image-background.svelte +10 -0
- package/build/svelte/image-background.svelte.d.ts +4 -0
- package/build/svelte/image.svelte +26 -0
- package/build/svelte/image.svelte.d.ts +10 -0
- package/build/svelte/index.d.ts +6 -0
- package/build/svelte/index.js +5 -0
- package/build/svelte/use-image.svelte.d.ts +10 -0
- package/build/svelte/use-image.svelte.js +26 -0
- package/build/vue/image-background.d.ts +3 -0
- package/build/vue/image-background.js +12 -0
- package/build/vue/image.d.ts +2 -0
- package/build/vue/image.js +4 -0
- package/build/vue/index.d.ts +4 -0
- package/build/vue/index.js +5 -0
- package/build/vue/use-image.d.ts +8 -0
- package/build/vue/use-image.js +18 -0
- package/build-ngc/angular/image/index.d.ts +23 -0
- package/build-ngc/angular/image/index.js +72 -0
- package/build-ngc/angular/image/index.js.map +1 -0
- package/build-ngc/angular/image-background/index.d.ts +17 -0
- package/build-ngc/angular/image-background/index.js +70 -0
- package/build-ngc/angular/image-background/index.js.map +1 -0
- package/build-ngc/angular/index.d.ts +4 -0
- package/build-ngc/angular/index.js +7 -0
- package/build-ngc/angular/index.js.map +1 -0
- package/build-ngc/angular/inject-image.d.ts +8 -0
- package/build-ngc/angular/inject-image.js +23 -0
- package/build-ngc/angular/inject-image.js.map +1 -0
- package/build-ngc/core/constants.d.ts +3 -0
- package/build-ngc/core/constants.js +5 -0
- package/build-ngc/core/constants.js.map +1 -0
- package/build-ngc/core/hash-strings.d.ts +5 -0
- package/build-ngc/core/hash-strings.js +23 -0
- package/build-ngc/core/hash-strings.js.map +1 -0
- package/build-ngc/core/image-api.d.ts +18 -0
- package/build-ngc/core/image-api.js +31 -0
- package/build-ngc/core/image-api.js.map +1 -0
- package/build-ngc/core/image-background.d.ts +11 -0
- package/build-ngc/core/image-background.js +30 -0
- package/build-ngc/core/image-background.js.map +1 -0
- package/build-ngc/core/image-loader.d.ts +20 -0
- package/build-ngc/core/image-loader.js +43 -0
- package/build-ngc/core/image-loader.js.map +1 -0
- package/build-ngc/core/image-ref-loader.d.ts +4 -0
- package/build-ngc/core/image-ref-loader.js +11 -0
- package/build-ngc/core/image-ref-loader.js.map +1 -0
- package/build-ngc/core/image-view-events.d.ts +9 -0
- package/build-ngc/core/image-view-events.js +35 -0
- package/build-ngc/core/image-view-events.js.map +1 -0
- package/build-ngc/core/image-view.d.ts +14 -0
- package/build-ngc/core/image-view.js +114 -0
- package/build-ngc/core/image-view.js.map +1 -0
- package/build-ngc/core/index.d.ts +10 -0
- package/build-ngc/core/index.js +8 -0
- package/build-ngc/core/index.js.map +1 -0
- package/build-ngc/core/native-module.d.ts +27 -0
- package/build-ngc/core/native-module.js +4 -0
- package/build-ngc/core/native-module.js.map +1 -0
- package/build-ngc/core/native-style.d.ts +19 -0
- package/build-ngc/core/native-style.js +66 -0
- package/build-ngc/core/native-style.js.map +1 -0
- package/build-ngc/core/props.d.ts +11 -0
- package/build-ngc/core/props.js +88 -0
- package/build-ngc/core/props.js.map +1 -0
- package/build-ngc/core/sources.d.ts +8 -0
- package/build-ngc/core/sources.js +62 -0
- package/build-ngc/core/sources.js.map +1 -0
- package/build-ngc/core/types.d.ts +186 -0
- package/build-ngc/core/types.js +2 -0
- package/build-ngc/core/types.js.map +1 -0
- package/native-link.json +13 -0
- package/package.json +145 -3
- package/src/angular/image/index.ts +79 -0
- package/src/angular/image-background/index.ts +72 -0
- package/src/angular/index.ts +7 -0
- package/src/angular/inject-image.ts +29 -0
- package/src/core/constants.ts +6 -0
- package/src/core/hash-strings.ts +29 -0
- package/src/core/image-api.ts +77 -0
- package/src/core/image-background.ts +47 -0
- package/src/core/image-loader.ts +72 -0
- package/src/core/image-ref-loader.ts +16 -0
- package/src/core/image-view-events.ts +47 -0
- package/src/core/image-view.ts +173 -0
- package/src/core/index.ts +50 -0
- package/src/core/native-module.ts +44 -0
- package/src/core/native-style.ts +96 -0
- package/src/core/props.ts +123 -0
- package/src/core/sources.ts +75 -0
- package/src/core/types.ts +275 -0
- package/src/react/image-background.ts +16 -0
- package/src/react/image.ts +17 -0
- package/src/react/index.ts +8 -0
- package/src/react/use-image.ts +29 -0
- package/src/solid/image-background.ts +12 -0
- package/src/solid/image.ts +9 -0
- package/src/solid/index.ts +7 -0
- package/src/solid/use-image.ts +30 -0
- package/src/svelte/image-background-props.ts +6 -0
- package/src/svelte/image-background.svelte +10 -0
- package/src/svelte/image.svelte +26 -0
- package/src/svelte/index.ts +8 -0
- package/src/svelte/svelte-ambient.d.ts +3 -0
- package/src/svelte/svelte-compile.test-helper.ts +6 -0
- package/src/svelte/use-image.svelte.ts +38 -0
- package/src/vue/image-background.ts +17 -0
- package/src/vue/image.ts +5 -0
- package/src/vue/index.ts +6 -0
- package/src/vue/use-image.ts +38 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import type { IAccessibilityProps, IAriaProps, IResponderProps } from '@symbiote-native/components';
|
|
2
|
+
import type { IColorValue, IStyleProp, ITextStyle, IViewStyle } from '@symbiote-native/engine';
|
|
3
|
+
import type { SharedRef } from 'expo-modules-core';
|
|
4
|
+
import type { SFSymbol } from 'sf-symbols-typescript';
|
|
5
|
+
export type IImageSource = {
|
|
6
|
+
/** `http(s)`, `file`, `data`, an asset URI and the `sf:/` and `blurhash:/` schemes */
|
|
7
|
+
uri?: string;
|
|
8
|
+
/** Sent with the request */
|
|
9
|
+
headers?: Record<string, string>;
|
|
10
|
+
/** Used for layout while the image loads, and the size of a hash placeholder */
|
|
11
|
+
width?: number | null;
|
|
12
|
+
height?: number | null;
|
|
13
|
+
/** A Blurhash string, the source becomes a `blurhash:/` uri */
|
|
14
|
+
blurhash?: string;
|
|
15
|
+
/** A Thumbhash string, the source becomes a `thumbhash:/` uri */
|
|
16
|
+
thumbhash?: string;
|
|
17
|
+
/** The key of the cache entry, the uri by default */
|
|
18
|
+
cacheKey?: string;
|
|
19
|
+
/** Web only */
|
|
20
|
+
webMaxViewportWidth?: number;
|
|
21
|
+
/** Plays the image as an animation, detected from the content by default */
|
|
22
|
+
isAnimated?: boolean;
|
|
23
|
+
};
|
|
24
|
+
export type IImageContentFit = 'cover' | 'contain' | 'fill' | 'none' | 'scale-down';
|
|
25
|
+
export type IImageDecodeFormat = 'argb' | 'rgb';
|
|
26
|
+
export type IImageResizeMode = 'cover' | 'contain' | 'stretch' | 'repeat' | 'center';
|
|
27
|
+
export type IImageContentPositionValue = number | string | `${number}%` | `${number}` | 'center';
|
|
28
|
+
export type IImageContentPositionString = 'center' | 'top' | 'right' | 'bottom' | 'left' | 'top center' | 'top right' | 'top left' | 'right center' | 'right top' | 'right bottom' | 'bottom center' | 'bottom right' | 'bottom left' | 'left center' | 'left top' | 'left bottom';
|
|
29
|
+
/** Two edges, the native side takes only this form */
|
|
30
|
+
export type IImageContentPositionObject = {
|
|
31
|
+
top?: IImageContentPositionValue;
|
|
32
|
+
right?: IImageContentPositionValue;
|
|
33
|
+
} | {
|
|
34
|
+
top?: IImageContentPositionValue;
|
|
35
|
+
left?: IImageContentPositionValue;
|
|
36
|
+
} | {
|
|
37
|
+
bottom?: IImageContentPositionValue;
|
|
38
|
+
right?: IImageContentPositionValue;
|
|
39
|
+
} | {
|
|
40
|
+
bottom?: IImageContentPositionValue;
|
|
41
|
+
left?: IImageContentPositionValue;
|
|
42
|
+
};
|
|
43
|
+
export type IImageContentPosition = IImageContentPositionObject | IImageContentPositionString;
|
|
44
|
+
export type IImageTransition = {
|
|
45
|
+
/** In milliseconds */
|
|
46
|
+
duration?: number;
|
|
47
|
+
timing?: 'ease-in-out' | 'ease-in' | 'ease-out' | 'linear';
|
|
48
|
+
effect?: 'cross-dissolve' | 'flip-from-top' | 'flip-from-right' | 'flip-from-bottom' | 'flip-from-left' | 'curl-up' | 'curl-down' | 'sf:replace' | 'sf:down-up' | 'sf:up-up' | 'sf:off-up' | null;
|
|
49
|
+
};
|
|
50
|
+
export type ISfSymbolEffectType = 'bounce' | 'bounce/up' | 'bounce/down' | 'pulse' | 'variable-color' | 'variable-color/iterative' | 'variable-color/cumulative' | 'scale' | 'scale/up' | 'scale/down' | 'appear' | 'disappear' | 'wiggle' | 'rotate' | 'breathe' | 'draw/on' | 'draw/off';
|
|
51
|
+
export type ISfSymbolEffectObject = {
|
|
52
|
+
effect: ISfSymbolEffectType;
|
|
53
|
+
/** `-1` repeats forever */
|
|
54
|
+
repeat?: number;
|
|
55
|
+
scope?: 'by-layer' | 'whole-symbol' | null;
|
|
56
|
+
};
|
|
57
|
+
/** iOS 17+ for an SF Symbol source */
|
|
58
|
+
export type ISfSymbolEffect = ISfSymbolEffectType | ISfSymbolEffectObject | (ISfSymbolEffectType | ISfSymbolEffectObject)[];
|
|
59
|
+
export type IImageLoadEventData = {
|
|
60
|
+
cacheType: 'none' | 'disk' | 'memory';
|
|
61
|
+
source: {
|
|
62
|
+
url: string;
|
|
63
|
+
width: number;
|
|
64
|
+
height: number;
|
|
65
|
+
mediaType: string | null;
|
|
66
|
+
isAnimated?: boolean;
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
export type IImageProgressEventData = {
|
|
70
|
+
loaded: number;
|
|
71
|
+
total: number;
|
|
72
|
+
};
|
|
73
|
+
export type IImageErrorEventData = {
|
|
74
|
+
error: string;
|
|
75
|
+
};
|
|
76
|
+
export type IImagePrefetchOptions = {
|
|
77
|
+
/** `memory-disk` by default */
|
|
78
|
+
cachePolicy?: 'disk' | 'memory-disk' | 'memory';
|
|
79
|
+
headers?: Record<string, string>;
|
|
80
|
+
};
|
|
81
|
+
export type IImageCacheConfig = {
|
|
82
|
+
/** In bytes */
|
|
83
|
+
maxDiskSize?: number;
|
|
84
|
+
/** In bytes */
|
|
85
|
+
maxMemoryCost?: number;
|
|
86
|
+
maxMemoryCount?: number;
|
|
87
|
+
};
|
|
88
|
+
export type IImageLoadOptions = {
|
|
89
|
+
maxWidth?: number;
|
|
90
|
+
maxHeight?: number;
|
|
91
|
+
tintColor?: IColorValue | number;
|
|
92
|
+
/** `retry` loads again */
|
|
93
|
+
onError?(error: Error, retry: () => void): void;
|
|
94
|
+
};
|
|
95
|
+
/** A reference to a native image, an image view takes it as its source */
|
|
96
|
+
export declare class ImageRef extends SharedRef<'image'> {
|
|
97
|
+
readonly width: number;
|
|
98
|
+
readonly height: number;
|
|
99
|
+
readonly scale: number;
|
|
100
|
+
readonly mediaType: string | null;
|
|
101
|
+
readonly isAnimated?: boolean;
|
|
102
|
+
/** The id the native view looks the shared object up by */
|
|
103
|
+
readonly __expo_shared_object_id__: number;
|
|
104
|
+
}
|
|
105
|
+
export type IImageStyle = IViewStyle & {
|
|
106
|
+
tintColor?: IColorValue;
|
|
107
|
+
resizeMode?: IImageResizeMode;
|
|
108
|
+
/** With `color` and `fontSize` for an SF Symbol */
|
|
109
|
+
fontWeight?: ITextStyle['fontWeight'];
|
|
110
|
+
color?: IColorValue;
|
|
111
|
+
fontSize?: number;
|
|
112
|
+
};
|
|
113
|
+
export type IImageSources = IImageSource | `sf:${SFSymbol}` | (string & {}) | number | IImageSource[] | string[] | SharedRef<'image'> | null;
|
|
114
|
+
export type IImageViewProps = IAccessibilityProps & IAriaProps & IResponderProps & {
|
|
115
|
+
style?: IStyleProp<IImageStyle>;
|
|
116
|
+
/** A uri, an asset, a source object, a list of them or an `ImageRef` */
|
|
117
|
+
source?: IImageSources;
|
|
118
|
+
/** Shown while `source` loads */
|
|
119
|
+
placeholder?: IImageSource | string | number | IImageSource[] | string[] | SharedRef<'image'> | null;
|
|
120
|
+
/** `cover` by default, `contain` for an SF Symbol */
|
|
121
|
+
contentFit?: IImageContentFit;
|
|
122
|
+
placeholderContentFit?: IImageContentFit;
|
|
123
|
+
/** `center` by default */
|
|
124
|
+
contentPosition?: IImageContentPosition;
|
|
125
|
+
/** A number is the duration of a cross dissolve */
|
|
126
|
+
transition?: IImageTransition | number | null;
|
|
127
|
+
blurRadius?: number;
|
|
128
|
+
tintColor?: IColorValue | null;
|
|
129
|
+
priority?: 'low' | 'normal' | 'high' | null;
|
|
130
|
+
loading?: 'lazy' | 'eager';
|
|
131
|
+
cachePolicy?: 'none' | 'disk' | 'memory' | 'memory-disk' | null;
|
|
132
|
+
/** How the image follows a changing view size */
|
|
133
|
+
responsivePolicy?: 'live' | 'initial' | 'static';
|
|
134
|
+
/** Lets a recycled list cell tell its images apart */
|
|
135
|
+
recyclingKey?: string | null;
|
|
136
|
+
/** Plays an animated image on its own, `true` by default */
|
|
137
|
+
autoplay?: boolean;
|
|
138
|
+
/** An effect of an SF Symbol source, iOS 17+ */
|
|
139
|
+
sfEffect?: ISfSymbolEffect | null;
|
|
140
|
+
onLoadStart?: () => void;
|
|
141
|
+
onLoad?: (event: IImageLoadEventData) => void;
|
|
142
|
+
onProgress?: (event: IImageProgressEventData) => void;
|
|
143
|
+
onError?: (event: IImageErrorEventData) => void;
|
|
144
|
+
onLoadEnd?: () => void;
|
|
145
|
+
onDisplay?: () => void;
|
|
146
|
+
/** @deprecated Use `placeholder` */
|
|
147
|
+
defaultSource?: IImageSource | null;
|
|
148
|
+
/** @deprecated Use `placeholder` */
|
|
149
|
+
loadingIndicatorSource?: IImageSource | null;
|
|
150
|
+
/** @deprecated Use `contentFit` */
|
|
151
|
+
resizeMode?: IImageResizeMode;
|
|
152
|
+
/** @deprecated Use `transition` */
|
|
153
|
+
fadeDuration?: number;
|
|
154
|
+
focusable?: boolean;
|
|
155
|
+
accessible?: boolean;
|
|
156
|
+
accessibilityLabel?: string;
|
|
157
|
+
/** The accessibility label when none is given */
|
|
158
|
+
alt?: string;
|
|
159
|
+
/** iOS only, lets the user select text in the image */
|
|
160
|
+
enableLiveTextInteraction?: boolean;
|
|
161
|
+
/** Downscales a larger image to the view, `true` by default */
|
|
162
|
+
allowDownscaling?: boolean;
|
|
163
|
+
/** Android only, `argb` by default */
|
|
164
|
+
decodeFormat?: IImageDecodeFormat;
|
|
165
|
+
/** iOS only */
|
|
166
|
+
useAppleWebpCodec?: boolean;
|
|
167
|
+
/** Android only */
|
|
168
|
+
enforceEarlyResizing?: boolean;
|
|
169
|
+
/** iOS only */
|
|
170
|
+
preferHighDynamicRange?: boolean;
|
|
171
|
+
/** Web only */
|
|
172
|
+
draggable?: boolean;
|
|
173
|
+
testID?: string;
|
|
174
|
+
nativeID?: string;
|
|
175
|
+
};
|
|
176
|
+
/** What a ref to the view hands out */
|
|
177
|
+
export type IImageViewHandle = {
|
|
178
|
+
/** Starts an animated image */
|
|
179
|
+
startAnimating(): Promise<void>;
|
|
180
|
+
stopAnimating(): Promise<void>;
|
|
181
|
+
/** Keeps the resource from being reloaded */
|
|
182
|
+
lockResourceAsync(): Promise<void>;
|
|
183
|
+
unlockResourceAsync(): Promise<void>;
|
|
184
|
+
/** Reloads the resource, the lock is ignored */
|
|
185
|
+
reloadAsync(): Promise<void>;
|
|
186
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ReactElement, ReactNode } from 'react';
|
|
2
|
+
import type { IImageBackgroundProps } from '../core';
|
|
3
|
+
export type IImageBackgroundReactProps = IImageBackgroundProps & {
|
|
4
|
+
children?: ReactNode;
|
|
5
|
+
};
|
|
6
|
+
/** React twin of `expo-image`'s `ImageBackground`, children paint over the image */
|
|
7
|
+
export declare function ImageBackground(props: IImageBackgroundReactProps): ReactElement;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { descriptorToReactWithChildren } from '@symbiote-native/react';
|
|
2
|
+
import { renderImageBackground } from '../core/index.js';
|
|
3
|
+
/** React twin of `expo-image`'s `ImageBackground`, children paint over the image */
|
|
4
|
+
export function ImageBackground(props) {
|
|
5
|
+
const { children, ...rest } = props;
|
|
6
|
+
return descriptorToReactWithChildren(renderImageBackground(rest), children);
|
|
7
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ReactElement, Ref } from 'react';
|
|
2
|
+
import type { IImageViewHandle, IImageViewProps } from '../core';
|
|
3
|
+
export type IImageReactProps = IImageViewProps & {
|
|
4
|
+
ref?: Ref<IImageViewHandle>;
|
|
5
|
+
className?: string;
|
|
6
|
+
};
|
|
7
|
+
/** React twin of `expo-image`'s `Image` */
|
|
8
|
+
export declare function Image({ ref, ...props }: IImageReactProps): ReactElement | null;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { useNativeViewController } from '@symbiote-native/react';
|
|
2
|
+
import { createImageView } from '../core/index.js';
|
|
3
|
+
/** React twin of `expo-image`'s `Image` */
|
|
4
|
+
export function Image({ ref, ...props }) {
|
|
5
|
+
return useNativeViewController(ref, createImageView, props);
|
|
6
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { Image } from './image';
|
|
2
|
+
export type { IImageReactProps } from './image';
|
|
3
|
+
export { ImageBackground } from './image-background';
|
|
4
|
+
export type { IImageBackgroundReactProps } from './image-background';
|
|
5
|
+
export { useImage } from './use-image';
|
|
6
|
+
export * from '../core';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// @symbiote-native/image/react: the image view, its cache and hash functions on a shared core
|
|
2
|
+
export { Image } from './image.js';
|
|
3
|
+
export { ImageBackground } from './image-background.js';
|
|
4
|
+
export { useImage } from './use-image.js';
|
|
5
|
+
export * from '../core/index.js';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { DependencyList } from 'react';
|
|
2
|
+
import type { IImageLoadOptions, IImageSource, ImageRef } from '../core';
|
|
3
|
+
/**
|
|
4
|
+
* Loads an image into a native `ImageRef`, `null` until the first one has loaded
|
|
5
|
+
*
|
|
6
|
+
* It loads again when the uri of the source or an item of `dependencies` changes
|
|
7
|
+
*/
|
|
8
|
+
export declare function useImage(source: IImageSource | string | number, options?: IImageLoadOptions, dependencies?: DependencyList): ImageRef | null;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { useEffect, useRef, useState } from 'react';
|
|
2
|
+
import { createImageRefLoader, resolveSource } from '../core/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Loads an image into a native `ImageRef`, `null` until the first one has loaded
|
|
5
|
+
*
|
|
6
|
+
* It loads again when the uri of the source or an item of `dependencies` changes
|
|
7
|
+
*/
|
|
8
|
+
export function useImage(source, options = {}, dependencies = []) {
|
|
9
|
+
const [image, setImage] = useState(null);
|
|
10
|
+
// The effect reads the options of the latest render, not the ones it started with
|
|
11
|
+
const latestOptions = useRef(options);
|
|
12
|
+
latestOptions.current = options;
|
|
13
|
+
const key = resolveSource(source)?.uri;
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
const loader = createImageRefLoader(setImage, () => latestOptions.current);
|
|
16
|
+
loader.load(source);
|
|
17
|
+
return loader.cancel;
|
|
18
|
+
}, [key, ...dependencies]);
|
|
19
|
+
return image;
|
|
20
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { JSX } from 'solid-js';
|
|
2
|
+
import type { IImageBackgroundProps } from '../core';
|
|
3
|
+
export type IImageBackgroundSolidProps = IImageBackgroundProps & {
|
|
4
|
+
children?: JSX.Element;
|
|
5
|
+
};
|
|
6
|
+
/** Solid twin of `expo-image`'s `ImageBackground`, children paint over the image */
|
|
7
|
+
export declare const ImageBackground: (props: IImageBackgroundSolidProps) => import("@symbiote-native/engine").ISymbioteNode;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { defineDescriptorComponent } from '@symbiote-native/solid';
|
|
2
|
+
import { renderImageBackground } from '../core/index.js';
|
|
3
|
+
/** Solid twin of `expo-image`'s `ImageBackground`, children paint over the image */
|
|
4
|
+
export const ImageBackground = defineDescriptorComponent(renderImageBackground);
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { IImageViewHandle } from '../core';
|
|
2
|
+
/** Solid twin of `expo-image`'s `Image`, `ref` gets the handle of the view */
|
|
3
|
+
export declare const Image: (props: import("@symbiote-native/components").IAccessibilityProps & import("@symbiote-native/components").IAriaProps & import("@symbiote-native/components").IResponderProps & {
|
|
4
|
+
style?: import("@symbiote-native/engine").IStyleProp<import(".").IImageStyle>;
|
|
5
|
+
source?: import(".").IImageSources;
|
|
6
|
+
placeholder?: import(".").IImageSource | string | number | import(".").IImageSource[] | string[] | import("expo-modules-core").SharedRef<"image"> | null;
|
|
7
|
+
contentFit?: import(".").IImageContentFit;
|
|
8
|
+
placeholderContentFit?: import(".").IImageContentFit;
|
|
9
|
+
contentPosition?: import(".").IImageContentPosition;
|
|
10
|
+
transition?: import(".").IImageTransition | number | null;
|
|
11
|
+
blurRadius?: number;
|
|
12
|
+
tintColor?: import("@symbiote-native/engine").IColorValue | null;
|
|
13
|
+
priority?: "low" | "normal" | "high" | null;
|
|
14
|
+
loading?: "lazy" | "eager";
|
|
15
|
+
cachePolicy?: "none" | "disk" | "memory" | "memory-disk" | null;
|
|
16
|
+
responsivePolicy?: "live" | "initial" | "static";
|
|
17
|
+
recyclingKey?: string | null;
|
|
18
|
+
autoplay?: boolean;
|
|
19
|
+
sfEffect?: import(".").ISfSymbolEffect | null;
|
|
20
|
+
onLoadStart?: () => void;
|
|
21
|
+
onLoad?: (event: import(".").IImageLoadEventData) => void;
|
|
22
|
+
onProgress?: (event: import(".").IImageProgressEventData) => void;
|
|
23
|
+
onError?: (event: import(".").IImageErrorEventData) => void;
|
|
24
|
+
onLoadEnd?: () => void;
|
|
25
|
+
onDisplay?: () => void;
|
|
26
|
+
defaultSource?: import(".").IImageSource | null;
|
|
27
|
+
loadingIndicatorSource?: import(".").IImageSource | null;
|
|
28
|
+
resizeMode?: import(".").IImageResizeMode;
|
|
29
|
+
fadeDuration?: number;
|
|
30
|
+
focusable?: boolean;
|
|
31
|
+
accessible?: boolean;
|
|
32
|
+
accessibilityLabel?: string;
|
|
33
|
+
alt?: string;
|
|
34
|
+
enableLiveTextInteraction?: boolean;
|
|
35
|
+
allowDownscaling?: boolean;
|
|
36
|
+
decodeFormat?: import(".").IImageDecodeFormat;
|
|
37
|
+
useAppleWebpCodec?: boolean;
|
|
38
|
+
enforceEarlyResizing?: boolean;
|
|
39
|
+
preferHighDynamicRange?: boolean;
|
|
40
|
+
draggable?: boolean;
|
|
41
|
+
testID?: string;
|
|
42
|
+
nativeID?: string;
|
|
43
|
+
} & {
|
|
44
|
+
ref?: ((handle: IImageViewHandle) => void) | undefined;
|
|
45
|
+
}) => import("@symbiote-native/engine").ISymbioteNode | null;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// @symbiote-native/image/solid: the image view, its cache and hash functions on a shared core
|
|
2
|
+
export { Image } from './image.js';
|
|
3
|
+
export { ImageBackground } from './image-background.js';
|
|
4
|
+
export { useImage } from './use-image.js';
|
|
5
|
+
export * from '../core/index.js';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Accessor } from 'solid-js';
|
|
2
|
+
import type { IImageLoadOptions, IImageSource, ImageRef } from '../core';
|
|
3
|
+
/**
|
|
4
|
+
* Solid twin of `expo-image`'s `useImage`, `null` until the first image has loaded
|
|
5
|
+
*
|
|
6
|
+
* It loads again when the uri of the source or a `dependencies` accessor changes
|
|
7
|
+
*/
|
|
8
|
+
export declare function useImage(source: Accessor<IImageSource | string | number>, options?: Accessor<IImageLoadOptions>, dependencies?: Accessor<unknown>[]): Accessor<ImageRef | null>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { createEffect, createSignal, on, onCleanup } from 'solid-js';
|
|
2
|
+
import { createImageRefLoader, resolveSource } from '../core/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Solid twin of `expo-image`'s `useImage`, `null` until the first image has loaded
|
|
5
|
+
*
|
|
6
|
+
* It loads again when the uri of the source or a `dependencies` accessor changes
|
|
7
|
+
*/
|
|
8
|
+
export function useImage(source, options = () => ({}), dependencies = []) {
|
|
9
|
+
const [image, setImage] = createSignal(null);
|
|
10
|
+
createEffect(on(() => [resolveSource(source())?.uri, ...dependencies.map(read => read())], () => {
|
|
11
|
+
const loader = createImageRefLoader(setImage, options);
|
|
12
|
+
loader.load(source());
|
|
13
|
+
onCleanup(loader.cancel);
|
|
14
|
+
}));
|
|
15
|
+
return image;
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import DescriptorHost from '@symbiote-native/svelte/descriptor-host';
|
|
3
|
+
import { renderImageBackground } from '../core';
|
|
4
|
+
import type { IImageBackgroundSvelteProps } from './image-background-props';
|
|
5
|
+
|
|
6
|
+
const { children, ...rest }: IImageBackgroundSvelteProps = $props();
|
|
7
|
+
const descriptor = $derived(renderImageBackground({ ...rest }));
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<DescriptorHost {descriptor} {children} />
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// The native view name is mixed-case, which a literal tag would parse as a component reference,
|
|
3
|
+
// so the tag is dynamic
|
|
4
|
+
import { hostProps } from '@symbiote-native/svelte/native-view-bridge';
|
|
5
|
+
import { useNativeViewController } from '@symbiote-native/svelte/runes/use-native-view-controller';
|
|
6
|
+
import { createImageView } from '../core';
|
|
7
|
+
import type { IImageViewProps } from '../core';
|
|
8
|
+
|
|
9
|
+
const props: IImageViewProps = $props();
|
|
10
|
+
const view = useNativeViewController(createImageView, () => ({ ...props }));
|
|
11
|
+
|
|
12
|
+
// The functions of the view are instance members, `bind:this` reaches them
|
|
13
|
+
export const startAnimating = view.handle.startAnimating;
|
|
14
|
+
export const stopAnimating = view.handle.stopAnimating;
|
|
15
|
+
export const lockResourceAsync = view.handle.lockResourceAsync;
|
|
16
|
+
export const unlockResourceAsync = view.handle.unlockResourceAsync;
|
|
17
|
+
export const reloadAsync = view.handle.reloadAsync;
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
{#if view.descriptor}
|
|
21
|
+
<svelte:element
|
|
22
|
+
this={view.descriptor.type}
|
|
23
|
+
{@attach view.attachHost}
|
|
24
|
+
{@attach hostProps(view.descriptor.props)}
|
|
25
|
+
/>
|
|
26
|
+
{/if}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { IImageViewProps } from '../core';
|
|
2
|
+
declare const Image: import("svelte").Component<IImageViewProps, {
|
|
3
|
+
startAnimating: () => Promise<void>;
|
|
4
|
+
stopAnimating: () => Promise<void>;
|
|
5
|
+
lockResourceAsync: () => Promise<void>;
|
|
6
|
+
unlockResourceAsync: () => Promise<void>;
|
|
7
|
+
reloadAsync: () => Promise<void>;
|
|
8
|
+
}, "">;
|
|
9
|
+
type Image = ReturnType<typeof Image>;
|
|
10
|
+
export default Image;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { default as Image } from './image.svelte';
|
|
2
|
+
export { default as ImageBackground } from './image-background.svelte';
|
|
3
|
+
export type { IImageBackgroundSvelteProps } from './image-background-props';
|
|
4
|
+
export { useImage } from './use-image.svelte';
|
|
5
|
+
export type { IUseImageResult } from './use-image.svelte';
|
|
6
|
+
export * from '../core';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// @symbiote-native/image/svelte: the image view, its cache and hash functions on a shared core
|
|
2
|
+
export { default as Image } from './image.svelte';
|
|
3
|
+
export { default as ImageBackground } from './image-background.svelte';
|
|
4
|
+
export { useImage } from './use-image.svelte';
|
|
5
|
+
export * from '../core/index.js';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { IImageLoadOptions, IImageSource, ImageRef } from '../core';
|
|
2
|
+
export type IUseImageResult = {
|
|
3
|
+
readonly current: ImageRef | null;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Svelte twin of `expo-image`'s `useImage`, boxed getter shape of the other hooks
|
|
7
|
+
*
|
|
8
|
+
* It loads again when the uri of the source or a value read by `getDependencies` changes
|
|
9
|
+
*/
|
|
10
|
+
export declare function useImage(getSource: () => IImageSource | string | number, getOptions?: () => IImageLoadOptions, getDependencies?: () => unknown[]): IUseImageResult;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { untrack } from 'svelte';
|
|
2
|
+
import { createImageRefLoader, resolveSource } from '../core/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Svelte twin of `expo-image`'s `useImage`, boxed getter shape of the other hooks
|
|
5
|
+
*
|
|
6
|
+
* It loads again when the uri of the source or a value read by `getDependencies` changes
|
|
7
|
+
*/
|
|
8
|
+
export function useImage(getSource, getOptions = () => ({}), getDependencies = () => []) {
|
|
9
|
+
let image = $state.raw(null);
|
|
10
|
+
const key = $derived(resolveSource(getSource())?.uri);
|
|
11
|
+
$effect(() => {
|
|
12
|
+
// Read so the effect tracks them, the source itself is not a trigger
|
|
13
|
+
void key;
|
|
14
|
+
getDependencies();
|
|
15
|
+
const loader = createImageRefLoader(loaded => {
|
|
16
|
+
image = loaded;
|
|
17
|
+
}, getOptions);
|
|
18
|
+
untrack(() => loader.load(getSource()));
|
|
19
|
+
return loader.cancel;
|
|
20
|
+
});
|
|
21
|
+
return {
|
|
22
|
+
get current() {
|
|
23
|
+
return image;
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { type VNode } from '@vue/runtime-core';
|
|
2
|
+
/** Vue twin of `expo-image`'s `ImageBackground`, the default slot paints over the image */
|
|
3
|
+
export declare const ImageBackground: import("vue").DefineComponent<{}, () => VNode, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { defineComponent } from '@vue/runtime-core';
|
|
2
|
+
import { descriptorToVue, normalizeVueAttrs } from '@symbiote-native/vue';
|
|
3
|
+
import { renderImageBackground } from '../core/index.js';
|
|
4
|
+
/** Vue twin of `expo-image`'s `ImageBackground`, the default slot paints over the image */
|
|
5
|
+
export const ImageBackground = defineComponent({
|
|
6
|
+
name: 'ImageBackground',
|
|
7
|
+
// Every attribute is a prop of the image or the view, nothing leaks onto the wrapper
|
|
8
|
+
inheritAttrs: false,
|
|
9
|
+
setup(_props, { attrs, slots }) {
|
|
10
|
+
return () => descriptorToVue(renderImageBackground(normalizeVueAttrs(attrs)), slots.default?.() ?? []);
|
|
11
|
+
},
|
|
12
|
+
});
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/** Vue twin of `expo-image`'s `Image`, `ref` gets the handle of the view */
|
|
2
|
+
export declare const Image: import("vue").DefineComponent<{}, () => import("vue").VNode | null, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { defineNativeViewComponent } from '@symbiote-native/vue';
|
|
2
|
+
import { createImageView } from '../core/index.js';
|
|
3
|
+
/** Vue twin of `expo-image`'s `Image`, `ref` gets the handle of the view */
|
|
4
|
+
export const Image = defineNativeViewComponent('Image', createImageView);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { MaybeRefOrGetter, ShallowRef, WatchSource } from '@vue/runtime-core';
|
|
2
|
+
import type { IImageLoadOptions, IImageSource, ImageRef } from '../core';
|
|
3
|
+
/**
|
|
4
|
+
* Vue twin of `expo-image`'s `useImage`, `null` until the first image has loaded
|
|
5
|
+
*
|
|
6
|
+
* It loads again when the uri of the source or a watched `dependencies` source changes
|
|
7
|
+
*/
|
|
8
|
+
export declare function useImage(source: MaybeRefOrGetter<IImageSource | string | number>, options?: MaybeRefOrGetter<IImageLoadOptions>, dependencies?: WatchSource[]): Readonly<ShallowRef<ImageRef | null>>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { shallowRef, toValue, watch } from '@vue/runtime-core';
|
|
2
|
+
import { createImageRefLoader, resolveSource } from '../core/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Vue twin of `expo-image`'s `useImage`, `null` until the first image has loaded
|
|
5
|
+
*
|
|
6
|
+
* It loads again when the uri of the source or a watched `dependencies` source changes
|
|
7
|
+
*/
|
|
8
|
+
export function useImage(source, options = {}, dependencies = []) {
|
|
9
|
+
const image = shallowRef(null);
|
|
10
|
+
watch([() => resolveSource(toValue(source))?.uri, ...dependencies], (_next, _previous, onCleanup) => {
|
|
11
|
+
const loader = createImageRefLoader(loaded => {
|
|
12
|
+
image.value = loaded;
|
|
13
|
+
}, () => toValue(options));
|
|
14
|
+
loader.load(toValue(source));
|
|
15
|
+
onCleanup(loader.cancel);
|
|
16
|
+
}, { immediate: true });
|
|
17
|
+
return image;
|
|
18
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { NativeViewBase } from '@symbiote-native/angular';
|
|
2
|
+
import type { IDescriptor } from '@symbiote-native/components';
|
|
3
|
+
import type { IStyleProp } from '@symbiote-native/engine';
|
|
4
|
+
import type { IImageStyle, IImageViewProps } from '../../core';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
declare const IMAGE_INPUTS: readonly ["source", "placeholder", "contentFit", "placeholderContentFit", "contentPosition", "transition", "blurRadius", "tintColor", "priority", "loading", "cachePolicy", "responsivePolicy", "recyclingKey", "autoplay", "sfEffect", "onLoadStart", "onLoad", "onProgress", "onError", "onLoadEnd", "onDisplay", "defaultSource", "loadingIndicatorSource", "resizeMode", "fadeDuration", "alt", "enableLiveTextInteraction", "allowDownscaling", "decodeFormat", "useAppleWebpCodec", "enforceEarlyResizing", "preferHighDynamicRange", "draggable"];
|
|
7
|
+
export interface ExpoImage extends Partial<Pick<IImageViewProps, (typeof IMAGE_INPUTS)[number]>> {
|
|
8
|
+
}
|
|
9
|
+
/** Angular twin of `expo-image`'s `Image`, `Image` itself is a primitive tag of the adapter */
|
|
10
|
+
export declare class ExpoImage extends NativeViewBase {
|
|
11
|
+
style?: IStyleProp<IImageStyle>;
|
|
12
|
+
private readonly view;
|
|
13
|
+
readonly startAnimating: () => Promise<void>;
|
|
14
|
+
readonly stopAnimating: () => Promise<void>;
|
|
15
|
+
readonly lockResourceAsync: () => Promise<void>;
|
|
16
|
+
readonly unlockResourceAsync: () => Promise<void>;
|
|
17
|
+
readonly reloadAsync: () => Promise<void>;
|
|
18
|
+
protected readonly propNames: readonly ["source", "placeholder", "contentFit", "placeholderContentFit", "contentPosition", "transition", "blurRadius", "tintColor", "priority", "loading", "cachePolicy", "responsivePolicy", "recyclingKey", "autoplay", "sfEffect", "onLoadStart", "onLoad", "onProgress", "onError", "onLoadEnd", "onDisplay", "defaultSource", "loadingIndicatorSource", "resizeMode", "fadeDuration", "alt", "enableLiveTextInteraction", "allowDownscaling", "decodeFormat", "useAppleWebpCodec", "enforceEarlyResizing", "preferHighDynamicRange", "draggable"];
|
|
19
|
+
protected renderView(props: object): IDescriptor | null;
|
|
20
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ExpoImage, never>;
|
|
21
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ExpoImage, "ExpoImage", never, { "source": { "alias": "source"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "contentFit": { "alias": "contentFit"; "required": false; }; "placeholderContentFit": { "alias": "placeholderContentFit"; "required": false; }; "contentPosition": { "alias": "contentPosition"; "required": false; }; "transition": { "alias": "transition"; "required": false; }; "blurRadius": { "alias": "blurRadius"; "required": false; }; "tintColor": { "alias": "tintColor"; "required": false; }; "priority": { "alias": "priority"; "required": false; }; "loading": { "alias": "loading"; "required": false; }; "cachePolicy": { "alias": "cachePolicy"; "required": false; }; "responsivePolicy": { "alias": "responsivePolicy"; "required": false; }; "recyclingKey": { "alias": "recyclingKey"; "required": false; }; "autoplay": { "alias": "autoplay"; "required": false; }; "sfEffect": { "alias": "sfEffect"; "required": false; }; "onLoadStart": { "alias": "onLoadStart"; "required": false; }; "onLoad": { "alias": "onLoad"; "required": false; }; "onProgress": { "alias": "onProgress"; "required": false; }; "onError": { "alias": "onError"; "required": false; }; "onLoadEnd": { "alias": "onLoadEnd"; "required": false; }; "onDisplay": { "alias": "onDisplay"; "required": false; }; "defaultSource": { "alias": "defaultSource"; "required": false; }; "loadingIndicatorSource": { "alias": "loadingIndicatorSource"; "required": false; }; "resizeMode": { "alias": "resizeMode"; "required": false; }; "fadeDuration": { "alias": "fadeDuration"; "required": false; }; "alt": { "alias": "alt"; "required": false; }; "enableLiveTextInteraction": { "alias": "enableLiveTextInteraction"; "required": false; }; "allowDownscaling": { "alias": "allowDownscaling"; "required": false; }; "decodeFormat": { "alias": "decodeFormat"; "required": false; }; "useAppleWebpCodec": { "alias": "useAppleWebpCodec"; "required": false; }; "enforceEarlyResizing": { "alias": "enforceEarlyResizing"; "required": false; }; "preferHighDynamicRange": { "alias": "preferHighDynamicRange"; "required": false; }; "draggable": { "alias": "draggable"; "required": false; }; }, {}, never, never, true, never>;
|
|
22
|
+
}
|
|
23
|
+
export {};
|