@modufolio/panel 0.1.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.
Files changed (194) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +165 -0
  3. package/dist/Builder/ImageNodeView.d.ts +33 -0
  4. package/dist/Builder/document.d.ts +17 -0
  5. package/dist/Builder/dragHandle.d.ts +13 -0
  6. package/dist/Builder/editing.d.ts +53 -0
  7. package/dist/Builder/plugins.d.ts +27 -0
  8. package/dist/Builder/schema.d.ts +20 -0
  9. package/dist/Components/Actions/Action.vue.d.ts +116 -0
  10. package/dist/Components/Actions/ActionGroup.vue.d.ts +25 -0
  11. package/dist/Components/Actions/ActionGroupItem.vue.d.ts +48 -0
  12. package/dist/Components/Auth/ForgotPassword.vue.d.ts +17 -0
  13. package/dist/Components/Auth/Login.vue.d.ts +33 -0
  14. package/dist/Components/Auth/ResetPassword.vue.d.ts +27 -0
  15. package/dist/Components/Auth/TwoFactor.vue.d.ts +32 -0
  16. package/dist/Components/Auth/TwoFactorVerify.vue.d.ts +31 -0
  17. package/dist/Components/Columns/BadgeColumn.vue.d.ts +34 -0
  18. package/dist/Components/Columns/BooleanColumn.vue.d.ts +78 -0
  19. package/dist/Components/Columns/CellActions.vue.d.ts +34 -0
  20. package/dist/Components/Columns/ColorColumn.vue.d.ts +84 -0
  21. package/dist/Components/Columns/CopyButton.vue.d.ts +15 -0
  22. package/dist/Components/Columns/DateColumn.vue.d.ts +60 -0
  23. package/dist/Components/Columns/IconColumn.vue.d.ts +56 -0
  24. package/dist/Components/Columns/ImageColumn.vue.d.ts +46 -0
  25. package/dist/Components/Columns/SelectColumn.vue.d.ts +71 -0
  26. package/dist/Components/Columns/TextColumn.vue.d.ts +69 -0
  27. package/dist/Components/Columns/TextInputColumn.vue.d.ts +75 -0
  28. package/dist/Components/Columns/ToggleColumn.vue.d.ts +91 -0
  29. package/dist/Components/Columns/TreeColumn.vue.d.ts +60 -0
  30. package/dist/Components/Columns/columnRegistry.d.ts +6 -0
  31. package/dist/Components/Composables/useInlineEdit.d.ts +27 -0
  32. package/dist/Components/Composables/useRelationship.d.ts +38 -0
  33. package/dist/Components/Core/Badge.vue.d.ts +47 -0
  34. package/dist/Components/Core/Button.vue.d.ts +131 -0
  35. package/dist/Components/Core/Dropdown.vue.d.ts +24 -0
  36. package/dist/Components/Core/Empty.vue.d.ts +54 -0
  37. package/dist/Components/Core/ErrorBoundary.vue.d.ts +24 -0
  38. package/dist/Components/Core/FlashMessages.vue.d.ts +7 -0
  39. package/dist/Components/Core/Icon.vue.d.ts +23 -0
  40. package/dist/Components/Core/Icons/DocumentLinesIcon.vue.d.ts +3 -0
  41. package/dist/Components/Core/Icons/SitemapIcon.vue.d.ts +3 -0
  42. package/dist/Components/Core/Label.vue.d.ts +52 -0
  43. package/dist/Components/Core/LoadingButton.vue.d.ts +18 -0
  44. package/dist/Components/Core/Modal.vue.d.ts +26 -0
  45. package/dist/Components/Core/Pagination.vue.d.ts +10 -0
  46. package/dist/Components/Core/SelectInput.vue.d.ts +26 -0
  47. package/dist/Components/Core/Tag.vue.d.ts +65 -0
  48. package/dist/Components/Core/TextInput.vue.d.ts +25 -0
  49. package/dist/Components/Core/iconRegistry.d.ts +3 -0
  50. package/dist/Components/Dialogs/ConfirmDialog.vue.d.ts +16 -0
  51. package/dist/Components/Dialogs/DeleteConfirmDialog.vue.d.ts +30 -0
  52. package/dist/Components/Dialogs/Dialog.vue.d.ts +81 -0
  53. package/dist/Components/Drawer/Drawer.vue.d.ts +130 -0
  54. package/dist/Components/Drawer/DrawerFieldGrid.vue.d.ts +39 -0
  55. package/dist/Components/Drawer/DrawerLink.vue.d.ts +96 -0
  56. package/dist/Components/Drawer/DrawerRelationList.vue.d.ts +81 -0
  57. package/dist/Components/Drawer/DrawerStack.vue.d.ts +93 -0
  58. package/dist/Components/Drawer/DrawerTabs.vue.d.ts +42 -0
  59. package/dist/Components/Drawer/NestedDrawerForm.vue.d.ts +55 -0
  60. package/dist/Components/Drawer/drawerFieldGrid.d.ts +25 -0
  61. package/dist/Components/Drawer/drawerTabs.d.ts +16 -0
  62. package/dist/Components/Drawer/useDrawerPage.d.ts +34 -0
  63. package/dist/Components/Drawer/useDrawerStack.d.ts +93 -0
  64. package/dist/Components/Drawer/useFocusedStackRow.d.ts +22 -0
  65. package/dist/Components/Drawer/useIsDrawer.d.ts +66 -0
  66. package/dist/Components/Drawer/visitDrawer.d.ts +48 -0
  67. package/dist/Components/Fields/BelongsToSelect.vue.d.ts +247 -0
  68. package/dist/Components/Fields/BlueprintForm.vue.d.ts +96 -0
  69. package/dist/Components/Fields/Calendar/CalendarPanel.vue.d.ts +63 -0
  70. package/dist/Components/Fields/Calendar/MonthGrid.vue.d.ts +82 -0
  71. package/dist/Components/Fields/CheckboxField.vue.d.ts +92 -0
  72. package/dist/Components/Fields/ColorPickerField.vue.d.ts +105 -0
  73. package/dist/Components/Fields/DatePickerField.vue.d.ts +102 -0
  74. package/dist/Components/Fields/DateRangePickerField.vue.d.ts +138 -0
  75. package/dist/Components/Fields/DateTimePickerField.vue.d.ts +134 -0
  76. package/dist/Components/Fields/FieldGrid.vue.d.ts +13 -0
  77. package/dist/Components/Fields/FileUploadField.vue.d.ts +117 -0
  78. package/dist/Components/Fields/MultiSelectField.vue.d.ts +129 -0
  79. package/dist/Components/Fields/ProseMirrorBuilderField.vue.d.ts +71 -0
  80. package/dist/Components/Fields/RangeField.vue.d.ts +122 -0
  81. package/dist/Components/Fields/RepeaterField.vue.d.ts +174 -0
  82. package/dist/Components/Fields/RichTextEditorField.vue.d.ts +118 -0
  83. package/dist/Components/Fields/SelectField.vue.d.ts +102 -0
  84. package/dist/Components/Fields/TagsField.vue.d.ts +102 -0
  85. package/dist/Components/Fields/TextField.vue.d.ts +138 -0
  86. package/dist/Components/Fields/TextareaField.vue.d.ts +111 -0
  87. package/dist/Components/Fields/TimePickerField.vue.d.ts +115 -0
  88. package/dist/Components/Fields/ToggleButtonsField.vue.d.ts +93 -0
  89. package/dist/Components/Fields/ToggleField.vue.d.ts +95 -0
  90. package/dist/Components/Fields/fieldRegistry.d.ts +25 -0
  91. package/dist/Components/Fields/fieldsFromSpec.d.ts +10 -0
  92. package/dist/Components/Fields/useBlueprint.d.ts +94 -0
  93. package/dist/Components/Fields/useFieldWidth.d.ts +10 -0
  94. package/dist/Components/Fields/validation.d.ts +43 -0
  95. package/dist/Components/Filters/DateRangeFilter.vue.d.ts +92 -0
  96. package/dist/Components/Filters/FacetedFilter.vue.d.ts +41 -0
  97. package/dist/Components/Filters/FilterIndicators.vue.d.ts +40 -0
  98. package/dist/Components/Filters/FilterPopover.vue.d.ts +38 -0
  99. package/dist/Components/Filters/MultiSelectFilter.vue.d.ts +51 -0
  100. package/dist/Components/Filters/NumberFilter.vue.d.ts +61 -0
  101. package/dist/Components/Filters/QueryBuilder.vue.d.ts +32 -0
  102. package/dist/Components/Filters/SelectFilter.vue.d.ts +61 -0
  103. package/dist/Components/Filters/TernaryFilter.vue.d.ts +73 -0
  104. package/dist/Components/Layout/AppLayout.vue.d.ts +137 -0
  105. package/dist/Components/Layout/Breadcrumbs.vue.d.ts +44 -0
  106. package/dist/Components/Layout/Cluster.vue.d.ts +88 -0
  107. package/dist/Components/Layout/Container.vue.d.ts +69 -0
  108. package/dist/Components/Layout/Grid.vue.d.ts +110 -0
  109. package/dist/Components/Layout/PageHeader.vue.d.ts +62 -0
  110. package/dist/Components/Layout/Sidebar.vue.d.ts +59 -0
  111. package/dist/Components/Layout/Stack.vue.d.ts +69 -0
  112. package/dist/Components/Layout/TopNavigation.vue.d.ts +124 -0
  113. package/dist/Components/Media/MediaPickerDialog.vue.d.ts +20 -0
  114. package/dist/Components/Media/mediaEndpoints.d.ts +18 -0
  115. package/dist/Components/Notifications/Toast.vue.d.ts +17 -0
  116. package/dist/Components/Notifications/useToast.d.ts +43 -0
  117. package/dist/Components/Relations/RelationManager.vue.d.ts +232 -0
  118. package/dist/Components/Sections/FieldsSection.vue.d.ts +56 -0
  119. package/dist/Components/Sections/FilesSection.vue.d.ts +120 -0
  120. package/dist/Components/Sections/FormSection.vue.d.ts +111 -0
  121. package/dist/Components/Sections/InfoSection.vue.d.ts +77 -0
  122. package/dist/Components/Sections/Section.vue.d.ts +67 -0
  123. package/dist/Components/Table/ColumnToggle.vue.d.ts +42 -0
  124. package/dist/Components/Table/ExportButton.vue.d.ts +93 -0
  125. package/dist/Components/Table/SchemaCell.d.ts +50 -0
  126. package/dist/Components/Table/SchemaFilterPanel.vue.d.ts +64 -0
  127. package/dist/Components/Table/SchemaTable.vue.d.ts +255 -0
  128. package/dist/Components/Table/Table.vue.d.ts +232 -0
  129. package/dist/Components/Table/TableEmptyState.vue.d.ts +24 -0
  130. package/dist/Components/Table/TablePagination.vue.d.ts +71 -0
  131. package/dist/Components/Table/TableSkeletonRows.vue.d.ts +52 -0
  132. package/dist/Components/Table/TableSortButton.vue.d.ts +38 -0
  133. package/dist/Components/Table/TableToolbar.vue.d.ts +62 -0
  134. package/dist/Components/Table/schemaLinks.d.ts +16 -0
  135. package/dist/Components/Table/tableSchema.d.ts +243 -0
  136. package/dist/Components/Table/tableTypes.d.ts +13 -0
  137. package/dist/Components/Table/useSchemaActions.d.ts +82 -0
  138. package/dist/Components/Table/useSchemaFilters.d.ts +28 -0
  139. package/dist/Components/Table/useTableExport.d.ts +16 -0
  140. package/dist/Components/Table/useTableGrouping.d.ts +9 -0
  141. package/dist/Components/Table/useTableRowFocus.d.ts +27 -0
  142. package/dist/Components/Table/useTableSelection.d.ts +15 -0
  143. package/dist/Components/Table/useTableTree.d.ts +23 -0
  144. package/dist/Components/Widgets/StatCard.vue.d.ts +81 -0
  145. package/dist/Components/Widgets/StatsWidget.vue.d.ts +27 -0
  146. package/dist/Components/Wizard/Wizard.vue.d.ts +99 -0
  147. package/dist/Composables/useAsyncData.d.ts +48 -0
  148. package/dist/Composables/useDeleteConfirmation.d.ts +86 -0
  149. package/dist/Composables/useDragReorder.d.ts +12 -0
  150. package/dist/Composables/useFieldSaver.d.ts +15 -0
  151. package/dist/Composables/useFocusTrap.d.ts +5 -0
  152. package/dist/Composables/useLocalStoragePersistence.d.ts +18 -0
  153. package/dist/Composables/useNestedDrawerForm.d.ts +58 -0
  154. package/dist/Composables/usePagination.d.ts +23 -0
  155. package/dist/Composables/usePendingKeys.d.ts +30 -0
  156. package/dist/Composables/useQuery.d.ts +61 -0
  157. package/dist/Composables/useReconciled.d.ts +22 -0
  158. package/dist/Composables/useUnsavedChangesWarning.d.ts +16 -0
  159. package/dist/Primitives/hideOthers.d.ts +12 -0
  160. package/dist/Primitives/teleportTarget.d.ts +2 -0
  161. package/dist/Primitives/useAnchoredPosition.d.ts +32 -0
  162. package/dist/Primitives/useArrowNavigation.d.ts +30 -0
  163. package/dist/Primitives/useBodyScrollLock.d.ts +9 -0
  164. package/dist/Primitives/useDismissableLayer.d.ts +46 -0
  165. package/dist/Primitives/useId.d.ts +13 -0
  166. package/dist/Primitives/useTypeahead.d.ts +11 -0
  167. package/dist/Utils/apiFetch.d.ts +28 -0
  168. package/dist/Utils/csrf.d.ts +2 -0
  169. package/dist/Utils/dates.d.ts +50 -0
  170. package/dist/Utils/moduleSingleton.d.ts +21 -0
  171. package/dist/Utils/optimistic.d.ts +33 -0
  172. package/dist/Utils/reconcile.d.ts +17 -0
  173. package/dist/Utils/tagsChanged.d.ts +16 -0
  174. package/dist/Utils/url.d.ts +40 -0
  175. package/dist/Utils/writeGate.d.ts +82 -0
  176. package/dist/index.css +1 -0
  177. package/dist/index.d.ts +157 -0
  178. package/dist/index.js +27193 -0
  179. package/dist/index.js.map +1 -0
  180. package/dist/injectionKeys.d.ts +10 -0
  181. package/dist/plugin.d.ts +36 -0
  182. package/dist/types/menu.d.ts +11 -0
  183. package/docs/async-writes.md +159 -0
  184. package/docs/custom-fields.md +71 -0
  185. package/docs/drawer-protocol.md +130 -0
  186. package/docs/overlays.md +106 -0
  187. package/docs/relation-fields.md +112 -0
  188. package/docs/roadmap.md +38 -0
  189. package/docs/table-schema.md +371 -0
  190. package/package.json +150 -0
  191. package/styles/buttons.css +31 -0
  192. package/styles/form.css +74 -0
  193. package/styles/index.css +15 -0
  194. package/styles/tokens.css +79 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Maarten Thiebou
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,165 @@
1
+ # @modufolio/panel
2
+
3
+ Schema-driven admin panel components for Inertia.js + Vue 3 — tables,
4
+ blueprint forms, filters, actions, drawers, widgets. Tables can be driven
5
+ entirely by a server-authored schema. The frontend companion
6
+ to [modufolio/appkit](https://github.com/modufolio/appkit), usable with any
7
+ Inertia-speaking backend.
8
+
9
+ > **Status: 0.x pre-release.** APIs may move between minors; the barrel
10
+ > export list (`src/index.ts`) is the public API surface.
11
+
12
+ ## Install
13
+
14
+ ```bash
15
+ npm install @modufolio/panel
16
+ ```
17
+
18
+ Peer dependencies: `vue ^3.5`, `@inertiajs/vue3 ^3`, `@heroicons/vue ^2`,
19
+ and (optional) `@vueuse/core`, `vuedraggable`, `lodash`.
20
+
21
+ ## Setup
22
+
23
+ One plugin call configures everything:
24
+
25
+ ```js
26
+ import { createPanel } from '@modufolio/panel'
27
+
28
+ createApp({ render: () => h(App, props) })
29
+ .use(createPanel({
30
+ baseUrl: '/panel', // your backend mount path
31
+ icons: { camera: CameraIcon }, // extend/override <Icon> names
32
+ fields: { // app-specific blueprint fields
33
+ 'block-editor': () => import('./Fields/BlockEditorField.vue'),
34
+ },
35
+ }))
36
+ .mount(el)
37
+ ```
38
+
39
+ Every URL the panel builds goes through `panelUrl()` with that `baseUrl` —
40
+ nothing in the package hardcodes a mount path (CI-enforced).
41
+
42
+ ## Styles (Tailwind CSS 4)
43
+
44
+ The package ships source `.vue` files and source CSS — your Tailwind build
45
+ compiles both. In your CSS entry:
46
+
47
+ ```css
48
+ @import 'tailwindcss';
49
+ @import '@modufolio/panel/styles' layer(components);
50
+ @source "../node_modules/@modufolio/panel";
51
+ ```
52
+
53
+ Theming: components use the semantic `--color-primary-*` / `success` /
54
+ `danger` / `warning` / `info` scales. Import
55
+ `@modufolio/panel/styles/tokens.css` for the defaults, then override any
56
+ value in your own `@theme` block to re-brand.
57
+
58
+ ## Quick example
59
+
60
+ ```vue
61
+ <script setup>
62
+ import { Table, BlueprintForm, Drawer, useResource, defineColumn, panelUrl } from '@modufolio/panel'
63
+
64
+ const resource = useResource({
65
+ endpoint: panelUrl('/api/users'),
66
+ columns: [
67
+ defineColumn({ name: 'name', label: 'Name', sortable: true }),
68
+ defineColumn({ name: 'email', label: 'Email' }),
69
+ ],
70
+ })
71
+
72
+ const fields = [
73
+ { type: 'text', key: 'name', label: 'Name', required: true, width: '1/2' },
74
+ { type: 'text', key: 'email', label: 'Email', width: '1/2' },
75
+ { type: 'toggle', key: 'active', label: 'Active', when: f => !!f.email },
76
+ ]
77
+ </script>
78
+
79
+ <template>
80
+ <Table :columns="resource.columns" :records="resource.records" />
81
+ <BlueprintForm v-model="form" :fields="fields" label="Profile" />
82
+ </template>
83
+ ```
84
+
85
+ ## Server-driven tables
86
+
87
+ `SchemaTable` renders columns, filters, groups, summaries and a query builder
88
+ from a description the backend sends as a prop — no `columns` array in the
89
+ page:
90
+
91
+ ```vue
92
+ <SchemaTable
93
+ :schema="table"
94
+ :records="organizations.data"
95
+ :summaries="organizations.meta?.summaries ?? {}"
96
+ :filter-values="form"
97
+ @update:filter="setFilter"
98
+ />
99
+ ```
100
+
101
+ It wraps `Table`, so pages using `Table` directly are unaffected, and any
102
+ `#cell-{key}` or `#filters` slot you pass overrides the generated one.
103
+ See [docs/table-schema.md](docs/table-schema.md).
104
+
105
+ ## Async writes
106
+
107
+ Overlapping writes are normal in an admin panel — a toggle in a row, a
108
+ debounced field, an optimistic star — and the failure modes are quiet. The
109
+ package ships the ordering primitives rather than leaving each page to
110
+ re-invent them:
111
+
112
+ ```js
113
+ import { optimistic, writeKey, usePendingKeys } from '@modufolio/panel'
114
+
115
+ const { isPending, run } = usePendingKeys() // which row is busy
116
+
117
+ const toggle = (row) => run(row.id, () => optimistic(
118
+ () => { const was = row.active; row.active = !was; return () => { row.active = was } },
119
+ () => apiFetch(url, { method: 'PATCH', body: { active: row.active } }),
120
+ writeKey('rows', row.id, 'active'), // orders overlapping writes
121
+ ))
122
+ ```
123
+
124
+ Also here: `useFieldSaver` (debounced saves with ordered status),
125
+ `useUnsavedChangesWarning` (prompt before a navigation discards edits,
126
+ logout included), `writeGate` (the ordering itself) and `moduleSingleton`
127
+ (state that survives a duplicated module copy).
128
+ See [docs/async-writes.md](docs/async-writes.md).
129
+
130
+ ## Extension seams
131
+
132
+ - `registerFieldType(type, loader)` — add custom blueprint field types
133
+ (rich-text editors, media pickers, ...) without forking the package.
134
+ See [docs/custom-fields.md](docs/custom-fields.md).
135
+ - `registerIcons(map)` — add or override icon names used by `<Icon>`.
136
+ - `setPanelBaseUrl('/admin')` / `panelUrl(path)` — mount-path handling.
137
+
138
+ ## Server contract
139
+
140
+ Works with any Inertia backend. A few small server-side conventions:
141
+
142
+ - **Overlays** — layer stack, scroll lock, positioning, keyboard:
143
+ [docs/overlays.md](docs/overlays.md)
144
+ - **Drawers** — [docs/drawer-protocol.md](docs/drawer-protocol.md)
145
+ - **Table schema** — [docs/table-schema.md](docs/table-schema.md)
146
+ - **Relation fields** — lookup search/create endpoints, repeater rows and
147
+ row-addressed errors: [docs/relation-fields.md](docs/relation-fields.md)
148
+
149
+ The reference implementation is appkit + appkit-portfolio.
150
+
151
+ ## Tests
152
+
153
+ ```bash
154
+ npm test # inside packages/panel
155
+ ```
156
+
157
+ Specs live in `tests/`, one file per module or component, run by the
158
+ package's own `vitest.config.ts` against `happy-dom`. Component specs mount
159
+ with `@vue/test-utils`; field components resolve asynchronously through the
160
+ registry, so wait for rendered output (`vi.waitFor`) rather than a fixed
161
+ number of ticks.
162
+
163
+ ## License
164
+
165
+ MIT
@@ -0,0 +1,33 @@
1
+ import { EditorView, NodeView } from 'prosemirror-view';
2
+ import { Node as PMNode } from 'prosemirror-model';
3
+ export interface ImageNodeViewOptions {
4
+ /** Opens the media library; resolves with the chosen image, or null. */
5
+ pickImage: () => Promise<{
6
+ id: string;
7
+ url: string;
8
+ thumbnail_url: string;
9
+ alt_text?: string;
10
+ caption?: string;
11
+ } | null>;
12
+ /** Opens the media detail view for an image, as double-click does in the library. */
13
+ openMedia?: (id: string) => void;
14
+ }
15
+ export declare class ImageNodeView implements NodeView {
16
+ private node;
17
+ private view;
18
+ private getPos;
19
+ private options;
20
+ dom: HTMLElement;
21
+ private img;
22
+ private captionEl;
23
+ private placeholder;
24
+ constructor(node: PMNode, view: EditorView, getPos: () => number | undefined, options: ImageNodeViewOptions);
25
+ private buildToolbar;
26
+ private pick;
27
+ private setAttrs;
28
+ private render;
29
+ update(node: PMNode): boolean;
30
+ /** The node has no editable content, so ignore mutations inside it. */
31
+ ignoreMutation(): boolean;
32
+ stopEvent(event: Event): boolean;
33
+ }
@@ -0,0 +1,17 @@
1
+ import { Node as PMNode } from 'prosemirror-model';
2
+ export type ParseStatus = 'ok' | 'empty' | 'unreadable';
3
+ export interface ParseResult {
4
+ doc: PMNode;
5
+ status: ParseStatus;
6
+ /** Set when status is 'unreadable': why, for the field to show. */
7
+ reason?: string;
8
+ }
9
+ export declare function emptyDoc(): PMNode;
10
+ /**
11
+ * Read a stored field value.
12
+ *
13
+ * Never throws. A document that cannot be parsed comes back as `unreadable`
14
+ * with an empty document alongside, so the caller can refuse to overwrite it.
15
+ */
16
+ export declare function parseStoredValue(value: string): ParseResult;
17
+ export declare function serializeDoc(doc: PMNode): string;
@@ -0,0 +1,13 @@
1
+ import { Plugin } from 'prosemirror-state';
2
+ import { EditorView } from 'prosemirror-view';
3
+ /**
4
+ * Begin dragging the top-level block at `pos`.
5
+ *
6
+ * Exported so it can be tested without a layout engine: everything above it is
7
+ * hover geometry, and everything below it is ProseMirror's.
8
+ *
9
+ * Returns false when the position does not hold a draggable block, leaving the
10
+ * event alone rather than starting a drag that cannot finish.
11
+ */
12
+ export declare function startBlockDrag(view: EditorView, pos: number, event: DragEvent): boolean;
13
+ export declare function blockDragHandle(): Plugin;
@@ -0,0 +1,53 @@
1
+ import { Command, EditorState } from 'prosemirror-state';
2
+ import { MarkType, NodeType } from 'prosemirror-model';
3
+ /** Whether `type` applies anywhere in the current selection. */
4
+ export declare function isMarkActive(state: EditorState, type: MarkType): boolean;
5
+ /** Whether the selection sits inside a `type` block with these attrs. */
6
+ export declare function isBlockActive(state: EditorState, type: NodeType, attrs?: Record<string, unknown>): boolean;
7
+ /** Whether the selection is inside a list of this type. */
8
+ export declare function isInList(state: EditorState, type: NodeType): boolean;
9
+ /** The href on the link mark under the cursor, or '' if there is none. */
10
+ export declare function activeLinkHref(state: EditorState): string;
11
+ export declare const commands: {
12
+ toggleStrong: Command;
13
+ toggleEm: Command;
14
+ toggleCode: Command;
15
+ setParagraph: Command;
16
+ setHeading: (level: number) => Command;
17
+ setCodeBlock: Command;
18
+ toggleBulletList: Command;
19
+ toggleOrderedList: Command;
20
+ wrapBlockquote: Command;
21
+ lift: Command;
22
+ undo: Command;
23
+ redo: Command;
24
+ /**
25
+ * Apply or replace the link mark over the selection.
26
+ *
27
+ * `href` is not validated here — `schema.marks.link` does it in `toDOM`, and
28
+ * the field validates before calling. Passing '' removes the mark.
29
+ */
30
+ setLink: (href: string) => Command;
31
+ /**
32
+ * Replace the current (empty) textblock with a node of `type`.
33
+ * Used by the slash menu, where the user has typed `/` into a fresh block.
34
+ */
35
+ replaceBlockWith: (type: NodeType, attrs?: Record<string, unknown>) => Command;
36
+ };
37
+ /**
38
+ * Markdown-ish shortcuts. These are *not* a Markdown parser — each rule fires
39
+ * on a literal prefix as it is typed and produces a schema node directly, so
40
+ * there is no intermediate HTML and nothing to keep in sync with the server.
41
+ */
42
+ export declare function builderInputRules(): import('prosemirror-state').Plugin<{
43
+ transform: import('prosemirror-state').Transaction;
44
+ from: number;
45
+ to: number;
46
+ text: string;
47
+ } | null>;
48
+ /**
49
+ * `onLink` is called for the link shortcut; the field opens its own input
50
+ * rather than a `window.prompt`, so the keymap only signals intent.
51
+ */
52
+ export declare function builderKeymap(onLink: () => void): import('prosemirror-state').Plugin<any>[];
53
+ export declare function builderHistory(): import('prosemirror-state').Plugin<any>;
@@ -0,0 +1,27 @@
1
+ import { Plugin, PluginKey, EditorState } from 'prosemirror-state';
2
+ /**
3
+ * Show `text` on the first block while the document is empty.
4
+ *
5
+ * Implemented as a widget-free node decoration carrying a CSS class, so the
6
+ * prompt lives in a `::before` and can never be mistaken for content.
7
+ */
8
+ export declare function placeholder(text: string): Plugin;
9
+ export declare const slashMenuKey: PluginKey<SlashMenuState>;
10
+ export interface SlashMenuState {
11
+ /** Position of the `/` in the document, or null when the menu is closed. */
12
+ from: number | null;
13
+ /** What the user has typed after the `/`, for filtering. */
14
+ query: string;
15
+ }
16
+ /**
17
+ * Track a `/` typed at the start of an empty paragraph, plus whatever is typed
18
+ * after it, so the field can render a filtered block menu.
19
+ *
20
+ * State only — the menu component decides what to show and dispatches the
21
+ * command. Closing is driven by the text no longer matching, so Escape and any
22
+ * edit elsewhere both dismiss it without extra bookkeeping.
23
+ */
24
+ export declare function slashMenu(): Plugin<SlashMenuState>;
25
+ export declare function getSlashMenuState(state: EditorState): SlashMenuState;
26
+ /** Close the menu and remove the `/query` text the user typed. */
27
+ export declare function closeSlashMenu(state: EditorState, clearText: boolean): import('prosemirror-state').Transaction;
@@ -0,0 +1,20 @@
1
+ import { Schema } from 'prosemirror-model';
2
+ export declare const HEADING_LEVELS: readonly [2, 3, 4, 5, 6];
3
+ export declare const IMAGE_WIDTHS: readonly ["default", "wide", "full"];
4
+ export declare const CODE_LANGUAGES: readonly ["plain", "bash", "css", "html", "json", "js", "ts", "php", "python", "sql", "vue", "yaml", "markdown"];
5
+ export type HeadingLevel = (typeof HEADING_LEVELS)[number];
6
+ export type ImageWidth = (typeof IMAGE_WIDTHS)[number];
7
+ export type CodeLanguage = (typeof CODE_LANGUAGES)[number];
8
+ /**
9
+ * An href we are willing to render, or null.
10
+ *
11
+ * Applied on the way in (`parseDOM`, so a pasted link cannot smuggle a scheme
12
+ * into the document) and again on the way out (`toDOM`, so a document that
13
+ * reached us some other way still cannot render one). ProseMirror does not
14
+ * validate URLs — this is the one classic XSS vector the document model does
15
+ * not close on its own, and it has produced High-severity advisories in other
16
+ * ProseMirror-based CMSs (see docs/prosemirror-builder.md §3.3).
17
+ */
18
+ export declare function safeHref(value: unknown): string | null;
19
+ export declare const schema: Schema<"text" | "blockquote" | "image" | "heading" | "doc" | "paragraph" | "code_block" | "bullet_list" | "ordered_list" | "list_item" | "hard_break", "code" | "em" | "link" | "strong">;
20
+ export type BuilderSchema = typeof schema;
@@ -0,0 +1,116 @@
1
+ import { PropType } from 'vue';
2
+ declare var __VLS_13: {}, __VLS_15: {}, __VLS_29: {};
3
+ type __VLS_Slots = {} & {
4
+ 'icon-before'?: (props: typeof __VLS_13) => any;
5
+ } & {
6
+ default?: (props: typeof __VLS_15) => any;
7
+ } & {
8
+ 'icon-after'?: (props: typeof __VLS_29) => any;
9
+ };
10
+ declare const __VLS_base: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
11
+ label: {
12
+ type: StringConstructor;
13
+ default: string;
14
+ };
15
+ ariaLabel: {
16
+ type: StringConstructor;
17
+ default: string;
18
+ };
19
+ icon: {
20
+ type: (StringConstructor | ObjectConstructor | FunctionConstructor)[];
21
+ default: null;
22
+ };
23
+ iconPosition: {
24
+ type: StringConstructor;
25
+ default: string;
26
+ validator: (value: unknown) => boolean;
27
+ };
28
+ color: {
29
+ type: StringConstructor;
30
+ default: string;
31
+ validator: (value: unknown) => boolean;
32
+ };
33
+ variant: {
34
+ type: StringConstructor;
35
+ default: string;
36
+ validator: (value: unknown) => boolean;
37
+ };
38
+ size: {
39
+ type: StringConstructor;
40
+ default: string;
41
+ validator: (value: unknown) => boolean;
42
+ };
43
+ disabled: {
44
+ type: BooleanConstructor;
45
+ default: boolean;
46
+ };
47
+ type: {
48
+ type: PropType<"button" | "submit" | "reset">;
49
+ default: string;
50
+ validator: (value: unknown) => boolean;
51
+ };
52
+ }>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
53
+ click: (...args: any[]) => void;
54
+ }, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
55
+ label: {
56
+ type: StringConstructor;
57
+ default: string;
58
+ };
59
+ ariaLabel: {
60
+ type: StringConstructor;
61
+ default: string;
62
+ };
63
+ icon: {
64
+ type: (StringConstructor | ObjectConstructor | FunctionConstructor)[];
65
+ default: null;
66
+ };
67
+ iconPosition: {
68
+ type: StringConstructor;
69
+ default: string;
70
+ validator: (value: unknown) => boolean;
71
+ };
72
+ color: {
73
+ type: StringConstructor;
74
+ default: string;
75
+ validator: (value: unknown) => boolean;
76
+ };
77
+ variant: {
78
+ type: StringConstructor;
79
+ default: string;
80
+ validator: (value: unknown) => boolean;
81
+ };
82
+ size: {
83
+ type: StringConstructor;
84
+ default: string;
85
+ validator: (value: unknown) => boolean;
86
+ };
87
+ disabled: {
88
+ type: BooleanConstructor;
89
+ default: boolean;
90
+ };
91
+ type: {
92
+ type: PropType<"button" | "submit" | "reset">;
93
+ default: string;
94
+ validator: (value: unknown) => boolean;
95
+ };
96
+ }>> & Readonly<{
97
+ onClick?: ((...args: any[]) => any) | undefined;
98
+ }>, {
99
+ size: string;
100
+ label: string;
101
+ type: "button" | "reset" | "submit";
102
+ disabled: boolean;
103
+ color: string;
104
+ icon: string | Function | Record<string, any>;
105
+ iconPosition: string;
106
+ variant: string;
107
+ ariaLabel: string;
108
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
109
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
110
+ declare const _default: typeof __VLS_export;
111
+ export default _default;
112
+ type __VLS_WithSlots<T, S> = T & {
113
+ new (): {
114
+ $slots: S;
115
+ };
116
+ };
@@ -0,0 +1,25 @@
1
+ declare var __VLS_13: {};
2
+ type __VLS_Slots = {} & {
3
+ default?: (props: typeof __VLS_13) => any;
4
+ };
5
+ declare const __VLS_base: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
6
+ label: {
7
+ type: StringConstructor;
8
+ default: string;
9
+ };
10
+ }>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
11
+ label: {
12
+ type: StringConstructor;
13
+ default: string;
14
+ };
15
+ }>> & Readonly<{}>, {
16
+ label: string;
17
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
18
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
19
+ declare const _default: typeof __VLS_export;
20
+ export default _default;
21
+ type __VLS_WithSlots<T, S> = T & {
22
+ new (): {
23
+ $slots: S;
24
+ };
25
+ };
@@ -0,0 +1,48 @@
1
+ declare var __VLS_11: {};
2
+ type __VLS_Slots = {} & {
3
+ default?: (props: typeof __VLS_11) => any;
4
+ };
5
+ declare const __VLS_base: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
6
+ label: {
7
+ type: StringConstructor;
8
+ required: true;
9
+ };
10
+ icon: {
11
+ type: (StringConstructor | ObjectConstructor)[];
12
+ default: null;
13
+ };
14
+ color: {
15
+ type: StringConstructor;
16
+ default: string;
17
+ validator: (value: string) => boolean;
18
+ };
19
+ }>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
20
+ click: (...args: any[]) => void;
21
+ }, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
22
+ label: {
23
+ type: StringConstructor;
24
+ required: true;
25
+ };
26
+ icon: {
27
+ type: (StringConstructor | ObjectConstructor)[];
28
+ default: null;
29
+ };
30
+ color: {
31
+ type: StringConstructor;
32
+ default: string;
33
+ validator: (value: string) => boolean;
34
+ };
35
+ }>> & Readonly<{
36
+ onClick?: ((...args: any[]) => any) | undefined;
37
+ }>, {
38
+ color: string;
39
+ icon: string | Record<string, any>;
40
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
41
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
42
+ declare const _default: typeof __VLS_export;
43
+ export default _default;
44
+ type __VLS_WithSlots<T, S> = T & {
45
+ new (): {
46
+ $slots: S;
47
+ };
48
+ };
@@ -0,0 +1,17 @@
1
+ declare var __VLS_6: {};
2
+ type __VLS_Slots = {} & {
3
+ logo?: (props: typeof __VLS_6) => any;
4
+ };
5
+ declare const __VLS_base: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
6
+ csrf_token: StringConstructor;
7
+ }>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
8
+ csrf_token: StringConstructor;
9
+ }>> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
10
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
11
+ declare const _default: typeof __VLS_export;
12
+ export default _default;
13
+ type __VLS_WithSlots<T, S> = T & {
14
+ new (): {
15
+ $slots: S;
16
+ };
17
+ };
@@ -0,0 +1,33 @@
1
+ declare var __VLS_6: {};
2
+ type __VLS_Slots = {} & {
3
+ logo?: (props: typeof __VLS_6) => any;
4
+ };
5
+ declare const __VLS_base: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
6
+ csrf_token: {
7
+ type: StringConstructor;
8
+ required: true;
9
+ };
10
+ google_enabled: {
11
+ type: BooleanConstructor;
12
+ default: boolean;
13
+ };
14
+ }>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
15
+ csrf_token: {
16
+ type: StringConstructor;
17
+ required: true;
18
+ };
19
+ google_enabled: {
20
+ type: BooleanConstructor;
21
+ default: boolean;
22
+ };
23
+ }>> & Readonly<{}>, {
24
+ google_enabled: boolean;
25
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
26
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
27
+ declare const _default: typeof __VLS_export;
28
+ export default _default;
29
+ type __VLS_WithSlots<T, S> = T & {
30
+ new (): {
31
+ $slots: S;
32
+ };
33
+ };
@@ -0,0 +1,27 @@
1
+ declare var __VLS_6: {};
2
+ type __VLS_Slots = {} & {
3
+ logo?: (props: typeof __VLS_6) => any;
4
+ };
5
+ declare const __VLS_base: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
6
+ valid: BooleanConstructor;
7
+ token: StringConstructor;
8
+ email: StringConstructor;
9
+ csrf_token: StringConstructor;
10
+ errors: ObjectConstructor;
11
+ }>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
12
+ valid: BooleanConstructor;
13
+ token: StringConstructor;
14
+ email: StringConstructor;
15
+ csrf_token: StringConstructor;
16
+ errors: ObjectConstructor;
17
+ }>> & Readonly<{}>, {
18
+ valid: boolean;
19
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
20
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
21
+ declare const _default: typeof __VLS_export;
22
+ export default _default;
23
+ type __VLS_WithSlots<T, S> = T & {
24
+ new (): {
25
+ $slots: S;
26
+ };
27
+ };
@@ -0,0 +1,32 @@
1
+ declare const __VLS_export: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
2
+ enabled: {
3
+ type: BooleanConstructor;
4
+ required: true;
5
+ };
6
+ confirmed: {
7
+ type: BooleanConstructor;
8
+ default: boolean;
9
+ };
10
+ enabled_at: {
11
+ type: StringConstructor;
12
+ default: null;
13
+ };
14
+ }>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
15
+ enabled: {
16
+ type: BooleanConstructor;
17
+ required: true;
18
+ };
19
+ confirmed: {
20
+ type: BooleanConstructor;
21
+ default: boolean;
22
+ };
23
+ enabled_at: {
24
+ type: StringConstructor;
25
+ default: null;
26
+ };
27
+ }>> & Readonly<{}>, {
28
+ confirmed: boolean;
29
+ enabled_at: string;
30
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
31
+ declare const _default: typeof __VLS_export;
32
+ export default _default;