@piying/view-svelte 1.4.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/builder.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import { FormBuilder } from '@piying/view-core';
2
+ import type { SvelteSchemaHandle } from './svelte-schema';
3
+ export declare class SvelteFormBuilder extends FormBuilder<SvelteSchemaHandle> {
4
+ }
package/builder.js ADDED
@@ -0,0 +1,24 @@
1
+ var __extends = (this && this.__extends) || (function () {
2
+ var extendStatics = function (d, b) {
3
+ extendStatics = Object.setPrototypeOf ||
4
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
5
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
6
+ return extendStatics(d, b);
7
+ };
8
+ return function (d, b) {
9
+ if (typeof b !== "function" && b !== null)
10
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
11
+ extendStatics(d, b);
12
+ function __() { this.constructor = d; }
13
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
14
+ };
15
+ })();
16
+ import { FormBuilder } from '@piying/view-core';
17
+ var SvelteFormBuilder = /** @class */ (function (_super) {
18
+ __extends(SvelteFormBuilder, _super);
19
+ function SvelteFormBuilder() {
20
+ return _super !== null && _super.apply(this, arguments) || this;
21
+ }
22
+ return SvelteFormBuilder;
23
+ }(FormBuilder));
24
+ export { SvelteFormBuilder };
@@ -0,0 +1,73 @@
1
+ <script lang="ts">
2
+ import type { PiResolvedViewFieldConfig } from '../type/group';
3
+ import { signalToRef } from '../util/signal-convert.svelte';
4
+ import { PI_VIEW_FIELD_TOKEN, InjectorToken } from '../token';
5
+ import { createViewControlLink, getLazyImport, isLazyMark } from '@piying/view-core';
6
+ import { getContext, setContext } from 'svelte';
7
+ import type { Injector } from 'static-injector';
8
+ import PiWrapper from './wrapper.svelte';
9
+ const props: {
10
+ field: PiResolvedViewFieldConfig;
11
+ } = $props();
12
+ const injector = getContext<Injector>(InjectorToken)!;
13
+ const fieldInputs = signalToRef(() => {
14
+ return {
15
+ ...props.field.attributes(),
16
+ ...props.field.inputs(),
17
+ // todo outputs不应该加signal,因为没必要动态更新?
18
+ ...props.field.outputs()
19
+ };
20
+ });
21
+ let controlRef = $state<any>();
22
+ const renderConfig = signalToRef(() => props.field.renderConfig());
23
+ const control = $derived.by(() => props.field.form.control);
24
+ $effect.pre(() => {
25
+ let dispose: (() => any) | undefined;
26
+ if (controlRef?.cva) {
27
+ dispose = createViewControlLink((() => control) as any, controlRef?.cva, injector);
28
+ }
29
+ return () => {
30
+ dispose?.();
31
+ dispose = undefined;
32
+ };
33
+ });
34
+ const fieldChildren = signalToRef(() => props.field.children?.());
35
+
36
+ const wrappers = signalToRef(() => props.field.wrappers());
37
+ const ComponentType = $derived.by(() => {
38
+ return props.field.define?.type;
39
+ });
40
+ const isLazy = $derived.by(() => {
41
+ return isLazyMark(props.field.define?.type);
42
+ });
43
+ const loading = $derived.by(() => {
44
+ return getLazyImport<() => Promise<any>>(props.field.define?.type)!();
45
+ });
46
+ const field = $derived(props.field);
47
+ setContext(PI_VIEW_FIELD_TOKEN, () => field);
48
+ </script>
49
+
50
+ {#if !renderConfig()?.hidden}
51
+ {#if field.define?.type}
52
+ {#snippet children()}
53
+ {#if isLazy}
54
+ {#await loading then LazyComponent}
55
+ {#if fieldChildren()}
56
+ <LazyComponent {...fieldInputs()}></LazyComponent>
57
+ {:else if field.form.control}
58
+ <LazyComponent {...fieldInputs()} bind:this={controlRef}></LazyComponent>
59
+ {:else}
60
+ <LazyComponent {...fieldInputs()}></LazyComponent>
61
+ {/if}
62
+ {/await}
63
+ {:else if fieldChildren()}
64
+ <ComponentType {...fieldInputs()}></ComponentType>
65
+ {:else if field.form.control}
66
+ <ComponentType {...fieldInputs()} bind:this={controlRef}></ComponentType>
67
+ {:else}
68
+ <ComponentType {...fieldInputs()}></ComponentType>
69
+ {/if}
70
+ {/snippet}
71
+ <PiWrapper wrappers={wrappers()!} {children}></PiWrapper>
72
+ {/if}
73
+ {/if}
@@ -0,0 +1,7 @@
1
+ import type { PiResolvedViewFieldConfig } from '../type/group';
2
+ type $$ComponentProps = {
3
+ field: PiResolvedViewFieldConfig;
4
+ };
5
+ declare const FieldTemplate: import("svelte").Component<$$ComponentProps, {}, "">;
6
+ type FieldTemplate = ReturnType<typeof FieldTemplate>;
7
+ export default FieldTemplate;
@@ -0,0 +1,13 @@
1
+ <script lang="ts">
2
+ import FieldTemplate from './field-template.svelte';
3
+ import { getContext } from 'svelte';
4
+ import { PI_VIEW_FIELD_TOKEN } from '../token';
5
+ import { signalToRef } from '../util/signal-convert.svelte';
6
+
7
+ const field = getContext<PI_VIEW_FIELD_TOKEN>(PI_VIEW_FIELD_TOKEN);
8
+ const children = signalToRef(() => field().children!())!;
9
+ </script>
10
+
11
+ {#each children()! as field, i (i)}
12
+ <FieldTemplate {field}></FieldTemplate>
13
+ {/each}
@@ -0,0 +1,18 @@
1
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
2
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
3
+ $$bindings?: Bindings;
4
+ } & Exports;
5
+ (internal: unknown, props: {
6
+ $$events?: Events;
7
+ $$slots?: Slots;
8
+ }): Exports & {
9
+ $set?: any;
10
+ $on?: any;
11
+ };
12
+ z_$$bindings?: Bindings;
13
+ }
14
+ declare const Group: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
15
+ [evt: string]: CustomEvent<any>;
16
+ }, {}, {}, string>;
17
+ type Group = InstanceType<typeof Group>;
18
+ export default Group;
@@ -0,0 +1,80 @@
1
+ <script lang="ts">
2
+ import * as v from 'valibot';
3
+ import { convert } from '@piying/view-core';
4
+ import {
5
+ ChangeDetectionScheduler,
6
+ ChangeDetectionSchedulerImpl,
7
+ createInjector,
8
+ createRootInjector,
9
+ DestroyRef,
10
+ untracked,
11
+ type EffectRef
12
+ } from 'static-injector';
13
+ import type { Injector } from 'static-injector';
14
+ import { setContext, untrack } from 'svelte';
15
+ import { InjectorToken } from '../token';
16
+ import { SvelteSchemaHandle } from '../svelte-schema';
17
+ import { SvelteFormBuilder } from '../builder';
18
+ import FieldTemplate from './field-template.svelte';
19
+ import { initListen } from '@piying/view-core';
20
+ let props: {
21
+ schema: v.BaseSchema<any, any, any> | v.SchemaWithPipe<any>;
22
+ model?: any;
23
+ modelChange?: (value: any) => void;
24
+ options: any;
25
+ } = $props();
26
+
27
+ const rootInjector = createRootInjector({
28
+ providers: [
29
+ {
30
+ provide: ChangeDetectionScheduler,
31
+ useClass: ChangeDetectionSchedulerImpl
32
+ }
33
+ ]
34
+ });
35
+ setContext(InjectorToken, rootInjector);
36
+ const [field, subInjector] = $derived.by(() => {
37
+ const subInjector = createInjector({ providers: [], parent: rootInjector });
38
+
39
+ const field = convert(props.schema as any, {
40
+ handle: SvelteSchemaHandle as any,
41
+ builder: SvelteFormBuilder,
42
+ injector: subInjector,
43
+ registerOnDestroy: (fn) => {
44
+ subInjector!.get(DestroyRef).onDestroy(() => {
45
+ fn();
46
+ });
47
+ },
48
+ ...props.options
49
+ });
50
+ return [field, subInjector];
51
+ });
52
+ $effect.pre(() => {
53
+ let ref: EffectRef | undefined;
54
+ if (field.form.control) {
55
+ const model = untrack(() => props.model);
56
+ ref = initListen(
57
+ typeof model !== 'undefined' ? model : undefined,
58
+ field!.form.control!,
59
+ subInjector as Injector,
60
+ (value) => {
61
+ untracked(() => {
62
+ if (field!.form.control?.valueNoError$$()) {
63
+ props.modelChange?.(value);
64
+ }
65
+ });
66
+ }
67
+ );
68
+ }
69
+ return () => {
70
+ subInjector.destroy();
71
+ ref?.destroy();
72
+ };
73
+ });
74
+
75
+ $effect.pre(() => {
76
+ field!.form.control?.updateValue(props.model);
77
+ });
78
+ </script>
79
+
80
+ <FieldTemplate {field}></FieldTemplate>
@@ -0,0 +1,10 @@
1
+ import * as v from 'valibot';
2
+ type $$ComponentProps = {
3
+ schema: v.BaseSchema<any, any, any> | v.SchemaWithPipe<any>;
4
+ model?: any;
5
+ modelChange?: (value: any) => void;
6
+ options: any;
7
+ };
8
+ declare const PiyingView: import("svelte").Component<$$ComponentProps, {}, "">;
9
+ type PiyingView = ReturnType<typeof PiyingView>;
10
+ export default PiyingView;
@@ -0,0 +1,25 @@
1
+ <script lang="ts">
2
+ import type { CoreResolvedWrapperConfig } from '@piying/view-core';
3
+ import { signalToRef } from '../util/signal-convert.svelte';
4
+ import PiWrapper from './wrapper.svelte';
5
+ const dProps: {
6
+ wrappers: CoreResolvedWrapperConfig[];
7
+ children: any;
8
+ } = $props();
9
+ const restWrappers = $derived.by(() => dProps.wrappers!.slice(1));
10
+ const wrapper = $derived.by(() => dProps.wrappers?.[0]);
11
+ const inputs = signalToRef(() => ({
12
+ ...wrapper?.inputs(),
13
+ ...wrapper?.attributes(),
14
+ ...wrapper?.outputs
15
+ }));
16
+ </script>
17
+
18
+ {#if wrapper}
19
+ {#snippet childWrapper()}
20
+ <PiWrapper wrappers={restWrappers} children={dProps.children}></PiWrapper>
21
+ {/snippet}
22
+ <wrapper.type {...inputs()} children={childWrapper}></wrapper.type>
23
+ {:else}
24
+ {@render dProps.children()}
25
+ {/if}
@@ -0,0 +1,8 @@
1
+ import type { CoreResolvedWrapperConfig } from '@piying/view-core';
2
+ type $$ComponentProps = {
3
+ wrappers: CoreResolvedWrapperConfig[];
4
+ children: any;
5
+ };
6
+ declare const Wrapper: import("svelte").Component<$$ComponentProps, {}, "">;
7
+ type Wrapper = ReturnType<typeof Wrapper>;
8
+ export default Wrapper;
package/index.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ import PiyingView from './component/piying-view.svelte';
2
+ export { PiyingView };
3
+ import PiyingFieldTemplate from './component/field-template.svelte';
4
+ export { PiyingFieldTemplate };
5
+ import PiyingViewGroup from './component/group.svelte';
6
+ export { PiyingViewGroup };
7
+ export * from './type';
8
+ export * from './token';
9
+ export * from './builder';
10
+ export * from './svelte-schema';
11
+ export * from './util/use-control-value-accessor.svelte';
12
+ export * from './util/signal-convert.svelte';
package/index.js ADDED
@@ -0,0 +1,12 @@
1
+ import PiyingView from './component/piying-view.svelte';
2
+ export { PiyingView };
3
+ import PiyingFieldTemplate from './component/field-template.svelte';
4
+ export { PiyingFieldTemplate };
5
+ import PiyingViewGroup from './component/group.svelte';
6
+ export { PiyingViewGroup };
7
+ export * from './type';
8
+ export * from './token';
9
+ export * from './builder';
10
+ export * from './svelte-schema';
11
+ export * from './util/use-control-value-accessor.svelte';
12
+ export * from './util/signal-convert.svelte';
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@piying/view-svelte",
3
+ "version": "1.4.0",
4
+ "description": "Piying view For Svelte;Valibot to Component",
5
+ "type": "module",
6
+ "homepage": "https://piying-org.github.io/website/docs/client/intro",
7
+ "repository": {
8
+ "url": "git+https://github.com/piying-org/piying-view.git",
9
+ "directory": "packages/svelte",
10
+ "type": "git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/piying-org/piying-view/issues"
14
+ },
15
+ "author": {
16
+ "name": "wszgrcy",
17
+ "url": "https://github.com/wszgrcy",
18
+ "email": "wszgrcy@gmail.com"
19
+ },
20
+ "keywords": [
21
+ "Svelte",
22
+ "form",
23
+ "valibot",
24
+ "validation",
25
+ "validator",
26
+ "layout",
27
+ "listen",
28
+ "field",
29
+ "control",
30
+ "group",
31
+ "array",
32
+ "control",
33
+ "metadata"
34
+ ],
35
+ "license": "MIT",
36
+ "dependencies": {
37
+ "@piying/view-core": "^1.4.0",
38
+ "fast-equals": "^5.2.2",
39
+ "static-injector": "^6.1.2",
40
+ "valibot": "^1.1.0"
41
+ },
42
+ "sideEffects": false,
43
+ "peerDependencies": {
44
+ "svelte": "^5.0.0"
45
+ },
46
+ "module": "index.js",
47
+ "typings": "index.d.ts",
48
+ "exports": {
49
+ "./package.json": {
50
+ "default": "./package.json"
51
+ },
52
+ ".": {
53
+ "types": "./index.d.ts",
54
+ "svelte": "./index.js",
55
+ "default": "./index.js"
56
+ }
57
+ }
58
+ }
package/readme.md ADDED
@@ -0,0 +1,27 @@
1
+ <div><a href="https://www.npmjs.com/package/@piying/view-core"><img src="https://img.shields.io/npm/v/@piying/view-core" alt="NPM Version" /></a> <a href="https://coveralls.io/github/piying-org/piying-view?branch=main"><img src="https://coveralls.io/repos/github/piying-org/piying-view/badge.svg" alt="Coverage Status" ></a> <a href=""><img src="https://img.shields.io/badge/License-MIT-teal.svg" alt="MIT License" /></a></div>
2
+
3
+ ## document
4
+
5
+ - https://piying-org.github.io/website/docs/client/intro
6
+
7
+ ## start
8
+
9
+ - npm i
10
+ - npm run build:core
11
+
12
+ ## test
13
+
14
+ - npx playwright install
15
+ - npm run test:all
16
+
17
+ ### test Core/Angular
18
+
19
+ - npm run test
20
+
21
+ ### test Vue
22
+
23
+ - npm run test:vue
24
+
25
+ ### test React
26
+
27
+ - npm run test:react
@@ -0,0 +1,6 @@
1
+ import { CoreSchemaHandle } from '@piying/view-core';
2
+ import type { PiResolvedViewFieldConfig } from './type/group';
3
+ export declare class SvelteSchemaHandle extends CoreSchemaHandle<SvelteSchemaHandle, () => PiResolvedViewFieldConfig> {
4
+ type?: any;
5
+ contents?: any[];
6
+ }
@@ -0,0 +1,24 @@
1
+ var __extends = (this && this.__extends) || (function () {
2
+ var extendStatics = function (d, b) {
3
+ extendStatics = Object.setPrototypeOf ||
4
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
5
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
6
+ return extendStatics(d, b);
7
+ };
8
+ return function (d, b) {
9
+ if (typeof b !== "function" && b !== null)
10
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
11
+ extendStatics(d, b);
12
+ function __() { this.constructor = d; }
13
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
14
+ };
15
+ })();
16
+ import { CoreSchemaHandle } from '@piying/view-core';
17
+ var SvelteSchemaHandle = /** @class */ (function (_super) {
18
+ __extends(SvelteSchemaHandle, _super);
19
+ function SvelteSchemaHandle() {
20
+ return _super !== null && _super.apply(this, arguments) || this;
21
+ }
22
+ return SvelteSchemaHandle;
23
+ }(CoreSchemaHandle));
24
+ export { SvelteSchemaHandle };
package/token.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import type { PiResolvedViewFieldConfig } from './type/group';
2
+ export declare const InjectorToken: unique symbol;
3
+ export declare const PI_VIEW_FIELD_TOKEN: unique symbol;
4
+ export type PI_VIEW_FIELD_TOKEN = () => PiResolvedViewFieldConfig;
package/token.js ADDED
@@ -0,0 +1,2 @@
1
+ export var InjectorToken = Symbol();
2
+ export var PI_VIEW_FIELD_TOKEN = Symbol();
@@ -0,0 +1,41 @@
1
+ import type { SvelteSchemaHandle } from '../svelte-schema';
2
+ import type { ConfigMergeStrategy, CoreResolvedComponentDefine, PiResolvedCommonViewFieldConfig } from '@piying/view-core';
3
+ import type { SetOptional } from '@piying/view-core';
4
+ export interface RawDirectiveOutputs {
5
+ [name: string]: (event: any, field: PiResolvedViewFieldConfig) => void;
6
+ }
7
+ export type RawWrapperDefine = {
8
+ inputs?: Record<string, any>;
9
+ type: string;
10
+ };
11
+ export type ResolvedrapperDefine = {
12
+ inputs?: Record<string, any>;
13
+ type: any;
14
+ };
15
+ export interface RawComponentDefine {
16
+ type: string;
17
+ }
18
+ export interface ComponentFieldConfig {
19
+ type?: string;
20
+ contents?: any[];
21
+ }
22
+ export type ResolvedComponentFieldConfig = Omit<ComponentFieldConfig, 'inputs' | 'outputs' | 'directives' | 'wrappers'>;
23
+ export type PiDefaultRawViewFieldConfig = Pick<SvelteSchemaHandle, 'inputs' | 'outputs' | 'wrappers' | 'formConfig' | 'renderConfig' | 'props'>;
24
+ export type PiResolvedViewFieldConfig = PiResolvedCommonViewFieldConfig<() => PiResolvedViewFieldConfig, CoreResolvedComponentDefine> & ResolvedComponentFieldConfig & {
25
+ /** 除了无component的控件,其他情况下都应该有define,group/array会赋值默认 */
26
+ define?: RawComponentDefine;
27
+ };
28
+ export type PiComponentDefaultConfig = {
29
+ type: any | (() => Promise<any>);
30
+ } & Omit<SetOptional<PiDefaultRawViewFieldConfig, 'formConfig'>, 'type'>;
31
+ export interface PiViewConfig {
32
+ types?: Record<string, PiComponentDefaultConfig>;
33
+ wrappers?: Record<string, {
34
+ type: any | (() => Promise<any>);
35
+ inputs?: Record<string, any>;
36
+ }>;
37
+ defaultConfig?: PiDefaultRawViewFieldConfig;
38
+ /** merge 数组/对象会合并 replace 优先自身/组件/全局 */
39
+ defaultConfigMergeStrategy?: ConfigMergeStrategy | ConfigMergeStrategyObject;
40
+ }
41
+ export type ConfigMergeStrategyObject = Record<keyof PiDefaultRawViewFieldConfig, ConfigMergeStrategy>;
package/type/group.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export * from './group';
package/type/index.js ADDED
@@ -0,0 +1 @@
1
+ export * from './group';
@@ -0,0 +1 @@
1
+ export declare function signalToRef<T>(value: () => T | undefined): () => T;
@@ -0,0 +1,20 @@
1
+ import { effect } from 'static-injector';
2
+ import { InjectorToken } from '../token';
3
+ import { getContext } from 'svelte';
4
+ export function signalToRef(value) {
5
+ var injector = getContext(InjectorToken);
6
+ var dataRef = $state.raw(undefined);
7
+ $effect.pre(function () {
8
+ dataRef = value();
9
+ var ref = effect(function () {
10
+ var currentValue = value();
11
+ if (!Object.is(dataRef, currentValue)) {
12
+ dataRef = currentValue;
13
+ }
14
+ }, { injector: injector });
15
+ return function () {
16
+ ref.destroy();
17
+ };
18
+ });
19
+ return function () { return dataRef; };
20
+ }
@@ -0,0 +1,9 @@
1
+ export declare function useControlValueAccessor(): {
2
+ cva: ControlValueAccessor;
3
+ cvaa: {
4
+ readonly value: unknown;
5
+ readonly disabled: boolean;
6
+ valueChange: (input: any) => void;
7
+ touchedChange: () => void;
8
+ };
9
+ };
@@ -0,0 +1,38 @@
1
+ export function useControlValueAccessor() {
2
+ var value = $state();
3
+ var disabled = $state(false);
4
+ var onChange;
5
+ var touched;
6
+ var instance = {
7
+ writeValue: function (obj) {
8
+ value = obj;
9
+ },
10
+ registerOnChange: function (fn) {
11
+ onChange = fn;
12
+ },
13
+ registerOnTouched: function (fn) {
14
+ touched = fn;
15
+ },
16
+ setDisabledState: function (value) {
17
+ disabled = value;
18
+ }
19
+ };
20
+ return {
21
+ cva: instance,
22
+ cvaa: {
23
+ get value() {
24
+ return value;
25
+ },
26
+ get disabled() {
27
+ return disabled;
28
+ },
29
+ valueChange: function (input) {
30
+ onChange === null || onChange === void 0 ? void 0 : onChange(input);
31
+ value = input;
32
+ },
33
+ touchedChange: function () {
34
+ touched();
35
+ }
36
+ }
37
+ };
38
+ }