@vertebr/react 0.9.0 → 0.11.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 (89) hide show
  1. package/dist/components/admin/AddonEditor.d.ts +3 -2
  2. package/dist/components/admin/AddonEditor.d.ts.map +1 -1
  3. package/dist/components/admin/AddonEditor.js +14 -10
  4. package/dist/components/admin/AdminContent.d.ts +4 -1
  5. package/dist/components/admin/AdminContent.d.ts.map +1 -1
  6. package/dist/components/admin/AdminContent.js +74 -12
  7. package/dist/components/admin/AdminSaveBar.d.ts.map +1 -1
  8. package/dist/components/admin/AdminSaveBar.js +6 -1
  9. package/dist/components/admin/AdminSyncPage.d.ts.map +1 -1
  10. package/dist/components/admin/AdminSyncPage.js +50 -6
  11. package/dist/components/admin/AdminTopBar.d.ts +6 -2
  12. package/dist/components/admin/AdminTopBar.d.ts.map +1 -1
  13. package/dist/components/admin/AdminTopBar.js +27 -4
  14. package/dist/components/admin/AuditBoard.d.ts +7 -0
  15. package/dist/components/admin/AuditBoard.d.ts.map +1 -0
  16. package/dist/components/admin/AuditBoard.js +43 -0
  17. package/dist/components/admin/HealthModal.d.ts +9 -0
  18. package/dist/components/admin/HealthModal.d.ts.map +1 -0
  19. package/dist/components/admin/HealthModal.js +59 -0
  20. package/dist/components/admin/PagePreviewPane.d.ts +3 -1
  21. package/dist/components/admin/PagePreviewPane.d.ts.map +1 -1
  22. package/dist/components/admin/PagePreviewPane.js +41 -9
  23. package/dist/components/admin/SyncPreviewFrame.d.ts +22 -0
  24. package/dist/components/admin/SyncPreviewFrame.d.ts.map +1 -0
  25. package/dist/components/admin/SyncPreviewFrame.js +135 -0
  26. package/dist/components/admin/VertebrAdmin.d.ts.map +1 -1
  27. package/dist/components/admin/VertebrAdmin.js +88 -22
  28. package/dist/components/admin/adminSearch.d.ts.map +1 -1
  29. package/dist/components/admin/adminSearch.js +9 -0
  30. package/dist/components/admin/breadcrumbs.d.ts.map +1 -1
  31. package/dist/components/admin/breadcrumbs.js +2 -0
  32. package/dist/components/admin/routes.d.ts.map +1 -1
  33. package/dist/components/admin/routes.js +13 -1
  34. package/dist/components/admin/types.d.ts +2 -0
  35. package/dist/components/admin/types.d.ts.map +1 -1
  36. package/dist/components/config/DatetimeInput.d.ts +15 -0
  37. package/dist/components/config/DatetimeInput.d.ts.map +1 -0
  38. package/dist/components/config/DatetimeInput.js +287 -0
  39. package/dist/components/config/EnumInput.d.ts.map +1 -1
  40. package/dist/components/config/EnumInput.js +4 -4
  41. package/dist/components/config/EnumListInput.d.ts.map +1 -1
  42. package/dist/components/config/EnumListInput.js +13 -3
  43. package/dist/components/config/ReferenceInput.d.ts +11 -0
  44. package/dist/components/config/ReferenceInput.d.ts.map +1 -0
  45. package/dist/components/config/ReferenceInput.js +99 -0
  46. package/dist/components/config/RevisionHistory.d.ts +12 -0
  47. package/dist/components/config/RevisionHistory.d.ts.map +1 -0
  48. package/dist/components/config/RevisionHistory.js +139 -0
  49. package/dist/components/config/form/ConfigField.d.ts +3 -2
  50. package/dist/components/config/form/ConfigField.d.ts.map +1 -1
  51. package/dist/components/config/form/ConfigField.js +4 -2
  52. package/dist/components/config/form/ConfigForm.d.ts +1 -1
  53. package/dist/components/config/form/ConfigForm.d.ts.map +1 -1
  54. package/dist/components/config/form/ConfigForm.js +66 -14
  55. package/dist/components/config/form/RecordConfigForm.d.ts +3 -2
  56. package/dist/components/config/form/RecordConfigForm.d.ts.map +1 -1
  57. package/dist/components/config/form/RecordConfigForm.js +2 -1
  58. package/dist/components/config/form/SettingsConfigForm.d.ts +3 -2
  59. package/dist/components/config/form/SettingsConfigForm.d.ts.map +1 -1
  60. package/dist/components/config/form/SettingsConfigForm.js +2 -2
  61. package/dist/components/config/form/types.d.ts +14 -1
  62. package/dist/components/config/form/types.d.ts.map +1 -1
  63. package/dist/components/resources/ResourceTable.d.ts +7 -1
  64. package/dist/components/resources/ResourceTable.d.ts.map +1 -1
  65. package/dist/components/resources/ResourceTable.js +56 -6
  66. package/dist/components/theme/ThemeToggle.d.ts +3 -1
  67. package/dist/components/theme/ThemeToggle.d.ts.map +1 -1
  68. package/dist/components/theme/ThemeToggle.js +2 -2
  69. package/dist/components/ui/icons.d.ts +1 -0
  70. package/dist/components/ui/icons.d.ts.map +1 -1
  71. package/dist/components/ui/icons.js +6 -1
  72. package/dist/hooks/useSaveBar.d.ts +6 -0
  73. package/dist/hooks/useSaveBar.d.ts.map +1 -1
  74. package/dist/index.d.ts +2 -1
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +1 -0
  77. package/dist/lib/capabilities.d.ts +4 -0
  78. package/dist/lib/capabilities.d.ts.map +1 -0
  79. package/dist/lib/capabilities.js +9 -0
  80. package/dist/styles/audit.css +34 -0
  81. package/dist/styles/form.css +587 -9
  82. package/dist/styles/index.css +1 -0
  83. package/dist/styles/modal.css +111 -0
  84. package/dist/styles/page-preview.css +84 -0
  85. package/dist/styles/select.css +23 -0
  86. package/dist/styles/shell.css +234 -18
  87. package/dist/styles/sync.css +388 -4
  88. package/dist/themes/light.css +27 -0
  89. package/package.json +3 -1
