@symbiote-native/linear-gradient 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.
Files changed (75) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +196 -2
  3. package/build/angular/index.d.ts +2 -0
  4. package/build/angular/index.js +3 -0
  5. package/build/angular/linear-gradient/index.android.d.ts +4 -0
  6. package/build/angular/linear-gradient/index.android.js +67 -0
  7. package/build/angular/linear-gradient/index.d.ts +1 -0
  8. package/build/angular/linear-gradient/index.ios.d.ts +5 -0
  9. package/build/angular/linear-gradient/index.ios.js +76 -0
  10. package/build/angular/linear-gradient/index.js +2 -0
  11. package/build/angular/linear-gradient/shared.d.ts +12 -0
  12. package/build/angular/linear-gradient/shared.js +97 -0
  13. package/build/core/index.d.ts +1 -0
  14. package/build/core/index.js +1 -0
  15. package/build/core/linear-gradient.d.ts +33 -0
  16. package/build/core/linear-gradient.js +105 -0
  17. package/build/react/index.d.ts +3 -0
  18. package/build/react/index.js +3 -0
  19. package/build/react/linear-gradient.d.ts +9 -0
  20. package/build/react/linear-gradient.js +7 -0
  21. package/build/solid/index.d.ts +3 -0
  22. package/build/solid/index.js +3 -0
  23. package/build/solid/linear-gradient.d.ts +10 -0
  24. package/build/solid/linear-gradient.js +4 -0
  25. package/build/svelte/index.d.ts +3 -0
  26. package/build/svelte/index.js +3 -0
  27. package/build/svelte/linear-gradient-props.d.ts +6 -0
  28. package/build/svelte/linear-gradient-props.js +1 -0
  29. package/build/svelte/linear-gradient.svelte +10 -0
  30. package/build/svelte/linear-gradient.svelte.d.ts +4 -0
  31. package/build/vue/index.d.ts +3 -0
  32. package/build/vue/index.js +3 -0
  33. package/build/vue/linear-gradient.d.ts +6 -0
  34. package/build/vue/linear-gradient.js +16 -0
  35. package/build-ngc/angular/index.d.ts +2 -0
  36. package/build-ngc/angular/index.js +4 -0
  37. package/build-ngc/angular/index.js.map +1 -0
  38. package/build-ngc/angular/linear-gradient/index.android.d.ts +7 -0
  39. package/build-ngc/angular/linear-gradient/index.android.js +28 -0
  40. package/build-ngc/angular/linear-gradient/index.android.js.map +1 -0
  41. package/build-ngc/angular/linear-gradient/index.d.ts +1 -0
  42. package/build-ngc/angular/linear-gradient/index.ios.d.ts +8 -0
  43. package/build-ngc/angular/linear-gradient/index.ios.js +37 -0
  44. package/build-ngc/angular/linear-gradient/index.ios.js.map +1 -0
  45. package/build-ngc/angular/linear-gradient/index.js +3 -0
  46. package/build-ngc/angular/linear-gradient/index.js.map +1 -0
  47. package/build-ngc/angular/linear-gradient/shared.d.ts +15 -0
  48. package/build-ngc/angular/linear-gradient/shared.js +39 -0
  49. package/build-ngc/angular/linear-gradient/shared.js.map +1 -0
  50. package/build-ngc/core/index.d.ts +1 -0
  51. package/build-ngc/core/index.js +2 -0
  52. package/build-ngc/core/index.js.map +1 -0
  53. package/build-ngc/core/linear-gradient.d.ts +33 -0
  54. package/build-ngc/core/linear-gradient.js +106 -0
  55. package/build-ngc/core/linear-gradient.js.map +1 -0
  56. package/native-link.json +12 -0
  57. package/package.json +145 -3
  58. package/src/angular/index.ts +10 -0
  59. package/src/angular/linear-gradient/index.android.ts +17 -0
  60. package/src/angular/linear-gradient/index.ios.ts +32 -0
  61. package/src/angular/linear-gradient/index.ts +2 -0
  62. package/src/angular/linear-gradient/shared.ts +27 -0
  63. package/src/core/index.ts +10 -0
  64. package/src/core/linear-gradient.ts +183 -0
  65. package/src/react/index.ts +10 -0
  66. package/src/react/linear-gradient.ts +18 -0
  67. package/src/solid/index.ts +10 -0
  68. package/src/solid/linear-gradient.ts +17 -0
  69. package/src/svelte/index.ts +10 -0
  70. package/src/svelte/linear-gradient-props.ts +9 -0
  71. package/src/svelte/linear-gradient.svelte +10 -0
  72. package/src/svelte/svelte-ambient.d.ts +6 -0
  73. package/src/svelte/svelte-compile.test-helper.ts +6 -0
  74. package/src/vue/index.ts +10 -0
  75. package/src/vue/linear-gradient.ts +23 -0
