@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.
Files changed (179) hide show
  1. package/dist/components/checkbox/CoarCheckbox.vue.d.ts +1 -1
  2. package/dist/components/checkbox/CoarCheckbox.vue.d.ts.map +1 -1
  3. package/dist/components/code-block/CoarCodeBlock.vue.d.ts +1 -1
  4. package/dist/components/code-block/CoarCodeBlock.vue.d.ts.map +1 -1
  5. package/dist/components/data-list/CoarDataList.vue.d.ts +158 -0
  6. package/dist/components/data-list/CoarDataList.vue.d.ts.map +1 -0
  7. package/dist/components/data-list/CoarDataListToolbar.vue.d.ts +30 -0
  8. package/dist/components/data-list/CoarDataListToolbar.vue.d.ts.map +1 -0
  9. package/dist/components/data-list/data-list-builder.d.ts +288 -0
  10. package/dist/components/data-list/data-list-builder.d.ts.map +1 -0
  11. package/dist/components/data-list/index.d.ts +12 -0
  12. package/dist/components/data-list/index.d.ts.map +1 -0
  13. package/dist/components/data-list/internal/compare.d.ts +14 -0
  14. package/dist/components/data-list/internal/compare.d.ts.map +1 -0
  15. package/dist/components/data-list/internal/reorder-core.d.ts +46 -0
  16. package/dist/components/data-list/internal/reorder-core.d.ts.map +1 -0
  17. package/dist/components/data-list/internal/search.d.ts +16 -0
  18. package/dist/components/data-list/internal/search.d.ts.map +1 -0
  19. package/dist/components/data-list/internal/useDataListLines.d.ts +92 -0
  20. package/dist/components/data-list/internal/useDataListLines.d.ts.map +1 -0
  21. package/dist/components/data-list/internal/useDataListReorder.d.ts +68 -0
  22. package/dist/components/data-list/internal/useDataListReorder.d.ts.map +1 -0
  23. package/dist/components/data-list/internal/useSearchHighlight.d.ts +19 -0
  24. package/dist/components/data-list/internal/useSearchHighlight.d.ts.map +1 -0
  25. package/dist/components/data-list/types.d.ts +185 -0
  26. package/dist/components/data-list/types.d.ts.map +1 -0
  27. package/dist/components/data-list/useDataListModel.d.ts +79 -0
  28. package/dist/components/data-list/useDataListModel.d.ts.map +1 -0
  29. package/dist/components/date-time/_shared/maskito-config.d.ts +7 -2
  30. package/dist/components/date-time/_shared/maskito-config.d.ts.map +1 -1
  31. package/dist/components/date-time/_shared/time-helpers.d.ts +11 -4
  32. package/dist/components/date-time/_shared/time-helpers.d.ts.map +1 -1
  33. package/dist/components/date-time/_shared/use-date-picker-base.d.ts +1 -1
  34. package/dist/components/date-time/plain-date-picker/CoarPlainDatePicker.vue.d.ts +1 -1
  35. package/dist/components/date-time/plain-date-picker/CoarPlainDatePicker.vue.d.ts.map +1 -1
  36. package/dist/components/date-time/plain-date-time-picker/CoarPlainDateTimePicker.vue.d.ts +1 -1
  37. package/dist/components/date-time/plain-date-time-picker/CoarPlainDateTimePicker.vue.d.ts.map +1 -1
  38. package/dist/components/date-time/zoned-date-time-picker/CoarZonedDateTimePicker.vue.d.ts +1 -1
  39. package/dist/components/date-time/zoned-date-time-picker/CoarZonedDateTimePicker.vue.d.ts.map +1 -1
  40. package/dist/components/dual-listbox/CoarDualListbox.vue.d.ts +3 -0
  41. package/dist/components/dual-listbox/CoarDualListbox.vue.d.ts.map +1 -1
  42. package/dist/components/form-field/CoarFormField.vue.d.ts +1 -1
  43. package/dist/components/form-field/CoarFormField.vue.d.ts.map +1 -1
  44. package/dist/components/icon/CoarIcon.vue.d.ts +2 -2
  45. package/dist/components/icon/CoarIcon.vue.d.ts.map +1 -1
  46. package/dist/components/listbox/CoarListbox.vue.d.ts +7 -0
  47. package/dist/components/listbox/CoarListbox.vue.d.ts.map +1 -1
  48. package/dist/components/number-input/CoarNumberInput.vue.d.ts +1 -1
  49. package/dist/components/number-input/CoarNumberInput.vue.d.ts.map +1 -1
  50. package/dist/components/otp-input/CoarOtpInput.vue.d.ts +1 -1
  51. package/dist/components/otp-input/CoarOtpInput.vue.d.ts.map +1 -1
  52. package/dist/components/password-input/CoarPasswordInput.vue.d.ts +1 -1
  53. package/dist/components/password-input/CoarPasswordInput.vue.d.ts.map +1 -1
  54. package/dist/components/switch/CoarSwitch.vue.d.ts +1 -1
  55. package/dist/components/switch/CoarSwitch.vue.d.ts.map +1 -1
  56. package/dist/components/text-input/CoarTextInput.vue.d.ts +1 -1
  57. package/dist/components/text-input/CoarTextInput.vue.d.ts.map +1 -1
  58. package/dist/composables/dragRegistry.d.ts +12 -0
  59. package/dist/composables/dragRegistry.d.ts.map +1 -1
  60. package/dist/composables/index.d.ts +2 -2
  61. package/dist/composables/index.d.ts.map +1 -1
  62. package/dist/composables/useDragDrop.d.ts +62 -6
  63. package/dist/composables/useDragDrop.d.ts.map +1 -1
  64. package/dist/composables/useVirtualList.d.ts +21 -1
  65. package/dist/composables/useVirtualList.d.ts.map +1 -1
  66. package/dist/index.css +1 -1
  67. package/dist/index.d.ts +4 -2
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +4508 -2039
  70. package/package.json +5 -3
  71. package/skills/cocoar-vue-ui/SKILL.md +244 -0
  72. package/skills/cocoar-vue-ui/references/components/avatar.md +178 -0
  73. package/skills/cocoar-vue-ui/references/components/badge.md +290 -0
  74. package/skills/cocoar-vue-ui/references/components/breadcrumb.md +238 -0
  75. package/skills/cocoar-vue-ui/references/components/button.md +252 -0
  76. package/skills/cocoar-vue-ui/references/components/calendar/agenda-view.md +353 -0
  77. package/skills/cocoar-vue-ui/references/components/calendar/coar-calendar.md +1645 -0
  78. package/skills/cocoar-vue-ui/references/components/calendar/day-view.md +361 -0
  79. package/skills/cocoar-vue-ui/references/components/calendar/index.md +312 -0
  80. package/skills/cocoar-vue-ui/references/components/calendar/month-view.md +475 -0
  81. package/skills/cocoar-vue-ui/references/components/calendar/performance.md +186 -0
  82. package/skills/cocoar-vue-ui/references/components/calendar/timeline-view.md +301 -0
  83. package/skills/cocoar-vue-ui/references/components/calendar/week-view.md +382 -0
  84. package/skills/cocoar-vue-ui/references/components/calendar/work-week-view.md +145 -0
  85. package/skills/cocoar-vue-ui/references/components/calendar/year-view.md +63 -0
  86. package/skills/cocoar-vue-ui/references/components/card.md +151 -0
  87. package/skills/cocoar-vue-ui/references/components/checkbox-group.md +103 -0
  88. package/skills/cocoar-vue-ui/references/components/checkbox.md +279 -0
  89. package/skills/cocoar-vue-ui/references/components/code-block.md +241 -0
  90. package/skills/cocoar-vue-ui/references/components/context-menu.md +355 -0
  91. package/skills/cocoar-vue-ui/references/components/data-grid/checkbox.md +213 -0
  92. package/skills/cocoar-vue-ui/references/components/data-grid/date-columns.md +272 -0
  93. package/skills/cocoar-vue-ui/references/components/data-grid/editing.md +236 -0
  94. package/skills/cocoar-vue-ui/references/components/data-grid/multi-select.md +193 -0
  95. package/skills/cocoar-vue-ui/references/components/data-grid/number.md +147 -0
  96. package/skills/cocoar-vue-ui/references/components/data-grid/select.md +202 -0
  97. package/skills/cocoar-vue-ui/references/components/data-grid/text.md +127 -0
  98. package/skills/cocoar-vue-ui/references/components/data-grid.md +1225 -0
  99. package/skills/cocoar-vue-ui/references/components/data-list.md +2121 -0
  100. package/skills/cocoar-vue-ui/references/components/date-or-time-picker.md +200 -0
  101. package/skills/cocoar-vue-ui/references/components/date-picker.md +203 -0
  102. package/skills/cocoar-vue-ui/references/components/date-time-picker.md +154 -0
  103. package/skills/cocoar-vue-ui/references/components/date-views.md +212 -0
  104. package/skills/cocoar-vue-ui/references/components/dialog.md +148 -0
  105. package/skills/cocoar-vue-ui/references/components/divider.md +157 -0
  106. package/skills/cocoar-vue-ui/references/components/document-viewer/annotations.md +400 -0
  107. package/skills/cocoar-vue-ui/references/components/document-viewer/coar-document-viewer.md +327 -0
  108. package/skills/cocoar-vue-ui/references/components/document-viewer/index.md +234 -0
  109. package/skills/cocoar-vue-ui/references/components/document-viewer/toolbar.md +221 -0
  110. package/skills/cocoar-vue-ui/references/components/drag-drop.md +267 -0
  111. package/skills/cocoar-vue-ui/references/components/dual-listbox.md +449 -0
  112. package/skills/cocoar-vue-ui/references/components/file-explorer/asset-store.md +327 -0
  113. package/skills/cocoar-vue-ui/references/components/file-explorer/in-memory-store.md +176 -0
  114. package/skills/cocoar-vue-ui/references/components/file-explorer/index.md +311 -0
  115. package/skills/cocoar-vue-ui/references/components/file-explorer/use-file-explorer.md +300 -0
  116. package/skills/cocoar-vue-ui/references/components/form-field.md +1025 -0
  117. package/skills/cocoar-vue-ui/references/components/fragment-parser.md +298 -0
  118. package/skills/cocoar-vue-ui/references/components/link.md +235 -0
  119. package/skills/cocoar-vue-ui/references/components/listbox.md +575 -0
  120. package/skills/cocoar-vue-ui/references/components/map/editor.md +448 -0
  121. package/skills/cocoar-vue-ui/references/components/map/index.md +351 -0
  122. package/skills/cocoar-vue-ui/references/components/markdown-diagrams.md +210 -0
  123. package/skills/cocoar-vue-ui/references/components/markdown-editor.md +1478 -0
  124. package/skills/cocoar-vue-ui/references/components/markdown-embeds.md +387 -0
  125. package/skills/cocoar-vue-ui/references/components/markdown-form.md +447 -0
  126. package/skills/cocoar-vue-ui/references/components/markdown.md +276 -0
  127. package/skills/cocoar-vue-ui/references/components/menu.md +380 -0
  128. package/skills/cocoar-vue-ui/references/components/mermaid.md +172 -0
  129. package/skills/cocoar-vue-ui/references/components/navbar.md +147 -0
  130. package/skills/cocoar-vue-ui/references/components/note.md +96 -0
  131. package/skills/cocoar-vue-ui/references/components/notice.md +131 -0
  132. package/skills/cocoar-vue-ui/references/components/number-input.md +215 -0
  133. package/skills/cocoar-vue-ui/references/components/otp-input.md +324 -0
  134. package/skills/cocoar-vue-ui/references/components/page-builder/authoring-contract.md +271 -0
  135. package/skills/cocoar-vue-ui/references/components/page-builder/coar-page-builder.md +476 -0
  136. package/skills/cocoar-vue-ui/references/components/page-builder/coar-page-renderer.md +677 -0
  137. package/skills/cocoar-vue-ui/references/components/page-builder/custom-elements.md +441 -0
  138. package/skills/cocoar-vue-ui/references/components/page-builder/idp-integration.md +122 -0
  139. package/skills/cocoar-vue-ui/references/components/page-builder/index.md +573 -0
  140. package/skills/cocoar-vue-ui/references/components/pagination.md +150 -0
  141. package/skills/cocoar-vue-ui/references/components/panel-layout.md +372 -0
  142. package/skills/cocoar-vue-ui/references/components/password-input.md +175 -0
  143. package/skills/cocoar-vue-ui/references/components/popconfirm.md +186 -0
  144. package/skills/cocoar-vue-ui/references/components/popover.md +173 -0
  145. package/skills/cocoar-vue-ui/references/components/progress-bar.md +178 -0
  146. package/skills/cocoar-vue-ui/references/components/radio-group.md +225 -0
  147. package/skills/cocoar-vue-ui/references/components/script-editor.md +1271 -0
  148. package/skills/cocoar-vue-ui/references/components/segmented-control.md +238 -0
  149. package/skills/cocoar-vue-ui/references/components/select.md +463 -0
  150. package/skills/cocoar-vue-ui/references/components/sidebar.md +421 -0
  151. package/skills/cocoar-vue-ui/references/components/spinner.md +132 -0
  152. package/skills/cocoar-vue-ui/references/components/switch.md +195 -0
  153. package/skills/cocoar-vue-ui/references/components/table.md +170 -0
  154. package/skills/cocoar-vue-ui/references/components/tabs.md +382 -0
  155. package/skills/cocoar-vue-ui/references/components/tag.md +178 -0
  156. package/skills/cocoar-vue-ui/references/components/text-input.md +256 -0
  157. package/skills/cocoar-vue-ui/references/components/toast.md +160 -0
  158. package/skills/cocoar-vue-ui/references/components/tooltip.md +121 -0
  159. package/skills/cocoar-vue-ui/references/components/transitions.md +193 -0
  160. package/skills/cocoar-vue-ui/references/components/tree.md +2388 -0
  161. package/skills/cocoar-vue-ui/references/components/virtual-list.md +212 -0
  162. package/skills/cocoar-vue-ui/references/components/wizard.md +251 -0
  163. package/skills/cocoar-vue-ui/references/components/zoned-date-time-picker.md +177 -0
  164. package/skills/cocoar-vue-ui/references/foundations/colors.md +708 -0
  165. package/skills/cocoar-vue-ui/references/foundations/design-principles.md +115 -0
  166. package/skills/cocoar-vue-ui/references/foundations/icons.md +381 -0
  167. package/skills/cocoar-vue-ui/references/foundations/localization/formatting.md +530 -0
  168. package/skills/cocoar-vue-ui/references/foundations/localization/setup.md +86 -0
  169. package/skills/cocoar-vue-ui/references/foundations/localization/timezones.md +182 -0
  170. package/skills/cocoar-vue-ui/references/foundations/localization/translations.md +305 -0
  171. package/skills/cocoar-vue-ui/references/foundations/motion.md +549 -0
  172. package/skills/cocoar-vue-ui/references/foundations/spacing.md +330 -0
  173. package/skills/cocoar-vue-ui/references/foundations/theming.md +140 -0
  174. package/skills/cocoar-vue-ui/references/foundations/typography.md +206 -0
  175. package/skills/cocoar-vue-ui/references/guide/error-handling.md +162 -0
  176. package/skills/cocoar-vue-ui/references/guide/getting-started.md +119 -0
  177. package/skills/cocoar-vue-ui/references/guide/migration-page-builder-3.md +207 -0
  178. package/skills/cocoar-vue-ui/references/guide/migration.md +140 -0
  179. 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.