vue-formless 0.1.1 → 0.2.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.en.md +58 -14
- package/README.md +57 -14
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +278 -422
- package/dist/index.js +618 -834
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,123 +1,88 @@
|
|
|
1
|
-
import { AllowedComponentProps } from 'vue';
|
|
2
1
|
import { Component } from 'vue';
|
|
3
|
-
import { ComponentCustomProps } from 'vue';
|
|
4
|
-
import { ComponentOptionsBase } from 'vue';
|
|
5
2
|
import { ComponentOptionsMixin } from 'vue';
|
|
6
3
|
import { ComponentProvideOptions } from 'vue';
|
|
7
|
-
import { CreateComponentPublicInstanceWithMixins } from 'vue';
|
|
8
4
|
import { DefineComponent } from 'vue';
|
|
9
5
|
import { ExtractPropTypes } from 'vue';
|
|
10
|
-
import { GlobalComponents } from 'vue';
|
|
11
|
-
import { GlobalDirectives } from 'vue';
|
|
12
|
-
import { InjectionKey } from 'vue';
|
|
13
6
|
import { PropType } from 'vue';
|
|
14
7
|
import { PublicProps } from 'vue';
|
|
15
|
-
import { Slot } from 'vue';
|
|
16
8
|
import { VNodeChild } from 'vue';
|
|
17
|
-
import { VNodeProps } from 'vue';
|
|
18
9
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
/** Slice a multi-port binding to one v-model port (ADR-013 `useFormItem('start')`). */
|
|
22
|
-
export declare function bindingForPort(binding: ResolvedControlBinding, port: string): ResolvedControlBinding;
|
|
23
|
-
|
|
24
|
-
export declare type CamelToPascal<S extends string> = S extends `${infer F}${infer R}` ? `${Uppercase<F>}${R}` : S;
|
|
25
|
-
|
|
26
|
-
/** `name` → `Name`, `idCard` → `IdCard` */
|
|
27
|
-
export declare function camelToPascal(key: string): string;
|
|
28
|
-
|
|
29
|
-
export declare type ColPlace = 'auto' | 'start' | 'end';
|
|
30
|
-
|
|
31
|
-
/** Author-facing Col width: omit / `'Nx'` / `'max'` / absolute 1–24. */
|
|
32
|
-
export declare type ColSpanSpec = string | number;
|
|
10
|
+
declare type ColSpan = IntRange<1, typeof GRID_TOTAL>;
|
|
33
11
|
|
|
34
12
|
/**
|
|
35
13
|
* Public `$props` of a Vue constructor, functional component, or SFC.
|
|
36
|
-
* `never` / omitted
|
|
14
|
+
* `never` / omitted controls yield `{}` (`never extends Constructor` is true in TS).
|
|
37
15
|
*/
|
|
38
|
-
|
|
16
|
+
declare type ComponentPublicProps<C> = [C] extends [never] ? {} : [C] extends [undefined] ? {} : C extends abstract new (...args: any) => {
|
|
39
17
|
$props: infer P;
|
|
40
18
|
} ? P : C extends (props: infer P, ...args: any) => unknown ? P : C extends {
|
|
41
19
|
$props: infer P;
|
|
42
20
|
} ? P : {};
|
|
43
21
|
|
|
44
|
-
export declare interface ControlBindingOverrides {
|
|
45
|
-
prop?: ControlProp;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export declare type ControlItemSetting = boolean | 'self';
|
|
49
|
-
|
|
50
|
-
export declare type ControlProp = string | readonly string[];
|
|
51
|
-
|
|
52
22
|
/**
|
|
53
|
-
*
|
|
54
|
-
*
|
|
23
|
+
* One field's declaration: the input of `createFormField` / each entry of
|
|
24
|
+
* `createFormFields` (design.md §11). It extends the augmentable
|
|
25
|
+
* `FormFieldCustomOptions`, so a consumer's `label` / `validation` joins the
|
|
26
|
+
* same shape and flows into the `FormFieldFormless` snapshot and the `fl:*` tag
|
|
27
|
+
* props.
|
|
28
|
+
*
|
|
29
|
+
* `component` stays `unknown` on purpose: a field table can pass any control
|
|
30
|
+
* and let the tag infer that control's public props.
|
|
55
31
|
*/
|
|
56
|
-
export declare interface
|
|
32
|
+
export declare interface CreateFormFieldOptions extends FormFieldCustomOptions {
|
|
57
33
|
/**
|
|
58
|
-
*
|
|
59
|
-
*
|
|
34
|
+
* The control only (no host Item). Receives v-model bindings from formless.
|
|
35
|
+
* A control may also declare static `formless: { model, item, field }`.
|
|
60
36
|
*/
|
|
61
|
-
component?:
|
|
62
|
-
/**
|
|
63
|
-
props?: HostProps<
|
|
37
|
+
component?: unknown;
|
|
38
|
+
/** Control defaults: static object, or derived from the field snapshot. */
|
|
39
|
+
props?: HostProps<FormFieldFormless>;
|
|
64
40
|
/**
|
|
65
|
-
* v-model names on the
|
|
66
|
-
* Locked with the component; tag cannot override. Prefer
|
|
41
|
+
* v-model names on the control (design.md §7.1). Default `'modelValue'`.
|
|
42
|
+
* Locked with the component; tag cannot override. Prefer control `formless.model`.
|
|
67
43
|
*/
|
|
68
|
-
model?:
|
|
44
|
+
model?: FormFieldVModelRaw;
|
|
69
45
|
/**
|
|
70
|
-
* Location(s) from FormView root (
|
|
46
|
+
* Location(s) from FormView root (design.md §7.1). Default: field key.
|
|
71
47
|
* Overridable via `:fl:prop`. Empty string is illegal.
|
|
72
48
|
* Nested: `buyers[0].name`, `` `buyers[${$index}].name` ``.
|
|
73
49
|
*/
|
|
74
|
-
prop?:
|
|
50
|
+
prop?: FormFieldPropRaw;
|
|
51
|
+
/**
|
|
52
|
+
* Host Item shell for this field: FormView default, then this, then tag `:fl:item`.
|
|
53
|
+
* Boolean only (design.md §9). Not “skip FormField”.
|
|
54
|
+
*/
|
|
55
|
+
item?: boolean;
|
|
75
56
|
/**
|
|
76
|
-
*
|
|
77
|
-
*
|
|
57
|
+
* Assembly placement (design.md §8). Omit = `'auto'`.
|
|
58
|
+
* Schema and tag merge by nearest-wins; the control is **not** a merge layer —
|
|
59
|
+
* its static `formless.field` is read at render and folded in (`auto`).
|
|
78
60
|
*/
|
|
79
|
-
|
|
61
|
+
field?: FormFieldFormlessFieldRaw;
|
|
62
|
+
/** Debug-only component name; `createFormFields` injects the table key. */
|
|
63
|
+
name?: string;
|
|
80
64
|
}
|
|
81
65
|
|
|
82
|
-
/** Adapter fields on ControlSchema (everything except kernel keys). */
|
|
83
|
-
declare type ControlSchemaExtras = Omit<ControlSchema, ControlSchemaKernelKey>;
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Constraint for `createFormControls` only. `component` stays `unknown` so object
|
|
87
|
-
* literals keep `typeof ElInput` instead of widening to Vue's `Component`.
|
|
88
|
-
*/
|
|
89
|
-
declare type ControlSchemaInput = Omit<ControlSchema, 'component'> & {
|
|
90
|
-
component?: unknown;
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
/** Kernel-owned ControlSchema keys. Not extras; tags already have matching `fl:*` where allowed. */
|
|
94
|
-
declare type ControlSchemaKernelKey = 'component' | 'props' | 'model' | 'prop' | 'item';
|
|
95
|
-
|
|
96
|
-
export declare type ControlVModel = string | readonly string[];
|
|
97
|
-
|
|
98
66
|
/**
|
|
99
|
-
* Build a static namespaced
|
|
100
|
-
* Schema keys are camelCase
|
|
67
|
+
* Build a static namespaced field table (design.md §11).
|
|
68
|
+
* Schema keys are camelCase (`timeRange`) or kebab-case (`time-range`) field
|
|
69
|
+
* names; only the **tag name** is normalized (`<User.TimeRange />`). The key as
|
|
70
|
+
* written still supplies the default `prop`.
|
|
101
71
|
*/
|
|
102
|
-
export declare function
|
|
103
|
-
[K in keyof S]:
|
|
104
|
-
}>(
|
|
105
|
-
|
|
106
|
-
export declare interface CreateFormControlsOptions {
|
|
107
|
-
/** Defaults for every control in this cluster (static or from the cell snapshot). */
|
|
108
|
-
props?: HostProps<ItemFl>;
|
|
109
|
-
}
|
|
72
|
+
export declare function createFormFields<const S extends {
|
|
73
|
+
[K in keyof S]: CreateFormFieldOptions;
|
|
74
|
+
}>(options: S): FormFields<S>;
|
|
110
75
|
|
|
111
76
|
/**
|
|
112
|
-
* Bind host layout / form / item once; returns a FormView (
|
|
77
|
+
* Bind host layout / form / item once; returns a FormView (design.md §10).
|
|
113
78
|
*
|
|
114
|
-
* Host shells stay in this closure.
|
|
79
|
+
* Host shells stay in this closure. Ad-hoc fields use `FormField`.
|
|
115
80
|
*
|
|
116
81
|
* @example
|
|
117
82
|
* ```ts
|
|
118
83
|
* export const FormView = createFormView({
|
|
119
|
-
* layout: { Row: ElRow, Col: ElCol,
|
|
120
|
-
* form: { component:
|
|
84
|
+
* layout: { Row: ElRow, Col: ElCol, props: { column: 2 } },
|
|
85
|
+
* form: { component: MyForm }, // MyForm declares `modelValue` → ElForm `model`
|
|
121
86
|
* item: { component: ElFormItem, props: toEpItemProps },
|
|
122
87
|
* })
|
|
123
88
|
* ```
|
|
@@ -125,381 +90,296 @@ export declare interface CreateFormControlsOptions {
|
|
|
125
90
|
export declare function createFormView(options?: CreateFormViewOptions): FormViewComponent;
|
|
126
91
|
|
|
127
92
|
export declare interface CreateFormViewOptions {
|
|
128
|
-
/** Row + Col for hosted grid, plus optional
|
|
93
|
+
/** Row + Col for the hosted grid, plus optional LayoutView props (density etc.). */
|
|
129
94
|
layout?: FormViewLayoutBind;
|
|
130
95
|
/** Host form shell. Omit or `:fl:form="false"` skips wrapping. */
|
|
131
|
-
form?:
|
|
132
|
-
/** Host item shell. `props` are defaults (static or from the
|
|
133
|
-
item?:
|
|
96
|
+
form?: FormViewFormBind;
|
|
97
|
+
/** Host item shell. `props` are defaults (static or from the field snapshot). */
|
|
98
|
+
item?: FormViewItemBind;
|
|
134
99
|
}
|
|
135
100
|
|
|
136
|
-
/**
|
|
137
|
-
* Bind host Row/Col once. Returns LayoutView.
|
|
138
|
-
* LayoutItem is not exported; cells call `useLayoutItem()`.
|
|
139
|
-
*/
|
|
101
|
+
/** Bind host Row/Col once. Returns LayoutView; items are `LayoutItem`. */
|
|
140
102
|
export declare function createLayoutView(options?: CreateLayoutViewOptions): Component;
|
|
141
103
|
|
|
142
|
-
|
|
104
|
+
declare interface CreateLayoutViewOptions {
|
|
143
105
|
Row?: Component;
|
|
144
106
|
Col?: Component;
|
|
145
107
|
column?: number;
|
|
146
108
|
}
|
|
147
109
|
|
|
148
|
-
|
|
149
|
-
export declare const DEFAULT_LAYOUT: {
|
|
150
|
-
readonly column: 1;
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
/** Tag attrs: `label?: string` → `'fl:label'?: string`. Always optional (override, not required). */
|
|
154
|
-
declare type FlExtraProps<T> = {
|
|
155
|
-
[K in keyof T as K extends string ? `fl:${K}` : never]+?: T[K];
|
|
156
|
-
};
|
|
110
|
+
declare type _Enumerate<N extends number, Acc extends number[] = []> = Acc['length'] extends N ? Acc[number] : _Enumerate<N, [...Acc, Acc['length']]>;
|
|
157
111
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
model
|
|
161
|
-
|
|
162
|
-
update: (prop: string, value: unknown) => void;
|
|
112
|
+
/** Static `formless` bag a control may declare on `ComponentCustomOptions`. */
|
|
113
|
+
export declare interface FormControlFormless {
|
|
114
|
+
/** v-model ports on the control (design.md §7.1). */
|
|
115
|
+
model?: FormFieldVModelRaw;
|
|
163
116
|
/**
|
|
164
|
-
*
|
|
165
|
-
*
|
|
117
|
+
* Composite marker (design.md §8): "my inner `<FormField>`s need an inner
|
|
118
|
+
* LayoutView whenever this field is boxed". Only `'embed'` is meaningful —
|
|
119
|
+
* it is the control's **nature**, not a placement, so it is read at render
|
|
120
|
+
* (`FormFieldCore`) and folded into `fl:field`, never merged as a preset layer.
|
|
166
121
|
*/
|
|
167
|
-
|
|
168
|
-
/** This FormView layer's Item switch. */
|
|
169
|
-
isItemEnabled: () => boolean;
|
|
170
|
-
/** This FormView's `:fl:layout` switch (page, not nearest LayoutView). */
|
|
171
|
-
isLayoutEnabled: () => boolean;
|
|
172
|
-
/** Factory `createLayoutView` result; reused for gear-4 inner host. */
|
|
173
|
-
LayoutView: Component;
|
|
174
|
-
/** `createFormView({ layout })` density; inner extra rows use this, not the page `:row:*`. */
|
|
175
|
-
factoryColumn: number;
|
|
176
|
-
factoryGutter: number;
|
|
122
|
+
field?: 'embed';
|
|
177
123
|
}
|
|
178
124
|
|
|
179
|
-
|
|
125
|
+
/** Control props that may appear on `<User.Xxx />` (v-model ports stripped). */
|
|
126
|
+
declare type FormControlProps<Def> = Def extends {
|
|
127
|
+
component?: infer C;
|
|
128
|
+
} ? [Exclude<C, undefined>] extends [never] ? {} : Omit<ComponentPublicProps<Exclude<C, undefined>>, LockedKeysForDef<Def>> : {};
|
|
180
129
|
|
|
181
|
-
export declare
|
|
130
|
+
export declare const FormField: FormFieldComponent<{}>;
|
|
182
131
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
export declare
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
132
|
+
export declare type FormFieldComponent<P = {}> = DefineComponent<FormFieldProps & P>;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* The single module-augmentation anchor for field extras (design.md §18), and
|
|
136
|
+
* the extras domain itself: `CreateFormFieldOptions` extends it, and both the
|
|
137
|
+
* `FormFieldFormless` snapshot and the `fl:*` tag props take their extras
|
|
138
|
+
* straight from it. Mirrors Vue's `ComponentCustomOptions`: declare `label` /
|
|
139
|
+
* `validation` here, and they land on the factory input, the snapshot, and the
|
|
140
|
+
* tag props. There is no separate `Omit`-derived "extras" alias — kernel keys
|
|
141
|
+
* live on `CreateFormFieldOptions` only.
|
|
142
|
+
*/
|
|
143
|
+
export declare interface FormFieldCustomOptions {
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* The **normalized** per-field snapshot (design.md §10.1 / §16.3): what
|
|
148
|
+
* `item.props` / field `props` functions receive, and what `FormField` hands
|
|
149
|
+
* down to its host `FormItem`. Not passed as a host component prop.
|
|
150
|
+
*
|
|
151
|
+
* Adapters declare their extras once, on `FormFieldCustomOptions` (module
|
|
152
|
+
* augmentation, design.md §18); `extends FormFieldCustomOptions` pulls them in,
|
|
153
|
+
* so a declared `label` is `fl.label` in the snapshot **and** `:fl:label` on the
|
|
154
|
+
* tag.
|
|
155
|
+
*
|
|
156
|
+
* `model` / `prop` are this field's **normalized** binding arrays — index-aligned
|
|
157
|
+
* (`model[i] ↔ prop[i]`), never empty and `prop` no longer than `model`. The
|
|
158
|
+
* kernel sends no identity **name**: a host Item `prop` is the adapter's own
|
|
159
|
+
* encoding, so an adapter that cannot encode the field simply leaves it unbound.
|
|
160
|
+
*
|
|
161
|
+
* **Only the keys the kernel resolves are declared here** — `model` / `prop` /
|
|
162
|
+
* `field` / `item` — plus the consumer's declared extras, pulled in by
|
|
163
|
+
* `extends FormFieldCustomOptions`. The raw bag's other keys (a raw `component`,
|
|
164
|
+
* an unread `props`) still ride through at runtime, but they are **not** part of
|
|
165
|
+
* this type: the snapshot is a closed shape, so reading an undeclared key is a
|
|
166
|
+
* compile error rather than a silent `unknown`.
|
|
167
|
+
*/
|
|
168
|
+
export declare interface FormFieldFormless extends FormFieldCustomOptions {
|
|
169
|
+
/** This field's v-model ports, index-aligned with `prop`. */
|
|
170
|
+
model: FormFieldVModel;
|
|
171
|
+
/** This field's locations, index-aligned with `model`; `undefined` when nothing bound them. */
|
|
172
|
+
prop: FormFieldProp | undefined;
|
|
173
|
+
/** Assembled placement (design.md §8). `'auto'` is resolved away, never sent. */
|
|
174
|
+
field: FormFieldFormlessField;
|
|
175
|
+
/**
|
|
176
|
+
* Host Item shell switch (design.md §9): the nearest FormView's page `fl:item`
|
|
177
|
+
* default ← this cell's `fl:item`, near wins; a bare attr (`''`) counts as
|
|
178
|
+
* `true`. Resolved in one place (`FormFieldCore`), so it is **always a boolean**
|
|
179
|
+
* and every consumer — the adapter `item.props` and the control `props`
|
|
180
|
+
* alike — sees the same value.
|
|
181
|
+
*/
|
|
199
182
|
item: boolean;
|
|
200
|
-
/** FormView write-model; map to the host via `form.props` (e.g. `{ model: fl.modelValue }`). */
|
|
201
|
-
modelValue: unknown;
|
|
202
183
|
}
|
|
203
184
|
|
|
204
|
-
|
|
185
|
+
/** The **assembled** placement. `'auto'` is resolved away, never sent. */
|
|
186
|
+
declare type FormFieldFormlessField = 'wrap' | 'embed' | 'wrap-embed';
|
|
205
187
|
|
|
206
|
-
/**
|
|
207
|
-
|
|
188
|
+
/**
|
|
189
|
+
* The **written** placement — the three writable values. Omit = `'auto'`: defer
|
|
190
|
+
* to the control's static `formless.field`. A leaf resolves to `'wrap'`, but
|
|
191
|
+
* that value is never writable.
|
|
192
|
+
*/
|
|
193
|
+
declare type FormFieldFormlessFieldRaw = 'auto' | 'embed' | 'wrap-embed';
|
|
208
194
|
|
|
209
|
-
|
|
210
|
-
export declare type FormLayoutOptions = Pick<FormViewLayoutBind, 'column'>;
|
|
195
|
+
declare type FormFieldProp = (string | undefined)[];
|
|
211
196
|
|
|
212
|
-
|
|
213
|
-
export declare type FormLayoutProp = boolean;
|
|
197
|
+
declare type FormFieldPropRaw = string | readonly string[];
|
|
214
198
|
|
|
215
199
|
/**
|
|
216
|
-
*
|
|
200
|
+
* Public props of `<FormField>` / `<User.Xxx />`. Kernel `fl:` / `item:` /
|
|
201
|
+
* `layout:` / `layout-item:` keys on `<FormField>` / `<User.Xxx />`.
|
|
202
|
+
* Schema extras are prefixed automatically.
|
|
203
|
+
* `fl:model` declares the v-model ports at the identity root and selects one declared port inside it.
|
|
204
|
+
* `layout:column` is formless density; other `layout:*` (e.g. gutter) stay attrs and fall through to LayoutView → Row.
|
|
205
|
+
*
|
|
206
|
+
* The declaration's own keys are **mapped**, not retyped: every core key has a
|
|
207
|
+
* matching `fl:` tag key (design.md §6), so the tag cannot drift from
|
|
208
|
+
* `CreateFormFieldOptions`. Two keys stay off the tag — `props` (it may be a
|
|
209
|
+
* snapshot function, which cannot ride in an attr: it enters as the first
|
|
210
|
+
* `control` layer instead, §16.3) and `name` (factory-private). `component` is
|
|
211
|
+
* the one key whose *type* changes: the declaration keeps `unknown` so a field
|
|
212
|
+
* table can pass any control, while the tag supplies a real `Component`
|
|
213
|
+
* (ad-hoc field / factory preset, §7.4). Extras need no separate term — they
|
|
214
|
+
* are part of the declaration, so the same mapper prefixes them.
|
|
215
|
+
*
|
|
216
|
+
* The `layout:` / `layout-item:` keys are not retyped either: they are mapped
|
|
217
|
+
* from `@vue-formless/layout`'s own prop bags by the same `ToFormlessProps` —
|
|
218
|
+
* `LayoutViewProps` under `'layout:'` and `LayoutItemProps` under
|
|
219
|
+
* `'layout-item:'` — so density and placement have a single source and cannot
|
|
220
|
+
* drift from the layout package. Nothing is `Omit`-ed: the kernel overrides
|
|
221
|
+
* `layout:disabled` at the page it forwards the bag to (spread first, then
|
|
222
|
+
* `disabled={!fl:layout}`), not by dropping it from the channel.
|
|
217
223
|
*/
|
|
218
|
-
export declare
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
type: PropType<unknown>;
|
|
222
|
-
default: undefined;
|
|
223
|
-
};
|
|
224
|
-
'fl:layout': {
|
|
225
|
-
type: PropType<FormLayoutProp>;
|
|
226
|
-
default: boolean;
|
|
227
|
-
};
|
|
228
|
-
'row:column': {
|
|
229
|
-
type: NumberConstructor;
|
|
230
|
-
default: undefined;
|
|
231
|
-
};
|
|
232
|
-
'row:gutter': {
|
|
233
|
-
type: NumberConstructor;
|
|
234
|
-
default: undefined;
|
|
235
|
-
};
|
|
236
|
-
'fl:form': {
|
|
237
|
-
type: PropType<FormFormProp>;
|
|
238
|
-
default: string;
|
|
239
|
-
};
|
|
240
|
-
'fl:item': {
|
|
241
|
-
type: BooleanConstructor;
|
|
242
|
-
default: boolean;
|
|
243
|
-
};
|
|
244
|
-
}>> & Readonly<{
|
|
245
|
-
"onUpdate:modelValue"?: ((_value: unknown) => any) | undefined;
|
|
246
|
-
}>, () => VNodeChild, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {
|
|
247
|
-
'update:modelValue': (_value: unknown) => boolean;
|
|
248
|
-
}, PublicProps, {
|
|
249
|
-
modelValue: undefined;
|
|
250
|
-
'fl:layout': boolean;
|
|
251
|
-
'row:column': number;
|
|
252
|
-
'row:gutter': number;
|
|
253
|
-
'fl:form': FormFormProp;
|
|
254
|
-
'fl:item': boolean;
|
|
255
|
-
}, true, {}, {}, GlobalComponents, GlobalDirectives, string, {}, any, ComponentProvideOptions, {
|
|
256
|
-
P: {};
|
|
257
|
-
B: {};
|
|
258
|
-
D: {};
|
|
259
|
-
C: {};
|
|
260
|
-
M: {};
|
|
261
|
-
Defaults: {};
|
|
262
|
-
}, Readonly<ExtractPropTypes< {
|
|
263
|
-
modelValue: {
|
|
264
|
-
type: PropType<unknown>;
|
|
265
|
-
default: undefined;
|
|
266
|
-
};
|
|
267
|
-
'fl:layout': {
|
|
268
|
-
type: PropType<FormLayoutProp>;
|
|
269
|
-
default: boolean;
|
|
270
|
-
};
|
|
271
|
-
'row:column': {
|
|
272
|
-
type: NumberConstructor;
|
|
273
|
-
default: undefined;
|
|
274
|
-
};
|
|
275
|
-
'row:gutter': {
|
|
276
|
-
type: NumberConstructor;
|
|
277
|
-
default: undefined;
|
|
278
|
-
};
|
|
279
|
-
'fl:form': {
|
|
280
|
-
type: PropType<FormFormProp>;
|
|
281
|
-
default: string;
|
|
282
|
-
};
|
|
283
|
-
'fl:item': {
|
|
284
|
-
type: BooleanConstructor;
|
|
285
|
-
default: boolean;
|
|
286
|
-
};
|
|
287
|
-
}>> & Readonly<{
|
|
288
|
-
"onUpdate:modelValue"?: ((_value: unknown) => any) | undefined;
|
|
289
|
-
}>, () => VNodeChild, {}, {}, {}, {
|
|
290
|
-
modelValue: undefined;
|
|
291
|
-
'fl:layout': boolean;
|
|
292
|
-
'row:column': number;
|
|
293
|
-
'row:gutter': number;
|
|
294
|
-
'fl:form': FormFormProp;
|
|
295
|
-
'fl:item': boolean;
|
|
296
|
-
}>;
|
|
297
|
-
__isFragment?: never;
|
|
298
|
-
__isTeleport?: never;
|
|
299
|
-
__isSuspense?: never;
|
|
300
|
-
} & ComponentOptionsBase<Readonly<ExtractPropTypes< {
|
|
301
|
-
modelValue: {
|
|
302
|
-
type: PropType<unknown>;
|
|
303
|
-
default: undefined;
|
|
304
|
-
};
|
|
305
|
-
'fl:layout': {
|
|
306
|
-
type: PropType<FormLayoutProp>;
|
|
307
|
-
default: boolean;
|
|
308
|
-
};
|
|
309
|
-
'row:column': {
|
|
310
|
-
type: NumberConstructor;
|
|
311
|
-
default: undefined;
|
|
312
|
-
};
|
|
313
|
-
'row:gutter': {
|
|
314
|
-
type: NumberConstructor;
|
|
315
|
-
default: undefined;
|
|
316
|
-
};
|
|
317
|
-
'fl:form': {
|
|
318
|
-
type: PropType<FormFormProp>;
|
|
319
|
-
default: string;
|
|
320
|
-
};
|
|
321
|
-
'fl:item': {
|
|
322
|
-
type: BooleanConstructor;
|
|
323
|
-
default: boolean;
|
|
324
|
-
};
|
|
325
|
-
}>> & Readonly<{
|
|
326
|
-
"onUpdate:modelValue"?: ((_value: unknown) => any) | undefined;
|
|
327
|
-
}>, () => VNodeChild, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {
|
|
328
|
-
'update:modelValue': (_value: unknown) => boolean;
|
|
329
|
-
}, string, {
|
|
330
|
-
modelValue: undefined;
|
|
331
|
-
'fl:layout': boolean;
|
|
332
|
-
'row:column': number;
|
|
333
|
-
'row:gutter': number;
|
|
334
|
-
'fl:form': FormFormProp;
|
|
335
|
-
'fl:item': boolean;
|
|
336
|
-
}, {}, string, {}, GlobalComponents, GlobalDirectives, string, ComponentProvideOptions> & VNodeProps & AllowedComponentProps & ComponentCustomProps & {
|
|
337
|
-
Item: typeof FormViewItem;
|
|
338
|
-
};
|
|
224
|
+
export declare type FormFieldProps = ToFormlessProps<Omit<CreateFormFieldOptions, 'props' | 'name' | 'component'> & {
|
|
225
|
+
component?: Component;
|
|
226
|
+
}> & ToFormlessProps<LayoutViewProps, 'layout:'> & ToFormlessProps<LayoutItemProps, 'layout-item:'>;
|
|
339
227
|
|
|
340
|
-
|
|
341
|
-
|
|
228
|
+
/**
|
|
229
|
+
* PascalCase field tags. `S` must not be `Record<string, _>` or `keyof` collapses
|
|
230
|
+
* to `string` and Volar/TS lose `User.Name` / `User.IdCard` as named keys.
|
|
231
|
+
* Tag props are `fl:*` plus the control's public props (v-model ports locked).
|
|
232
|
+
*
|
|
233
|
+
* Keys may be camelCase (`timeRange`) or kebab-case (`time-range`); both land on
|
|
234
|
+
* the same tag (`<User.TimeRange />`). The runtime normalizes via
|
|
235
|
+
* `upperFirst(toCamel(key))`, so the type must mirror it exactly. Normalizing
|
|
236
|
+
* the tag is all this mapping does — `prop` is not derived from the tag name.
|
|
237
|
+
*/
|
|
238
|
+
export declare type FormFields<S> = {
|
|
239
|
+
[K in keyof S & string as UpperFirst<ToCamel<K>>]: FormFieldComponent<FormControlProps<S[K]>>;
|
|
342
240
|
};
|
|
343
241
|
|
|
344
|
-
export declare interface
|
|
345
|
-
|
|
346
|
-
props?: HostProps<TFl>;
|
|
242
|
+
export declare interface FormFieldSlotProps {
|
|
243
|
+
$bindings: Record<string, unknown>;
|
|
347
244
|
}
|
|
348
245
|
|
|
349
|
-
/**
|
|
350
|
-
|
|
246
|
+
/**
|
|
247
|
+
* The **normalized** binding arrays. A port that is not a string stays as an
|
|
248
|
+
* `undefined` placeholder so the `model[i] ↔ prop[i]` alignment survives.
|
|
249
|
+
*/
|
|
250
|
+
declare type FormFieldVModel = (string | undefined)[];
|
|
351
251
|
|
|
352
|
-
|
|
252
|
+
/**
|
|
253
|
+
* Field binding (design.md §7.1):
|
|
254
|
+
* - `model` — v-model names on the control (identity). Default `'modelValue'`.
|
|
255
|
+
* - `prop` — location(s) from FormView root (`name`, `buyers[0].name`).
|
|
256
|
+
*
|
|
257
|
+
* `prop` array pairs with `model` (prefix-aligned). Extra model ports are unbound.
|
|
258
|
+
*/
|
|
259
|
+
declare type FormFieldVModelRaw = string | readonly string[];
|
|
353
260
|
|
|
354
|
-
|
|
355
|
-
export declare type FormViewItemProps = {
|
|
356
|
-
'fl:prop'?: string | string[];
|
|
357
|
-
'col:span'?: string | number;
|
|
358
|
-
'col:place'?: 'auto' | 'start' | 'end';
|
|
359
|
-
} & FlExtraProps<ControlSchemaExtras>;
|
|
261
|
+
export declare type FormViewComponent = DefineComponent<FormViewProps>;
|
|
360
262
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
263
|
+
/**
|
|
264
|
+
* Host Form shell. `props` are **static** defaults: formless has no form-level
|
|
265
|
+
* snapshot to project from — the write model reaches the host as the bare
|
|
266
|
+
* `modelValue` attr (no-prefix rule, design.md §10.1). A library whose model
|
|
267
|
+
* port is named differently (`ElForm` → `model`) wraps the host in its own
|
|
268
|
+
* component that declares `modelValue` and forwards it (`MyForm`).
|
|
269
|
+
*/
|
|
270
|
+
declare interface FormViewFormBind {
|
|
271
|
+
component: Component;
|
|
272
|
+
props?: Record<string, unknown>;
|
|
364
273
|
}
|
|
365
274
|
|
|
366
|
-
|
|
275
|
+
declare type FormViewFormProp = boolean | 'auto';
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Host item shell. `props` are defaults, static or mapped from the field
|
|
279
|
+
* snapshot (`HostProps<FormFieldFormless>`); `createFormItem` does the
|
|
280
|
+
* projection.
|
|
281
|
+
*/
|
|
282
|
+
declare interface FormViewItemBind {
|
|
283
|
+
component: Component;
|
|
284
|
+
props?: HostProps<FormFieldFormless>;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
declare interface FormViewLayoutBind {
|
|
367
288
|
Row: Component;
|
|
368
289
|
Col: Component;
|
|
369
|
-
|
|
370
|
-
|
|
290
|
+
/**
|
|
291
|
+
* Default LayoutView props (density etc.): a static object. Tag `:layout:*`
|
|
292
|
+
* overlays them (near wins). `disabled` stays kernel-owned: always the
|
|
293
|
+
* `fl:layout` polarity flip.
|
|
294
|
+
*/
|
|
295
|
+
props?: Record<string, unknown>;
|
|
371
296
|
}
|
|
372
297
|
|
|
298
|
+
/** FormView `:fl:layout` is a boolean switch. Density is factory `layout.props` / `:layout:*`. */
|
|
299
|
+
declare type FormViewLayoutProp = boolean;
|
|
300
|
+
|
|
373
301
|
export declare interface FormViewProps {
|
|
302
|
+
/**
|
|
303
|
+
* FormView write model (the DTO). It is **not** a declared prop: the bare key
|
|
304
|
+
* stays in `attrs` and, per the no-prefix rule, also reaches the host Form — a
|
|
305
|
+
* host that wants it declares `modelValue` itself (wrap ElForm in a `MyForm`;
|
|
306
|
+
* design.md §10.1). The `onUpdate:modelValue` listener is read here
|
|
307
|
+
* (`useFormViewValue`) and also rides through to the host Form.
|
|
308
|
+
*/
|
|
374
309
|
modelValue?: unknown;
|
|
375
310
|
/**
|
|
376
311
|
* Grid hosting switch. Default `false`.
|
|
377
|
-
* Density:
|
|
378
|
-
*
|
|
312
|
+
* Density: factory `layout.props` plus `:layout:*` for **this** page LayoutView only.
|
|
313
|
+
* wrap-embed inner LayoutView inherits neither. Other `:layout:*` fall through to the host Row.
|
|
379
314
|
*/
|
|
380
|
-
'fl:layout'?:
|
|
381
|
-
'
|
|
382
|
-
'row:gutter'?: number;
|
|
315
|
+
'fl:layout'?: FormViewLayoutProp;
|
|
316
|
+
'layout:column'?: LayoutViewProps['column'];
|
|
383
317
|
/**
|
|
384
318
|
* Wrap the factory `form`. Default `'auto'`: on at the root, off when nested.
|
|
385
319
|
* Explicit `true` / `false` win.
|
|
386
320
|
*/
|
|
387
|
-
'fl:form'?:
|
|
388
|
-
/** Wrap the factory `item` per
|
|
321
|
+
'fl:form'?: FormViewFormProp;
|
|
322
|
+
/** Wrap the factory `item` per field (default `true` when `item.component` is bound). */
|
|
389
323
|
'fl:item'?: boolean;
|
|
390
324
|
}
|
|
391
325
|
|
|
392
|
-
export declare function getIn(root: unknown, prop: string): unknown;
|
|
393
|
-
|
|
394
326
|
/** Host Col span modulus (Element / Ant Design 24-grid). */
|
|
395
|
-
|
|
327
|
+
declare const GRID_TOTAL = 24;
|
|
396
328
|
|
|
397
329
|
/** Static host props, or derived from that layer's snapshot. */
|
|
398
|
-
|
|
330
|
+
declare type HostProps<TFl> = Record<string, unknown> | ((fl: TFl) => Record<string, unknown> | undefined);
|
|
399
331
|
|
|
400
332
|
/**
|
|
401
|
-
*
|
|
402
|
-
*
|
|
333
|
+
* 通用整数范围类型工具
|
|
334
|
+
* @example IntRange<1, 24> 会生成 1 到 24 的联合类型
|
|
403
335
|
*/
|
|
404
|
-
|
|
405
|
-
controlKey: string;
|
|
406
|
-
binding: ResolvedControlBinding;
|
|
407
|
-
getValues: () => unknown[];
|
|
408
|
-
[extra: string]: unknown;
|
|
409
|
-
} & ControlSchemaExtras;
|
|
410
|
-
|
|
411
|
-
export declare interface LayoutItemProps {
|
|
412
|
-
span?: ColSpanSpec;
|
|
413
|
-
place?: ColPlace;
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
export declare interface LayoutViewProps {
|
|
417
|
-
disabled?: boolean;
|
|
418
|
-
column?: number;
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
declare type LockedKeysForDef<Def> = LockedVModelKeys<SchemaModel<Def> extends ControlVModel | undefined ? SchemaModel<Def> : undefined>;
|
|
422
|
-
|
|
423
|
-
export declare type LockedVModelKeys<M extends ControlVModel | undefined> = ModelPortNames<M> | `onUpdate:${ModelPortNames<M>}`;
|
|
424
|
-
|
|
425
|
-
/** Widget `formless.item` vs schema `item`. `'self'` vs `false` is illegal. */
|
|
426
|
-
export declare function mergeInternalItem(widget?: ControlItemSetting, schema?: ControlItemSetting): ControlItemSetting | undefined;
|
|
336
|
+
declare type IntRange<F extends number, T extends number> = Exclude<_Enumerate<T>, _Enumerate<F>> | T;
|
|
427
337
|
|
|
428
|
-
declare
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
* to `string` and Volar/TS lose `User.Name` / `User.IdCard` as named keys.
|
|
433
|
-
* Tag props are `fl:*` plus the widget's public props (v-model ports locked).
|
|
434
|
-
*/
|
|
435
|
-
export declare type NamespacedControls<S> = {
|
|
436
|
-
[K in keyof S & string as CamelToPascal<K>]: FormControlComponent<WidgetTagProps<S[K]>>;
|
|
338
|
+
export declare const LayoutItem: DefineComponent<ExtractPropTypes< {
|
|
339
|
+
span: {
|
|
340
|
+
type: PropType<LayoutItemSpan>;
|
|
341
|
+
default: undefined;
|
|
437
342
|
};
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
*/
|
|
451
|
-
export declare type PathSegment = {
|
|
452
|
-
type: 'key';
|
|
453
|
-
key: string;
|
|
454
|
-
} | {
|
|
455
|
-
type: 'index';
|
|
456
|
-
index: number;
|
|
343
|
+
place: {
|
|
344
|
+
type: PropType<LayoutItemPlace>;
|
|
345
|
+
default: undefined;
|
|
346
|
+
};
|
|
347
|
+
}>, () => VNodeChild, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, PublicProps, Readonly<ExtractPropTypes< {
|
|
348
|
+
span: {
|
|
349
|
+
type: PropType<LayoutItemSpan>;
|
|
350
|
+
default: undefined;
|
|
351
|
+
};
|
|
352
|
+
place: {
|
|
353
|
+
type: PropType<LayoutItemPlace>;
|
|
354
|
+
default: undefined;
|
|
457
355
|
};
|
|
356
|
+
}>> & Readonly<{}>, {
|
|
357
|
+
place: LayoutItemPlace;
|
|
358
|
+
span: LayoutItemSpan;
|
|
359
|
+
}, {}, {}, {}, string, ComponentProvideOptions, true, {}, any>;
|
|
458
360
|
|
|
459
|
-
|
|
460
|
-
model?: ControlVModel;
|
|
461
|
-
prop?: ControlProp;
|
|
462
|
-
}, overrides?: ControlBindingOverrides): ResolvedControlBinding;
|
|
361
|
+
declare type LayoutItemPlace = 'auto' | 'start' | 'end';
|
|
463
362
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
* wraps outer Item (and Col when page layout is on) and asks for an inner Row.
|
|
468
|
-
* Col follows the Row host only; no control/cell layout switch.
|
|
469
|
-
*/
|
|
470
|
-
export declare function resolveControlShell(input: ResolveControlShellInput): ResolvedControlShell;
|
|
471
|
-
|
|
472
|
-
declare interface ResolveControlShellInput {
|
|
473
|
-
pageItem: boolean;
|
|
474
|
-
pageLayoutOn: boolean;
|
|
475
|
-
internalItem?: ControlItemSetting;
|
|
476
|
-
/** Tag `:fl:item`. Omitted ≠ `true`. */
|
|
477
|
-
tagItem?: boolean;
|
|
363
|
+
declare interface LayoutItemProps {
|
|
364
|
+
span?: LayoutItemSpan;
|
|
365
|
+
place?: LayoutItemPlace;
|
|
478
366
|
}
|
|
479
367
|
|
|
480
|
-
|
|
481
|
-
models: string[];
|
|
482
|
-
props: string[];
|
|
483
|
-
}
|
|
368
|
+
declare type LayoutItemSpan = ColSpan | `${ColSpan}` | `${ColSpan}x` | 'max';
|
|
484
369
|
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
extraRow: boolean;
|
|
489
|
-
self: boolean;
|
|
370
|
+
declare interface LayoutViewProps {
|
|
371
|
+
disabled?: boolean;
|
|
372
|
+
column?: number;
|
|
490
373
|
}
|
|
491
374
|
|
|
492
|
-
|
|
493
|
-
* Optional Element-style encoding: one location → dotted path; several →
|
|
494
|
-
* control key. Kernel does not put this on Item `fl` — the adapter Item
|
|
495
|
-
* calls this (or encodes another way) when mapping to host `prop`.
|
|
496
|
-
*/
|
|
497
|
-
export declare function resolveFormItemProp(binding: ResolvedControlBinding, controlKey: string): string;
|
|
375
|
+
declare type LockedKeysForDef<Def> = LockedVModelKeys<SchemaModel<Def> extends FormFieldVModelRaw | undefined ? SchemaModel<Def> : undefined>;
|
|
498
376
|
|
|
499
|
-
|
|
377
|
+
declare type LockedVModelKeys<M extends FormFieldVModelRaw | undefined> = ModelPortNames<M> | `onUpdate:${ModelPortNames<M>}`;
|
|
378
|
+
|
|
379
|
+
declare type ModelPortNames<M> = [M] extends [undefined] ? 'modelValue' : M extends string ? M : M extends readonly [infer F extends string, ...infer R] ? F | ModelPortNames<R> : 'modelValue';
|
|
500
380
|
|
|
501
381
|
/**
|
|
502
|
-
* v-model ports locked on the tag (
|
|
382
|
+
* v-model ports locked on the tag (design.md §7.2 / §17). Schema `model` wins;
|
|
503
383
|
* omitted `model` locks the default `'modelValue'`.
|
|
504
384
|
* Widened `string[]` is not treated as port names (would Omit every string key).
|
|
505
385
|
*/
|
|
@@ -507,55 +387,31 @@ declare type SchemaModel<Def> = Def extends {
|
|
|
507
387
|
model: infer M;
|
|
508
388
|
} ? M : undefined;
|
|
509
389
|
|
|
510
|
-
/**
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
export declare function toBindingList(value: ControlVModel | ControlProp): string[];
|
|
514
|
-
|
|
515
|
-
export declare function useFormContext(): FormContext;
|
|
390
|
+
/** Type-level `toCamel` (built-in `Capitalize`): `'layout-item'` → `'layoutItem'`. */
|
|
391
|
+
declare type ToCamel<S extends string> = S extends `${infer Head}-${infer Tail}` ? `${Head}${Capitalize<ToCamel<Tail>>}` : S;
|
|
516
392
|
|
|
517
393
|
/**
|
|
518
|
-
*
|
|
519
|
-
*
|
|
520
|
-
*
|
|
521
|
-
*
|
|
394
|
+
* Any declaration bag → its optional tag props under `Prefix` (`label` →
|
|
395
|
+
* `'fl:label'` under the default prefix). Always optional (override, not
|
|
396
|
+
* required).
|
|
397
|
+
*
|
|
398
|
+
* The prefix is the kernel channel the keys land on: `fl:` for the field
|
|
399
|
+
* declaration, `layout:` / `layout-item:` for the layout package's prop bags.
|
|
400
|
+
* One mapper therefore produces every prefixed tag key space instead of each
|
|
401
|
+
* one being retyped.
|
|
522
402
|
*/
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
export declare function useLayoutItem(): Component;
|
|
527
|
-
|
|
528
|
-
export declare interface WidgetFormless {
|
|
529
|
-
model?: string | string[];
|
|
530
|
-
item?: boolean | 'self';
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
/** Widget props that may appear on `<User.Xxx />` (v-model ports stripped). */
|
|
534
|
-
export declare type WidgetTagProps<Def> = Def extends {
|
|
535
|
-
component?: infer C;
|
|
536
|
-
} ? [Exclude<C, undefined>] extends [never] ? {} : Omit<ComponentPublicProps<Exclude<C, undefined>>, LockedKeysForDef<Def>> : {};
|
|
537
|
-
|
|
538
|
-
/** FormView-owned Item shell. Col is owned by LayoutView / useLayoutItem. */
|
|
539
|
-
export declare type WrapControl = (body: VNodeChild, meta: WrapControlMeta) => VNodeChild;
|
|
403
|
+
declare type ToFormlessProps<T, Prefix extends string = 'fl:'> = {
|
|
404
|
+
[K in keyof T as K extends string ? `${Prefix}${K}` : never]+?: T[K];
|
|
405
|
+
};
|
|
540
406
|
|
|
541
|
-
/**
|
|
542
|
-
|
|
543
|
-
/**
|
|
544
|
-
* This wrap only. `false` skips Item even when FormView `item` is on.
|
|
545
|
-
* `true` forces Item even when FormView `item` is off. Omit = follow FormView.
|
|
546
|
-
*/
|
|
547
|
-
item?: boolean;
|
|
548
|
-
fl: ItemFl;
|
|
549
|
-
itemAttrs: Record<string, unknown>;
|
|
550
|
-
itemOn: Record<string, unknown>;
|
|
551
|
-
itemSlots: Record<string, Slot>;
|
|
552
|
-
}
|
|
407
|
+
/** Type-level `upperFirst`: `'name'` → `'Name'` (design.md §11). */
|
|
408
|
+
declare type UpperFirst<S extends string> = S extends `${infer F}${infer R}` ? `${Uppercase<F>}${R}` : S;
|
|
553
409
|
|
|
554
410
|
export { }
|
|
555
411
|
|
|
556
412
|
|
|
557
413
|
declare module 'vue' {
|
|
558
414
|
interface ComponentCustomOptions {
|
|
559
|
-
formless?:
|
|
415
|
+
formless?: FormControlFormless;
|
|
560
416
|
}
|
|
561
417
|
}
|