@@ -130,15 +130,17 @@ function titleFromFilename(name) {
130
130
  .replace(/\s+/g, " ")
131
131
  .trim();
132
132
  }
133
- export function ResourcePanel({ schema, items, permissions, actions = {}, label, uploads, rowIdKeys = ["id", "slug", "uid", "email"], storageKey, onUpdate, onCreate, onDelete, onAction, onActionDone, onPreviewMail, collectionActions = {}, onCollectionAction, onUpload, galleryUpload, onListGallery, onUploadGallery, initialEditRowId, onEditRowIdChange, }) {
133
+ export function ResourcePanel({ schema, items, permissions, actions = {}, label, uploads, rowIdKeys = ["id", "slug", "uid", "email"], storageKey, onUpdate, onCreate, onDelete, onAction, onActionDone, onPreviewMail, collectionActions = {}, onCollectionAction, bulkActions = {}, onBulkAction, listQuery, total, searchQuery = "", onSearchChange, onUpload, galleryUpload, onListGallery, onUploadGallery, initialEditRowId, onEditRowIdChange, }) {
134
134
  const [editing, setEditing] = useState(null);
135
135
  const [creating, setCreating] = useState(false);
136
136
  const [viewing, setViewing] = useState(null);
137
137
  const [bulkOpen, setBulkOpen] = useState(false);
138
138
  const [busyAction, setBusyAction] = useState(null);
139
139
  const [selected, setSelected] = useState(new Set());
140
+ const [searchDraft, setSearchDraft] = useState(searchQuery);
140
141
  const [pendingAction, setPendingAction] = useState(null);
141
142
  const [pendingCollectionAction, setPendingCollectionAction] = useState(null);
143
+ const [pendingBulkAction, setPendingBulkAction] = useState(null);
142
144
  const tableWrapRef = useRef(null);
143
145
  const [tableOverflow, setTableOverflow] = useState({
144
146
  overflow: false,
@@ -156,9 +158,24 @@ export function ResourcePanel({ schema, items, permissions, actions = {}, label,
156
158
  const canUpload = Boolean(uploads && onUpload && Object.keys(uploads).length);
157
159
  const actionEntries = Object.entries(actions);
158
160
  const collectionActionEntries = Object.entries(collectionActions);
161
+ const bulkActionEntries = Object.entries(bulkActions);
159
162
  const fieldKeys = Object.keys(schema);
160
163
  const visibilityFields = useMemo(() => fieldKeys.filter((key) => isListVisibilityField(key, schema[key])), [fieldKeys, schema]);
161
- const selectable = Boolean(onAction && actionEntries.length > 0);
164
+ const selectable = Boolean((onAction && actionEntries.length > 0) ||
165
+ (onBulkAction && bulkActionEntries.length > 0));
166
+ const showSearch = Boolean(listQuery && onSearchChange);
167
+ useEffect(() => {
168
+ setSearchDraft(searchQuery);
169
+ }, [searchQuery]);
170
+ useEffect(() => {
171
+ if (!onSearchChange)
172
+ return;
173
+ const handle = window.setTimeout(() => {
174
+ if (searchDraft !== searchQuery)
175
+ onSearchChange(searchDraft);
176
+ }, 250);
177
+ return () => window.clearTimeout(handle);
178
+ }, [searchDraft, searchQuery, onSearchChange]);
162
179
  const openEdit = useCallback((row) => {
163
180
  setEditing(row);
164
181
  onEditRowIdChange?.(resolveRowId(row, rowIdKeys));
@@ -332,6 +349,38 @@ export function ResourcePanel({ schema, items, permissions, actions = {}, label,
332
349
  return;
333
350
  void runCollectionAction(actionId);
334
351
  }, [collectionActions, onCollectionAction, runCollectionAction]);
352
+ const runBulkAction = useCallback(async (actionId, rowIds, input) => {
353
+ if (!onBulkAction || rowIds.length === 0)
354
+ return;
355
+ setBusyAction(actionId);
356
+ try {
357
+ await onBulkAction(actionId, rowIds, input);
358
+ await onActionDone?.();
359
+ setSelected(new Set());
360
+ }
361
+ catch (error) {
362
+ window.alert(error instanceof Error ? error.message : "Bulk action failed");
363
+ }
364
+ finally {
365
+ setBusyAction(null);
366
+ setPendingBulkAction(null);
367
+ }
368
+ }, [onBulkAction, onActionDone]);
369
+ const queueBulkAction = useCallback((actionId, rowIds) => {
370
+ const meta = bulkActions[actionId];
371
+ if (!meta || rowIds.length === 0 || !onBulkAction)
372
+ return;
373
+ if (actionHasInput(meta)) {
374
+ setPendingBulkAction(actionId);
375
+ return;
376
+ }
377
+ const detail = meta.confirm
378
+ ? `${meta.label} on ${rowIds.length} row(s)?\n\n${meta.confirm}`
379
+ : `${meta.label} on ${rowIds.length} row(s)?`;
380
+ if (!window.confirm(detail))
381
+ return;
382
+ void runBulkAction(actionId, rowIds);
383
+ }, [bulkActions, onBulkAction, runBulkAction]);
335
384
  useEffect(() => {
336
385
  setColumnVisibility(readVisibility(storageKey, schema));
337
386
  }, [storageKey]);
@@ -510,7 +559,7 @@ export function ResourcePanel({ schema, items, permissions, actions = {}, label,
510
559
  closeEdit();
511
560
  } })] }));
512
561
  }
513
- const toolbar = (_jsxs("div", { className: "vertebr-table-toolbar", children: [_jsxs("div", { className: "vertebr-table-toolbar-start", children: [columnOptions.length > 0 ? (_jsx(ColumnVisibilityMenu, { columns: columnOptions, visibility: columnVisibility, onChange: setColumnVisibility })) : null, canUpload ? (_jsxs("button", { type: "button", className: "vertebr-btn vertebr-btn-quiet vertebr-btn-icon", onClick: () => setBulkOpen(true), children: [_jsx(ImageUploadIcon, {}), "Bulk upload"] })) : null, visibilityFields.length > 0 && dirtyVisibilityCount > 0 ? (_jsxs(_Fragment, { children: [_jsxs("span", { className: "vertebr-count", children: [dirtyVisibilityCount, " visibility change", dirtyVisibilityCount === 1 ? "" : "s"] }), _jsx("button", { type: "button", className: "vertebr-btn vertebr-btn-primary", disabled: savingVisibility, onClick: () => void saveVisibility(), children: savingVisibility ? "Saving…" : "Save visibility" }), _jsx("button", { type: "button", className: "vertebr-btn vertebr-btn-quiet", disabled: savingVisibility, onClick: () => setVisibilityDrafts({}), children: "Discard" })] })) : null, collectionActionEntries.map(([actionId, meta]) => (_jsx("button", { type: "button", className: "vertebr-btn vertebr-btn-quiet", disabled: busyAction != null, onClick: () => queueCollectionAction(actionId), children: meta.label }, actionId))), selectable && selected.size > 0 ? (_jsxs(_Fragment, { children: [_jsxs("span", { className: "vertebr-count", children: [selected.size, " selected"] }), actionEntries.map(([actionId, meta]) => (_jsx("button", { type: "button", className: "vertebr-btn vertebr-btn-quiet", disabled: busyAction != null, onClick: () => queueAction(actionId, [...selected]), children: meta.label }, actionId))), _jsx("button", { type: "button", className: "vertebr-btn vertebr-btn-quiet", onClick: () => setSelected(new Set()), children: "Clear" })] })) : null] }), tableOverflow.overflow ? (_jsxs("div", { className: "vertebr-table-scroll-controls", role: "group", "aria-label": "Scroll columns", children: [_jsx("button", { type: "button", className: "vertebr-btn vertebr-btn-quiet vertebr-btn-icon vertebr-table-scroll-btn", disabled: !tableOverflow.canLeft, onClick: () => scrollTable("left"), "aria-label": "Scroll columns left", children: _jsx(ChevronLeftIcon, {}) }), _jsx("button", { type: "button", className: "vertebr-btn vertebr-btn-quiet vertebr-btn-icon vertebr-table-scroll-btn", disabled: !tableOverflow.canRight, onClick: () => scrollTable("right"), "aria-label": "Scroll columns right", children: _jsx(ChevronRightIcon, {}) })] })) : null] }));
562
+ const toolbar = (_jsxs("div", { className: "vertebr-table-toolbar", children: [_jsxs("div", { className: "vertebr-table-toolbar-start", children: [columnOptions.length > 0 ? (_jsx(ColumnVisibilityMenu, { columns: columnOptions, visibility: columnVisibility, onChange: setColumnVisibility })) : null, canUpload ? (_jsxs("button", { type: "button", className: "vertebr-btn vertebr-btn-quiet vertebr-btn-icon", onClick: () => setBulkOpen(true), children: [_jsx(ImageUploadIcon, {}), "Bulk upload"] })) : null, visibilityFields.length > 0 && dirtyVisibilityCount > 0 ? (_jsxs(_Fragment, { children: [_jsxs("span", { className: "vertebr-count", children: [dirtyVisibilityCount, " visibility change", dirtyVisibilityCount === 1 ? "" : "s"] }), _jsx("button", { type: "button", className: "vertebr-btn vertebr-btn-primary", disabled: savingVisibility, onClick: () => void saveVisibility(), children: savingVisibility ? "Saving…" : "Save visibility" }), _jsx("button", { type: "button", className: "vertebr-btn vertebr-btn-quiet", disabled: savingVisibility, onClick: () => setVisibilityDrafts({}), children: "Discard" })] })) : null, collectionActionEntries.map(([actionId, meta]) => (_jsx("button", { type: "button", className: "vertebr-btn vertebr-btn-quiet", disabled: busyAction != null, onClick: () => queueCollectionAction(actionId), children: meta.label }, actionId))), selectable && selected.size > 0 ? (_jsxs(_Fragment, { children: [_jsxs("span", { className: "vertebr-count", children: [selected.size, " selected"] }), actionEntries.map(([actionId, meta]) => (_jsx("button", { type: "button", className: "vertebr-btn vertebr-btn-quiet", disabled: busyAction != null, onClick: () => queueAction(actionId, [...selected]), children: meta.label }, actionId))), bulkActionEntries.map(([actionId, meta]) => (_jsx("button", { type: "button", className: "vertebr-btn vertebr-btn-quiet", disabled: busyAction != null, onClick: () => queueBulkAction(actionId, [...selected]), children: meta.label }, `bulk:${actionId}`))), _jsx("button", { type: "button", className: "vertebr-btn vertebr-btn-quiet", onClick: () => setSelected(new Set()), children: "Clear" })] })) : null] }), tableOverflow.overflow ? (_jsxs("div", { className: "vertebr-table-scroll-controls", role: "group", "aria-label": "Scroll columns", children: [_jsx("button", { type: "button", className: "vertebr-btn vertebr-btn-quiet vertebr-btn-icon vertebr-table-scroll-btn", disabled: !tableOverflow.canLeft, onClick: () => scrollTable("left"), "aria-label": "Scroll columns left", children: _jsx(ChevronLeftIcon, {}) }), _jsx("button", { type: "button", className: "vertebr-btn vertebr-btn-quiet vertebr-btn-icon vertebr-table-scroll-btn", disabled: !tableOverflow.canRight, onClick: () => scrollTable("right"), "aria-label": "Scroll columns right", children: _jsx(ChevronRightIcon, {}) })] })) : null] }));
514
563
  const bulkModal = bulkOpen && uploads && onUpload ? (_jsx(BulkImageUploadModal, { uploads: uploads, canCreate: canCreate, fieldLabels: Object.fromEntries(Object.keys(uploads).map((key) => [
515
564
  key,
516
565
  schema[key]?.label ?? humanizeKey(key),
@@ -538,13 +587,14 @@ export function ResourcePanel({ schema, items, permissions, actions = {}, label,
538
587
  : `Send to ${pendingAction.rowIds.length}`, onClose: () => setPendingAction(null), onSubmit: (value) => runActions(pendingAction.actionId, pendingAction.rowIds, value) })) : null) : null;
539
588
  const pendingCollectionModal = pendingCollectionAction &&
540
589
  collectionActions[pendingCollectionAction]?.input ? (_jsx(ResourceActionModal, { title: collectionActions[pendingCollectionAction]?.label ?? "Run action", eyebrow: "This resource", schema: actionInputSchema(collectionActions[pendingCollectionAction].input), submitLabel: busyAction ? "Working…" : "Run", onClose: () => setPendingCollectionAction(null), onSubmit: (value) => runCollectionAction(pendingCollectionAction, value) })) : null;
541
- const recordsHead = (_jsxs("div", { className: "vertebr-panel-head", children: [_jsx("h2", { children: "Records" }), _jsxs("div", { className: "vertebr-panel-head-actions", children: [canCreate ? (_jsxs("button", { type: "button", className: "vertebr-btn vertebr-btn-quiet vertebr-btn-icon", onClick: () => setCreating(true), children: [_jsx(PlusIcon, {}), createLabel] })) : null, _jsx("span", { className: "vertebr-count", children: items.length })] })] }));
590
+ const pendingBulkModal = pendingBulkAction && bulkActions[pendingBulkAction]?.input ? (_jsx(ResourceActionModal, { title: bulkActions[pendingBulkAction]?.label ?? "Bulk action", eyebrow: `${selected.size} selected`, schema: actionInputSchema(bulkActions[pendingBulkAction].input), submitLabel: busyAction ? "Working…" : "Run", onClose: () => setPendingBulkAction(null), onSubmit: (value) => runBulkAction(pendingBulkAction, [...selected], value) })) : null;
591
+ const recordsHead = (_jsxs("div", { className: "vertebr-panel-head", children: [_jsx("h2", { children: "Records" }), _jsxs("div", { className: "vertebr-panel-head-actions", children: [showSearch ? (_jsx("input", { className: "vertebr-resource-search", type: "search", placeholder: "Search\u2026", value: searchDraft, onChange: (event) => setSearchDraft(event.target.value), "aria-label": "Search records" })) : null, canCreate ? (_jsxs("button", { type: "button", className: "vertebr-btn vertebr-btn-quiet vertebr-btn-icon", onClick: () => setCreating(true), children: [_jsx(PlusIcon, {}), createLabel] })) : null, _jsx("span", { className: "vertebr-count", children: total != null ? `${items.length} of ${total}` : items.length })] })] }));
542
592
  if (items.length === 0) {
543
593
  return (_jsxs("div", { className: "vertebr-resource-body", children: [recordsHead, canUpload ||
544
594
  columnOptions.length > 0 ||
545
595
  collectionActionEntries.length > 0
546
596
  ? toolbar
547
- : null, _jsx("div", { className: "vertebr-empty", children: "No rows yet." }), bulkModal, createModal, pendingActionModal, pendingCollectionModal] }));
597
+ : null, _jsx("div", { className: "vertebr-empty", children: "No rows yet." }), bulkModal, createModal, pendingActionModal, pendingCollectionModal, pendingBulkModal] }));
548
598
  }
549
599
  return (_jsxs("div", { className: "vertebr-resource-body", children: [recordsHead, toolbar, _jsx("div", { className: "vertebr-table-wrap", ref: tableWrapRef, "data-overflow": tableOverflow.overflow ? "true" : undefined, "data-overflow-left": tableOverflow.canLeft ? "true" : undefined, "data-overflow-right": tableOverflow.canRight ? "true" : undefined, children: _jsxs("table", { className: "vertebr-table", children: [_jsx("thead", { children: table.getHeaderGroups().map((headerGroup) => (_jsx("tr", { children: headerGroup.headers.map((header) => (_jsx("th", { className: header.column.id === "_actions"
550
600
  ? "vertebr-col-actions"
@@ -568,7 +618,7 @@ export function ResourcePanel({ schema, items, permissions, actions = {}, label,
568
618
  : undefined, children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id))) }, row.id))) })] }) }), viewing ? (_jsx(ResourceViewModal, { schema: schema, row: viewing, title: rowTitle(viewing, rowIdKeys), canEdit: canUpdate, onClose: () => setViewing(null), onEdit: () => {
569
619
  openEdit(viewing);
570
620
  setViewing(null);
571
- } })) : null, pendingActionModal, pendingCollectionModal, bulkModal, createModal] }));
621
+ } })) : null, pendingActionModal, pendingCollectionModal, pendingBulkModal, bulkModal, createModal] }));
572
622
  }
