@cocoar/vue-ui 3.1.0 → 3.2.0-beta.6
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/dist/components/checkbox/CoarCheckbox.vue.d.ts +1 -1
- package/dist/components/checkbox/CoarCheckbox.vue.d.ts.map +1 -1
- package/dist/components/code-block/CoarCodeBlock.vue.d.ts +1 -1
- package/dist/components/code-block/CoarCodeBlock.vue.d.ts.map +1 -1
- package/dist/components/data-list/CoarDataList.vue.d.ts +158 -0
- package/dist/components/data-list/CoarDataList.vue.d.ts.map +1 -0
- package/dist/components/data-list/CoarDataListToolbar.vue.d.ts +30 -0
- package/dist/components/data-list/CoarDataListToolbar.vue.d.ts.map +1 -0
- package/dist/components/data-list/data-list-builder.d.ts +288 -0
- package/dist/components/data-list/data-list-builder.d.ts.map +1 -0
- package/dist/components/data-list/index.d.ts +12 -0
- package/dist/components/data-list/index.d.ts.map +1 -0
- package/dist/components/data-list/internal/compare.d.ts +14 -0
- package/dist/components/data-list/internal/compare.d.ts.map +1 -0
- package/dist/components/data-list/internal/reorder-core.d.ts +46 -0
- package/dist/components/data-list/internal/reorder-core.d.ts.map +1 -0
- package/dist/components/data-list/internal/search.d.ts +16 -0
- package/dist/components/data-list/internal/search.d.ts.map +1 -0
- package/dist/components/data-list/internal/useDataListLines.d.ts +92 -0
- package/dist/components/data-list/internal/useDataListLines.d.ts.map +1 -0
- package/dist/components/data-list/internal/useDataListReorder.d.ts +68 -0
- package/dist/components/data-list/internal/useDataListReorder.d.ts.map +1 -0
- package/dist/components/data-list/internal/useSearchHighlight.d.ts +19 -0
- package/dist/components/data-list/internal/useSearchHighlight.d.ts.map +1 -0
- package/dist/components/data-list/types.d.ts +185 -0
- package/dist/components/data-list/types.d.ts.map +1 -0
- package/dist/components/data-list/useDataListModel.d.ts +79 -0
- package/dist/components/data-list/useDataListModel.d.ts.map +1 -0
- package/dist/components/date-time/_shared/maskito-config.d.ts +7 -2
- package/dist/components/date-time/_shared/maskito-config.d.ts.map +1 -1
- package/dist/components/date-time/_shared/time-helpers.d.ts +11 -4
- package/dist/components/date-time/_shared/time-helpers.d.ts.map +1 -1
- package/dist/components/date-time/_shared/use-date-picker-base.d.ts +1 -1
- package/dist/components/date-time/plain-date-picker/CoarPlainDatePicker.vue.d.ts +1 -1
- package/dist/components/date-time/plain-date-picker/CoarPlainDatePicker.vue.d.ts.map +1 -1
- package/dist/components/date-time/plain-date-time-picker/CoarPlainDateTimePicker.vue.d.ts +1 -1
- package/dist/components/date-time/plain-date-time-picker/CoarPlainDateTimePicker.vue.d.ts.map +1 -1
- package/dist/components/date-time/zoned-date-time-picker/CoarZonedDateTimePicker.vue.d.ts +1 -1
- package/dist/components/date-time/zoned-date-time-picker/CoarZonedDateTimePicker.vue.d.ts.map +1 -1
- package/dist/components/dual-listbox/CoarDualListbox.vue.d.ts +3 -0
- package/dist/components/dual-listbox/CoarDualListbox.vue.d.ts.map +1 -1
- package/dist/components/form-field/CoarFormField.vue.d.ts +1 -1
- package/dist/components/form-field/CoarFormField.vue.d.ts.map +1 -1
- package/dist/components/icon/CoarIcon.vue.d.ts +2 -2
- package/dist/components/icon/CoarIcon.vue.d.ts.map +1 -1
- package/dist/components/listbox/CoarListbox.vue.d.ts +7 -0
- package/dist/components/listbox/CoarListbox.vue.d.ts.map +1 -1
- package/dist/components/number-input/CoarNumberInput.vue.d.ts +1 -1
- package/dist/components/number-input/CoarNumberInput.vue.d.ts.map +1 -1
- package/dist/components/otp-input/CoarOtpInput.vue.d.ts +1 -1
- package/dist/components/otp-input/CoarOtpInput.vue.d.ts.map +1 -1
- package/dist/components/password-input/CoarPasswordInput.vue.d.ts +1 -1
- package/dist/components/password-input/CoarPasswordInput.vue.d.ts.map +1 -1
- package/dist/components/switch/CoarSwitch.vue.d.ts +1 -1
- package/dist/components/switch/CoarSwitch.vue.d.ts.map +1 -1
- package/dist/components/text-input/CoarTextInput.vue.d.ts +1 -1
- package/dist/components/text-input/CoarTextInput.vue.d.ts.map +1 -1
- package/dist/composables/dragRegistry.d.ts +12 -0
- package/dist/composables/dragRegistry.d.ts.map +1 -1
- package/dist/composables/index.d.ts +2 -2
- package/dist/composables/index.d.ts.map +1 -1
- package/dist/composables/useDragDrop.d.ts +62 -6
- package/dist/composables/useDragDrop.d.ts.map +1 -1
- package/dist/composables/useVirtualList.d.ts +21 -1
- package/dist/composables/useVirtualList.d.ts.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4508 -2039
- package/package.json +5 -3
- package/skills/cocoar-vue-ui/SKILL.md +244 -0
- package/skills/cocoar-vue-ui/references/components/avatar.md +178 -0
- package/skills/cocoar-vue-ui/references/components/badge.md +290 -0
- package/skills/cocoar-vue-ui/references/components/breadcrumb.md +238 -0
- package/skills/cocoar-vue-ui/references/components/button.md +252 -0
- package/skills/cocoar-vue-ui/references/components/calendar/agenda-view.md +353 -0
- package/skills/cocoar-vue-ui/references/components/calendar/coar-calendar.md +1645 -0
- package/skills/cocoar-vue-ui/references/components/calendar/day-view.md +361 -0
- package/skills/cocoar-vue-ui/references/components/calendar/index.md +312 -0
- package/skills/cocoar-vue-ui/references/components/calendar/month-view.md +475 -0
- package/skills/cocoar-vue-ui/references/components/calendar/performance.md +186 -0
- package/skills/cocoar-vue-ui/references/components/calendar/timeline-view.md +301 -0
- package/skills/cocoar-vue-ui/references/components/calendar/week-view.md +382 -0
- package/skills/cocoar-vue-ui/references/components/calendar/work-week-view.md +145 -0
- package/skills/cocoar-vue-ui/references/components/calendar/year-view.md +63 -0
- package/skills/cocoar-vue-ui/references/components/card.md +151 -0
- package/skills/cocoar-vue-ui/references/components/checkbox-group.md +103 -0
- package/skills/cocoar-vue-ui/references/components/checkbox.md +279 -0
- package/skills/cocoar-vue-ui/references/components/code-block.md +241 -0
- package/skills/cocoar-vue-ui/references/components/context-menu.md +355 -0
- package/skills/cocoar-vue-ui/references/components/data-grid/checkbox.md +213 -0
- package/skills/cocoar-vue-ui/references/components/data-grid/date-columns.md +272 -0
- package/skills/cocoar-vue-ui/references/components/data-grid/editing.md +236 -0
- package/skills/cocoar-vue-ui/references/components/data-grid/multi-select.md +193 -0
- package/skills/cocoar-vue-ui/references/components/data-grid/number.md +147 -0
- package/skills/cocoar-vue-ui/references/components/data-grid/select.md +202 -0
- package/skills/cocoar-vue-ui/references/components/data-grid/text.md +127 -0
- package/skills/cocoar-vue-ui/references/components/data-grid.md +1225 -0
- package/skills/cocoar-vue-ui/references/components/data-list.md +2121 -0
- package/skills/cocoar-vue-ui/references/components/date-or-time-picker.md +200 -0
- package/skills/cocoar-vue-ui/references/components/date-picker.md +203 -0
- package/skills/cocoar-vue-ui/references/components/date-time-picker.md +154 -0
- package/skills/cocoar-vue-ui/references/components/date-views.md +212 -0
- package/skills/cocoar-vue-ui/references/components/dialog.md +148 -0
- package/skills/cocoar-vue-ui/references/components/divider.md +157 -0
- package/skills/cocoar-vue-ui/references/components/document-viewer/annotations.md +400 -0
- package/skills/cocoar-vue-ui/references/components/document-viewer/coar-document-viewer.md +327 -0
- package/skills/cocoar-vue-ui/references/components/document-viewer/index.md +234 -0
- package/skills/cocoar-vue-ui/references/components/document-viewer/toolbar.md +221 -0
- package/skills/cocoar-vue-ui/references/components/drag-drop.md +267 -0
- package/skills/cocoar-vue-ui/references/components/dual-listbox.md +449 -0
- package/skills/cocoar-vue-ui/references/components/file-explorer/asset-store.md +327 -0
- package/skills/cocoar-vue-ui/references/components/file-explorer/in-memory-store.md +176 -0
- package/skills/cocoar-vue-ui/references/components/file-explorer/index.md +311 -0
- package/skills/cocoar-vue-ui/references/components/file-explorer/use-file-explorer.md +300 -0
- package/skills/cocoar-vue-ui/references/components/form-field.md +1025 -0
- package/skills/cocoar-vue-ui/references/components/fragment-parser.md +298 -0
- package/skills/cocoar-vue-ui/references/components/link.md +235 -0
- package/skills/cocoar-vue-ui/references/components/listbox.md +575 -0
- package/skills/cocoar-vue-ui/references/components/map/editor.md +448 -0
- package/skills/cocoar-vue-ui/references/components/map/index.md +351 -0
- package/skills/cocoar-vue-ui/references/components/markdown-diagrams.md +210 -0
- package/skills/cocoar-vue-ui/references/components/markdown-editor.md +1478 -0
- package/skills/cocoar-vue-ui/references/components/markdown-embeds.md +387 -0
- package/skills/cocoar-vue-ui/references/components/markdown-form.md +447 -0
- package/skills/cocoar-vue-ui/references/components/markdown.md +276 -0
- package/skills/cocoar-vue-ui/references/components/menu.md +380 -0
- package/skills/cocoar-vue-ui/references/components/mermaid.md +172 -0
- package/skills/cocoar-vue-ui/references/components/navbar.md +147 -0
- package/skills/cocoar-vue-ui/references/components/note.md +96 -0
- package/skills/cocoar-vue-ui/references/components/notice.md +131 -0
- package/skills/cocoar-vue-ui/references/components/number-input.md +215 -0
- package/skills/cocoar-vue-ui/references/components/otp-input.md +324 -0
- package/skills/cocoar-vue-ui/references/components/page-builder/authoring-contract.md +271 -0
- package/skills/cocoar-vue-ui/references/components/page-builder/coar-page-builder.md +476 -0
- package/skills/cocoar-vue-ui/references/components/page-builder/coar-page-renderer.md +677 -0
- package/skills/cocoar-vue-ui/references/components/page-builder/custom-elements.md +441 -0
- package/skills/cocoar-vue-ui/references/components/page-builder/idp-integration.md +122 -0
- package/skills/cocoar-vue-ui/references/components/page-builder/index.md +573 -0
- package/skills/cocoar-vue-ui/references/components/pagination.md +150 -0
- package/skills/cocoar-vue-ui/references/components/panel-layout.md +372 -0
- package/skills/cocoar-vue-ui/references/components/password-input.md +175 -0
- package/skills/cocoar-vue-ui/references/components/popconfirm.md +186 -0
- package/skills/cocoar-vue-ui/references/components/popover.md +173 -0
- package/skills/cocoar-vue-ui/references/components/progress-bar.md +178 -0
- package/skills/cocoar-vue-ui/references/components/radio-group.md +225 -0
- package/skills/cocoar-vue-ui/references/components/script-editor.md +1271 -0
- package/skills/cocoar-vue-ui/references/components/segmented-control.md +238 -0
- package/skills/cocoar-vue-ui/references/components/select.md +463 -0
- package/skills/cocoar-vue-ui/references/components/sidebar.md +421 -0
- package/skills/cocoar-vue-ui/references/components/spinner.md +132 -0
- package/skills/cocoar-vue-ui/references/components/switch.md +195 -0
- package/skills/cocoar-vue-ui/references/components/table.md +170 -0
- package/skills/cocoar-vue-ui/references/components/tabs.md +382 -0
- package/skills/cocoar-vue-ui/references/components/tag.md +178 -0
- package/skills/cocoar-vue-ui/references/components/text-input.md +256 -0
- package/skills/cocoar-vue-ui/references/components/toast.md +160 -0
- package/skills/cocoar-vue-ui/references/components/tooltip.md +121 -0
- package/skills/cocoar-vue-ui/references/components/transitions.md +193 -0
- package/skills/cocoar-vue-ui/references/components/tree.md +2388 -0
- package/skills/cocoar-vue-ui/references/components/virtual-list.md +212 -0
- package/skills/cocoar-vue-ui/references/components/wizard.md +251 -0
- package/skills/cocoar-vue-ui/references/components/zoned-date-time-picker.md +177 -0
- package/skills/cocoar-vue-ui/references/foundations/colors.md +708 -0
- package/skills/cocoar-vue-ui/references/foundations/design-principles.md +115 -0
- package/skills/cocoar-vue-ui/references/foundations/icons.md +381 -0
- package/skills/cocoar-vue-ui/references/foundations/localization/formatting.md +530 -0
- package/skills/cocoar-vue-ui/references/foundations/localization/setup.md +86 -0
- package/skills/cocoar-vue-ui/references/foundations/localization/timezones.md +182 -0
- package/skills/cocoar-vue-ui/references/foundations/localization/translations.md +305 -0
- package/skills/cocoar-vue-ui/references/foundations/motion.md +549 -0
- package/skills/cocoar-vue-ui/references/foundations/spacing.md +330 -0
- package/skills/cocoar-vue-ui/references/foundations/theming.md +140 -0
- package/skills/cocoar-vue-ui/references/foundations/typography.md +206 -0
- package/skills/cocoar-vue-ui/references/guide/error-handling.md +162 -0
- package/skills/cocoar-vue-ui/references/guide/getting-started.md +119 -0
- package/skills/cocoar-vue-ui/references/guide/migration-page-builder-3.md +207 -0
- package/skills/cocoar-vue-ui/references/guide/migration.md +140 -0
- package/skills/cocoar-vue-ui/references/guide/theming.md +98 -0
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
<!-- Generated from apps/docs/components/markdown-form.md by apps/docs/scripts/sync-skill.mjs. Do not edit; edit the docs page. -->
|
|
2
|
+
|
|
3
|
+
# Markdown Form
|
|
4
|
+
|
|
5
|
+
`CoarMarkdownForm` turns a Markdown string into a form-like document. Headings,
|
|
6
|
+
labels, lists and explanatory text stay fixed; only explicit field directives
|
|
7
|
+
can be changed. Field values live in a separate object and never rewrite the
|
|
8
|
+
template.
|
|
9
|
+
|
|
10
|
+
The package currently renders and fills an existing template. It does not yet
|
|
11
|
+
contain a visual template designer. Templates can be constants in the app,
|
|
12
|
+
separate `.md` assets, or strings loaded from an API or database.
|
|
13
|
+
|
|
14
|
+
## Smallest complete example
|
|
15
|
+
|
|
16
|
+
```vue
|
|
17
|
+
<script setup lang="ts">
|
|
18
|
+
import { ref } from 'vue';
|
|
19
|
+
import { CoarMarkdownForm, type MarkdownFormValues } from '@cocoar/vue-markdown-form';
|
|
20
|
+
import '@cocoar/vue-markdown-form/styles';
|
|
21
|
+
|
|
22
|
+
const template = `# Meeting protocol
|
|
23
|
+
|
|
24
|
+
**Name:** :field{id=name type=text layout=row width=fill required placeholder="Full name"}
|
|
25
|
+
|
|
26
|
+
**Date:** :field{id=date type=date required}
|
|
27
|
+
|
|
28
|
+
## Summary
|
|
29
|
+
|
|
30
|
+
:::field{id=summary type=markdown required placeholder="What was discussed?"}
|
|
31
|
+
`;
|
|
32
|
+
|
|
33
|
+
const values = ref<MarkdownFormValues>({
|
|
34
|
+
name: '',
|
|
35
|
+
date: '',
|
|
36
|
+
summary: '',
|
|
37
|
+
});
|
|
38
|
+
</script>
|
|
39
|
+
|
|
40
|
+
<template>
|
|
41
|
+
<CoarMarkdownForm v-model:values="values" :template="template" mode="fill" />
|
|
42
|
+
</template>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The template and values are deliberately independent:
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
// The reusable, fixed document structure
|
|
49
|
+
const template = '# Protocol\n\n**Name:** :field{id=name type=text}';
|
|
50
|
+
|
|
51
|
+
// The data belonging to one filled document
|
|
52
|
+
const values = { name: 'Ada Lovelace' };
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Copyable protocol template
|
|
56
|
+
|
|
57
|
+
This example uses every built-in field type and can be copied directly into a
|
|
58
|
+
JavaScript or TypeScript template string:
|
|
59
|
+
|
|
60
|
+
```md
|
|
61
|
+
# Gesprächsprotokoll
|
|
62
|
+
|
|
63
|
+
**Name:** :field{id=personName type=text layout=row width=fill required placeholder="Vor- und Nachname"}
|
|
64
|
+
|
|
65
|
+
**Datum:** :field{id=meetingDate type=datetime width=14.5rem required placeholder="Datum und Uhrzeit"}
|
|
66
|
+
**Rolle:** :field{id=role type=select width=large options="po:Product Owner|dev:Developer|design:Design" placeholder="Rolle"}
|
|
67
|
+
**Dauer:** :field{id=durationMinutes type=number width=10rem min=15 max=240 step=15 suffix="Min."}
|
|
68
|
+
|
|
69
|
+
**Thema:** :field{id=topic type=text layout=stacked width=full required placeholder="Thema des Gesprächs"}
|
|
70
|
+
|
|
71
|
+
**Freigegeben:** :field{id=approved type=boolean trueLabel="Ja" falseLabel="Nein"}
|
|
72
|
+
|
|
73
|
+
## Zusammenfassung
|
|
74
|
+
|
|
75
|
+
:::field{id=summary type=markdown label="Gesprächszusammenfassung" required placeholder="Was wurde besprochen?"}
|
|
76
|
+
|
|
77
|
+
## Nächste Schritte
|
|
78
|
+
|
|
79
|
+
:::field{id=actions type=markdown label="Vereinbarte Schritte" placeholder="- [ ] Aufgabe ergänzen …"}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Its initial values object can look like this:
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
const values = ref<MarkdownFormValues>({
|
|
86
|
+
personName: '',
|
|
87
|
+
meetingDate: '',
|
|
88
|
+
role: null,
|
|
89
|
+
durationMinutes: null,
|
|
90
|
+
topic: '',
|
|
91
|
+
approved: false,
|
|
92
|
+
summary: '',
|
|
93
|
+
actions: '',
|
|
94
|
+
});
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Field syntax
|
|
98
|
+
|
|
99
|
+
### Inline field
|
|
100
|
+
|
|
101
|
+
Use `:field{...}` for a short control inside a normal Markdown paragraph:
|
|
102
|
+
|
|
103
|
+
```md
|
|
104
|
+
**Duration:** :field{id=duration type=number min=15 step=15 suffix="min"}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
The directive can appear next to ordinary Markdown, including bold labels.
|
|
108
|
+
Attribute values containing spaces must be quoted.
|
|
109
|
+
|
|
110
|
+
### Block field
|
|
111
|
+
|
|
112
|
+
Use `:::field{...}` on its own line for a Markdown editor:
|
|
113
|
+
|
|
114
|
+
```md
|
|
115
|
+
## Decisions
|
|
116
|
+
|
|
117
|
+
:::field{id=decisions type=markdown required placeholder="Add decisions …"}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
A block field is a single directive line. It has no closing `:::` marker and no
|
|
121
|
+
editable content inside the template. Its content comes from
|
|
122
|
+
`values.decisions`.
|
|
123
|
+
|
|
124
|
+
The legacy POC spelling `:::markdown-field{id=decisions}` remains readable, but
|
|
125
|
+
new templates should use `:::field{type=markdown ...}`.
|
|
126
|
+
|
|
127
|
+
### Attribute rules
|
|
128
|
+
|
|
129
|
+
- Attributes are separated by whitespace.
|
|
130
|
+
- Quote values containing whitespace: `placeholder="Full name"`.
|
|
131
|
+
- Flags do not need a value: `required` is the same as `required=true`.
|
|
132
|
+
- `required=false`, `required=0`, `required=no` and `required=off` disable the
|
|
133
|
+
flag.
|
|
134
|
+
- IDs must be present and unique within a template. Prefer stable identifiers
|
|
135
|
+
such as `personName`; changing an ID also changes the key in `values`.
|
|
136
|
+
- An escaped `\:field{...}` is rendered as ordinary Markdown text instead of a
|
|
137
|
+
field directive.
|
|
138
|
+
|
|
139
|
+
## Common attributes
|
|
140
|
+
|
|
141
|
+
| Attribute | Values / default | Description |
|
|
142
|
+
| ------------- | ------------------------------------------------ | ----------------------------------------------------------------------------------- |
|
|
143
|
+
| `id` | required | Stable, unique key in the values object. |
|
|
144
|
+
| `type` | registered type; default `text` | Selects the field control. |
|
|
145
|
+
| `label` | string | Accessible name and validation label. Visible labels can remain normal Markdown. |
|
|
146
|
+
| `required` | boolean flag; default `false` | Enables validation. For a boolean field this means that it must be checked. |
|
|
147
|
+
| `placeholder` | string | Hint shown while the control is empty. |
|
|
148
|
+
| `layout` | `inline`, `row`, `stacked`, `block` | Arranges the field and its surrounding Markdown paragraph. |
|
|
149
|
+
| `width` | `small`, `medium`, `large`, `fill`, `full`, unit | Named, flexible, or fixed width. Fixed widths accept bounded `ch` and `rem` values. |
|
|
150
|
+
|
|
151
|
+
`small`, `medium` and `large` default to `10ch`, `18ch` and `32ch`. Apps can
|
|
152
|
+
replace those values through the typed context.
|
|
153
|
+
|
|
154
|
+
## Layout cookbook
|
|
155
|
+
|
|
156
|
+
### Keep a small value in the text flow
|
|
157
|
+
|
|
158
|
+
```md
|
|
159
|
+
**Age:** :field{id=age type=number width=small}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
`layout=inline` is the default for `:field`. It behaves like an inline part of
|
|
163
|
+
the paragraph.
|
|
164
|
+
|
|
165
|
+
### Label on the left, field uses the remaining row
|
|
166
|
+
|
|
167
|
+
```md
|
|
168
|
+
**Full name:** :field{id=fullName type=text layout=row width=fill}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
`layout=row` turns the paragraph into a label/value row. For predictable
|
|
172
|
+
results, use one `row` field per paragraph.
|
|
173
|
+
|
|
174
|
+
### Label above a full-width field
|
|
175
|
+
|
|
176
|
+
```md
|
|
177
|
+
**Topic:** :field{id=topic type=text layout=stacked width=full}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
`layout=stacked` places the Markdown text above the control. `width=full` makes
|
|
181
|
+
the field use the complete row.
|
|
182
|
+
|
|
183
|
+
### Markdown editor below a fixed heading
|
|
184
|
+
|
|
185
|
+
```md
|
|
186
|
+
## Notes
|
|
187
|
+
|
|
188
|
+
:::field{id=notes type=markdown placeholder="Add notes …"}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
`markdown` supports block layout only. The heading remains part of the fixed
|
|
192
|
+
template even when the Markdown value is completely empty.
|
|
193
|
+
|
|
194
|
+
## Built-in field reference
|
|
195
|
+
|
|
196
|
+
| Type | Stored value | Default empty value | Control |
|
|
197
|
+
| ---------- | ------------------------------------ | ------------------- | ------------------------------------- |
|
|
198
|
+
| `text` | `string` | `''` | `CoarTextInput` |
|
|
199
|
+
| `number` | `number \| null` | `null` | `CoarNumberInput` |
|
|
200
|
+
| `date` | `YYYY-MM-DD` string | `''` | `CoarPlainDatePicker` |
|
|
201
|
+
| `datetime` | `YYYY-MM-DDTHH:mm` local-time string | `''` | `CoarPlainDateTimePicker` |
|
|
202
|
+
| `boolean` | `boolean` | `false` | `CoarCheckbox` |
|
|
203
|
+
| `select` | `string \| null` | `null` | `CoarSelect` |
|
|
204
|
+
| `markdown` | Markdown string | `''` | `CoarMarkdownEditor` / `CoarMarkdown` |
|
|
205
|
+
|
|
206
|
+
### `text`
|
|
207
|
+
|
|
208
|
+
```md
|
|
209
|
+
:field{id=email type=text inputType=email maxLength=120 placeholder="name@example.com"}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
| Attribute | Description |
|
|
213
|
+
| ------------------ | ---------------------------------------------------------- |
|
|
214
|
+
| `inputType` | `text`, `email`, `url`, `tel` or `search`; default `text`. |
|
|
215
|
+
| `rows` | Text rows. Values greater than `1` render a text area. |
|
|
216
|
+
| `minLength` | Minimum length used by form validation. |
|
|
217
|
+
| `maxLength` | Maximum length used by the control and form validation. |
|
|
218
|
+
| `minLengthMessage` | Optional custom validation message. |
|
|
219
|
+
| `maxLengthMessage` | Optional custom validation message. |
|
|
220
|
+
|
|
221
|
+
For formatted long text, prefer `type=markdown` instead of `rows`.
|
|
222
|
+
|
|
223
|
+
### `number`
|
|
224
|
+
|
|
225
|
+
```md
|
|
226
|
+
:field{id=duration type=number min=15 max=240 step=15 decimals=0 suffix="Min."}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
| Attribute | Description |
|
|
230
|
+
| --------------- | ----------------------------------------------- |
|
|
231
|
+
| `min` | Minimum accepted value. |
|
|
232
|
+
| `max` | Maximum accepted value. |
|
|
233
|
+
| `step` | Stepper increment; default `1`. |
|
|
234
|
+
| `decimals` | Displayed decimal places; default `0`. |
|
|
235
|
+
| `suffix` | Display suffix, for example `kg` or `Min.`. |
|
|
236
|
+
| `numberMessage` | Message for a value that is not a valid number. |
|
|
237
|
+
| `minMessage` | Optional custom minimum validation message. |
|
|
238
|
+
| `maxMessage` | Optional custom maximum validation message. |
|
|
239
|
+
|
|
240
|
+
### `date`
|
|
241
|
+
|
|
242
|
+
```md
|
|
243
|
+
:field{id=birthday type=date min=1900-01-01 max=2030-12-31}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
`min` and `max` use ISO dates (`YYYY-MM-DD`). The stored value is also an ISO
|
|
247
|
+
date string; readonly mode formats it using `context.locale`.
|
|
248
|
+
|
|
249
|
+
### `datetime`
|
|
250
|
+
|
|
251
|
+
```md
|
|
252
|
+
:field{id=startsAt type=datetime minuteStep=15 min="2026-01-01T08:00" max="2026-12-31T18:00"}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
`min` and `max` use local ISO date-times. `minuteStep` accepts `1`, `5`, `10` or
|
|
256
|
+
`15` and defaults to `15`. The value intentionally has no timezone because the
|
|
257
|
+
control stores a local date and time.
|
|
258
|
+
|
|
259
|
+
### `boolean`
|
|
260
|
+
|
|
261
|
+
```md
|
|
262
|
+
:field{id=approved type=boolean trueLabel="Approved" falseLabel="Not approved"}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
`trueLabel` and `falseLabel` control readonly output. A `required` boolean is
|
|
266
|
+
valid only when its value is `true`.
|
|
267
|
+
|
|
268
|
+
### `select`
|
|
269
|
+
|
|
270
|
+
```md
|
|
271
|
+
:field{id=role type=select options="po:Product Owner|dev:Developer|design:Design" placeholder="Select a role"}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
Options are `value:label` entries separated by `|`. The stored value is the
|
|
275
|
+
part before the colon (`po`, `dev` or `design` in this example). Escape literal
|
|
276
|
+
separators as `\|` and label colons as `\:`. `optionMessage` overrides the
|
|
277
|
+
validation message for a value not present in the option list.
|
|
278
|
+
|
|
279
|
+
### `markdown`
|
|
280
|
+
|
|
281
|
+
```md
|
|
282
|
+
:::field{id=summary type=markdown required placeholder="Write a summary …"}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
Markdown fields must use the block syntax. Fill mode renders a
|
|
286
|
+
`CoarMarkdownEditor`; readonly mode renders the saved value through
|
|
287
|
+
`CoarMarkdown`.
|
|
288
|
+
|
|
289
|
+
## Shared Markdown toolbar
|
|
290
|
+
|
|
291
|
+
Markdown block fields use `toolbar-mode="external"`. Wrap the form and one
|
|
292
|
+
toolbar in `CoarMarkdownEditorGroup`; the toolbar automatically targets the
|
|
293
|
+
focused Markdown field and stays disabled when no Markdown field is active.
|
|
294
|
+
|
|
295
|
+
```vue
|
|
296
|
+
<script setup lang="ts">
|
|
297
|
+
import { CoarMarkdownEditorGroup, CoarMarkdownToolbar } from '@cocoar/vue-markdown-editor';
|
|
298
|
+
import { CoarMarkdownForm } from '@cocoar/vue-markdown-form';
|
|
299
|
+
</script>
|
|
300
|
+
|
|
301
|
+
<template>
|
|
302
|
+
<CoarMarkdownEditorGroup>
|
|
303
|
+
<CoarMarkdownToolbar position="top" />
|
|
304
|
+
<CoarMarkdownForm v-model:values="values" :template="template" />
|
|
305
|
+
</CoarMarkdownEditorGroup>
|
|
306
|
+
</template>
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
The toolbar is optional. Without a group and external toolbar, Markdown values
|
|
310
|
+
can still be typed, but formatting commands are not shown.
|
|
311
|
+
|
|
312
|
+
## Fill and readonly modes
|
|
313
|
+
|
|
314
|
+
```vue
|
|
315
|
+
<CoarMarkdownForm
|
|
316
|
+
v-model:values="values"
|
|
317
|
+
:template="template"
|
|
318
|
+
:mode="editing ? 'fill' : 'readonly'"
|
|
319
|
+
/>
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
- `fill` renders registered controls and allows only field values to change.
|
|
323
|
+
- `readonly` formats the values as a finished document. No field is editable.
|
|
324
|
+
- Fixed Markdown is never editable in either mode.
|
|
325
|
+
|
|
326
|
+
## Validation
|
|
327
|
+
|
|
328
|
+
Validation is always calculated, while `show-errors` controls its visual
|
|
329
|
+
presentation. The component emits `validation` and exposes `validate()`.
|
|
330
|
+
|
|
331
|
+
```vue
|
|
332
|
+
<CoarMarkdownForm
|
|
333
|
+
ref="form"
|
|
334
|
+
v-model:values="values"
|
|
335
|
+
:template="template"
|
|
336
|
+
:show-errors="submitted"
|
|
337
|
+
@validation="validation = $event"
|
|
338
|
+
/>
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
Template analysis reports missing IDs, duplicate IDs, unknown types and layouts
|
|
342
|
+
unsupported by their registered type. Built-ins validate required values;
|
|
343
|
+
`text`, `number` and `select` additionally validate their type-specific
|
|
344
|
+
constraints.
|
|
345
|
+
|
|
346
|
+
```ts
|
|
347
|
+
interface MarkdownFormValidationResult {
|
|
348
|
+
valid: boolean;
|
|
349
|
+
errors: Readonly<Record<string, string>>;
|
|
350
|
+
issues: readonly MarkdownFormTemplateIssue[];
|
|
351
|
+
}
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
`errors` are instance-value errors keyed by field ID. `issues` are structural
|
|
355
|
+
problems in the template itself.
|
|
356
|
+
|
|
357
|
+
## Typed context
|
|
358
|
+
|
|
359
|
+
`context` controls presentation without coupling field controls to a specific
|
|
360
|
+
app. Nested properties are merged with package defaults.
|
|
361
|
+
|
|
362
|
+
```ts
|
|
363
|
+
const context = {
|
|
364
|
+
design: 'coar',
|
|
365
|
+
locale: 'de-AT',
|
|
366
|
+
widths: {
|
|
367
|
+
small: '10ch',
|
|
368
|
+
medium: '20ch',
|
|
369
|
+
large: '36ch',
|
|
370
|
+
},
|
|
371
|
+
decorations: {
|
|
372
|
+
markdownFrame: true,
|
|
373
|
+
inlineUnderline: false,
|
|
374
|
+
},
|
|
375
|
+
};
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
`design` is either `coar` or `basic`. Readonly decorations affect only
|
|
379
|
+
`mode="readonly"`; fill mode always keeps the Markdown editor frame visible.
|
|
380
|
+
The context can also replace validation messages and the tools available to
|
|
381
|
+
Markdown fields.
|
|
382
|
+
|
|
383
|
+
## Custom field controls
|
|
384
|
+
|
|
385
|
+
`fields` merges additively over the built-in registry. A field definition owns
|
|
386
|
+
the fill control, value semantics, supported layouts, validation and optional
|
|
387
|
+
readonly rendering.
|
|
388
|
+
|
|
389
|
+
```ts
|
|
390
|
+
import type { MarkdownFormFieldRegistry } from '@cocoar/vue-markdown-form';
|
|
391
|
+
import RatingControl from './RatingControl.vue';
|
|
392
|
+
|
|
393
|
+
const fields: MarkdownFormFieldRegistry = {
|
|
394
|
+
rating: {
|
|
395
|
+
control: RatingControl,
|
|
396
|
+
valueType: 'number',
|
|
397
|
+
layouts: ['inline', 'row'],
|
|
398
|
+
defaultValue: () => null,
|
|
399
|
+
isEmpty: (value) => value == null,
|
|
400
|
+
},
|
|
401
|
+
};
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
```vue
|
|
405
|
+
<CoarMarkdownForm :fields="fields" :template="template" v-model:values="values" />
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
The matching template syntax is then:
|
|
409
|
+
|
|
410
|
+
```md
|
|
411
|
+
**Rating:** :field{id=rating type=rating}
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
A control receives `field`, `modelValue`, the resolved typed `context`, and an
|
|
415
|
+
optional `error`; it writes through `update:modelValue`. This is deliberately
|
|
416
|
+
separate from Markdown's `EmbedDefinition.editor`: embed editors rewrite
|
|
417
|
+
directive attributes in Markdown, while form controls update the external
|
|
418
|
+
values object.
|
|
419
|
+
|
|
420
|
+
## Props and events
|
|
421
|
+
|
|
422
|
+
| API | Type | Description |
|
|
423
|
+
| -------------------------- | --------------------------- | ----------------------------------------------------------- |
|
|
424
|
+
| `template` | `string` | Fixed Markdown template. |
|
|
425
|
+
| `values` / `update:values` | `MarkdownFormValues` | Separate typed instance values. |
|
|
426
|
+
| `mode` | `'fill' \| 'readonly'` | Interactive controls or formatted output. |
|
|
427
|
+
| `fields` | `MarkdownFormFieldRegistry` | Consumer field registrations/overrides. |
|
|
428
|
+
| `context` | `MarkdownFormContextInput` | Typed presentation context. |
|
|
429
|
+
| `embeds` | `EmbedRegistry` | Additional ordinary block embeds in fixed template content. |
|
|
430
|
+
| `showErrors` | `boolean` | Show current validation messages. |
|
|
431
|
+
| `validation` | event | Reactive `MarkdownFormValidationResult`. |
|
|
432
|
+
|
|
433
|
+
## Template checklist
|
|
434
|
+
|
|
435
|
+
Before shipping a template:
|
|
436
|
+
|
|
437
|
+
1. Give every field a stable, unique `id`.
|
|
438
|
+
2. Initialize every field key in the instance values object with its documented
|
|
439
|
+
empty value.
|
|
440
|
+
3. Use `:field{...}` for inline controls and `:::field{type=markdown ...}` for
|
|
441
|
+
Markdown blocks.
|
|
442
|
+
4. Quote attribute values containing whitespace.
|
|
443
|
+
5. Use `layout=row width=fill` when a control should take the rest of a label
|
|
444
|
+
row.
|
|
445
|
+
6. Use `layout=stacked width=full` when the label should sit above a full-width
|
|
446
|
+
control.
|
|
447
|
+
7. Run `validate()` or handle the `validation` event before saving.
|