@modufolio/panel 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/Builder/dragHandle.d.ts +10 -0
- package/dist/Builder/schema.d.ts +1 -1
- package/dist/Components/Actions/Action.vue.d.ts +1 -1
- package/dist/Components/Columns/CellActions.vue.d.ts +7 -7
- package/dist/Components/Columns/SelectColumn.vue.d.ts +8 -2
- package/dist/Components/Core/Button.vue.d.ts +2 -2
- package/dist/Components/Core/FlashMessages.vue.d.ts +6 -1
- package/dist/Components/Core/SelectInput.vue.d.ts +1 -1
- package/dist/Components/Core/TextInput.vue.d.ts +1 -1
- package/dist/Components/Dialogs/Dialog.vue.d.ts +1 -1
- package/dist/Components/Drawer/Drawer.vue.d.ts +1 -1
- package/dist/Components/Drawer/DrawerLink.vue.d.ts +4 -3
- package/dist/Components/Drawer/DrawerRelationList.vue.d.ts +12 -10
- package/dist/Components/Drawer/DrawerStack.vue.d.ts +14 -14
- package/dist/Components/Drawer/useDrawerDirtyGuard.d.ts +17 -0
- package/dist/Components/Drawer/useDrawerStack.d.ts +1 -1
- package/dist/Components/Drawer/useIsDrawer.d.ts +8 -0
- package/dist/Components/Fields/BelongsToSelect.vue.d.ts +14 -9
- package/dist/Components/Fields/CheckboxField.vue.d.ts +2 -2
- package/dist/Components/Fields/ColorPickerField.vue.d.ts +3 -3
- package/dist/Components/Fields/DataField.vue.d.ts +55 -0
- package/dist/Components/Fields/DatePickerField.vue.d.ts +2 -2
- package/dist/Components/Fields/DateRangePickerField.vue.d.ts +2 -2
- package/dist/Components/Fields/DateTimePickerField.vue.d.ts +2 -2
- package/dist/Components/Fields/EmbedField.vue.d.ts +95 -0
- package/dist/Components/Fields/FieldDescription.vue.d.ts +25 -0
- package/dist/Components/Fields/FieldLabel.vue.d.ts +67 -0
- package/dist/Components/Fields/FieldMessage.vue.d.ts +25 -0
- package/dist/Components/Fields/FieldPrimitive.vue.d.ts +127 -0
- package/dist/Components/Fields/FileUploadField.vue.d.ts +2 -2
- package/dist/Components/Fields/HiddenField.vue.d.ts +28 -0
- package/dist/Components/Fields/MultiSelectField.vue.d.ts +3 -3
- package/dist/Components/Fields/ProseMirrorBuilderField.vue.d.ts +1 -1
- package/dist/Components/Fields/RangeField.vue.d.ts +2 -2
- package/dist/Components/Fields/RepeaterField.vue.d.ts +29 -15
- package/dist/Components/Fields/RichTextEditorField.vue.d.ts +3 -3
- package/dist/Components/Fields/SelectField.vue.d.ts +6 -5
- package/dist/Components/Fields/SetField.vue.d.ts +77 -0
- package/dist/Components/Fields/TagsField.vue.d.ts +3 -3
- package/dist/Components/Fields/TextField.vue.d.ts +4 -4
- package/dist/Components/Fields/TextareaField.vue.d.ts +3 -3
- package/dist/Components/Fields/TimePickerField.vue.d.ts +2 -2
- package/dist/Components/Fields/ToggleButtonsField.vue.d.ts +10 -5
- package/dist/Components/Fields/ToggleField.vue.d.ts +2 -2
- package/dist/Components/Fields/fieldsFromSpec.d.ts +10 -2
- package/dist/Components/Fields/useBlueprint.d.ts +4 -0
- package/dist/Components/Filters/DateRangeFilter.vue.d.ts +1 -1
- package/dist/Components/Filters/MultiSelectFilter.vue.d.ts +2 -2
- package/dist/Components/Filters/NumberFilter.vue.d.ts +1 -1
- package/dist/Components/Filters/SelectFilter.vue.d.ts +2 -2
- package/dist/Components/Filters/TernaryFilter.vue.d.ts +1 -1
- package/dist/Components/Layout/AppLayout.vue.d.ts +5 -3
- package/dist/Components/Layout/Breadcrumbs.vue.d.ts +2 -2
- package/dist/Components/Layout/Sidebar.vue.d.ts +22 -3
- package/dist/Components/Relations/RelationManager.vue.d.ts +4 -3
- package/dist/Components/Table/ExportButton.vue.d.ts +3 -3
- package/dist/Components/Table/SchemaCell.d.ts +7 -7
- package/dist/Components/Table/SchemaTable.vue.d.ts +21 -20
- package/dist/Components/Table/schemaLinks.d.ts +11 -3
- package/dist/Components/Table/tableSchema.d.ts +28 -11
- package/dist/Components/Table/tableTypes.d.ts +14 -1
- package/dist/Components/Table/useSchemaActions.d.ts +9 -26
- package/dist/Composables/useDeleteConfirmation.d.ts +11 -31
- package/dist/Composables/useNestedDrawerForm.d.ts +7 -0
- package/dist/index.css +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +9951 -9770
- package/dist/index.js.map +1 -1
- package/docs/custom-fields.md +54 -2
- package/docs/drawer-protocol.md +27 -1
- package/docs/table-schema.md +5 -0
- package/package.json +2 -2
package/docs/custom-fields.md
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Blueprint forms resolve field components through a registry. Built-ins cover
|
|
4
4
|
the standard inputs (`text`, `textarea`, `select`, `multiselect`, `toggle`,
|
|
5
|
-
`checkbox`, `
|
|
6
|
-
`
|
|
5
|
+
`checkbox`, `range`, `date`, `datetime`, `time`, `date-range`, `file`, `color`,
|
|
6
|
+
`tags`, `belongs-to`, `repeater`, `toggle-buttons`, `set`, `embed`, `data`,
|
|
7
|
+
`hidden`). Anything app-specific is registered at boot:
|
|
7
8
|
|
|
8
9
|
```js
|
|
9
10
|
createPanel({
|
|
@@ -51,6 +52,57 @@ A field component receives (via `useBlueprint`'s `fieldProps`):
|
|
|
51
52
|
plus anything passed through the FieldDef's `props` object. Emit
|
|
52
53
|
`update:modelValue` with the new value.
|
|
53
54
|
|
|
55
|
+
### Render it inside `FieldPrimitive`
|
|
56
|
+
|
|
57
|
+
Do not hand-roll the label, the help text or the error message. `FieldPrimitive`
|
|
58
|
+
is the frame every built-in field renders inside — it owns the grid width, the
|
|
59
|
+
label, the description, the message, and the ARIA relationships between them —
|
|
60
|
+
and it hands the control what it needs through slot props:
|
|
61
|
+
|
|
62
|
+
```vue
|
|
63
|
+
<template>
|
|
64
|
+
<FieldPrimitive
|
|
65
|
+
v-bind="{ width, id, label, help, error, required }"
|
|
66
|
+
wrapper-class="ui-field-signature"
|
|
67
|
+
v-slot="{ describedBy, invalid }"
|
|
68
|
+
>
|
|
69
|
+
<canvas :id="id" :aria-describedby="describedBy" :aria-invalid="invalid" />
|
|
70
|
+
</FieldPrimitive>
|
|
71
|
+
</template>
|
|
72
|
+
|
|
73
|
+
<script setup lang="ts">
|
|
74
|
+
import { FieldPrimitive, fieldWidthProp } from '@modufolio/panel'
|
|
75
|
+
|
|
76
|
+
const props = defineProps({ ...fieldWidthProp, /* … */ })
|
|
77
|
+
</script>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
| Slot prop | Use |
|
|
81
|
+
|---|---|
|
|
82
|
+
| `describedBy` | `aria-describedby` — the help and error ids, or `undefined` |
|
|
83
|
+
| `invalid` | `aria-invalid` — `true` while there is an error, else `undefined` |
|
|
84
|
+
| `descriptionId` / `errorId` | The individual ids, when the control wires them itself |
|
|
85
|
+
|
|
86
|
+
Pass the same `id` to the frame and to the control: the help and error ids
|
|
87
|
+
derive from it, and that is what connects the three.
|
|
88
|
+
|
|
89
|
+
A field wrapping **several** controls passes `as="fieldset"`, which renders the
|
|
90
|
+
caption as a `<legend>` — `<label for>` may only point at one control, so a
|
|
91
|
+
group's label would otherwise label nothing.
|
|
92
|
+
|
|
93
|
+
A layout the stacked frame cannot express — a checkbox whose label sits beside
|
|
94
|
+
the box — composes the parts instead:
|
|
95
|
+
|
|
96
|
+
```vue
|
|
97
|
+
import { FieldLabel, FieldDescription, FieldMessage } from '@modufolio/panel'
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
That split is what the built-ins do, and it exists because twenty-two of them
|
|
101
|
+
used to render this scaffolding themselves: three different spacings for the
|
|
102
|
+
gap under a label, `role="alert"` on some error paragraphs and not others, and
|
|
103
|
+
`aria-describedby` missing from most of them, so their help text was visible to
|
|
104
|
+
sighted users only.
|
|
105
|
+
|
|
54
106
|
### Container fields
|
|
55
107
|
|
|
56
108
|
A field holding a list of rows (a repeater, a matrix) also receives:
|
package/docs/drawer-protocol.md
CHANGED
|
@@ -71,7 +71,7 @@ stack's shared overlay stands down when no item in the stack is a drawer.
|
|
|
71
71
|
**Frames are pointers, which is the point.** A row action can carry a dialog
|
|
72
72
|
URL (`RowAction::dialog()`) instead of naming a behaviour the table has to
|
|
73
73
|
implement, so a new interaction is a new route rather than a new case in the
|
|
74
|
-
client. See [table-schema.md](
|
|
74
|
+
client. See [table-schema.md](../../docs/table-schema.md#actions).
|
|
75
75
|
|
|
76
76
|
## Client components
|
|
77
77
|
|
|
@@ -88,6 +88,32 @@ client. See [table-schema.md](../../../docs/table-schema.md#actions).
|
|
|
88
88
|
given a `stack` prop, so the highlighted row follows record pagination;
|
|
89
89
|
reach for the composable directly only outside `SchemaTable`.
|
|
90
90
|
|
|
91
|
+
## Unsaved changes
|
|
92
|
+
|
|
93
|
+
Closing a frame with edits in it must ask first, and there are five ways to
|
|
94
|
+
close one: the X, the back arrow, the backdrop, Escape, and clicking a frame
|
|
95
|
+
further down the pile. Each used to decide for itself, so a form was protected
|
|
96
|
+
on some paths and not others.
|
|
97
|
+
|
|
98
|
+
They now all route through **one** discard dialog, raised whenever any frame
|
|
99
|
+
the action would remove reports unsaved changes. A form opts in by reporting
|
|
100
|
+
its own dirtiness:
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
import { useDrawerDirtyGuard } from '@modufolio/panel'
|
|
104
|
+
|
|
105
|
+
const isDirty = computed(() => form.isDirty)
|
|
106
|
+
useDrawerDirtyGuard(isDirty)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Nothing is guarded by default — a frame that never calls this closes without a
|
|
110
|
+
prompt, which is right for a read-only drawer. `NestedDrawerForm` is a real
|
|
111
|
+
`<form>` (so Enter submits), and its composable exposes `getChangedData()` for
|
|
112
|
+
sending only the delta on edit.
|
|
113
|
+
|
|
114
|
+
Background frames scale down as they recede, so a stack reads as depth rather
|
|
115
|
+
than as overlapping panels.
|
|
116
|
+
|
|
91
117
|
## Never hand-write the visit
|
|
92
118
|
|
|
93
119
|
The request side is three things at once — the header, `only: ['stack']`, and
|
package/docs/table-schema.md
CHANGED
|
@@ -319,6 +319,11 @@ operator from that field's type, and value(s). Each operator carries its
|
|
|
319
319
|
arity (`0`, `1` or `2`), so the UI knows how many inputs to draw. Conditions
|
|
320
320
|
are ANDed and sent as `constraints[]`.
|
|
321
321
|
|
|
322
|
+
The value input follows the constraint's `type`: a number spinner, a date
|
|
323
|
+
picker, a Yes/No select for a boolean (whose single `is` operator takes a
|
|
324
|
+
value, rather than the pair of valueless operators it used to have), and a text
|
|
325
|
+
box otherwise.
|
|
326
|
+
|
|
322
327
|
The server must treat both the field and the operator as allowlists — the
|
|
323
328
|
client is a convenience, not a guarantee.
|
|
324
329
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@modufolio/panel",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Schema-driven admin panel components for Inertia.js + Vue 3 — tables, blueprint forms, filters, actions, drawers, widgets.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"prepublishOnly": "npm run build",
|
|
31
31
|
"test": "vitest --run --config vitest.config.ts",
|
|
32
32
|
"type-check": "vue-tsc --noEmit -p tsconfig.json",
|
|
33
|
-
"lint": "eslint src"
|
|
33
|
+
"lint": "eslint src --max-warnings 0"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
36
|
"@heroicons/vue": "^2.0.0",
|