573
623
  /** @deprecated Prefer ResourcePanel */
574
624
  export function ResourceTable(props) {
@@ -2,6 +2,8 @@ import type { VbTheme } from "../../hooks/useVertebrTheme";
2
2
  export type ThemeToggleProps = {
3
3
  theme: VbTheme;
4
4
  onChange: (theme: VbTheme) => void;
5
+ /** Icon-only control for dense chrome (top bar). */
6
+ compact?: boolean;
5
7
  };
6
- export declare function ThemeToggle({ theme, onChange }: ThemeToggleProps): import("react").JSX.Element;
8
+ export declare function ThemeToggle({ theme, onChange, compact }: ThemeToggleProps): import("react").JSX.Element;
7
9
  //# sourceMappingURL=ThemeToggle.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ThemeToggle.d.ts","sourceRoot":"","sources":["../../../src/components/theme/ThemeToggle.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAE3D,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACpC,CAAC;AAEF,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,gBAAgB,+BA+BhE"}
1
+ {"version":3,"file":"ThemeToggle.d.ts","sourceRoot":"","sources":["../../../src/components/theme/ThemeToggle.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAE3D,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,oDAAoD;IACpD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,gBAAgB,+BAmCzE"}
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- export function ThemeToggle({ theme, onChange }) {
3
- return (_jsx("div", { className: "vertebr-theme", children: _jsxs("div", { className: "vertebr-theme-toggle", role: "group", "aria-label": "Appearance", children: [_jsxs("button", { type: "button", className: "vertebr-theme-option", "data-active": theme === "light", "aria-pressed": theme === "light", onClick: () => onChange("light"), children: [_jsx(ThemeSunIcon, {}), "Light"] }), _jsxs("button", { type: "button", className: "vertebr-theme-option", "data-active": theme === "dark", "aria-pressed": theme === "dark", onClick: () => onChange("dark"), children: [_jsx(ThemeMoonIcon, {}), "Dark"] })] }) }));
2
+ export function ThemeToggle({ theme, onChange, compact }) {
3
+ return (_jsx("div", { className: "vertebr-theme", "data-compact": compact ? "true" : undefined, children: _jsxs("div", { className: "vertebr-theme-toggle", role: "group", "aria-label": "Appearance", children: [_jsxs("button", { type: "button", className: "vertebr-theme-option", "data-active": theme === "light", "aria-pressed": theme === "light", "aria-label": "Light", title: "Light", onClick: () => onChange("light"), children: [_jsx(ThemeSunIcon, {}), compact ? null : "Light"] }), _jsxs("button", { type: "button", className: "vertebr-theme-option", "data-active": theme === "dark", "aria-pressed": theme === "dark", "aria-label": "Dark", title: "Dark", onClick: () => onChange("dark"), children: [_jsx(ThemeMoonIcon, {}), compact ? null : "Dark"] })] }) }));
4
4
  }
5
5
  function ThemeSunIcon() {
6
6
  return (_jsxs("svg", { className: "vertebr-theme-icon", width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("circle", { cx: "12", cy: "12", r: "4" }), _jsx("path", { d: "M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41" })] }));
@@ -11,6 +11,7 @@ export declare function IconChart(props: IconProps): import("react").JSX.Element
11
11
  export declare function IconChevronLeft(props: IconProps): import("react").JSX.Element;
12
12
  export declare function IconSearch(props: IconProps): import("react").JSX.Element;
13
13
  export declare function IconSync(props: IconProps): import("react").JSX.Element;
14
+ export declare function IconMenu(props: IconProps): import("react").JSX.Element;
14
15
  export declare function IconAddon(props: IconProps): import("react").JSX.Element;
15
16
  export declare function iconForNavKey(key: string): typeof IconHome;
16
17
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../../src/components/ui/icons.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEtC,KAAK,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,CAAC;AAiBzC,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,+BAMxC;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,+BAO5C;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,+BAQ3C;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,+BAOzC;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,+BAOxC;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,+BAOzC;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,+BAO5C;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,+BAMzC;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,+BAM/C;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,+BAO1C;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,+BASxC;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,+BASzC;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,mBAWxC"}
1
+ {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../../src/components/ui/icons.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEtC,KAAK,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,CAAC;AAiBzC,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,+BAMxC;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,+BAO5C;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,+BAQ3C;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,+BAOzC;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,+BAOxC;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,+BAOzC;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,+BAO5C;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,+BAMzC;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,+BAM/C;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,+BAO1C;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,+BASxC;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,+BAQxC;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,+BASzC;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,mBAYxC"}
@@ -44,7 +44,10 @@ export function IconSearch(props) {
44
44
  return (_jsxs("svg", { ...base(props), children: [_jsx("circle", { cx: "9", cy: "9", r: "4.75" }), _jsx("path", { d: "M13 13l3.5 3.5" })] }));
45
45
  }
46
46
  export function IconSync(props) {
47
- return (_jsxs("svg", { ...base(props), children: [_jsx("path", { d: "M4 7h8" }), _jsx("path", { d: "M10 5l2 2-2 2" }), _jsx("path", { d: "M16 13H8" }), _jsx("path", { d: "M10 11l-2 2 2 2" })] }));
47
+ return (_jsxs("svg", { ...base(props), children: [_jsx("path", { d: "M14.5 7.2A6 6 0 0 0 5.2 8.5" }), _jsx("path", { d: "M5 5.5v3.2h3.2" }), _jsx("path", { d: "M5.5 12.8A6 6 0 0 0 14.8 11.5" }), _jsx("path", { d: "M15 14.5v-3.2h-3.2" })] }));
48
+ }
49
+ export function IconMenu(props) {
50
+ return (_jsxs("svg", { ...base(props), children: [_jsx("path", { d: "M4 6.5h12" }), _jsx("path", { d: "M4 10h12" }), _jsx("path", { d: "M4 13.5h12" })] }));
48
51
  }
49
52
  export function IconAddon(props) {
50
53
  return (_jsxs("svg", { ...base(props), children: [_jsx("path", { d: "M8 3.5h4v4H8z" }), _jsx("path", { d: "M3.5 8h4v4h-4z" }), _jsx("path", { d: "M12.5 8h4v4h-4z" }), _jsx("path", { d: "M8 12.5h4v4H8z" })] }));
@@ -52,6 +55,8 @@ export function IconAddon(props) {
52
55
  export function iconForNavKey(key) {
53
56
  if (key === "overview")
54
57
  return IconHome;
58
+ if (key === "audit")
59
+ return IconChart;
55
60
  if (key.startsWith("resource:"))
56
61
  return IconProducts;
57
62
  if (key === "gallery")
@@ -5,8 +5,14 @@ export type SaveBarState = {
5
5
  tone?: "ok" | "danger";
6
6
  isDirty: boolean;
7
7
  saving: boolean;
8
+ /** Primary save button label. @default "Save" */
9
+ saveLabel?: string;
8
10
  onSave?: () => void | Promise<void>;
9
11
  onDiscard?: () => void;
12
+ /** Optional publish action when revisions are enabled. */
13
+ publishLabel?: string;
14
+ onPublish?: () => void | Promise<void>;
15
+ publishing?: boolean;
10
16
  };
11
17
  type SaveBarContextValue = {
12
18
  state: SaveBarState;
@@ -1 +1 @@
1
- {"version":3,"file":"useSaveBar.d.ts","sourceRoot":"","sources":["../../src/hooks/useSaveBar.tsx"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,IAAI,GAAG,QAAQ,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACzB,KAAK,EAAE,YAAY,CAAC;IACpB,QAAQ,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC;IAChD,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB,CAAC;AAUF,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,+BAuBpE;AAED,wBAAgB,UAAU,wBAMzB"}
1
+ {"version":3,"file":"useSaveBar.d.ts","sourceRoot":"","sources":["../../src/hooks/useSaveBar.tsx"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,IAAI,GAAG,QAAQ,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACzB,KAAK,EAAE,YAAY,CAAC;IACpB,QAAQ,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC;IAChD,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB,CAAC;AAUF,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,+BAuBpE;AAED,wBAAgB,UAAU,wBAMzB"}
package/dist/index.d.ts CHANGED
@@ -29,5 +29,6 @@ export { createVertebrCatalog, catalogHref, catalogMatch, } from "@vertebr/clien
29
29
  export type { VertebrCatalog, VertebrCatalogOptions, PublicResourceResponse, } from "@vertebr/client";
30
30
  export { VertebrCatalogProvider, useVertebrCatalog, useVertebrCatalogItem, } from "@vertebr/client/react";
31
31
  export type { VertebrCatalogProviderProps, VertebrCatalogState, } from "@vertebr/client/react";
32
- export type { VertebrClient, VertebrClientOptions, VertebrMetricsOptions, VertebrReadOptions, AdminEnvironment, BootstrapResponse, CatalogResponse, CatalogResource, CatalogConfig, CatalogConfigSection, EnvironmentAuthPublic, FieldSchema, FieldType, GalleryItem, GalleryMeta, GalleryResponse, MailPreviewResponse, MailLibraryTemplate, MailHistoryEntry, MailProductOption, MailDiscountOption, EmailsBoardResponse, MetricCard, MetricChart, MetricsResponse, ResourceListResponse, ResourceActionMeta, ResourceUploadMeta, ResourceUploadResponse, ResourceBulkUploadResponse, ConfigResponse, VertebrControlsMap, } from "@vertebr/client";
32
+ export type { VertebrClient, VertebrClientOptions, VertebrMetricsOptions, VertebrReadOptions, AdminEnvironment, AuditEntry, AuditListResponse, BootstrapResponse, CatalogResponse, CatalogResource, CatalogConfig, CatalogConfigSection, EnvironmentAuthPublic, FieldSchema, FieldType, GalleryItem, GalleryMeta, GalleryResponse, HealthCheck, HealthResponse, Job, JobsResponse, MailPreviewResponse, MailLibraryTemplate, MailHistoryEntry, MailProductOption, MailDiscountOption, EmailsBoardResponse, MetricCard, MetricChart, MetricsResponse, ResourceListResponse, ResourceActionMeta, ResourceUploadMeta, ResourceUploadResponse, ResourceBulkUploadResponse, Revision, RevisionMeta, ConfigResponse, VertebrControlsMap, } from "@vertebr/client";
33
+ export { hasCap } from "./lib/capabilities";
33
34
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -16,3 +16,4 @@ export { createVertebrClient, VERTEBR_ENV_HEADER, renderMarkdown, isVertebrPrevi
16
16
  export { VertebrMarkdown } from "@vertebr/client/react";
17
17
  export { createVertebrCatalog, catalogHref, catalogMatch, } from "@vertebr/client";
18
18
  export { VertebrCatalogProvider, useVertebrCatalog, useVertebrCatalogItem, } from "@vertebr/client/react";
19
+ export { hasCap } from "./lib/capabilities";
@@ -0,0 +1,4 @@
1
+ import type { CatalogResponse } from "@vertebr/client";
2
+ /** True when the catalog grants `cap` (or `*`). Missing capabilities ⇒ allow. */
3
+ export declare function hasCap(catalog: CatalogResponse | null | undefined, cap: string): boolean;
4
+ //# sourceMappingURL=capabilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../src/lib/capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEvD,iFAAiF;AACjF,wBAAgB,MAAM,CACpB,OAAO,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,EAC3C,GAAG,EAAE,MAAM,GACV,OAAO,CAKT"}
@@ -0,0 +1,9 @@
1
+ /** True when the catalog grants `cap` (or `*`). Missing capabilities ⇒ allow. */
2
+ export function hasCap(catalog, cap) {
3
+ const caps = catalog?.capabilities;
4
+ if (!caps?.length)
5
+ return true;
6
+ if (caps.includes("*"))
7
+ return true;
8
+ return caps.includes(cap);
9
+ }
@@ -0,0 +1,34 @@
1
+ /* ── Audit board ─────────────────────────────────────── */
2
+
3
+ .vertebr-audit {
4
+ flex: 1 1 auto;
5
+ min-height: 0;
6
+ display: flex;
7
+ flex-direction: column;
8
+ gap: 0.75rem;
9
+ overflow: hidden;
10
+ }
11
+
12
+ .vertebr-audit-table td {
13
+ white-space: nowrap;
14
+ max-width: 22rem;
15
+ }
16
+
17
+ .vertebr-audit-when {
18
+ font-family: var(--vb-mono);
19
+ font-size: 0.78rem;
20
+ color: var(--vb-text-subtle);
21
+ }
22
+
23
+ .vertebr-audit-action {
24
+ font-family: var(--vb-mono);
25
+ font-size: 0.72rem;
26
+ padding: 0.15rem 0.4rem;
27
+ border-radius: 4px;
28
+ background: var(--vb-surface-tint);
29
+ }
30
+
31
+ .vertebr-audit-target {
32
+ font-size: 0.82rem;
33
+ color: var(--vb-text-subtle);
34
+ }