@burgantech/pseudo-ui 0.1.0 → 0.1.1
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.md +261 -130
- package/dist/adapters/vue/DynamicRenderer.vue.js +1 -1
- package/dist/adapters/vue/DynamicRenderer.vue2.js +565 -614
- package/dist/adapters/vue/NestedComponentWrapper.vue.js +42 -72
- package/dist/adapters/vue/index.d.ts +1 -0
- package/dist/adapters/vue/index.js +17 -13
- package/dist/adapters/vue/useLovLoader.d.ts +24 -0
- package/dist/adapters/vue/useLovLoader.js +101 -0
- package/dist/engine/bindResolver.d.ts +15 -0
- package/dist/engine/bindResolver.js +48 -0
- package/dist/engine/index.d.ts +2 -0
- package/dist/engine/types.d.ts +1 -0
- package/dist/index.js +18 -15
- package/dist/pseudo-ui.css +1 -1
- package/package.json +8 -4
package/README.md
CHANGED
|
@@ -35,97 +35,294 @@ npm install vue@^3.5 primevue@^4.5 @primeuix/themes@^2 primeicons@^7
|
|
|
35
35
|
|
|
36
36
|
## Quick Start
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
Two steps: first a minimal form, then we enrich it with a nested component and a dropdown. Each step is self-contained.
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
---
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
import type { PseudoViewDelegate } from '@burgantech/pseudo-ui'
|
|
42
|
+
### Step 1: Minimal form
|
|
44
43
|
|
|
45
|
-
|
|
46
|
-
async requestData(ref, params) {
|
|
47
|
-
const res = await fetch(`/api/functions/${ref}`, {
|
|
48
|
-
method: 'POST',
|
|
49
|
-
headers: { 'Content-Type': 'application/json' },
|
|
50
|
-
body: JSON.stringify({ params }),
|
|
51
|
-
})
|
|
52
|
-
return res.json()
|
|
53
|
-
},
|
|
44
|
+
Name, surname, birth date, and a Submit button. No dropdowns, no nested components — just schema, view, and a minimal delegate.
|
|
54
45
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
46
|
+
**Schema:**
|
|
47
|
+
```json
|
|
48
|
+
{
|
|
49
|
+
"$schema": "https://amorphie.io/meta/view-model-vocabulary",
|
|
50
|
+
"$id": "urn:amorphie:res:schema:demo:quick-start",
|
|
51
|
+
"type": "object",
|
|
52
|
+
"required": ["name", "surname"],
|
|
53
|
+
"properties": {
|
|
54
|
+
"name": { "type": "string", "minLength": 1, "x-labels": { "en": "First Name", "tr": "Ad" } },
|
|
55
|
+
"surname": { "type": "string", "minLength": 1, "x-labels": { "en": "Surname", "tr": "Soyad" } },
|
|
56
|
+
"birthDate": { "type": "string", "format": "date", "x-labels": { "en": "Date of Birth", "tr": "Doğum Tarihi" } }
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
62
60
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
61
|
+
**View:**
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"$schema": "https://amorphie.io/meta/view-vocabulary/1.0",
|
|
65
|
+
"dataSchema": "urn:amorphie:res:schema:demo:quick-start",
|
|
66
|
+
"view": {
|
|
67
|
+
"type": "Column",
|
|
68
|
+
"gap": "md",
|
|
69
|
+
"children": [
|
|
70
|
+
{ "type": "TextField", "bind": "name" },
|
|
71
|
+
{ "type": "TextField", "bind": "surname" },
|
|
72
|
+
{ "type": "DatePicker", "bind": "birthDate" },
|
|
73
|
+
{ "type": "Button", "label": { "en": "Submit", "tr": "Gönder" }, "variant": "filled", "action": "submit" }
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Delegate + render:** `requestData` and `loadComponent` are never called here, so we stub them to throw. Only `onAction` matters.
|
|
80
|
+
|
|
81
|
+
```vue
|
|
82
|
+
<script setup lang="ts">
|
|
83
|
+
import { provideDelegate } from '@burgantech/pseudo-ui/vue'
|
|
84
|
+
import { PseudoView } from '@burgantech/pseudo-ui/vue'
|
|
85
|
+
import '@burgantech/pseudo-ui/vue/style.css'
|
|
86
|
+
|
|
87
|
+
import type { PseudoViewDelegate, DataSchema, ViewDefinition } from '@burgantech/pseudo-ui'
|
|
88
|
+
|
|
89
|
+
const schema: DataSchema = {
|
|
90
|
+
$schema: 'https://amorphie.io/meta/view-model-vocabulary',
|
|
91
|
+
$id: 'urn:amorphie:res:schema:demo:quick-start',
|
|
92
|
+
type: 'object',
|
|
93
|
+
required: ['name', 'surname'],
|
|
94
|
+
properties: {
|
|
95
|
+
name: { type: 'string', minLength: 1, 'x-labels': { en: 'First Name', tr: 'Ad' } },
|
|
96
|
+
surname: { type: 'string', minLength: 1, 'x-labels': { en: 'Surname', tr: 'Soyad' } },
|
|
97
|
+
birthDate: { type: 'string', format: 'date', 'x-labels': { en: 'Date of Birth', tr: 'Doğum Tarihi' } },
|
|
71
98
|
},
|
|
99
|
+
}
|
|
72
100
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
101
|
+
const view: ViewDefinition = {
|
|
102
|
+
$schema: 'https://amorphie.io/meta/view-vocabulary/1.0',
|
|
103
|
+
dataSchema: 'urn:amorphie:res:schema:demo:quick-start',
|
|
104
|
+
view: {
|
|
105
|
+
type: 'Column',
|
|
106
|
+
gap: 'md',
|
|
107
|
+
children: [
|
|
108
|
+
{ type: 'TextField', bind: 'name' },
|
|
109
|
+
{ type: 'TextField', bind: 'surname' },
|
|
110
|
+
{ type: 'DatePicker', bind: 'birthDate' },
|
|
111
|
+
{ type: 'Button', label: { en: 'Submit', tr: 'Gönder' }, variant: 'filled', action: 'submit' },
|
|
112
|
+
],
|
|
82
113
|
},
|
|
114
|
+
}
|
|
83
115
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
116
|
+
const delegate: PseudoViewDelegate = {
|
|
117
|
+
async requestData() { throw new Error('No LOV in this example — add a dropdown to trigger this') },
|
|
118
|
+
async loadComponent() { throw new Error('No nested components — add type: "Component" to trigger this') },
|
|
119
|
+
async onAction(action, formData) {
|
|
120
|
+
if (action === 'submit') console.log('Form submitted:', formData)
|
|
87
121
|
},
|
|
88
122
|
}
|
|
123
|
+
</script>
|
|
124
|
+
|
|
125
|
+
<template>
|
|
126
|
+
<PseudoView :schema="schema" :view="view" lang="en" :delegate="delegate" />
|
|
127
|
+
</template>
|
|
89
128
|
```
|
|
90
129
|
|
|
91
|
-
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
### Step 2: Add a continent dropdown (nested component + LOV)
|
|
133
|
+
|
|
134
|
+
We extend the form with a **continent** field. The dropdown lives in a nested sub-component and gets its options via `requestData` — so you see both `loadComponent` (nested UI) and `requestData` (LOV data) in action. All data is inline.
|
|
135
|
+
|
|
136
|
+
**Add to main schema:**
|
|
137
|
+
```json
|
|
138
|
+
"continent": { "type": "string", "x-labels": { "en": "Continent you live in", "tr": "Yaşadığınız kıta" } }
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**Add to main view** (between DatePicker and Button):
|
|
142
|
+
```json
|
|
143
|
+
{
|
|
144
|
+
"type": "Component",
|
|
145
|
+
"ref": "continent-selector",
|
|
146
|
+
"bind": { "continent": "$form.continent" }
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**Sub-component schema** (continent-selector — has `x-lov`, so the SDK calls `requestData("get-continents")`):
|
|
151
|
+
```json
|
|
152
|
+
{
|
|
153
|
+
"$schema": "https://amorphie.io/meta/view-model-vocabulary",
|
|
154
|
+
"$id": "urn:amorphie:res:schema:demo:continent-selector",
|
|
155
|
+
"type": "object",
|
|
156
|
+
"required": ["continent"],
|
|
157
|
+
"properties": {
|
|
158
|
+
"continent": {
|
|
159
|
+
"type": "string",
|
|
160
|
+
"x-labels": { "en": "Continent you live in", "tr": "Yaşadığınız kıta" },
|
|
161
|
+
"x-lov": {
|
|
162
|
+
"source": "get-continents",
|
|
163
|
+
"valueField": "$.response.data.code",
|
|
164
|
+
"displayField": "$.response.data.name"
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**Sub-component view:**
|
|
172
|
+
```json
|
|
173
|
+
{
|
|
174
|
+
"$schema": "https://amorphie.io/meta/view-vocabulary/1.0",
|
|
175
|
+
"dataSchema": "urn:amorphie:res:schema:demo:continent-selector",
|
|
176
|
+
"view": { "type": "Dropdown", "bind": "continent" }
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**Full delegate** (replace the stubs with real implementations):
|
|
92
181
|
|
|
93
182
|
```vue
|
|
94
183
|
<script setup lang="ts">
|
|
95
|
-
import { ref, onMounted } from 'vue'
|
|
96
184
|
import { provideDelegate } from '@burgantech/pseudo-ui/vue'
|
|
97
185
|
import { PseudoView } from '@burgantech/pseudo-ui/vue'
|
|
98
186
|
import '@burgantech/pseudo-ui/vue/style.css'
|
|
99
187
|
|
|
100
|
-
import type { DataSchema, ViewDefinition } from '@burgantech/pseudo-ui'
|
|
188
|
+
import type { PseudoViewDelegate, DataSchema, ViewDefinition } from '@burgantech/pseudo-ui'
|
|
189
|
+
|
|
190
|
+
const CONTINENTS = [
|
|
191
|
+
{ code: 'eu', name: 'Europe' },
|
|
192
|
+
{ code: 'as', name: 'Asia' },
|
|
193
|
+
{ code: 'na', name: 'North America' },
|
|
194
|
+
{ code: 'sa', name: 'South America' },
|
|
195
|
+
{ code: 'af', name: 'Africa' },
|
|
196
|
+
{ code: 'oc', name: 'Oceania' },
|
|
197
|
+
{ code: 'an', name: 'Antarctica' },
|
|
198
|
+
]
|
|
199
|
+
|
|
200
|
+
const mainSchema: DataSchema = {
|
|
201
|
+
$schema: 'https://amorphie.io/meta/view-model-vocabulary',
|
|
202
|
+
$id: 'urn:amorphie:res:schema:demo:quick-start',
|
|
203
|
+
type: 'object',
|
|
204
|
+
required: ['name', 'surname'],
|
|
205
|
+
properties: {
|
|
206
|
+
name: { type: 'string', minLength: 1, 'x-labels': { en: 'First Name', tr: 'Ad' } },
|
|
207
|
+
surname: { type: 'string', minLength: 1, 'x-labels': { en: 'Surname', tr: 'Soyad' } },
|
|
208
|
+
birthDate: { type: 'string', format: 'date', 'x-labels': { en: 'Date of Birth', tr: 'Doğum Tarihi' } },
|
|
209
|
+
continent: { type: 'string', 'x-labels': { en: 'Continent you live in', tr: 'Yaşadığınız kıta' } },
|
|
210
|
+
},
|
|
211
|
+
}
|
|
101
212
|
|
|
102
|
-
|
|
213
|
+
const continentSchema: DataSchema = {
|
|
214
|
+
$schema: 'https://amorphie.io/meta/view-model-vocabulary',
|
|
215
|
+
$id: 'urn:amorphie:res:schema:demo:continent-selector',
|
|
216
|
+
type: 'object',
|
|
217
|
+
required: ['continent'],
|
|
218
|
+
properties: {
|
|
219
|
+
continent: {
|
|
220
|
+
type: 'string',
|
|
221
|
+
'x-labels': { en: 'Continent you live in', tr: 'Yaşadığınız kıta' },
|
|
222
|
+
'x-lov': { source: 'get-continents', valueField: '$.response.data.code', displayField: '$.response.data.name' },
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
}
|
|
103
226
|
|
|
104
|
-
const
|
|
105
|
-
|
|
227
|
+
const mainView: ViewDefinition = {
|
|
228
|
+
$schema: 'https://amorphie.io/meta/view-vocabulary/1.0',
|
|
229
|
+
dataSchema: 'urn:amorphie:res:schema:demo:quick-start',
|
|
230
|
+
view: {
|
|
231
|
+
type: 'Column',
|
|
232
|
+
gap: 'md',
|
|
233
|
+
children: [
|
|
234
|
+
{ type: 'TextField', bind: 'name' },
|
|
235
|
+
{ type: 'TextField', bind: 'surname' },
|
|
236
|
+
{ type: 'DatePicker', bind: 'birthDate' },
|
|
237
|
+
{ type: 'Component', ref: 'continent-selector', bind: { continent: '$form.continent' } },
|
|
238
|
+
{ type: 'Button', label: { en: 'Submit', tr: 'Gönder' }, variant: 'filled', action: 'submit' },
|
|
239
|
+
],
|
|
240
|
+
},
|
|
241
|
+
}
|
|
106
242
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
243
|
+
const delegate: PseudoViewDelegate = {
|
|
244
|
+
async requestData(ref, params) {
|
|
245
|
+
if (ref === 'get-continents') return { response: { data: CONTINENTS } }
|
|
246
|
+
throw new Error(`Unknown data source: ${ref}`)
|
|
247
|
+
},
|
|
248
|
+
async loadComponent(ref) {
|
|
249
|
+
if (ref === 'continent-selector') {
|
|
250
|
+
return {
|
|
251
|
+
schema: continentSchema,
|
|
252
|
+
view: { $schema: 'https://amorphie.io/meta/view-vocabulary/1.0', dataSchema: 'urn:amorphie:res:schema:demo:continent-selector', view: { type: 'Dropdown', bind: 'continent' } },
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
throw new Error(`Unknown component: ${ref}`)
|
|
256
|
+
},
|
|
257
|
+
async onAction(action, formData) {
|
|
258
|
+
if (action === 'submit') console.log('Form submitted:', formData)
|
|
259
|
+
},
|
|
260
|
+
}
|
|
115
261
|
</script>
|
|
116
262
|
|
|
117
263
|
<template>
|
|
118
|
-
<PseudoView
|
|
119
|
-
v-if="schema && view"
|
|
120
|
-
:schema="schema"
|
|
121
|
-
:view="view"
|
|
122
|
-
lang="en"
|
|
123
|
-
@form-change="console.log('form data:', $event)"
|
|
124
|
-
@validation-change="console.log('is valid:', $event)"
|
|
125
|
-
/>
|
|
264
|
+
<PseudoView :schema="mainSchema" :view="mainView" lang="en" :delegate="delegate" />
|
|
126
265
|
</template>
|
|
127
266
|
```
|
|
128
267
|
|
|
268
|
+
Step 1 gives you the basics. Step 2 shows how to add a nested component and LOV — `requestData` serves dropdown options, `loadComponent` serves the sub-component.
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
### Initial data (optional)
|
|
273
|
+
|
|
274
|
+
You can pass initial values when the view first renders:
|
|
275
|
+
|
|
276
|
+
| Prop | Purpose |
|
|
277
|
+
|---|---|
|
|
278
|
+
| `formData` | Pre-fill editable fields (e.g. user draft, edit mode). Fields are bound to `$form` and can be changed by the user. |
|
|
279
|
+
| `instanceData` | Backend/persisted data (e.g. read-only display, lookup filters). Used by `$instance` expressions and summary views. |
|
|
280
|
+
|
|
281
|
+
```vue
|
|
282
|
+
<PseudoView
|
|
283
|
+
:schema="schema"
|
|
284
|
+
:view="view"
|
|
285
|
+
:form-data="{ name: 'Jane', surname: 'Doe', birthDate: '1990-05-15' }"
|
|
286
|
+
:instance-data="{ status: 'active', createdAt: '2024-01-01' }"
|
|
287
|
+
lang="en"
|
|
288
|
+
:delegate="delegate"
|
|
289
|
+
/>
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
`formData` is for user-editable data. `instanceData` is for backend state that drives display and lookups — both are optional and merged when the view mounts.
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
### Lookups (enrichment)
|
|
297
|
+
|
|
298
|
+
When a schema property has `x-lookup`, the SDK fetches enrichment data via `requestData`. You must **activate** the lookup by listing it in the view's `lookups` array — otherwise it won't run.
|
|
299
|
+
|
|
300
|
+
**Schema** (defines the lookup):
|
|
301
|
+
```json
|
|
302
|
+
{
|
|
303
|
+
"branchDetail": {
|
|
304
|
+
"type": "object",
|
|
305
|
+
"x-lookup": {
|
|
306
|
+
"source": "get-branch-details",
|
|
307
|
+
"resultField": "$.response.data",
|
|
308
|
+
"filter": [{ "param": "branchCode", "value": "$param.selectedBranchCode", "required": true }]
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
**View** (activates it):
|
|
315
|
+
```json
|
|
316
|
+
{
|
|
317
|
+
"$schema": "https://amorphie.io/meta/view-vocabulary/1.0",
|
|
318
|
+
"dataSchema": "urn:amorphie:res:schema:shared:branch-info",
|
|
319
|
+
"lookups": ["branchDetail"],
|
|
320
|
+
"view": { ... }
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
Then use `$lookup.branchDetail.address`, `$lookup.branchDetail.phone`, etc. in Text or other components. The SDK calls `requestData(source, filterParams)` when the view mounts; the delegate returns the enrichment payload.
|
|
325
|
+
|
|
129
326
|
## Package Exports
|
|
130
327
|
|
|
131
328
|
| Import path | Content |
|
|
@@ -176,77 +373,11 @@ onMounted(async () => {
|
|
|
176
373
|
| **View** | `view.json` | UI component tree — layout, binding, actions, transient UI state |
|
|
177
374
|
| **Model** | Backend | Persisted data, served via delegate's `requestData` |
|
|
178
375
|
|
|
179
|
-
### Schema example (ViewModel)
|
|
180
|
-
|
|
181
|
-
```json
|
|
182
|
-
{
|
|
183
|
-
"$id": "urn:amorphie:res:schema:shared:customer-form",
|
|
184
|
-
"type": "object",
|
|
185
|
-
"required": ["fullName", "city"],
|
|
186
|
-
"properties": {
|
|
187
|
-
"fullName": {
|
|
188
|
-
"type": "string",
|
|
189
|
-
"minLength": 2,
|
|
190
|
-
"x-labels": { "en": "Full Name", "tr": "Ad Soyad" },
|
|
191
|
-
"x-errorMessages": {
|
|
192
|
-
"required": { "en": "Required", "tr": "Zorunlu" }
|
|
193
|
-
}
|
|
194
|
-
},
|
|
195
|
-
"city": {
|
|
196
|
-
"type": "string",
|
|
197
|
-
"x-labels": { "en": "City", "tr": "Şehir" },
|
|
198
|
-
"x-lov": {
|
|
199
|
-
"source": "urn:amorphie:func:domain:shared:get-cities",
|
|
200
|
-
"valueField": "$.response.data.code",
|
|
201
|
-
"displayField": "$.response.data.name"
|
|
202
|
-
}
|
|
203
|
-
},
|
|
204
|
-
"companyName": {
|
|
205
|
-
"type": "string",
|
|
206
|
-
"x-labels": { "en": "Company", "tr": "Şirket" },
|
|
207
|
-
"x-conditional": {
|
|
208
|
-
"showIf": {
|
|
209
|
-
"allOf": [
|
|
210
|
-
{ "field": "accountType", "operator": "equals", "value": "corporate" },
|
|
211
|
-
{ "field": "age", "operator": "greaterThan", "value": 17 }
|
|
212
|
-
]
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
### View example
|
|
221
|
-
|
|
222
|
-
```json
|
|
223
|
-
{
|
|
224
|
-
"$schema": "https://amorphie.io/meta/view-vocabulary/1.0",
|
|
225
|
-
"dataSchema": "urn:amorphie:res:schema:shared:customer-form",
|
|
226
|
-
"uiState": { "showDialog": false },
|
|
227
|
-
"view": {
|
|
228
|
-
"type": "Column",
|
|
229
|
-
"gap": "md",
|
|
230
|
-
"children": [
|
|
231
|
-
{ "type": "TextField", "bind": "fullName" },
|
|
232
|
-
{ "type": "Dropdown", "bind": "city" },
|
|
233
|
-
{ "type": "TextField", "bind": "companyName" },
|
|
234
|
-
{
|
|
235
|
-
"type": "Button",
|
|
236
|
-
"label": { "en": "Submit", "tr": "Gönder" },
|
|
237
|
-
"variant": "filled",
|
|
238
|
-
"action": "submit"
|
|
239
|
-
}
|
|
240
|
-
]
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
```
|
|
244
|
-
|
|
245
376
|
## Delegate Interface
|
|
246
377
|
|
|
247
378
|
```typescript
|
|
248
379
|
interface PseudoViewDelegate {
|
|
249
|
-
/** Fetch data from backend (LOV items, lookup enrichment) */
|
|
380
|
+
/** Fetch data from backend (LOV items, lookup enrichment). ref = source (required); params = resolved filter from x-lookup (optional when no filter). */
|
|
250
381
|
requestData(ref: string, params?: Record<string, string>): Promise<unknown>
|
|
251
382
|
|
|
252
383
|
/** Load a nested component's schema + view by reference */
|
|
@@ -329,7 +460,7 @@ import viewModelVocab from '@burgantech/pseudo-ui/vocabularies/view-model-vocabu
|
|
|
329
460
|
|
|
330
461
|
## Cross-Platform
|
|
331
462
|
|
|
332
|
-
This package provides the **TypeScript/Vue** implementation. A **Dart/Flutter** package
|
|
463
|
+
This package provides the **TypeScript/Vue** implementation. A **Dart/Flutter** package is planned and will render the same JSON schemas and views using Material 3 widgets. Both will share the same vocabulary definitions, ensuring consistent behavior across platforms.
|
|
333
464
|
|
|
334
465
|
## License
|
|
335
466
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import o from "./DynamicRenderer.vue2.js";
|
|
2
2
|
/* empty css */
|
|
3
3
|
import r from "../../_virtual/_plugin-vue_export-helper.js";
|
|
4
|
-
const a = /* @__PURE__ */ r(o, [["__scopeId", "data-v-
|
|
4
|
+
const a = /* @__PURE__ */ r(o, [["__scopeId", "data-v-3324b6bc"]]);
|
|
5
5
|
export {
|
|
6
6
|
a as default
|
|
7
7
|
};
|