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 CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  English | [简体中文](./README.md)
4
4
 
5
- > Vue 3 form library: a page-level control table plus FormView, with layout kept off the inputs. **0.1.1** — APIs may still change in 0.x.
5
+ > Vue 3 form library: a page-level control table plus FormView, with layout kept off the inputs. **0.2.0** — APIs may still change in 0.x.
6
6
 
7
7
  Same mixed layout: Element Row/Col/Item on the left, `<User.*>` plus nested `FormView` density on the right.
8
8
 
@@ -25,30 +25,64 @@ Bind host Form / Item / Row / Col once in the project (no official Element adapt
25
25
 
26
26
  ```ts
27
27
  import { ElCol, ElForm, ElFormItem, ElInput, ElRow } from 'element-plus'
28
- import { createFormControls, createFormView, resolveFormItemProp, type ItemFl } from 'vue-formless'
28
+ import { defineComponent, h, ref, type PropType } from 'vue'
29
+ import { createFormFields, createFormView, type FormFieldFormless } from 'vue-formless'
29
30
 
30
31
  declare module 'vue-formless' {
31
- interface ControlSchema {
32
+ interface FormFieldCustomOptions {
32
33
  label?: string
33
34
  }
34
35
  }
35
36
 
36
- export const FormView = createFormView({
37
- layout: { Row: ElRow, Col: ElCol, column: 2, gutter: 16 },
38
- form: {
39
- component: ElForm,
40
- props: (fl) => ({ model: fl.modelValue }),
37
+ // ElFormItem `prop` speaks dot paths; the kernel location (`buyers[0].name`)
38
+ // is encoded here, in the adapter (design.md §20.9). One host `prop` cannot hold
39
+ // several ports, so such a field stays unbound (`undefined`) — use
40
+ // `fl:field="wrap-embed"` (one port per field) when the host must validate it.
41
+ function toItemProp(prop: FormFieldFormless['prop']): string | undefined {
42
+ if (prop == null || prop.length !== 1) return undefined
43
+ const [location] = prop
44
+ if (location == null) return undefined
45
+ const dotted = location.replace(/\[(\d+)\]/g, '.$1').replace(/^\./, '')
46
+ if (!dotted || /[[\]]/.test(dotted)) return undefined // unencodable: leave unbound
47
+ return dotted
48
+ }
49
+
50
+ // The no-prefix write model `modelValue` falls through to the host Form, but
51
+ // ElForm names its model port `model`: the adapter wraps it in a MyForm that
52
+ // maps the port and forwards ElForm's exposed instance methods (validate /
53
+ // resetFields) up to FormView's ref proxy. The factory no longer takes a
54
+ // functional `form.props`.
55
+ const MyForm = defineComponent({
56
+ inheritAttrs: false,
57
+ props: { modelValue: { type: [Object, Array] as PropType<unknown>, default: undefined } },
58
+ setup(props, { attrs, slots, expose }) {
59
+ const form = ref<Record<string, unknown> | null>(null)
60
+ expose(new Proxy({}, {
61
+ get: (_, key) => {
62
+ const inner = form.value
63
+ if (inner == null) return undefined
64
+ const value = Reflect.get(inner, key, inner)
65
+ return typeof value === 'function' ? value.bind(inner) : value
66
+ },
67
+ has: (_, key) => form.value != null && key in form.value,
68
+ }))
69
+ return () => h(ElForm, { ...attrs, ref: form, model: props.modelValue }, slots)
41
70
  },
71
+ })
72
+
73
+ export const FormView = createFormView({
74
+ layout: { Row: ElRow, Col: ElCol, props: { column: 2 } },
75
+ form: { component: MyForm },
42
76
  item: {
43
77
  component: ElFormItem,
44
- props: (fl: ItemFl) => ({
78
+ props: (fl: FormFieldFormless) => ({
45
79
  label: fl.label,
46
- prop: resolveFormItemProp(fl.binding, fl.controlKey),
80
+ prop: toItemProp(fl.prop),
47
81
  }),
48
82
  },
49
83
  })
50
84
 
51
- export const User = createFormControls({
85
+ export const User = createFormFields({
52
86
  name: { label: 'Name', component: ElInput },
53
87
  })
54
88
  ```
@@ -56,11 +90,20 @@ export const User = createFormControls({
56
90
  ```vue
57
91
  <FormView ref="formRef" v-model="form" fl:layout label-width="96px">
58
92
  <User.Name />
59
- <User.Name col:span="max" />
93
+ <User.Name layout-item:span="max" />
60
94
  </FormView>
61
95
  ```
62
96
 
63
- `validate()` / `resetFields()` go through the FormView ref (proxied host Form). Layout details: [docs/adr](./docs/adr/README.md).
97
+ `validate()` / `resetFields()` go through the FormView ref (proxied host Form). Layout details: [docs/adr](./docs/adr.md).
98
+
99
+ ## Live playgrounds
100
+
101
+ GitHub Pages (set **Settings → Pages → Source** to GitHub Actions; deploys from `main`):
102
+
103
+ - Forms: [https://xuyimingwork.github.io/vue-formx/](https://xuyimingwork.github.io/vue-formx/)
104
+ - 24-col layout: [https://xuyimingwork.github.io/vue-formx/layout/](https://xuyimingwork.github.io/vue-formx/layout/)
105
+
106
+ Local preview of the Pages bundle: `PAGES_BASE=/vue-formx/ pnpm build:pages`, then serve `site/`.
64
107
 
65
108
  ## Layout
66
109
 
@@ -68,7 +111,8 @@ export const User = createFormControls({
68
111
  packages/vue-formless # kernel (npm: vue-formless)
69
112
  packages/layout # internal grid, bundled into the kernel
70
113
  playground # Element Plus baseline vs Formless
71
- docs/adr # architecture decisions
114
+ playground-layout # 24-col layout studio
115
+ docs/adr.md # architecture decisions (single doc)
72
116
  ```
73
117
 
74
118
  ## Development
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  简体中文 | [English](./README.en.md)
4
4
 
5
- > Vue 3 表单组合式库:控件表 + FormView,布局与输入拆开。当前 **0.1.1**,`0.x` 期间 API 仍可能调整。
5
+ > Vue 3 表单组合式库:控件表 + FormView,布局与输入拆开。当前 **0.2.0**,`0.x` 期间 API 仍可能调整。
6
6
 
7
7
  同一套混合布局:左边手写 Element Row/Col/Item,右边 `<User.*>` + 嵌套 `FormView` 换密度。
8
8
 
@@ -25,30 +25,61 @@ peer:`vue` ^3.3。
25
25
 
26
26
  ```ts
27
27
  import { ElCol, ElForm, ElFormItem, ElInput, ElRow } from 'element-plus'
28
- import { createFormControls, createFormView, resolveFormItemProp, type ItemFl } from 'vue-formless'
28
+ import { defineComponent, h, ref, type PropType } from 'vue'
29
+ import { createFormFields, createFormView, type FormFieldFormless } from 'vue-formless'
29
30
 
30
31
  declare module 'vue-formless' {
31
- interface ControlSchema {
32
+ interface FormFieldCustomOptions {
32
33
  label?: string
33
34
  }
34
35
  }
35
36
 
36
- export const FormView = createFormView({
37
- layout: { Row: ElRow, Col: ElCol, column: 2, gutter: 16 },
38
- form: {
39
- component: ElForm,
40
- props: (fl) => ({ model: fl.modelValue }),
37
+ // ElFormItem 的 `prop` 用点分路径;内核位置(`buyers[0].name`)由本层编码(design.md §20.9)。
38
+ // 一个宿主 `prop` 装不下多个口 → 多口一格不绑宿主(`undefined`),
39
+ // 需要宿主校验就用 `fl:field="wrap-embed"` 拆成一格一口。
40
+ function toItemProp(prop: FormFieldFormless['prop']): string | undefined {
41
+ if (prop == null || prop.length !== 1) return undefined
42
+ const [location] = prop
43
+ if (location == null) return undefined
44
+ const dotted = location.replace(/\[(\d+)\]/g, '.$1').replace(/^\./, '')
45
+ if (!dotted || /[[\]]/.test(dotted)) return undefined // 编不出来:不绑宿主
46
+ return dotted
47
+ }
48
+
49
+ // 无前缀的写口 `modelValue` 按 no-prefix 规则透传到宿主 Form,而 ElForm 的 model
50
+ // 口叫 `model`:适配层用一个 MyForm 包住 ElForm 完成映射,并把 ElForm 实例的
51
+ // validate / resetFields 透出给 FormView 的 ref 代理。工厂不再接受 form.props 函数。
52
+ const MyForm = defineComponent({
53
+ inheritAttrs: false,
54
+ props: { modelValue: { type: [Object, Array] as PropType<unknown>, default: undefined } },
55
+ setup(props, { attrs, slots, expose }) {
56
+ const form = ref<Record<string, unknown> | null>(null)
57
+ expose(new Proxy({}, {
58
+ get: (_, key) => {
59
+ const inner = form.value
60
+ if (inner == null) return undefined
61
+ const value = Reflect.get(inner, key, inner)
62
+ return typeof value === 'function' ? value.bind(inner) : value
63
+ },
64
+ has: (_, key) => form.value != null && key in form.value,
65
+ }))
66
+ return () => h(ElForm, { ...attrs, ref: form, model: props.modelValue }, slots)
41
67
  },
68
+ })
69
+
70
+ export const FormView = createFormView({
71
+ layout: { Row: ElRow, Col: ElCol, props: { column: 2 } },
72
+ form: { component: MyForm },
42
73
  item: {
43
74
  component: ElFormItem,
44
- props: (fl: ItemFl) => ({
75
+ props: (fl: FormFieldFormless) => ({
45
76
  label: fl.label,
46
- prop: resolveFormItemProp(fl.binding, fl.controlKey),
77
+ prop: toItemProp(fl.prop),
47
78
  }),
48
79
  },
49
80
  })
50
81
 
51
- export const User = createFormControls({
82
+ export const User = createFormFields({
52
83
  name: { label: '姓名', component: ElInput },
53
84
  })
54
85
  ```
@@ -56,11 +87,20 @@ export const User = createFormControls({
56
87
  ```vue
57
88
  <FormView ref="formRef" v-model="form" fl:layout label-width="96px">
58
89
  <User.Name />
59
- <User.Name col:span="max" />
90
+ <User.Name layout-item:span="max" />
60
91
  </FormView>
61
92
  ```
62
93
 
63
- `validate()` / `resetFields()` 走 FormView 的 ref(代理内层 Form)。栅格细节见 [docs/adr](./docs/adr/README.md)。
94
+ `validate()` / `resetFields()` 走 FormView 的 ref(代理内层 Form)。栅格细节见 [docs/adr](./docs/adr.md)。
95
+
96
+ ## 在线 Playground
97
+
98
+ GitHub Pages(仓库需在 **Settings → Pages → Source** 选 GitHub Actions,推 `main` 后生成):
99
+
100
+ - 表单对照:[https://xuyimingwork.github.io/vue-formx/](https://xuyimingwork.github.io/vue-formx/)
101
+ - 24 格布局:[https://xuyimingwork.github.io/vue-formx/layout/](https://xuyimingwork.github.io/vue-formx/layout/)
102
+
103
+ 本地预览打包结果:`PAGES_BASE=/vue-formx/ pnpm build:pages`,再用任意静态服务器打开 `site/`。
64
104
 
65
105
  ## 仓库结构
66
106
 
@@ -68,7 +108,8 @@ export const User = createFormControls({
68
108
  packages/vue-formless # 内核(npm:vue-formless)
69
109
  packages/layout # 内部栅格,打进内核 dist
70
110
  playground # Element Plus 基线 vs Formless
71
- docs/adr # 架构决策
111
+ playground-layout # 24 格布局工作台
112
+ docs/adr.md # 架构决策(单篇汇总)
72
113
  ```
73
114
 
74
115
  ## 开发
@@ -86,6 +127,8 @@ Playground 对照:基础表单、筛选条、只读详情、混合布局、Dat
86
127
  ```bash
87
128
  pnpm playground
88
129
  # http://localhost:5173
130
+ pnpm playground:layout
131
+ # http://localhost:5174
89
132
  ```
90
133
 
91
134
  ## License
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("vue"),N=Symbol("vue-formless.formContext");function Y(){const e=l.inject(N,null);if(!e)throw new Error("[vue-formless] useFormContext() must be used inside <FormView>.");return e}function D(e){if(!e)return[];const t=[];let o=0;for(;o<e.length;){if(e[o]==="."){o++;continue}if(e[o]==="["){const n=e.indexOf("]",o+1);if(n===-1)throw new Error(`Invalid path "${e}": unclosed bracket`);const r=e.slice(o+1,n),s=Number(r);if(!Number.isInteger(s)||String(s)!==r||s<0)throw new Error(`Invalid path "${e}": index must be a non-negative integer`);t.push({type:"index",index:s}),o=n+1}else{const n=/^[a-zA-Z_$][a-zA-Z0-9_$]*/.exec(e.slice(o));if(!n)throw new Error(`Invalid path "${e}" at position ${o}`);t.push({type:"key",key:n[0]}),o+=n[0].length}}return t}function Ne(e,t){let o=e;for(const n of t)n.type==="key"?o=o[n.key]:o=o[n.index];return o}function _e(e,t){if(t.type==="key")return e==null||typeof e!="object"||Array.isArray(e)?void 0:e[t.key];if(Array.isArray(e))return e[t.index]}function k(e,t){const o=D(t);if(o.length===0)return;const n=o[o.length-1],r=Ne(e,o.slice(0,-1));return _e(r,n)}function J(e,t,o,n){const r=t[o],s=o===t.length-1;if(r.type==="key"){if(Array.isArray(e))throw new Error(`Cannot set "${r.key}" on an array node`);const i=e!=null&&typeof e=="object"?e:{};return s?{...i,[r.key]:n}:{...i,[r.key]:J(i[r.key],t,o+1,n)}}const u=Array.isArray(e)?[...e]:[];return s?(u[r.index]=n,u):(u[r.index]=J(u[r.index],t,o+1,n),u)}function we(e,t,o){const n=D(t);if(n.length===0)throw new Error("Cannot set an empty prop");return J(e,n,0,o)}function ye(e){return D(e).map(t=>t.type==="key"?t.key:String(t.index)).join(".")}function Me(e,t){let o=null;function n(r,s){o||(o=[],l.nextTick(()=>{if(!o?.length){o=null;return}let u=e();for(const i of o)u=we(u,i.prop,i.value);o=null,t(u)})),o.push({prop:r,value:s})}return{update:n}}const p=24,V={column:1};function Te(e){const t=Math.floor(Number(e));return t===1/0?p:Number.isFinite(t)?Math.min(p,Math.max(1,t)):V.column}function Be(...e){return Te(e.find(t=>t!=null)??V.column)}function Ue(e,t){const o=t>0?t:V.column,n=Math.max(1,Math.floor(p/o));if(e==null||e==="")return n;if(typeof e=="number")return ce(e),e;const r=e.trim();if(r==="max")return p;const s=/^(\d+)x$/.exec(r);if(s){const u=Number(s[1]);if(u<1)throw new Error(`[vue-formless] col:span "${e}" is invalid`);return Math.min(p,u*n)}if(/^\d+$/.test(r)){const u=Number(r);return ce(u),u}throw new Error(`[vue-formless] col:span "${e}" is invalid`)}function ce(e){if(!Number.isInteger(e)||e<1||e>p)throw new Error(`[vue-formless] col:span ${e} must be an integer 1–${p}`)}function We(e){if(e==null||e===""||e==="auto")return"auto";if(e==="start"||e==="end")return e;throw new Error(`[vue-formless] col:place "${String(e)}" is invalid`)}const W=Symbol("vue-formless:layout-view");function Ge(e,t,o={childList:!0}){if(typeof MutationObserver>"u")return;let n=null;function r(u){n?.disconnect(),n=null,u&&(n=new MutationObserver(t),n.observe(u,o))}l.onMounted(()=>r(l.toValue(e)));const s=l.watch(()=>l.toValue(e),r,{flush:"post"});l.onBeforeUnmount(()=>{s(),n?.disconnect(),n=null})}function Ye(e,t=0){const o=l.ref([]);function n(){const r=l.toValue(e);o.value=r?Array.from(r.children):[]}return l.watch(()=>[l.toValue(e),l.toValue(t)],n,{immediate:!0}),Ge(e,n),o}function De(e,t,o){const n=[];if(o==="auto")return e.n+t>p&&(e.n=0),n;if(o==="start")return e.n>0&&(n.push(p-e.n),e.n=0),n;e.n+t>p&&e.n>0&&(n.push(p-e.n),e.n=0);const r=p-e.n-t;return r>0&&(n.push(r),e.n+=r),n}function ze(e){return l.computed(()=>{const t={n:0},o=new Map;for(const n of l.toValue(e)){const r=De(t,n.span,n.place);o.set(n.id,r),t.n+=n.span}return o})}function ge(e){if(e==null||typeof e!="object")return null;if(typeof Element<"u"&&e instanceof Element)return e;const t=e;return U(t.vnode?.el)??U(t.subTree?.el)??U(t.subTree?.component?.vnode?.el)??U(t.$el)}function U(e){if(typeof Element<"u"&&e instanceof Element)return e;if(e&&e.nodeType===8){for(let t=e.nextSibling;t;t=t.nextSibling)if(typeof Element<"u"&&t instanceof Element)return t}return null}const Ke=l.defineComponent({name:"LayoutBlanks",inheritAttrs:!1,props:{is:{type:Object,default:void 0},spans:{type:Array,required:!0}},setup(e){return()=>{if(e.spans.length===0||e.is==null)return null;const t=e.is;return l.createVNode(l.Fragment,null,[e.spans.map((o,n)=>l.createVNode(t,{key:n,span:o},null))])}}}),qe=l.defineComponent({name:"LayoutItem",inheritAttrs:!1,props:{span:{type:[String,Number],default:void 0},place:{type:String,default:void 0}},setup(e,{slots:t}){const o=l.inject(W,null);if(!o)return()=>t.default?.()??null;const{span:n,blanks:r,itemRef:s,Col:u,disabled:i}=o(()=>e.span,()=>e.place);return()=>{if(i.value)return t.default?.()??null;const f=u;return l.createVNode(l.Fragment,null,[l.createVNode(Ke,{is:u,spans:r.value},null),l.createVNode(f,{ref:s,span:n.value},{default:()=>[t.default?.()??null]})])}}}),He=l.defineComponent({name:"LayoutItemPassThrough",inheritAttrs:!1,setup(e,{slots:t}){return()=>t.default?.()??null}});function he(){return l.inject(W,null)?qe:He}function Xe(e){const t=l.ref({});let o=0;return{get value(){return t.value},setup(n,r){const s=String(++o),u=l.computed(()=>Ue(l.toValue(n),l.toValue(e))),i=l.computed(()=>We(l.toValue(r)));return t.value[s]={span:u,place:i,el:null,mounted:!1},l.onMounted(()=>{const f=t.value[s];f&&(f.mounted=!0)}),l.onBeforeUnmount(()=>{delete t.value[s]}),s},span(n){return t.value[n]?.span??0},ref(n,r){const s=t.value[n];if(!s)return;const u=ge(r);s.el!==u&&(s.el=u)}}}function Ze(e,t){const o=new Map(Object.entries(e).filter(([,n])=>n.el).map(([n,r])=>[r.el,{id:n,span:r.span,place:r.place}]));return t.filter(n=>o.has(n)).map(n=>o.get(n))}function Je(e,t){const o=Ye(()=>ge(t.value),()=>Object.keys(e.value).filter(n=>e.value[n].mounted).join(","));return ze(()=>Ze(e.value,o.value))}function ne(e={}){const{Row:t,Col:o}=e;return l.defineComponent({name:"LayoutView",inheritAttrs:!1,props:{disabled:{type:Boolean,default:!1},column:{type:Number,default:void 0}},setup(n,{slots:r,attrs:s}){const u=l.computed(()=>!t||!o||n.disabled),i=Xe(()=>Be(n.column,e.column)),f=l.ref(null),a=Je(i,f);return l.provide(W,(m,g)=>{l.provide(W,null);const w=i.setup(m,g);return{span:l.computed(()=>i.span(w)),blanks:l.computed(()=>a.value.get(w)??[]),itemRef:b=>i.ref(w,b),Col:o,disabled:u}}),()=>{if(u.value)return r.default?.()??null;const m=t;return l.createVNode(m,l.mergeProps({ref:f},s),{default:()=>[r.default?.()??null]})}}})}const Qe=new Set(["item","layout","model","span"]),et=new Set(["component","props","model","prop","item","layout"]);function Q(e){const t={};for(const[o,n]of Object.entries(e))n!==void 0&&(t[o]=n);return t}function oe(e){const t={};for(const[o,n]of Object.entries(e))o==="span"&&n!==void 0&&console.warn("[vue-formless] fl:span is removed; use col:span"),Qe.has(o)||(t[o]=n);return t}function tt(e){const t={};for(const[o,n]of Object.entries(e))!et.has(o)&&n!==void 0&&(t[o]=n);return t}function nt(e){if(e==null||typeof e!="object")return{};const t=e.formless;if(t==null||typeof t!="object")return{};const{model:o,item:n}=t;return Q({model:o,item:n})}function ve(e){const t={};for(const[o,n]of Object.entries(e))!o.startsWith("fl:")||o.length<=3||n===void 0||(t[o.slice(3)]=n);return t}function ot(e,t){const o=new Set;for(const r of t)o.add(r),o.add(`onUpdate:${r}`);const n={};for(const[r,s]of Object.entries(e))o.has(r)||(n[r]=s);return n}function $(e,t){return e==null?{}:Q(typeof e=="function"?e(t)??{}:e)}function z(...e){const t={};for(const o of e)if(o!=null)for(const[n,r]of Object.entries(o))r!==void 0&&(t[n]=r);return t}function rt(e){const t=e.Item?l.markRaw(e.Item):void 0;return(o,n)=>t&&n.item!==!1&&(n.item===!0||(e.isItemEnabled?.()??!0))?l.h(t,z($(e.itemProps,n.fl),n.itemAttrs,n.itemOn),{...n.itemSlots,default:()=>o}):o}function ee(e){return typeof e=="string"?[e]:[...e]}function re(e,t={},o={}){if(o.prop==="")throw new Error(`[vue-formless] fl:prop cannot be an empty string (control "${e}")`);if(t.prop==="")throw new Error(`[vue-formless] prop cannot be an empty string (control "${e}")`);const n=ee(t.model??"modelValue"),r=ee(o.prop!==void 0?o.prop:t.prop??e);if(r.length>n.length)throw new Error(`createFormControls: prop cannot be longer than model (control "${e}": model has ${n.length}, prop has ${r.length})`);if(r.some(s=>s===""))throw new Error(`[vue-formless] prop cannot be an empty string (control "${e}")`);return{models:n,props:r}}function lt(e,t){return e.props.length===1?ye(e.props[0]):t}function be(e,t){const o=e.models.indexOf(t);if(o===-1)throw new Error(`[vue-formless] useFormItem("${t}"): not a v-model port of this control`);const n=e.props[o];if(n===void 0)throw new Error(`[vue-formless] useFormItem("${t}"): port is not bound to a prop`);return{models:[t],props:[n]}}function le(e,t,o){const n={};for(let r=0;r<t.props.length;r++){const s=t.models[r],u=t.props[r];n[s]=k(e,u),n[`onUpdate:${s}`]=i=>{o(u,i)}}return n}const O="item:",q="onItem:",H="fl:",X="row:",Z="col:",st=new Set(["column","gutter"]),ut=new Set(["span","place"]);function fe(e){console.warn(e)}function Ie(e){const t={},o={};for(const n of Object.keys(e)){const r=e[n];r&&(n.startsWith(O)&&n.length>O.length?t[n.slice(O.length)]=r:o[n]=r)}return{itemSlots:t,inputSlots:o}}function Ce(e){const t={},o={};for(const[n,r]of Object.entries(e))n.startsWith(H)&&n.length>H.length?t[n.slice(H.length)]=r:o[n]=r;return{fl:t,rest:o}}function Fe(e){const t={},o={},n={};for(const[r,s]of Object.entries(e))if(r.startsWith(X)&&r.length>X.length){const u=r.slice(X.length);st.has(u)?t[u]=s:fe(`[vue-formless] unknown row:${u} is ignored`)}else if(r.startsWith(Z)&&r.length>Z.length){const u=r.slice(Z.length);ut.has(u)?o[u]=s:fe(`[vue-formless] unknown col:${u} is ignored`)}else n[r]=s;return{row:t,col:o,rest:n}}function me(e){if(e==null||e==="")return;const t=typeof e=="number"?e:Number(e);if(Number.isFinite(t))return t}function Ee(e){const t={},o={},n={};for(const[r,s]of Object.entries(e))r.startsWith(q)&&r.length>q.length?o[it(r.slice(q.length))]=s:r.startsWith(O)&&r.length>O.length?t[r.slice(O.length)]=s:n[r]=s;return{itemAttrs:t,itemOn:o,inputAttrs:n}}function it(e){const t=e.indexOf(":");return t===-1?`on${de(e)}`:`on${de(e.slice(0,t))}:${e.slice(t+1)}`}function de(e){return e&&e.charAt(0).toUpperCase()+e.slice(1)}const Ve=Symbol("vue-formless.controlRuntime");function at(e){l.provide(Ve,e)}const ct={"fl:prop":{type:[String,Array],default:void 0},"col:span":{type:[String,Number],default:void 0},"col:place":{type:String,default:void 0}};function Se(e){return l.defineComponent({name:e?`FormViewItem_${e}`:"FormViewItem",inheritAttrs:!1,props:ct,setup(t,{slots:o,attrs:n}){const r=Y(),s=he(),u=l.inject(Ve,null);if(e!=null&&!u)throw new Error("[vue-formless] useFormItem(port) must be used inside a namespaced control.");return()=>ft(r,s,u,e,o,n,t)}})}const se=Se();function Ae(e){return Y(),e===void 0?se:Se(e)}function ft(e,t,o,n,r,s,u){const{fl:i,rest:f}=Ce(s),{row:a,col:m,rest:g}=Fe(f),w={...i,...ve(u)},{itemAttrs:b,itemOn:v,inputAttrs:S}=Ee(g),I={...b,...S},{itemSlots:y}=Ie(r),d=n==null&&o!=null,C=u["col:span"]??m.span,A=u["col:place"]??m.place,c=o?.getFrame(),L=C??(d?c?.colSpan:void 0),x=A??(d?c?.colPlace:void 0),_=mt(e,o,n,w),M=le(e.model,_.binding,e.update),K=r.default?.({field:M})??null;!d&&(a.column!=null||a.gutter!=null)&&console.warn("[vue-formless] :row:* is ignored on a leaf cell");let F=I,E=v,T=y;d&&c&&(F={...c.itemAttrs,...I},E={...c.itemOn,...v},T={...c.itemSlots,...y});let R,B,P=!1;d&&c&&(R=c.wrapItem,B=c.wrapCol,P=c.extraRow);let h=K;if(P&&c){const j=h;h=l.h(e.LayoutView,{disabled:!e.isLayoutEnabled(),column:c.rowColumn??e.factoryColumn,gutter:c.rowGutter??e.factoryGutter},()=>j)}if(h=e.wrap(h,{item:R===!1?!1:R===!0?!0:void 0,fl:_.fl,itemAttrs:F,itemOn:E,itemSlots:T}),B!==!1){const j=h;h=l.h(t,{span:L,place:x},()=>j)}return h}function mt(e,t,o,n){const r=oe(n);if(t){const a=t.getFrame(),m=o!=null?be(a.binding,o):a.binding,g={...a.fl,...r,controlKey:t.controlKey,binding:m,getValues:()=>m.props.map(w=>k(e.model,w))};return{binding:m,fl:g}}const s=n.prop;if(s==="")throw new Error("[vue-formless] fl:prop cannot be an empty string");const u=typeof s=="string"?s:Array.isArray(s)&&s[0]?String(s[0]):"",i=s===void 0?{models:["modelValue"],props:[]}:re(u||"field",{prop:s}),f={...r,controlKey:u,binding:i,getValues:()=>i.props.map(a=>k(e.model,a))};return{binding:i,fl:f}}function Le(e){const t=e;return t.Item=se,t}const te=0;function dt(e){return new Proxy({},{get(t,o){const n=e.value;if(n==null)return;const r=Reflect.get(n,o,n);return typeof r=="function"?r.bind(n):r},has(t,o){return e.value!=null&&o in e.value}})}const Oe={modelValue:{type:[Object,Array],default:void 0},"fl:layout":{type:Boolean,default:!1},"row:column":{type:Number,default:void 0},"row:gutter":{type:Number,default:void 0},"fl:form":{type:[Boolean,String],default:"auto"},"fl:item":{type:Boolean,default:!0}},ke={"update:modelValue":e=>!0};function G(e){if(e!=null&&typeof e=="object")throw new Error("[vue-formless] fl:layout is boolean only; use :row:column / :row:gutter");return e===!0||e===""}function pt(e,t){return e===!0||e===!1?e:!t}function wt(e){return e==null?!1:"modelValue"in e||"model-value"in e||"onUpdate:modelValue"in e||"onUpdate:model-value"in e}function xe(e){const t=rt({Item:e.Item,itemProps:e.itemProps,isItemEnabled:e.isItemEnabled}),o=e.isItemEnabled??(()=>!0);l.provide(N,l.reactive({get model(){return e.getModel()},update:e.update,wrap:t,isItemEnabled:o,isLayoutEnabled:e.isLayoutEnabled,LayoutView:l.markRaw(e.LayoutView),factoryColumn:e.factoryColumn,factoryGutter:e.factoryGutter}))}function Re(e,t){const o=l.inject(N,null);if(wt(l.getCurrentInstance()?.vnode.props)){const r=Me(e,t);return{getModel:e,update:r.update}}if(o)return{getModel:()=>o.model,update:o.update};throw new Error("[vue-formless] FormView requires v-model unless nested inside another FormView.")}function yt(e){if(e!=null){if(e.Row==null||e.Col==null)throw new Error("[vue-formless] createFormView layout requires both Row and Col.");return{Row:l.markRaw(e.Row),Col:l.markRaw(e.Col),column:e.column,gutter:e.gutter}}}function gt(e={}){const t=yt(e.layout),o=e.form?.component?l.markRaw(e.form.component):void 0,n=e.form?.props,r=e.item?.component?l.markRaw(e.item.component):void 0,s=e.item?.props,u=ne(t?{Row:t.Row,Col:t.Col}:{}),i=t?.column??V.column,f=t?.gutter??te;return Le(l.defineComponent({name:"FormView",inheritAttrs:!1,props:Oe,emits:ke,setup(a,{slots:m,emit:g,attrs:w,expose:b}){const v=l.ref(null);b(dt(v));const S=l.inject(N,null)!=null,{getModel:I,update:y}=Re(()=>a.modelValue,d=>g("update:modelValue",d));return xe({getModel:I,update:y,Item:r,itemProps:s,isItemEnabled:()=>a["fl:item"]!==!1,isLayoutEnabled:()=>G(a["fl:layout"]),LayoutView:u,factoryColumn:i,factoryGutter:f}),()=>{const d=m.default?.()??null,C=G(a["fl:layout"]),A={column:a["row:column"]??i,gutter:a["row:gutter"]??f},c=l.h(u,{disabled:!C,column:A.column,gutter:A.gutter},()=>d),L=o?pt(a["fl:form"],S):!1;if(!o||!L)return c;const x={layout:C,form:L,item:a["fl:item"]!==!1,modelValue:I()};return l.h(o,{ref:v,...z($(n,x),w)},{default:()=>c})}}}))}const pe=ne(),ht=Le(l.defineComponent({name:"FormView",inheritAttrs:!1,props:Oe,emits:ke,setup(e,{slots:t,emit:o}){const{getModel:n,update:r}=Re(()=>e.modelValue,s=>o("update:modelValue",s));return xe({getModel:n,update:r,isLayoutEnabled:()=>G(e["fl:layout"]),LayoutView:pe,factoryColumn:V.column,factoryGutter:te}),()=>l.h(pe,{disabled:!G(e["fl:layout"]),column:e["row:column"]??V.column,gutter:e["row:gutter"]??te},()=>t.default?.()??null)}}));function ue(e){return e&&e.charAt(0).toUpperCase()+e.slice(1)}function vt(e){return e&&e.charAt(0).toLowerCase()+e.slice(1)}function Pe(e,t){if(e==="self"&&t===!1||e===!1&&t==="self")throw new Error('[vue-formless] formless.item "self" conflicts with schema item: false');return e??t}function je(e){const t=e.internalItem==="self";let o;e.tagItem===!0?o=!0:e.tagItem===!1||t||e.internalItem===!1?o=!1:e.internalItem===!0?o=!0:o=e.pageItem;let n=e.pageLayoutOn;t&&e.tagItem!==!0&&(o=!1,n=!1);const r=t&&e.tagItem===!0&&e.pageLayoutOn;return{wrapItem:o,wrapCol:n,extraRow:r,self:t}}const bt={"fl:prop":{type:[String,Array],default:void 0},"fl:item":{type:Boolean,default:void 0},"col:span":{type:[String,Number],default:void 0},"col:place":{type:String,default:void 0},"row:column":{type:Number,default:void 0},"row:gutter":{type:Number,default:void 0}};function It(e,t){const o=Et(e),n={};for(const r of Object.keys(o)){const s=o[r];if(!s)continue;const u=ue(r);n[u]=Ct(r,s,t)}return n}function Ct(e,t,o){const n=nt(t.component),r=n.model??t.model,s=Pe(n.item,t.item);return l.defineComponent({name:`Control_${ue(e)}`,inheritAttrs:!1,props:bt,setup(u,{attrs:i,slots:f}){const a=Y();let m;at({controlKey:e,getFrame:()=>m});const g=Ae();return()=>{const{fl:w,rest:b}=Ce(i),{row:v,col:S,rest:I}=Fe(b),y={...w,...ve(u)},d=re(e,{model:r,prop:t.prop},{prop:y.prop}),C=t.component,{itemSlots:A,inputSlots:c}=Ie(f),{itemAttrs:L,itemOn:x,inputAttrs:_}=Ee(I),M=tt(t),K=y.item===!0?!0:y.item===!1?!1:void 0,F=je({pageItem:a.isItemEnabled(),pageLayoutOn:a.isLayoutEnabled(),internalItem:s,tagItem:K}),E=Ft(a,e,d,M,y),T=z($(o?.props,E),$(t.props,E),ot(_,d.models)),R=le(a.model,d,a.update),B=d.props[0]??e,P=typeof E.label=="string"?E.label:void 0,h=u["col:span"]??S.span,j=u["col:place"]??S.place,ie=me(u["row:column"]??v.column),ae=me(u["row:gutter"]??v.gutter);!F.extraRow&&(ie!=null||ae!=null)&&console.warn("[vue-formless] :row:* is ignored on a leaf control");const $e=C?l.h(C,{...T,...R},c):l.h("div",{class:"vue-formless-control","data-control":e},[P?l.h("label",{class:"vue-formless-control__label"},String(P)):null,String(k(a.model,B)??"")]);return m={fl:{...M,...oe(y)},binding:d,wrapItem:F.wrapItem,wrapCol:F.wrapCol,extraRow:F.extraRow,colSpan:h,colPlace:j,rowColumn:ie,rowGutter:ae,itemAttrs:L,itemOn:x,itemSlots:A},l.h(g,null,()=>$e)}}})}function Ft(e,t,o,n,r){return{...n,...oe(r),controlKey:t,binding:o,getValues:()=>o.props.map(s=>k(e.model,s))}}function Et(e){const t={...e};for(const o of Object.keys(t)){const n=t[o];n&&(t[o]={...n,component:n.component&&typeof n.component=="object"?l.markRaw(n.component):n.component})}return t}exports.DEFAULT_LAYOUT=V;exports.FormView=ht;exports.FormViewItem=se;exports.GRID_TOTAL=p;exports.applyControlBinding=le;exports.bindingForPort=be;exports.camelToPascal=ue;exports.createFormControls=It;exports.createFormView=gt;exports.createLayoutView=ne;exports.formContextKey=N;exports.formItemProp=ye;exports.getIn=k;exports.mergeInternalItem=Pe;exports.overlayProps=z;exports.parsePath=D;exports.pascalToCamel=vt;exports.resolveControlBinding=re;exports.resolveControlShell=je;exports.resolveFormItemProp=lt;exports.resolveProps=$;exports.setIn=we;exports.toBindingList=ee;exports.useFormContext=Y;exports.useFormItem=Ae;exports.useLayoutItem=he;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("vue"),F=24,Y=1;function E(e){return Math.min(F,Math.max(1,e))}function G(e){return Math.floor(F/R(e))}function R(e){const t=Math.floor(Number(e));return Number.isNaN(t)?Y:E(t)}function Z(...e){return R([...e].reverse().find(t=>t!=null))}function X(e,t){const n=G(t);if(typeof e!="number"&&typeof e!="string"||(e=typeof e=="string"?e.trim().toLowerCase():e,e===""))return n;if(e==="max")return F;if(typeof e=="string"&&e.endsWith("x")){const r=Math.floor(Number(e.substring(0,e.length-1)));return Number.isNaN(r)?n:E(E(r)*n)}return e=Math.floor(Number(e)),Number.isNaN(e)?n:E(e)}function J(e){return e=typeof e=="string"?e.trim().toLowerCase():e,e==="start"||e==="end"?e:"auto"}const w=Symbol("vue-formless:layout-view");function Q(e){return e.reduce((t,n,r)=>{const o=t[r-1],i=o?o.$start+o.$occupied:0,c=i%F,d=ee({cursor:c,span:n.span,place:n.place});return t.push({...n,$start:i,$occupied:d}),t},[])}function ee({cursor:e,place:t,span:n}){const r=F-e;return t==="start"?e===0?n:r+n:t==="end"?r>=n?r:r+F:r>=n?n:r+n}function te(e,t,n){const r=e%F,o=r+t>F?F-r:0,i=t-o-n;return[o,i].filter(c=>c>0)}function ne(e,t,n={childList:!0}){if(typeof MutationObserver>"u")return;let r=null;function o(c){r?.disconnect(),r=null,c&&(r=new MutationObserver(t),r.observe(c,n))}u.onMounted(()=>o(u.toValue(e)));const i=u.watch(()=>u.toValue(e),o,{flush:"post"});u.onBeforeUnmount(()=>{i(),r?.disconnect(),r=null})}function re(e,t=0){const n=u.ref([]);function r(){const o=u.toValue(e);n.value=o?Array.from(o.children):[]}return u.watch(()=>[u.toValue(e),u.toValue(t)],r,{immediate:!0}),ne(e,r),n}function S(e){if(e==null||typeof e!="object")return null;if(typeof Element<"u"&&e instanceof Element)return e;const t=e.$el;return typeof Element<"u"&&t instanceof Element?t:null}const j=u.defineComponent({name:"LayoutBlanks",inheritAttrs:!1,props:{is:{type:Object,default:void 0},spans:{type:Array,required:!0}},setup(e){return()=>{if(e.spans.length===0||e.is==null)return null;const t=e.is;return u.createVNode(u.Fragment,null,[e.spans.map((n,r)=>u.createVNode(t,{key:r,span:n,"aria-hidden":"true","data-layout-blank":""},null))])}}}),T=u.defineComponent({name:"LayoutItem",inheritAttrs:!1,props:{span:{type:[String,Number],default:void 0},place:{type:String,default:void 0}},setup(e,{slots:t,attrs:n,expose:r}){const o=u.inject(w,null);if(!o)return()=>t.default?.()??null;const{span:i,blank:c,ref:d,Col:a,disabled:s,place:f}=o(()=>e.span,()=>e.place),m=u.ref(null);r({el:u.computed(()=>S(m.value))});function y(p){m.value=p,d(p)}return()=>{if(s.value)return t.default?.()??null;const p=a;return u.createVNode(u.Fragment,null,[u.createVNode(j,{is:a,spans:c.value.before},null),u.createVNode(p,u.mergeProps(n,{ref:y,span:i.value,"data-layout-item":"","data-layout-place":f.value}),{default:()=>[t.default?.()??null]}),u.createVNode(j,{is:a,spans:c.value.after},null)])}}});function ue({column:e,rowRef:t}){let n=0;const r=u.ref({}),o=re(()=>S(t.value),()=>Object.keys(r.value).filter(a=>r.value[a].mounted).join(",")),i=u.computed(()=>oe(r.value,o.value)),c=u.computed(()=>Q(i.value)),d=u.computed(()=>new Map(c.value.map(a=>[a.id,te(a.$start,a.$occupied,a.span)])));return{setup(a,s){const f=String(++n);return r.value[f]={span:u.computed(()=>X(u.toValue(a),u.toValue(e))),place:u.computed(()=>J(u.toValue(s))),el:null,mounted:!1},u.onMounted(()=>{const m=r.value[f];m&&(m.mounted=!0)}),u.onBeforeUnmount(()=>{delete r.value[f]}),f},span(a){return r.value[a]?.span??0},blank(a){return{before:d.value.get(a)??[],after:[]}},place(a){return r.value[a]?.place??"unknown"},ref(a,s){const f=r.value[a];if(!f)return;const m=S(s);f.el!==m&&(f.el=m)},placed(a){return c.value.findIndex(s=>s.id===a)>-1}}}function oe(e,t){const n=new Map(Object.entries(e).filter(([,r])=>r.el).map(([r,o])=>[o.el,{id:r,span:o.span,place:o.place}]));return t.filter(r=>n.has(r)).map(r=>n.get(r))}function P(e={}){const{Row:t,Col:n}=e;return u.defineComponent({name:"LayoutView",inheritAttrs:!1,props:{disabled:{type:Boolean,default:!1},column:{type:Number,default:void 0}},setup(r,{slots:o,attrs:i}){const c=u.computed(()=>!t||!n||r.disabled),d=u.computed(()=>Z(e.column,r.column)),a=u.ref(null),s=ue({column:d,rowRef:a});return u.provide(w,(f,m)=>{u.provide(w,null);const y=s.setup(f,m);return{span:u.computed(()=>s.span(y)),blank:u.computed(()=>s.blank(y)),ref:p=>s.ref(y,p),place:u.computed(()=>s.place(y)),placed:u.computed(()=>s.placed(y)),Col:n,disabled:c}}),()=>{if(c.value)return o.default?.()??null;const f=t;return u.createVNode(f,u.mergeProps({ref:a},i,{"data-layout-row":""}),{default:()=>[o.default?.()??null]})}}})}function le(e={}){const t=e.component?u.markRaw(e.component):void 0;return u.defineComponent({name:"FormItem",inheritAttrs:!1,props:{fl:{type:Object,required:!0},item:{type:Object,required:!0}},setup(n,{slots:r}){return()=>{if(!t||!n.fl?.item)return r.default?.()??null;const o=t,i=typeof e.props=="function"?e.props(n.fl):e.props;return u.createVNode(o,{...i,...n.item},r)}}})}const k=Symbol("vue-formless:form-view"),_=Symbol("vue-formless:form-field"),A=Symbol("EOF"),g=Symbol("failed"),ae=/[a-zA-Z_$0-9]/,ie=/[a-zA-Z0-9_$]/,ce=/[0-9]/;function $(e){if(!e)return;const t=[];let n="",r="",o=0;function i(l){if(l==="[")return s;if(l!==A)return typeof l=="string"&&ae.test(l)?(n=l,a):g}function c(l){return l==="."?d:i(l)}function d(l){return l===A||l==="."?g:i(l)}function a(l){return typeof l=="string"&&ie.test(l)?(n+=l,a):(t.push({type:"key",key:n}),n="",c(l))}function s(l){if(l===A)return g;if(typeof l=="string"&&(l==='"'||l==="'"))return r=l,n="",f;if(typeof l=="string"&&ce.test(l))return n+=l,s;if(l!=="]")return g;const v=Number(n);return n===""||String(v)!==n||v<0?g:(t.push({type:"index",index:v}),n="",c)}function f(l){return l===A?g:l==="\\"?m:l===r?y:(n+=l,f)}function m(l){return l===A?g:(n+=l,f)}function y(l){return l===A||l!=="]"?g:(t.push({type:"key",key:n}),n="",c)}let p=i;for(;o<e.length;o++){const l=p(e[o]);if(l===g)return;p=l}if(p(A)!==g)return t}function H(e){return typeof e=="object"&&e!==null}const se=Object.prototype.hasOwnProperty;function fe(e,t){return se.call(e,t)?e[t]:void 0}function q(e,t){if(H(e)){if(t.type==="key")return Array.isArray(e)?void 0:fe(e,t.key);if(t.type==="index")return Array.isArray(e)?e[t.index]:void 0}}function de(e,t){let n=e;for(const r of t)n=q(n,r);return n}function me(e,t){const n=$(t);return n?de(e,n):void 0}function pe(e,t,n){const r=$(t);return r?D(e,r,n):e}function D(e,t,n){if(!t.length)return e;if(t.length===1)return x(e,t[0],n);const[r,...o]=t;return x(e,r,D(q(e,r),o,n))}function x(e,t,n){if(t.type==="key")return{...H(e)&&!Array.isArray(e)?e:{},[t.key]:n};if(t.type==="index"){const r=Array.isArray(e)?[...e]:[];return r[t.index]=n,r}return e}function ye(e){let t=null;function n(o){return me(e.value,o)}function r(o,i){t||(t=[],u.nextTick(()=>{const c=t;if(t=null,!c?.length)return;let d=e.value;for(const a of c)d=pe(d,a.path,a.value);e.value=d})),t.push({path:o,value:i})}return{getIn:n,setIn:r}}const ve=["modelValue","model-value"],be=["onUpdate:modelValue","onUpdate:model-value"];function ge(e,t){const n=u.computed(()=>ve.find(i=>i in e)),r=u.computed(()=>be.find(i=>typeof e[i]=="function")),o=u.computed(()=>n.value?"controlled":t?"inherit":"local");return{key:n,event:r,source:o}}function Fe(){const e=u.useAttrs(),t=u.inject(k,null),{source:n,key:r,event:o}=ge(e,!!t),i=u.ref(),c=u.computed({get:()=>n.value==="controlled"?e[r.value]:i.value,set:m=>{n.value==="local"&&(i.value=m),o.value&&e[o.value](m)}}),d=ye(c),a=u.computed(()=>n.value==="inherit"?t.value.value:c.value);function s(m){return n.value==="inherit"?t.getIn(m):d.getIn(m)}function f(m,y){return n.value==="inherit"?t.setIn(m,y):d.setIn(m,y)}return u.provide(k,{value:a,getIn:s,setIn:f}),{value:a,getIn:s,setIn:f}}function C(e){return e&&e.charAt(0).toUpperCase()+e.slice(1)}function B(...e){const t=n=>{if(n!==void 0)return n===""?!0:!!n};return e.reduce((n,r)=>typeof t(r)=="boolean"?t(r):n,void 0)}function L(e){return e.replace(/-([a-z])/g,(t,n)=>n.toUpperCase())}const Ve=["fl","layout-item","layout","item"],Ie=new Map(Ve.map(e=>{const t=L(e);return[[`${e}:`,{channel:e,type:"prop"}],[`${t}:`,{channel:e,type:"prop"}],[`on${C(e)}:`,{channel:e,type:"listener"}],[`on${C(t)}:`,{channel:e,type:"listener"}]]}).flat());function U(e,t,n={}){const r=n.prefix==="keep",o={};for(const c of[...t,"default"])o[c]=Object.create(null);const i=Object.entries(e).map(([c,d])=>({...Ne(c,t),rawKey:c,value:d}));for(const{rawKey:c,key:d,value:a,channel:s,type:f}of i)f!=="listener"&&(o[s||"default"][r&&s?c:d]=a);for(const{rawKey:c,key:d,value:a,channel:s,type:f}of i)f==="listener"&&(o[s||"default"][r&&s?c:d]=a);return o}function Ne(e,t){const n=e.indexOf(":");if(n===-1)return{key:e};const r=e.substring(0,n+1);if(e.length===r.length)return{key:e};const o=Ie.get(r);return!o||!t.includes(o.channel)?{key:e}:{key:o.type==="listener"?`on${C(e.replace(r,""))}`:e.replace(r,""),channel:o.channel,type:o.type}}const he=["fl","layout"],Ae=["fl","layout","layout-item","item"],Oe=["item"];function z(e,t,n){const r=u.computed(()=>U(e,t,n)),o={};for(const i of t)o[L(i)]=u.computed(()=>r.value[i]);return o.default=u.computed(()=>r.value.default),o}function Ce(e){return new Proxy({},{get(t,n){const r=e.value;if(r==null)return;const o=Reflect.get(r,n,r);return typeof o=="function"?o.bind(r):o},has(t,n){return e.value!=null&&n in e.value}})}function Ee(e={}){const{Row:t,Col:n}=e.layout??{},r=P({Row:t,Col:n}),o=e.form?.component?u.markRaw(e.form.component):void 0,i=le(e.item);return u.defineComponent({name:"FormView",inheritAttrs:!1,setup(c,{slots:d,attrs:a,expose:s}){const f=u.ref(null);s(Ce(f));const y=u.inject(k,null)!=null,{fl:p,layout:l,default:v}=z(a,he),N=u.computed(()=>B(!1,p.value.layout)),V=u.computed(()=>{const b=p.value.form;return b===void 0||b==="auto"?!y:b===""?!0:!!b}),{getIn:I,setIn:h}=Fe();return u.provide(_,{access(b){return{value:u.computed(()=>I(u.toValue(b))),update:O=>h(u.toValue(b),O)}},FormItem:u.markRaw(i),LayoutView:u.markRaw(r),fl:p}),()=>{const b=r,O=u.createVNode(b,u.mergeProps({...e.layout?.props,...l.value},{disabled:!N.value}),{default:d.default});if(!o||!V.value)return O;const W=o;return u.createVNode(W,u.mergeProps({ref:f},{...e.form?.props,...v.value}),{default:()=>O})}}})}function Le(e){return typeof e=="function"||Object.prototype.toString.call(e)==="[object Object]"&&!u.isVNode(e)}function M(e){if(!(typeof e>"u"))return(Array.isArray(e)?e:[e]).map(t=>{if(typeof t=="string")return t})}function we(e){if(!(typeof e>"u"))return(Array.isArray(e)?e:[e]).map(t=>{if(typeof t=="string")return t})}const Se=u.defineComponent({name:"FormFieldCore",inheritAttrs:!1,props:{preset:{type:Object},fl:{type:Object,required:!0},layoutItem:{type:Object,required:!0},layout:{type:Object,required:!0},item:{type:Object,required:!0},control:{type:[Object,Function],required:!0}},setup(e,{slots:t}){const n=u.inject(_,null),r=u.computed(()=>e.fl?.component?.formless),o=u.computed(()=>({...e.preset?.fl,...e.fl})),i=u.computed(()=>M(o.value?.model)||M(r.value?.model)||["modelValue"]),c=u.computed(()=>we(o.value?.prop)||n?.getProp?.(i.value)),d=u.computed(()=>{const p={},l={};return i.value.forEach((v,N)=>{if(typeof v!="string"||v.trim()==="")return;const V=c.value?.[N];if(typeof V!="string"||V.trim()==="")return;const I=n?.access(V);if(!I)return;const h=L(v);p[h]=I.value.value,l[`onUpdate:${h}`]=I.update}),{values:p,events:l}}),a=u.computed(()=>({...d.value.values,...d.value.events}));u.provide(_,{...n,getProp(p){return p.map(l=>{if(typeof l!="string")return;const v=i.value.indexOf(l);return v!==-1?c.value?.[v]:void 0})}});const s=u.computed(()=>{const p=r.value?.field==="embed"?"embed":"auto",l=o.value?.field==="embed"?"embed":o.value?.field==="wrap-embed"?"wrap-embed":"auto";return p==="auto"?l==="auto"?"wrap":l:l==="auto"?"embed":l}),f=u.computed(()=>B(!0,u.toValue(n?.fl)?.item,o.value?.item)),m=u.computed(()=>({...o.value,model:i.value,prop:c.value,field:s.value,item:f.value})),y=u.computed(()=>{const p=typeof e.preset?.props=="function"?e.preset?.props(m.value):e.preset?.props;return u.mergeProps(d.value.events,{...p,...e.control},d.value.values)});return()=>{const{item:p,default:l}=U(t,Oe),v=e.fl.component,N=v?u.createVNode(v,y.value,l):t.default?.({$bindings:a.value})??null;if(s.value==="embed")return N;const V=n?.LayoutView,I=s.value==="wrap-embed"&&V?u.createVNode(V,e.layout,{default:()=>N}):N,h=n?.FormItem,b=h?u.createVNode(h,{fl:m.value,item:e.item},{...p,default:()=>I}):I;return u.createVNode(T,e.layoutItem,Le(b)?b:{default:()=>[b]})}}});function K(e={}){const{name:t,component:n,props:r,...o}=e;return u.defineComponent({name:t?`FormField${C(t)}`:"FormField",inheritAttrs:!1,setup(i,{attrs:c,slots:d}){const{fl:a,layoutItem:s,layout:f,item:m,default:y}=z(c,Ae);return()=>u.createVNode(Se,{preset:{fl:o,props:r},fl:{...a.value,component:n??a.value.component},layoutItem:s.value,layout:f.value,item:m.value,control:y.value},d)}})}const ke=K();function _e(e){const t={};for(const n of Object.keys(e)){const r=e[n];if(!r)continue;const o=C(L(n));t[o]=K({name:o,prop:n,...r})}return t}exports.FormField=ke;exports.LayoutItem=T;exports.createFormFields=_e;exports.createFormView=Ee;exports.createLayoutView=P;