package/package.json CHANGED
@@ -1,6 +1,148 @@
1
1
  {
2
2
  "name": "@symbiote-native/linear-gradient",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.1.0",
4
+ "description": "expo-linear-gradient wrapped for SymbioteNative — one framework-agnostic core, built once and reachable from the React, Vue, Svelte, Solid, and Angular adapters. A native view that paints a multi-color linear gradient behind its children.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/OneEyed1366/symbiote-native.git",
9
+ "directory": "packages/linear-gradient"
10
+ },
11
+ "homepage": "https://github.com/OneEyed1366/symbiote-native/tree/master/packages/linear-gradient#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/OneEyed1366/symbiote-native/issues"
14
+ },
15
+ "author": "Andrey Prokopenko <psevdoproger@gmail.com>",
16
+ "keywords": [
17
+ "react-native",
18
+ "symbiote-native",
19
+ "expo-linear-gradient",
20
+ "react",
21
+ "vue",
22
+ "svelte",
23
+ "solid",
24
+ "angular",
25
+ "gradient",
26
+ "linear-gradient"
27
+ ],
28
+ "type": "module",
29
+ "main": "./build/core/index.js",
30
+ "module": "./build/core/index.js",
31
+ "types": "./build/core/index.d.ts",
32
+ "exports": {
33
+ ".": {
34
+ "types": "./build/core/index.d.ts",
35
+ "default": "./build/core/index.js"
36
+ },
37
+ "./vue": {
38
+ "types": "./build/vue/index.d.ts",
39
+ "default": "./build/vue/index.js"
40
+ },
41
+ "./react": {
42
+ "types": "./build/react/index.d.ts",
43
+ "default": "./build/react/index.js"
44
+ },
45
+ "./svelte": "./src/svelte/index.ts",
46
+ "./solid": {
47
+ "types": "./build/solid/index.d.ts",
48
+ "default": "./build/solid/index.js"
49
+ },
50
+ "./angular": {
51
+ "types": "./build-ngc/angular/index.d.ts",
52
+ "react-native": "./build-ngc/angular/index.js",
53
+ "default": "./src/angular/index.ts"
54
+ }
55
+ },
56
+ "files": [
57
+ "src",
58
+ "build",
59
+ "build-ngc",
60
+ "native-link.json",
61
+ "!src/**/*.test.*",
62
+ "!src/**/*.spec.*",
63
+ "!src/**/*.detox.*"
64
+ ],
65
+ "publishConfig": {
66
+ "access": "public"
67
+ },
68
+ "dependencies": {
69
+ "expo-linear-gradient": "57.0.2",
70
+ "expo-modules-core": "57.0.20",
71
+ "@symbiote-native/components": "3.2.0"
72
+ },
73
+ "peerDependencies": {
74
+ "@angular/core": ">=20",
75
+ "@vue/runtime-core": "^3.5.13",
76
+ "react": ">=19.0.0",
77
+ "react-native": ">=0.86",
78
+ "solid-js": ">=1.9.0",
79
+ "svelte": ">=5.56.0",
80
+ "vue": ">=3.5.0",
81
+ "@symbiote-native/angular": "^3.3.0",
82
+ "@symbiote-native/engine": "^1.6.0",
83
+ "@symbiote-native/react": "^3.3.0",
84
+ "@symbiote-native/solid": "^3.2.0",
85
+ "@symbiote-native/svelte": "^3.2.0",
86
+ "@symbiote-native/vue": "^3.3.0"
87
+ },
88
+ "peerDependenciesMeta": {
89
+ "@symbiote-native/angular": {
90
+ "optional": true
91
+ },
92
+ "@symbiote-native/react": {
93
+ "optional": true
94
+ },
95
+ "@symbiote-native/solid": {
96
+ "optional": true
97
+ },
98
+ "@symbiote-native/svelte": {
99
+ "optional": true
100
+ },
101
+ "@symbiote-native/vue": {
102
+ "optional": true
103
+ },
104
+ "@angular/core": {
105
+ "optional": true
106
+ },
107
+ "@vue/runtime-core": {
108
+ "optional": true
109
+ },
110
+ "react": {
111
+ "optional": true
112
+ },
113
+ "solid-js": {
114
+ "optional": true
115
+ },
116
+ "svelte": {
117
+ "optional": true
118
+ },
119
+ "vue": {
120
+ "optional": true
121
+ }
122
+ },
123
+ "devDependencies": {
124
+ "@angular/compiler": "~22.0.8",
125
+ "@angular/compiler-cli": "~22.0.8",
126
+ "@angular/core": "~22.0.8",
127
+ "@types/node": "^26.0.0",
128
+ "@types/react": "^19.2.0",
129
+ "@vue/runtime-core": "^3.5.13",
130
+ "react": "19.2.3",
131
+ "solid-js": "^1.9.14",
132
+ "svelte": "^5.56.0",
133
+ "typescript": "~6.0.0",
134
+ "@symbiote-native/angular": "3.3.0",
135
+ "@symbiote-native/engine": "1.6.0",
136
+ "@symbiote-native/react": "3.3.0",
137
+ "@symbiote-native/solid": "3.2.0",
138
+ "@symbiote-native/svelte": "3.2.0",
139
+ "@symbiote-native/test-utils": "0.4.7",
140
+ "@symbiote-native/vue": "3.3.0"
141
+ },
142
+ "scripts": {
143
+ "typecheck": "tsc --build",
144
+ "clean": "rm -rf build-ngc",
145
+ "ng:build": "pnpm run clean && ngc -p tsconfig.angular.json",
146
+ "format": "prettier --write \"src/**/*.{ts,tsx}\""
147
+ }
6
148
  }
