@stonecrop/aform 0.13.14 → 0.14.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.md +59 -9
- package/dist/aform.d.ts +24 -5
- package/dist/aform.js +2541 -2490
- package/dist/aform.js.map +1 -1
- package/dist/assets/index.css +1 -1
- package/dist/probe.tsbuildinfo +1 -0
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -3
- package/dist/src/types/index.d.ts +21 -2
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/theme/login.css +1 -0
- package/package.json +7 -5
- package/src/components/AForm.vue +19 -8
- package/src/components/form/ACheckbox.vue +7 -3
- package/src/components/form/ADate.vue +12 -2
- package/src/components/form/ADatePicker.vue +85 -69
- package/src/components/form/ADateRange.vue +5 -2
- package/src/components/form/ADropdown.vue +18 -1
- package/src/components/form/ANumericInput.vue +8 -2
- package/src/components/form/ATextInput.vue +6 -3
- package/src/components/form/ATextarea.vue +31 -0
- package/src/components/utilities/Login.vue +0 -1
- package/src/index.ts +3 -3
- package/src/theme/login.css +0 -1
- package/src/types/index.ts +34 -3
- package/src/components/form/AComboBox.vue +0 -17
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @stonecrop/aform
|
|
2
2
|
|
|
3
|
-
Schema-driven form components for the Stonecrop framework. Renders a `ResolvedField[]` array
|
|
3
|
+
Schema-driven form components for the Stonecrop framework. Renders a `ResolvedField[]` array into a form, wiring field values to a `data` object via `v-model:data`. The array usually comes from `registry.resolveSchema()`, but may also be hand-authored for view chrome that has no backing doctype — see [Authoring space vs rendering space](#authoring-space-vs-rendering-space).
|
|
4
4
|
|
|
5
5
|
## Components
|
|
6
6
|
|
|
@@ -8,15 +8,19 @@ Schema-driven form components for the Stonecrop framework. Renders a `ResolvedFi
|
|
|
8
8
|
|---|---|
|
|
9
9
|
| `AForm` | Root form renderer — iterates schema, renders child components, handles nested forms |
|
|
10
10
|
| `ACheckbox` | Boolean toggle |
|
|
11
|
-
| `AComboBox` | Editable combo box with option list |
|
|
12
11
|
| `ADate` | Date text input |
|
|
13
12
|
| `ADatePicker` | Date picker with calendar UI |
|
|
13
|
+
| `ADateTime` | Combined date and time input |
|
|
14
|
+
| `ADateRange` | Date-range input (start and end) |
|
|
15
|
+
| `ADateSelection` | Wrapper combining a date picker and time input |
|
|
16
|
+
| `ADuration` | Duration input |
|
|
14
17
|
| `ADropdown` | Single-select dropdown for string enum fields |
|
|
15
18
|
| `AFieldset` | Collapsible grouping container for other fields |
|
|
16
19
|
| `AFileAttach` | File upload and attachment |
|
|
17
20
|
| `AFormLink` | Linked document selector with search dropdown and navigation arrow |
|
|
18
21
|
| `ANumericInput` | Numeric input with type-specific formatting |
|
|
19
22
|
| `ATextInput` | Single-line text input |
|
|
23
|
+
| `ATextarea` | Multi-line text input |
|
|
20
24
|
|
|
21
25
|
## Installation
|
|
22
26
|
|
|
@@ -32,12 +36,58 @@ This registers all components globally. They can also be imported individually.
|
|
|
32
36
|
|
|
33
37
|
## AForm
|
|
34
38
|
|
|
39
|
+
### Authoring space vs rendering space
|
|
40
|
+
|
|
41
|
+
Stonecrop has two field shapes, and AForm consumes only the second:
|
|
42
|
+
|
|
43
|
+
| | Type | Produced by | Table columns live under |
|
|
44
|
+
|---|---|---|---|
|
|
45
|
+
| **Authoring space** | `DoctypeField[]` (`@stonecrop/schema`) | hand-authored doctype JSON, the docbuilder, the GraphQL converter | `columns` |
|
|
46
|
+
| **Rendering space** | `ResolvedField[]` (this package) | `registry.resolveSchema()` | `schema` |
|
|
47
|
+
|
|
48
|
+
`resolveSchema()` renames a table's `columns` to `schema` because `schema` is the ATable prop that runs
|
|
49
|
+
`schemaToColumns()`; ATable's own `columns` prop means already-converted `TableColumn[]`. Passing an
|
|
50
|
+
authoring-space field straight to AForm therefore does **not** render a table.
|
|
51
|
+
|
|
52
|
+
`kind` is required and is the only thing AForm dispatches on — it does not infer a field's type from its
|
|
53
|
+
structure. Every path into rendering space sets it: Zod's preprocess, `Doctype.fromObject`, and the
|
|
54
|
+
registry. When hand-authoring, declare it yourself and use `satisfies` to stay checked:
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
import type { ResolvedField, ResolvedTable } from '@stonecrop/aform/types'
|
|
58
|
+
|
|
59
|
+
const schema: ResolvedField[] = [
|
|
60
|
+
{
|
|
61
|
+
kind: 'table',
|
|
62
|
+
fieldname: 'line_items',
|
|
63
|
+
component: 'ATable',
|
|
64
|
+
schema: [{ fieldname: 'item_code', label: 'SKU', component: 'ATextInput' }],
|
|
65
|
+
config: { view: 'list' },
|
|
66
|
+
} satisfies ResolvedTable,
|
|
67
|
+
]
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Each column needs a `component`: `schemaToColumns()` drops entries without one, since absence is what
|
|
71
|
+
marks a non-scalar entry.
|
|
72
|
+
|
|
73
|
+
### Table rows come from the data model
|
|
74
|
+
|
|
75
|
+
A table's rows are never part of its schema. AForm reads them from `dataModel[fieldname]`, so a `rows`
|
|
76
|
+
key on the schema field is ignored, and a table whose `fieldname` has no matching data key renders empty:
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
// schema declares fieldname: 'line_items' → rows are read from here
|
|
80
|
+
const data = ref({ line_items: [{ item_code: 'LAPTOP-PRO-15', quantity: 2 }] })
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
For a table nested in a fieldset, the rows nest the same way — `data[fieldsetFieldname][tableFieldname]`.
|
|
84
|
+
|
|
35
85
|
### Field width
|
|
36
86
|
|
|
37
87
|
Set `width` on any schema field to control its share of the form row. The value is any valid CSS size and is applied as `flex-basis` + `width` directly on the field's flex item:
|
|
38
88
|
|
|
39
89
|
```json
|
|
40
|
-
{ "fieldname": "notes", "
|
|
90
|
+
{ "fieldname": "notes", "component": "ATextInput", "label": "Notes", "width": "100%" }
|
|
41
91
|
```
|
|
42
92
|
|
|
43
93
|
| Value | Effect |
|
|
@@ -52,7 +102,7 @@ Fields without `width` continue to share space equally (`flex-grow: 1; min-width
|
|
|
52
102
|
|
|
53
103
|
## AFormLink
|
|
54
104
|
|
|
55
|
-
A form input for selecting and navigating to linked documents (`
|
|
105
|
+
A form input for selecting and navigating to linked documents (fields carrying a `doctype` marker). Combines a searchable text input, an optional dropdown of results, and a navigation arrow button.
|
|
56
106
|
|
|
57
107
|
### Value shape
|
|
58
108
|
|
|
@@ -142,21 +192,21 @@ If no navigator is provided, the arrow button is still rendered but navigation c
|
|
|
142
192
|
|
|
143
193
|
### Via resolveSchema
|
|
144
194
|
|
|
145
|
-
For
|
|
195
|
+
For fields carrying a `doctype` marker with no matching `links` declaration and no `component`, `Registry.resolveSchema()` automatically assigns `component: 'AFormLink'`. No manual wiring required:
|
|
146
196
|
|
|
147
197
|
```typescript
|
|
148
198
|
const config: DoctypeConfig = {
|
|
149
|
-
|
|
199
|
+
name: 'Sales Order',
|
|
150
200
|
fields: [
|
|
151
|
-
{ fieldname: 'order_number',
|
|
152
|
-
{ fieldname: 'territory',
|
|
201
|
+
{ fieldname: 'order_number', component: 'ATextInput', label: 'Order Number' },
|
|
202
|
+
{ fieldname: 'territory', doctype: 'territory', label: 'Territory' },
|
|
153
203
|
// no 'links' entry for territory
|
|
154
204
|
],
|
|
155
205
|
}
|
|
156
206
|
|
|
157
207
|
registry.addDoctype(Doctype.fromObject(config))
|
|
158
208
|
const resolved = registry.resolveSchema(registry.registry['sales-order'])
|
|
159
|
-
// resolved[1] === { fieldname: 'territory', component: 'AFormLink', doctype: 'territory', label: 'Territory' }
|
|
209
|
+
// resolved[1] === { kind: 'field', fieldname: 'territory', component: 'AFormLink', doctype: 'territory', label: 'Territory' }
|
|
160
210
|
|
|
161
211
|
// Pass to AForm as normal — the territory field renders as AFormLink automatically
|
|
162
212
|
```
|
package/dist/aform.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import ACheckbox from './components/form/ACheckbox.vue';
|
|
2
|
-
import AComboBox from './components/form/AComboBox.vue';
|
|
3
2
|
import ADate from './components/form/ADate.vue';
|
|
4
3
|
import ADatePicker from './components/form/ADatePicker.vue';
|
|
5
4
|
import ADateRange from './components/form/ADateRange.vue';
|
|
@@ -13,6 +12,7 @@ import AForm from './components/AForm.vue';
|
|
|
13
12
|
import AFormLink from './components/form/AFormLink.vue';
|
|
14
13
|
import ANumericInput from './components/form/ANumericInput.vue';
|
|
15
14
|
import type { App } from 'vue';
|
|
15
|
+
import ATextarea from './components/form/ATextarea.vue';
|
|
16
16
|
import ATextInput from './components/form/ATextInput.vue';
|
|
17
17
|
import type { ColumnSchema } from '@stonecrop/schema';
|
|
18
18
|
import type { FieldValidation } from '@stonecrop/schema';
|
|
@@ -23,8 +23,6 @@ import type { ValueField } from '@stonecrop/schema';
|
|
|
23
23
|
|
|
24
24
|
export { ACheckbox }
|
|
25
25
|
|
|
26
|
-
export { AComboBox }
|
|
27
|
-
|
|
28
26
|
export { ADate }
|
|
29
27
|
|
|
30
28
|
export { ADatePicker }
|
|
@@ -71,6 +69,8 @@ export declare interface AFormLinkValue {
|
|
|
71
69
|
|
|
72
70
|
export { ANumericInput }
|
|
73
71
|
|
|
72
|
+
export { ATextarea }
|
|
73
|
+
|
|
74
74
|
export { ATextInput }
|
|
75
75
|
|
|
76
76
|
/**
|
|
@@ -124,6 +124,13 @@ export declare type ComponentProps = {
|
|
|
124
124
|
errorMessage: string;
|
|
125
125
|
[key: string]: any;
|
|
126
126
|
};
|
|
127
|
+
/**
|
|
128
|
+
* Inline validation error messages to display on this field. Fed by the host
|
|
129
|
+
* (e.g. mapped from the core validation store) — the renderer stays dumb and just
|
|
130
|
+
* shows what it is given. Takes precedence over the static `validation.errorMessage`.
|
|
131
|
+
* @public
|
|
132
|
+
*/
|
|
133
|
+
errors?: string[];
|
|
127
134
|
};
|
|
128
135
|
|
|
129
136
|
/**
|
|
@@ -154,9 +161,13 @@ export { InteractionMode }
|
|
|
154
161
|
export { Login }
|
|
155
162
|
|
|
156
163
|
/**
|
|
157
|
-
* The discriminated union of all resolved field types — what AForm consumes
|
|
158
|
-
* after `resolveSchema()` has transformed the authoring `DoctypeField[]
|
|
164
|
+
* The discriminated union of all resolved field types — what AForm consumes,
|
|
165
|
+
* usually after `resolveSchema()` has transformed the authoring `DoctypeField[]`,
|
|
166
|
+
* but also valid hand-authored for view chrome with no backing doctype.
|
|
159
167
|
* Narrowed by `kind`: `'field'` | `'link'` | `'table'` | `'fieldset'`.
|
|
168
|
+
*
|
|
169
|
+
* `kind` is required — AForm dispatches on it alone and does not infer a field's
|
|
170
|
+
* type from its structure.
|
|
160
171
|
* @public
|
|
161
172
|
*/
|
|
162
173
|
export declare type ResolvedField = ResolvedScalar | ResolvedLink | ResolvedTable | ResolvedFieldset;
|
|
@@ -225,6 +236,14 @@ export declare type ResolvedScalar = Omit<ValueField, 'cardinality'> & {
|
|
|
225
236
|
* A resolved table — either from a Link with `noneOrMany`/`atLeastOne` cardinality,
|
|
226
237
|
* or from an inline TableField. ATable receives columns via `:schema` (ColumnSchema[])
|
|
227
238
|
* and row data via `:rows` from formData at render time.
|
|
239
|
+
*
|
|
240
|
+
* Note the key rename: an authoring `TableField` declares its columns under `columns`;
|
|
241
|
+
* `resolveSchema` moves them to `schema` here, because `schema` is the ATable prop that
|
|
242
|
+
* runs `schemaToColumns()` (ATable's own `columns` prop means already-converted
|
|
243
|
+
* `TableColumn[]`). A hand-authored table must therefore use `schema`, not `columns`.
|
|
244
|
+
*
|
|
245
|
+
* Rows are never part of the schema. AForm sources them from the data model at
|
|
246
|
+
* `dataModel[fieldname]`, so a `rows` key placed on this object is ignored.
|
|
228
247
|
* @public
|
|
229
248
|
*/
|
|
230
249
|
export declare interface ResolvedTable {
|