@@ -0,0 +1,10 @@
1
+ // @symbiote-native/linear-gradient/angular: компонент `LinearGradient` поверх общего ядра
2
+
3
+ export { LinearGradient } from './linear-gradient';
4
+ export {
5
+ LINEAR_GRADIENT_MODULE_NAME,
6
+ linearGradientViewName,
7
+ type ILinearGradientProps,
8
+ type ILinearGradientPoint,
9
+ type INativeLinearGradientPoint,
10
+ } from '../core';
@@ -0,0 +1,17 @@
1
+ import { ChangeDetectionStrategy, Component } from '@angular/core';
2
+ import { DescriptorHost } from '@symbiote-native/angular';
3
+ import { LinearGradientBase } from './shared';
4
+
5
+ /** Angular twin of `expo-linear-gradient`'s `LinearGradient`, a View wraps the gradient leaf */
6
+ @Component({
7
+ selector: 'LinearGradient',
8
+ standalone: true,
9
+ imports: [DescriptorHost],
10
+ changeDetection: ChangeDetectionStrategy.OnPush,
11
+ template: `@if (descriptor; as node) {
12
+ <symbiote-descriptor-host [node]="node"
13
+ ><ng-content
14
+ /></symbiote-descriptor-host>
15
+ }`,
16
+ })
17
+ export class LinearGradient extends LinearGradientBase {}
@@ -0,0 +1,32 @@
1
+ import {
2
+ ChangeDetectionStrategy,
3
+ Component,
4
+ NO_ERRORS_SCHEMA,
5
+ } from '@angular/core';
6
+ import { SymbioteHostPropsDirective } from '@symbiote-native/angular';
7
+ import { warnIfViewNameIsDynamic } from '@symbiote-native/engine';
8
+ import { LINEAR_GRADIENT_MODULE_NAME } from '../../core';
9
+ import { LinearGradientBase } from './shared';
10
+
11
+ const TEMPLATE_TAG = 'ViewManagerAdapter_ExpoLinearGradient';
12
+
13
+ /** Angular twin of `expo-linear-gradient`'s `LinearGradient`, children go inside the native view */
14
+ @Component({
15
+ selector: 'LinearGradient',
16
+ standalone: true,
17
+ imports: [SymbioteHostPropsDirective],
18
+ schemas: [NO_ERRORS_SCHEMA],
19
+ changeDetection: ChangeDetectionStrategy.OnPush,
20
+ // Имя тега это нативное имя view, его нельзя собрать динамически
21
+ template: `@if (descriptor; as node) {
22
+ <ViewManagerAdapter_ExpoLinearGradient [symbioteHostProps]="node.props">
23
+ <ng-content />
24
+ </ViewManagerAdapter_ExpoLinearGradient>
25
+ }`,
26
+ })
27
+ export class LinearGradient extends LinearGradientBase {
28
+ constructor() {
29
+ super();
30
+ warnIfViewNameIsDynamic(TEMPLATE_TAG, LINEAR_GRADIENT_MODULE_NAME);
31
+ }
32
+ }
@@ -0,0 +1,2 @@
1
+ // Базовая точка для headless и tsc, Metro берёт `index.ios` или `index.android`
2
+ export { LinearGradient } from './index.ios';
@@ -0,0 +1,27 @@
1
+ import { Directive, Input } from '@angular/core';
2
+ import { NativeViewBase } from '@symbiote-native/angular';
3
+ import type { IDescriptor } from '@symbiote-native/components';
4
+ import { renderLinearGradient } from '../../core/linear-gradient';
5
+ import type { ILinearGradientProps } from '../../core/linear-gradient';
6
+
7
+ // Inputs и сборка дескриптора общие, платформы различаются только шаблоном
8
+ @Directive()
9
+ export abstract class LinearGradientBase extends NativeViewBase {
10
+ @Input({ required: true }) colors!: ILinearGradientProps['colors'];
11
+ @Input() locations?: ILinearGradientProps['locations'];
12
+ @Input() start?: ILinearGradientProps['start'];
13
+ @Input() end?: ILinearGradientProps['end'];
14
+ @Input() dither?: ILinearGradientProps['dither'];
15
+
16
+ protected override readonly propNames = [
17
+ 'colors',
18
+ 'locations',
19
+ 'start',
20
+ 'end',
21
+ 'dither',
22
+ ] as const satisfies readonly (keyof LinearGradientBase)[];
23
+
24
+ protected override renderView(props: object): IDescriptor {
25
+ return renderLinearGradient(props);
26
+ }
27
+ }
@@ -0,0 +1,10 @@
1
+ export {
2
+ LINEAR_GRADIENT_MODULE_NAME,
3
+ ensureLinearGradientRegistered,
4
+ linearGradientViewName,
5
+ normalizePoint,
6
+ renderLinearGradient,
7
+ type ILinearGradientPoint,
8
+ type ILinearGradientProps,
9
+ type INativeLinearGradientPoint,
10
+ } from './linear-gradient';
@@ -0,0 +1,183 @@
1
+ // Ядро `LinearGradient`, порт `LinearGradient.tsx` из expo-linear-gradient
2
+ import { Platform, requireNativeViewManager } from 'expo-modules-core';
3
+ import { el } from '@symbiote-native/components';
4
+ import type {
5
+ IAccessibilityProps,
6
+ IAriaProps,
7
+ IDescriptor,
8
+ IResponderProps,
9
+ } from '@symbiote-native/components';
10
+ import {
11
+ expoViewManagerName,
12
+ flattenStyle,
13
+ processColor,
14
+ styleOfProps,
15
+ tryRegisterNativeView,
16
+ } from '@symbiote-native/engine';
17
+ import type {
18
+ IColorValue,
19
+ IStyleProp,
20
+ ISymbioteEvent,
21
+ IViewStyle,
22
+ } from '@symbiote-native/engine';
23
+
24
+ export const LINEAR_GRADIENT_MODULE_NAME = 'ExpoLinearGradient';
25
+
26
+ export type INativeLinearGradientPoint = [x: number, y: number];
27
+
28
+ /** Доли размера градиента от 0 до 1, объект `{ x, y }` или пара `[x, y]` */
29
+ export type ILinearGradientPoint =
30
+ { x: number; y: number } | INativeLinearGradientPoint;
31
+
32
+ export type ILinearGradientProps = IAccessibilityProps &
33
+ IAriaProps &
34
+ IResponderProps & {
35
+ /** Минимум два цвета, для одного используйте `style.backgroundColor` у View */
36
+ colors: readonly [IColorValue, IColorValue, ...IColorValue[]];
37
+ /** Позиции остановок от 0 до 1 по возрастанию, той же длины, что и `colors` */
38
+ locations?: readonly [number, number, ...number[]] | null;
39
+ /** @default { x: 0.5, y: 0.0 } */
40
+ start?: ILinearGradientPoint | null;
41
+ /** @default { x: 0.5, y: 1.0 } */
42
+ end?: ILinearGradientPoint | null;
43
+ /**
44
+ * Дизеринг убирает полосы в градиенте, false может ускорить отрисовку
45
+ * @default true
46
+ * @platform android
47
+ */
48
+ dither?: boolean;
49
+ style?: IStyleProp<IViewStyle>;
50
+ testID?: string;
51
+ nativeID?: string;
52
+ onLayout?: (event: ISymbioteEvent) => void;
53
+ };
54
+
55
+ // Эти ключи разбираются здесь, остальное уходит на хост как есть
56
+ const GRADIENT_KEYS: ReadonlySet<string> = new Set<keyof ILinearGradientProps>([
57
+ 'colors',
58
+ 'locations',
59
+ 'start',
60
+ 'end',
61
+ 'dither',
62
+ ]);
63
+
64
+ const ABSOLUTE_FILL = {
65
+ position: 'absolute',
66
+ left: 0,
67
+ right: 0,
68
+ top: 0,
69
+ bottom: 0,
70
+ };
71
+
72
+ export function linearGradientViewName(): string {
73
+ return expoViewManagerName(LINEAR_GRADIENT_MODULE_NAME);
74
+ }
75
+
76
+ // Регистрирует view config в реестре RN, из него движок берёт события и процессоры пропсов
77
+ // Зовётся при рендере, а не при импорте: регистрация в побочном эффекте барреля теряется в release
78
+ export function ensureLinearGradientRegistered(): boolean {
79
+ return tryRegisterNativeView(() =>
80
+ requireNativeViewManager(LINEAR_GRADIENT_MODULE_NAME),
81
+ );
82
+ }
83
+
84
+ function isNumber(value: unknown): value is number {
85
+ return typeof value === 'number';
86
+ }
87
+
88
+ export function normalizePoint(
89
+ point: unknown,
90
+ ): INativeLinearGradientPoint | undefined {
91
+ if (!point) return undefined;
92
+ if (Array.isArray(point)) {
93
+ const [x, y] = point;
94
+ if (point.length === 2 && isNumber(x) && isNumber(y)) return [x, y];
95
+ console.warn(
96
+ 'start and end props for LinearGradient must be of the format [x,y] or {x, y}',
97
+ );
98
+ return undefined;
99
+ }
100
+ const x: unknown = Reflect.get(Object(point), 'x');
101
+ const y: unknown = Reflect.get(Object(point), 'y');
102
+ return isNumber(x) && isNumber(y) ? [x, y] : undefined;
103
+ }
104
+
105
+ function resolveLocations(
106
+ colors: readonly unknown[],
107
+ locations: unknown,
108
+ ): readonly number[] | undefined {
109
+ if (!Array.isArray(locations)) return undefined;
110
+ if (locations.length === colors.length) return locations;
111
+ console.warn(
112
+ 'LinearGradient colors and locations props should be arrays of the same length',
113
+ );
114
+ return locations.slice(0, colors.length);
115
+ }
116
+
117
+ function radiusOr(value: unknown, fallback: number): number {
118
+ return isNumber(value) ? value : fallback;
119
+ }
120
+
121
+ // Формат из `Path.addRoundRect`: по два значения на угол, начиная с верхнего левого
122
+ function borderRadiiOf(style: unknown): number[] {
123
+ const flat = flattenStyle(style) ?? {};
124
+ const base = radiusOr(flat.borderRadius, 0);
125
+ const topLeft = radiusOr(flat.borderTopLeftRadius, base);
126
+ const topRight = radiusOr(flat.borderTopRightRadius, base);
127
+ const bottomRight = radiusOr(flat.borderBottomRightRadius, base);
128
+ const bottomLeft = radiusOr(flat.borderBottomLeftRadius, base);
129
+ return [
130
+ topLeft,
131
+ topLeft,
132
+ topRight,
133
+ topRight,
134
+ bottomRight,
135
+ bottomRight,
136
+ bottomLeft,
137
+ bottomLeft,
138
+ ];
139
+ }
140
+
141
+ function withoutUndefined(
142
+ props: Record<string, unknown>,
143
+ ): Record<string, unknown> {
144
+ return Object.fromEntries(
145
+ Object.entries(props).filter(([, value]) => value !== undefined),
146
+ );
147
+ }
148
+
149
+ // `object`, а не тип пропсов: Vue и Angular отдают нетипизированный набор атрибутов
150
+ export function renderLinearGradient(props: object): IDescriptor {
151
+ const hostProps = Object.fromEntries(
152
+ Object.entries(props).filter(([key]) => !GRADIENT_KEYS.has(key)),
153
+ );
154
+ if (!ensureLinearGradientRegistered()) {
155
+ console.warn('LinearGradient is not available on this platform');
156
+ return el('view', hostProps);
157
+ }
158
+
159
+ const colors: unknown = Reflect.get(props, 'colors');
160
+ const colorList = Array.isArray(colors) ? colors : [];
161
+ const nativeProps = withoutUndefined({
162
+ colors: colorList.map(color => processColor(color)),
163
+ locations: resolveLocations(colorList, Reflect.get(props, 'locations')),
164
+ startPoint: normalizePoint(Reflect.get(props, 'start')),
165
+ endPoint: normalizePoint(Reflect.get(props, 'end')),
166
+ });
167
+
168
+ if (!Platform.select({ android: true, default: false })) {
169
+ return el(linearGradientViewName(), { ...hostProps, ...nativeProps });
170
+ }
171
+
172
+ // Нативный градиент заполняет View и сам скругляет углы, т.к. RN не обрезает по радиусу
173
+ const native = el(
174
+ linearGradientViewName(),
175
+ withoutUndefined({
176
+ ...nativeProps,
177
+ style: ABSOLUTE_FILL,
178
+ borderRadii: borderRadiiOf(styleOfProps(props)),
179
+ dither: Reflect.get(props, 'dither'),
180
+ }),
181
+ );
182
+ return el('view', hostProps, [native]);
183
+ }
@@ -0,0 +1,10 @@
1
+ // @symbiote-native/linear-gradient/react: компонент `LinearGradient` поверх общего ядра
2
+
3
+ export { LinearGradient } from './linear-gradient';
4
+ export type { ILinearGradientProps } from './linear-gradient';
5
+ export {
6
+ LINEAR_GRADIENT_MODULE_NAME,
7
+ linearGradientViewName,
8
+ type ILinearGradientPoint,
9
+ type INativeLinearGradientPoint,
10
+ } from '../core';
@@ -0,0 +1,18 @@
1
+ import type { ReactElement, ReactNode } from 'react';
2
+ import { descriptorToReactWithChildren } from '@symbiote-native/react';
3
+ import type { IViewProps } from '@symbiote-native/react';
4
+ import { renderLinearGradient } from '../core/linear-gradient';
5
+ import type { ILinearGradientProps as ILinearGradientBaseProps } from '../core/linear-gradient';
6
+
7
+ // Поверхность View как у `ViewProps` в upstream, дети и `className` свои у React
8
+ export type ILinearGradientProps = ILinearGradientBaseProps &
9
+ Omit<IViewProps, keyof ILinearGradientBaseProps | 'children'> & {
10
+ children?: ReactNode;
11
+ className?: string;
12
+ };
13
+
14
+ /** React twin of `expo-linear-gradient`'s `LinearGradient`, children paint over the gradient */
15
+ export function LinearGradient(props: ILinearGradientProps): ReactElement {
16
+ const { children, ...rest } = props;
17
+ return descriptorToReactWithChildren(renderLinearGradient(rest), children);
18
+ }
@@ -0,0 +1,10 @@
1
+ // @symbiote-native/linear-gradient/solid: компонент `LinearGradient` поверх общего ядра
2
+
3
+ export { LinearGradient } from './linear-gradient';
4
+ export type { ILinearGradientProps } from './linear-gradient';
5
+ export {
6
+ LINEAR_GRADIENT_MODULE_NAME,
7
+ linearGradientViewName,
8
+ type ILinearGradientPoint,
9
+ type INativeLinearGradientPoint,
10
+ } from '../core';
@@ -0,0 +1,17 @@
1
+ import type { JSX } from 'solid-js';
2
+ import { defineDescriptorComponent } from '@symbiote-native/solid';
3
+ import type { IViewProps } from '@symbiote-native/solid';
4
+ import type { IClassNameValue } from '@symbiote-native/engine';
5
+ import { renderLinearGradient } from '../core/linear-gradient';
6
+ import type { ILinearGradientProps as ILinearGradientBaseProps } from '../core/linear-gradient';
7
+
8
+ // Поверхность View как у `ViewProps` в upstream, дети и `class` свои у Solid
9
+ export type ILinearGradientProps = ILinearGradientBaseProps &
10
+ Omit<IViewProps, keyof ILinearGradientBaseProps | 'children' | 'ref'> & {
11
+ children?: JSX.Element;
12
+ class?: IClassNameValue;
13
+ };
14
+
15
+ /** Solid twin of `expo-linear-gradient`'s `LinearGradient`, children paint over the gradient */
16
+ export const LinearGradient =
17
+ defineDescriptorComponent<ILinearGradientProps>(renderLinearGradient);
@@ -0,0 +1,10 @@
1
+ // @symbiote-native/linear-gradient/svelte: компонент `LinearGradient` поверх общего ядра
2
+
3
+ export { default as LinearGradient } from './linear-gradient.svelte';
4
+ export type { ILinearGradientProps } from './linear-gradient-props';
5
+ export {
6
+ LINEAR_GRADIENT_MODULE_NAME,
7
+ linearGradientViewName,
8
+ type ILinearGradientPoint,
9
+ type INativeLinearGradientPoint,
10
+ } from '../core';
@@ -0,0 +1,9 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { IViewProps } from '@symbiote-native/svelte';
3
+ import type { ILinearGradientProps as ILinearGradientBaseProps } from '../core/linear-gradient';
4
+
5
+ // Поверхность View как у `ViewProps` в upstream, дети идут сниппетом
6
+ export type ILinearGradientProps = ILinearGradientBaseProps &
7
+ Omit<IViewProps, keyof ILinearGradientBaseProps | 'children'> & {
8
+ children?: Snippet;
9
+ };
@@ -0,0 +1,10 @@
1
+ <script lang="ts">
2
+ import DescriptorHost from '@symbiote-native/svelte/descriptor-host';
3
+ import { renderLinearGradient } from '../core/linear-gradient';
4
+ import type { ILinearGradientProps } from './linear-gradient-props';
5
+
6
+ const { children, ...rest }: ILinearGradientProps = $props();
7
+ const descriptor = $derived(renderLinearGradient({ ...rest }));
8
+ </script>
9
+
10
+ <DescriptorHost {descriptor} {children} />
@@ -0,0 +1,6 @@
1
+ // Pulls in svelte's ambient global declarations ($state/$effect/...) for this package's tsc
2
+ // program. adapters/svelte gets these for free because render.ts does a real value import from
3
+ // 'svelte' (any file in a program importing a module loads its ambient globals for the whole
4
+ // program); this package has no such import, so a triple-slash reference does the same job
5
+ // explicitly rather than relying on an incidental side-effect.
6
+ /// <reference types="svelte" />
@@ -0,0 +1,6 @@
1
+ // Re-exports the existing harness instead of another copy
2
+ export {
3
+ createSvelteHarness,
4
+ loadComponent,
5
+ type ISvelteHarness,
6
+ } from '../../../sqlite/src/svelte/svelte-compile.test-helper';
@@ -0,0 +1,10 @@
1
+ // @symbiote-native/linear-gradient/vue: компонент `LinearGradient` поверх общего ядра
2
+
3
+ export { LinearGradient } from './linear-gradient';
4
+ export type { ILinearGradientProps } from './linear-gradient';
5
+ export {
6
+ LINEAR_GRADIENT_MODULE_NAME,
7
+ linearGradientViewName,
8
+ type ILinearGradientPoint,
9
+ type INativeLinearGradientPoint,
10
+ } from '../core';
@@ -0,0 +1,23 @@
1
+ import { defineComponent, type VNode } from '@vue/runtime-core';
2
+ import { descriptorToVue, normalizeVueAttrs } from '@symbiote-native/vue';
3
+ import type { IViewProps } from '@symbiote-native/vue';
4
+ import { renderLinearGradient } from '../core/linear-gradient';
5
+ import type { ILinearGradientProps as ILinearGradientBaseProps } from '../core/linear-gradient';
6
+
7
+ // Поверхность View как у `ViewProps` в upstream, дети идут слотом по умолчанию
8
+ export type ILinearGradientProps = ILinearGradientBaseProps &
9
+ Omit<IViewProps, keyof ILinearGradientBaseProps>;
10
+
11
+ /** Vue twin of `expo-linear-gradient`'s `LinearGradient`, the default slot paints over it */
12
+ export const LinearGradient = defineComponent({
13
+ name: 'LinearGradient',
14
+ // Все атрибуты это пропсы нативного view, на обёртку ничего не должно просочиться
15
+ inheritAttrs: false,
16
+ setup(_props, { attrs, slots }) {
17
+ return (): VNode => {
18
+ const descriptor = renderLinearGradient(normalizeVueAttrs(attrs));
19
+ // Слот приложения идёт в корень после собственных детей дескриптора
20
+ return descriptorToVue(descriptor, slots.default?.() ?? []);
21
+ };
22
+ },
23
+ });