@payload-onpage/react 0.2.1 → 0.3.1
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 +6 -0
- package/dist/OnPageClient.d.ts.map +1 -1
- package/dist/OnPageClient.js +9 -5
- package/dist/OnPageClient.js.map +1 -1
- package/dist/annotations.d.ts +1 -1
- package/dist/annotations.d.ts.map +1 -1
- package/dist/context.d.ts +19 -5
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +31 -7
- package/dist/context.js.map +1 -1
- package/dist/dom.d.ts +16 -12
- package/dist/dom.d.ts.map +1 -1
- package/dist/dom.js +16 -16
- package/dist/dom.js.map +1 -1
- package/dist/editor/FieldHost.d.ts.map +1 -1
- package/dist/editor/FieldHost.js +18 -11
- package/dist/editor/FieldHost.js.map +1 -1
- package/dist/editor/OnPageEditor.d.ts +15 -8
- package/dist/editor/OnPageEditor.d.ts.map +1 -1
- package/dist/editor/OnPageEditor.js +73 -103
- package/dist/editor/OnPageEditor.js.map +1 -1
- package/dist/editor/editTarget.d.ts +28 -0
- package/dist/editor/editTarget.d.ts.map +1 -0
- package/dist/editor/editTarget.js +20 -0
- package/dist/editor/editTarget.js.map +1 -0
- package/dist/editor/useClientDocs.d.ts +4 -0
- package/dist/editor/useClientDocs.d.ts.map +1 -0
- package/dist/editor/useClientDocs.js +16 -0
- package/dist/editor/useClientDocs.js.map +1 -0
- package/dist/editor/useEditorSession.d.ts +13 -0
- package/dist/editor/useEditorSession.d.ts.map +1 -0
- package/dist/editor/useEditorSession.js +30 -0
- package/dist/editor/useEditorSession.js.map +1 -0
- package/dist/editor/useFlash.d.ts +4 -0
- package/dist/editor/useFlash.d.ts.map +1 -0
- package/dist/editor/useFlash.js +16 -0
- package/dist/editor/useFlash.js.map +1 -0
- package/dist/editor/useGhosts.d.ts +5 -7
- package/dist/editor/useGhosts.d.ts.map +1 -1
- package/dist/editor/useGhosts.js.map +1 -1
- package/dist/editor/usePageEvents.d.ts.map +1 -1
- package/dist/editor/usePageEvents.js +16 -16
- package/dist/editor/usePageEvents.js.map +1 -1
- package/dist/editor-kit.d.ts +10 -6
- package/dist/editor-kit.d.ts.map +1 -1
- package/dist/editor-kit.js +8 -5
- package/dist/editor-kit.js.map +1 -1
- package/dist/editors/CheckboxEditor.d.ts +6 -1
- package/dist/editors/CheckboxEditor.d.ts.map +1 -1
- package/dist/editors/CheckboxEditor.js +6 -3
- package/dist/editors/CheckboxEditor.js.map +1 -1
- package/dist/editors/ColorEditor.d.ts +3 -1
- package/dist/editors/ColorEditor.d.ts.map +1 -1
- package/dist/editors/ColorEditor.js +9 -15
- package/dist/editors/ColorEditor.js.map +1 -1
- package/dist/editors/DateEditor.d.ts +3 -1
- package/dist/editors/DateEditor.d.ts.map +1 -1
- package/dist/editors/DateEditor.js +10 -12
- package/dist/editors/DateEditor.js.map +1 -1
- package/dist/editors/InlineText.d.ts +2 -2
- package/dist/editors/InlineText.d.ts.map +1 -1
- package/dist/editors/InlineText.js +2 -3
- package/dist/editors/InlineText.js.map +1 -1
- package/dist/editors/NumberEditor.d.ts +3 -1
- package/dist/editors/NumberEditor.d.ts.map +1 -1
- package/dist/editors/NumberEditor.js +9 -17
- package/dist/editors/NumberEditor.js.map +1 -1
- package/dist/editors/RelationshipEditor.d.ts +7 -1
- package/dist/editors/RelationshipEditor.d.ts.map +1 -1
- package/dist/editors/RelationshipEditor.js +10 -18
- package/dist/editors/RelationshipEditor.js.map +1 -1
- package/dist/editors/SelectEditor.d.ts +4 -1
- package/dist/editors/SelectEditor.d.ts.map +1 -1
- package/dist/editors/SelectEditor.js +8 -13
- package/dist/editors/SelectEditor.js.map +1 -1
- package/dist/editors/UploadEditor.d.ts +7 -1
- package/dist/editors/UploadEditor.d.ts.map +1 -1
- package/dist/editors/UploadEditor.js +5 -5
- package/dist/editors/UploadEditor.js.map +1 -1
- package/dist/editors/index.d.ts +0 -1
- package/dist/editors/index.d.ts.map +1 -1
- package/dist/editors/index.js +56 -16
- package/dist/editors/index.js.map +1 -1
- package/dist/editors/kit.d.ts +39 -0
- package/dist/editors/kit.d.ts.map +1 -0
- package/dist/editors/kit.js +44 -0
- package/dist/editors/kit.js.map +1 -0
- package/dist/editors/useDebouncedSearch.d.ts +10 -6
- package/dist/editors/useDebouncedSearch.d.ts.map +1 -1
- package/dist/editors/useDebouncedSearch.js +11 -7
- package/dist/editors/useDebouncedSearch.js.map +1 -1
- package/dist/geometry.d.ts +49 -0
- package/dist/geometry.d.ts.map +1 -0
- package/dist/geometry.js +48 -0
- package/dist/geometry.js.map +1 -0
- package/dist/hub.d.ts +4 -4
- package/dist/hub.d.ts.map +1 -1
- package/dist/hub.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/layout.d.ts.map +1 -1
- package/dist/layout.js +4 -2
- package/dist/layout.js.map +1 -1
- package/dist/locators.d.ts +0 -2
- package/dist/locators.d.ts.map +1 -1
- package/dist/locators.js +10 -16
- package/dist/locators.js.map +1 -1
- package/dist/messages.d.ts +15 -2
- package/dist/messages.d.ts.map +1 -1
- package/dist/messages.js +5 -0
- package/dist/messages.js.map +1 -1
- package/dist/registry.d.ts +21 -2
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +31 -6
- package/dist/registry.js.map +1 -1
- package/dist/rowOps.d.ts +20 -0
- package/dist/rowOps.d.ts.map +1 -0
- package/dist/rowOps.js +48 -0
- package/dist/rowOps.js.map +1 -0
- package/dist/sanitize.d.ts +2 -0
- package/dist/sanitize.d.ts.map +1 -1
- package/dist/sanitize.js +3 -0
- package/dist/sanitize.js.map +1 -1
- package/dist/settings.d.ts +10 -0
- package/dist/settings.d.ts.map +1 -0
- package/dist/settings.js +30 -0
- package/dist/settings.js.map +1 -0
- package/dist/styles.d.ts +1 -5
- package/dist/styles.d.ts.map +1 -1
- package/dist/styles.js +5 -4
- package/dist/styles.js.map +1 -1
- package/dist/targets.d.ts +1 -1
- package/dist/targets.d.ts.map +1 -1
- package/dist/types.d.ts +71 -46
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/BlockPicker.d.ts.map +1 -1
- package/dist/ui/BlockPicker.js +6 -5
- package/dist/ui/BlockPicker.js.map +1 -1
- package/dist/ui/Dialog.d.ts +0 -5
- package/dist/ui/Dialog.d.ts.map +1 -1
- package/dist/ui/Dialog.js +10 -6
- package/dist/ui/Dialog.js.map +1 -1
- package/dist/ui/Dock.d.ts +1 -6
- package/dist/ui/Dock.d.ts.map +1 -1
- package/dist/ui/Dock.js +46 -28
- package/dist/ui/Dock.js.map +1 -1
- package/dist/ui/Overlay.d.ts.map +1 -1
- package/dist/ui/Overlay.js +39 -37
- package/dist/ui/Overlay.js.map +1 -1
- package/dist/ui/PreviewToolbar.d.ts +3 -3
- package/dist/ui/PreviewToolbar.d.ts.map +1 -1
- package/dist/ui/PreviewToolbar.js +4 -6
- package/dist/ui/PreviewToolbar.js.map +1 -1
- package/dist/ui/SettingsPanel.d.ts +0 -9
- package/dist/ui/SettingsPanel.d.ts.map +1 -1
- package/dist/ui/SettingsPanel.js +36 -41
- package/dist/ui/SettingsPanel.js.map +1 -1
- package/dist/ui/ToolbarButton.d.ts +12 -0
- package/dist/ui/ToolbarButton.d.ts.map +1 -0
- package/dist/ui/ToolbarButton.js +7 -0
- package/dist/ui/ToolbarButton.js.map +1 -0
- package/dist/useEvent.d.ts +1 -1
- package/dist/useEvent.d.ts.map +1 -1
- package/dist/useEvent.js +3 -1
- package/dist/useEvent.js.map +1 -1
- package/dist/useIsClient.d.ts +5 -0
- package/dist/useIsClient.d.ts.map +1 -0
- package/dist/useIsClient.js +8 -0
- package/dist/useIsClient.js.map +1 -0
- package/package.json +15 -4
- package/src/OnPageClient.tsx +9 -5
- package/src/annotations.ts +1 -1
- package/src/context.tsx +53 -10
- package/src/dom.ts +17 -18
- package/src/editor/FieldHost.tsx +26 -11
- package/src/editor/OnPageEditor.tsx +103 -160
- package/src/editor/editTarget.ts +41 -0
- package/src/editor/useClientDocs.ts +19 -0
- package/src/editor/useEditorSession.ts +36 -0
- package/src/editor/useFlash.ts +18 -0
- package/src/editor/useGhosts.ts +5 -7
- package/src/editor/usePageEvents.ts +13 -14
- package/src/editor-kit.ts +10 -6
- package/src/editors/CheckboxEditor.tsx +11 -12
- package/src/editors/ColorEditor.tsx +15 -35
- package/src/editors/DateEditor.tsx +18 -37
- package/src/editors/InlineText.tsx +4 -5
- package/src/editors/NumberEditor.tsx +15 -36
- package/src/editors/RelationshipEditor.tsx +18 -36
- package/src/editors/SelectEditor.tsx +14 -22
- package/src/editors/UploadEditor.tsx +6 -6
- package/src/editors/index.ts +56 -16
- package/src/editors/kit.tsx +97 -0
- package/src/editors/useDebouncedSearch.ts +18 -10
- package/src/geometry.ts +62 -0
- package/src/hub.ts +5 -5
- package/src/index.ts +5 -2
- package/src/layout.ts +5 -2
- package/src/locators.ts +11 -14
- package/src/messages.ts +26 -5
- package/src/registry.ts +42 -8
- package/src/rowOps.ts +64 -0
- package/src/sanitize.ts +6 -0
- package/src/settings.ts +49 -0
- package/src/styles.ts +5 -4
- package/src/targets.ts +1 -1
- package/src/types.ts +78 -45
- package/src/ui/BlockPicker.tsx +6 -7
- package/src/ui/Dialog.tsx +9 -5
- package/src/ui/Dock.tsx +67 -50
- package/src/ui/Overlay.tsx +75 -102
- package/src/ui/PreviewToolbar.tsx +7 -15
- package/src/ui/SettingsPanel.tsx +84 -81
- package/src/ui/ToolbarButton.tsx +36 -0
- package/src/useEvent.ts +4 -2
- package/src/useIsClient.ts +15 -0
package/dist/styles.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* The editor's own styles, injected once. Everything is prefixed `po-` and set
|
|
3
3
|
* explicitly, so the host site's CSS (and its absence) doesn't matter.
|
|
4
4
|
*/
|
|
5
|
+
import { DOM_ATTR } from "./dom.js";
|
|
5
6
|
export const PO_Z = 2147483000;
|
|
6
7
|
export const PO_CSS = `
|
|
7
8
|
.po-layer{position:fixed;inset:0;pointer-events:none;z-index:${PO_Z};font:13px/1.35 system-ui,-apple-system,"Segoe UI",sans-serif;color:#0f172a}
|
|
@@ -50,14 +51,14 @@ export const PO_CSS = `
|
|
|
50
51
|
.po-blocks{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:10px}
|
|
51
52
|
.po-blocks button{all:unset;padding:14px;border:1px solid #e2e8f0;border-radius:10px;cursor:pointer;font:600 13px system-ui,sans-serif}
|
|
52
53
|
.po-blocks button:hover,.po-blocks button:focus-visible{border-color:#4f7cff;background:#f5f8ff}
|
|
53
|
-
.po-dock{position:fixed;left:50%;bottom:16px;transform:translateX(-50%);display:flex;align-items:center;gap:4px;padding:6px;background:#0f172a;color:#fff;border-radius:12px;box-shadow:0 12px 40px #0f172a55;pointer-events:auto;max-width:calc(100vw - 24px);flex-wrap:wrap}
|
|
54
|
+
.po-dock{position:fixed;left:50%;width:max-content;bottom:16px;transform:translateX(-50%);display:flex;align-items:center;gap:4px;padding:6px;background:#0f172a;color:#fff;border-radius:12px;box-shadow:0 12px 40px #0f172a55;pointer-events:auto;max-width:calc(100vw - 24px);flex-wrap:wrap}
|
|
54
55
|
.po-dock .po-status{padding:0 10px;font-size:12px;opacity:.85;white-space:nowrap}
|
|
55
56
|
.po-dock .po-status.is-bad{color:#fca5a5;opacity:1}
|
|
56
57
|
.po-dock .po-sep{width:1px;height:20px;background:#ffffff26;margin:0 4px}
|
|
57
58
|
.po-dock .po-primary{background:#3b63e0}
|
|
58
59
|
.po-dock .po-primary:hover{background:#2f5bd9}
|
|
59
60
|
.po-chip-locale{padding:2px 7px;border-radius:999px;background:#ffffff1f;font-size:11px;font-weight:700;text-transform:uppercase}
|
|
60
|
-
.po-notice{position:fixed;left:50%;bottom:72px;transform:translateX(-50%);max-width:min(560px,calc(100vw - 24px));padding:8px 12px;border-radius:10px;background:#fffbeb;color:#78350f;border:1px solid #fcd34d;font-size:12px;pointer-events:auto}
|
|
61
|
+
.po-notice{position:fixed;left:50%;width:max-content;bottom:72px;transform:translateX(-50%);max-width:min(560px,calc(100vw - 24px));padding:8px 12px;border-radius:10px;background:#fffbeb;color:#78350f;border:1px solid #fcd34d;font-size:12px;pointer-events:auto}
|
|
61
62
|
.po-doc-layer{position:absolute;top:0;left:0;width:0;height:0;overflow:visible;z-index:${PO_Z};pointer-events:none;font:13px/1.35 system-ui,-apple-system,"Segoe UI",sans-serif}
|
|
62
63
|
.po-inline{position:absolute;pointer-events:auto;outline:2px solid #4f7cff;outline-offset:2px;border-radius:2px;background:transparent;white-space:pre-wrap;word-break:break-word;caret-color:currentColor;cursor:text}
|
|
63
64
|
.po-inline:focus{outline-color:#4f7cff}
|
|
@@ -80,7 +81,7 @@ export const PO_CSS = `
|
|
|
80
81
|
.po-opaque{display:inline-flex;align-items:center;gap:6px;margin:6px 0;padding:6px 10px;border:1px dashed #94a3b8;border-radius:8px;background:#f8fafc;color:#475569;font:12px system-ui,sans-serif;user-select:none}
|
|
81
82
|
html[data-onpage-editing] [data-onpage-field]{cursor:pointer}
|
|
82
83
|
[data-onpage-hidden="true"]{visibility:hidden!important}
|
|
83
|
-
.po-preview{position:fixed;left:50%;bottom:16px;transform:translateX(-50%);display:flex;align-items:center;gap:6px;padding:6px;background:#0f172a;color:#fff;border-radius:12px;box-shadow:0 12px 40px #0f172a55;pointer-events:auto;max-width:calc(100vw - 24px);flex-wrap:wrap}
|
|
84
|
+
.po-preview{position:fixed;left:50%;width:max-content;bottom:16px;transform:translateX(-50%);display:flex;align-items:center;gap:6px;padding:6px;background:#0f172a;color:#fff;border-radius:12px;box-shadow:0 12px 40px #0f172a55;pointer-events:auto;max-width:calc(100vw - 24px);flex-wrap:wrap}
|
|
84
85
|
.po-preview .po-status{padding:0 8px;font-size:12px;opacity:.85}
|
|
85
86
|
.po-rel-item{display:flex;align-items:center;gap:6px;padding:4px 6px;border-radius:6px;background:#f1f5f9;font-size:12px;margin:0 0 4px}
|
|
86
87
|
.po-rel-item button{all:unset;cursor:pointer;margin-left:auto;padding:0 4px;color:#64748b}
|
|
@@ -115,7 +116,7 @@ export function injectStyles() {
|
|
|
115
116
|
return;
|
|
116
117
|
injected = true;
|
|
117
118
|
const el = document.createElement('style');
|
|
118
|
-
el.setAttribute(
|
|
119
|
+
el.setAttribute(DOM_ATTR.styles, '');
|
|
119
120
|
el.textContent = PO_CSS;
|
|
120
121
|
document.head.appendChild(el);
|
|
121
122
|
}
|
package/dist/styles.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styles.js","sourceRoot":"","sources":["../src/styles.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,UAAU,CAAA;AAE9B,MAAM,CAAC,MAAM,MAAM,GAAG;+DACyC,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yFAsDsB,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkD5F,CAAA;AAED,IAAI,QAAQ,GAAG,KAAK,CAAA;AACpB,MAAM,UAAU,YAAY;IAC1B,IAAI,QAAQ,IAAI,OAAO,QAAQ,KAAK,WAAW;QAAE,OAAM;IACvD,QAAQ,GAAG,IAAI,CAAA;IACf,MAAM,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAA;IAC1C,EAAE,CAAC,YAAY,CAAC,
|
|
1
|
+
{"version":3,"file":"styles.js","sourceRoot":"","sources":["../src/styles.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AACnC,MAAM,CAAC,MAAM,IAAI,GAAG,UAAU,CAAA;AAE9B,MAAM,CAAC,MAAM,MAAM,GAAG;+DACyC,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yFAsDsB,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkD5F,CAAA;AAED,IAAI,QAAQ,GAAG,KAAK,CAAA;AACpB,MAAM,UAAU,YAAY;IAC1B,IAAI,QAAQ,IAAI,OAAO,QAAQ,KAAK,WAAW;QAAE,OAAM;IACvD,QAAQ,GAAG,IAAI,CAAA;IACf,MAAM,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAA;IAC1C,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IACpC,EAAE,CAAC,WAAW,GAAG,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;AAC/B,CAAC"}
|
package/dist/targets.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export declare const isRowTarget: (t: Target) => boolean;
|
|
|
11
11
|
export declare function buildIndex(all: Target[]): TargetIndex;
|
|
12
12
|
/** The innermost field target and all row targets (innermost first) at or above `el`. */
|
|
13
13
|
export declare function targetsAt(index: TargetIndex, el: Element | null): {
|
|
14
|
-
field?: Target;
|
|
14
|
+
field?: Target | undefined;
|
|
15
15
|
rows: Target[];
|
|
16
16
|
};
|
|
17
17
|
export declare function useTargets(locator: Locator, root: () => ParentNode | null): TargetIndex;
|
package/dist/targets.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"targets.d.ts","sourceRoot":"","sources":["../src/targets.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,OAAO,EAAa,KAAK,OAAO,EAAE,KAAK,MAAM,EAAmB,MAAM,sBAAsB,CAAA;AAI5F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAG7C,eAAO,MAAM,aAAa,GAAI,GAAG,MAAM,KAAG,OAAkC,CAAA;AAC5E,eAAO,MAAM,WAAW,GAAI,GAAG,MAAM,KAAG,OAA4B,CAAA;AAEpE,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,WAAW,CAoBrD;AAED,yFAAyF;AACzF,wBAAgB,SAAS,CACvB,KAAK,EAAE,WAAW,EAClB,EAAE,EAAE,OAAO,GAAG,IAAI,GACjB;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"targets.d.ts","sourceRoot":"","sources":["../src/targets.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,OAAO,EAAa,KAAK,OAAO,EAAE,KAAK,MAAM,EAAmB,MAAM,sBAAsB,CAAA;AAI5F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAG7C,eAAO,MAAM,aAAa,GAAI,GAAG,MAAM,KAAG,OAAkC,CAAA;AAC5E,eAAO,MAAM,WAAW,GAAI,GAAG,MAAM,KAAG,OAA4B,CAAA;AAEpE,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,WAAW,CAoBrD;AAED,yFAAyF;AACzF,wBAAgB,SAAS,CACvB,KAAK,EAAE,WAAW,EAClB,EAAE,EAAE,OAAO,GAAG,IAAI,GACjB;IAAE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAUhD;AAYD,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,GAAG,IAAI,GAAG,WAAW,CAkCvF"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,43 +1,47 @@
|
|
|
1
1
|
/** Public types of the editor UI. */
|
|
2
2
|
import type { ComponentType } from 'react';
|
|
3
|
-
import type { DocRef, EditorSession, MediaLibrary, Renderer, SchemaField, SessionSnapshot, Target, TargetKind } from '@payload-onpage/core';
|
|
4
|
-
import type {
|
|
3
|
+
import type { DocRef, EditorSession, MediaLibrary, Renderer, SchemaField, SchemaFieldType, SessionSnapshot, Target, TargetKind, RefKey } from '@payload-onpage/core';
|
|
4
|
+
import type { Translate } from './messages.ts';
|
|
5
5
|
export interface EditingState {
|
|
6
6
|
/** refKey of the document */
|
|
7
|
-
key:
|
|
7
|
+
key: RefKey;
|
|
8
8
|
path: string;
|
|
9
9
|
/** Editor id from the registry ("text", "richText", …). */
|
|
10
10
|
editor: string;
|
|
11
11
|
point?: {
|
|
12
12
|
x: number;
|
|
13
13
|
y: number;
|
|
14
|
-
};
|
|
14
|
+
} | undefined;
|
|
15
15
|
/** The element that was clicked (several elements may show one field). */
|
|
16
|
-
el?: Element;
|
|
16
|
+
el?: Element | undefined;
|
|
17
17
|
}
|
|
18
|
+
/** Which panel is open. */
|
|
18
19
|
export type Panel = {
|
|
19
20
|
kind: 'settings';
|
|
20
|
-
key:
|
|
21
|
+
key: RefKey;
|
|
21
22
|
path: string;
|
|
22
23
|
title: string;
|
|
23
24
|
} | {
|
|
24
25
|
kind: 'blocks';
|
|
25
|
-
key:
|
|
26
|
+
key: RefKey;
|
|
26
27
|
listPath: string;
|
|
27
28
|
index: number;
|
|
28
29
|
} | null;
|
|
29
30
|
export interface Selection {
|
|
30
|
-
key:
|
|
31
|
+
key: RefKey;
|
|
31
32
|
path: string;
|
|
32
33
|
}
|
|
33
|
-
/**
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Props a field editor receives. `F` is the field kind it edits (e.g.
|
|
36
|
+
* `NumberField`, with `min`/`max`) and `V` its value after `normalize`.
|
|
37
|
+
*/
|
|
38
|
+
export interface FieldEditorProps<F extends SchemaField = SchemaField, V = unknown> {
|
|
39
|
+
docKey: RefKey;
|
|
36
40
|
path: string;
|
|
37
|
-
field:
|
|
41
|
+
field: F;
|
|
38
42
|
/** The element showing the field (re-resolved after each refresh). */
|
|
39
43
|
element: () => Element | null;
|
|
40
|
-
value:
|
|
44
|
+
value: V;
|
|
41
45
|
/** Commit a value (one undo step, autosaved). */
|
|
42
46
|
commit: (value: unknown) => void;
|
|
43
47
|
/** Live preview while editing (no history entry, not saved). */
|
|
@@ -45,29 +49,36 @@ export interface FieldEditorProps {
|
|
|
45
49
|
/** Close the editor (after commit, or to cancel: transient previews are reverted). */
|
|
46
50
|
close: () => void;
|
|
47
51
|
/** Leave a stand-in showing the new content until the page re-renders (refresh mode). */
|
|
48
|
-
ghost: (g:
|
|
49
|
-
html: string;
|
|
50
|
-
className?: string;
|
|
51
|
-
style?: Partial<CSSStyleDeclaration>;
|
|
52
|
-
}) => void;
|
|
52
|
+
ghost: (g: GhostInput) => void;
|
|
53
53
|
/** True when the page renders this document from editor state (instant); false = server refresh. */
|
|
54
54
|
live: boolean;
|
|
55
55
|
point?: {
|
|
56
56
|
x: number;
|
|
57
57
|
y: number;
|
|
58
|
-
};
|
|
58
|
+
} | undefined;
|
|
59
59
|
/** UI strings. */
|
|
60
60
|
t: Translate;
|
|
61
61
|
}
|
|
62
|
+
/** What an editor leaves on the page until it re-renders. */
|
|
63
|
+
export interface GhostInput {
|
|
64
|
+
html: string;
|
|
65
|
+
className?: string | undefined;
|
|
66
|
+
style?: Partial<CSSStyleDeclaration> | undefined;
|
|
67
|
+
}
|
|
62
68
|
/**
|
|
63
69
|
* A field editor (the FieldEditor port). `inline` editors replace the element
|
|
64
70
|
* in place (text, rich text); `popover` editors open beside it or as a dialog
|
|
65
71
|
* (select, date, relationship, image…). Register your own by id and refer to it
|
|
66
72
|
* from a field with `admin: { custom: { onpage: { editor: 'my-id' } } }`, or by
|
|
67
|
-
* field type ("json", "code"…) to replace or add a default.
|
|
73
|
+
* field type ("json", "code"…) to replace or add a default. Build one with
|
|
74
|
+
* `defineEditor()` so its props are typed by the field kinds it accepts.
|
|
68
75
|
*/
|
|
69
76
|
export interface FieldEditorDef {
|
|
70
77
|
mode: 'inline' | 'popover';
|
|
78
|
+
/** Field types it can edit. The registry never hands it any other kind. Default: any. */
|
|
79
|
+
accepts?: readonly SchemaFieldType[];
|
|
80
|
+
/** The raw stored value → the editor's value. Default: passed through. */
|
|
81
|
+
normalize?: (raw: unknown, field: SchemaField) => unknown;
|
|
71
82
|
component: ComponentType<FieldEditorProps>;
|
|
72
83
|
}
|
|
73
84
|
export type EditorRegistry = Record<string, FieldEditorDef>;
|
|
@@ -81,51 +92,65 @@ export interface TargetIndex {
|
|
|
81
92
|
all: Target[];
|
|
82
93
|
/** Targets whose element is exactly `el`. */
|
|
83
94
|
at: (el: Element) => Target[];
|
|
84
|
-
find: (key:
|
|
95
|
+
find: (key: RefKey, path: string, kinds?: TargetKind[]) => Target | undefined;
|
|
96
|
+
}
|
|
97
|
+
/** A short message shown in the dock. */
|
|
98
|
+
export interface Flash {
|
|
99
|
+
text: string;
|
|
100
|
+
bad?: boolean | undefined;
|
|
85
101
|
}
|
|
86
|
-
/**
|
|
87
|
-
|
|
102
|
+
/**
|
|
103
|
+
* The editor's stable API: the session, configuration and actions. It changes
|
|
104
|
+
* only when the editor is reconfigured, so components that only act (toolbars,
|
|
105
|
+
* custom UI, client-mode documents) don't re-render on every keystroke.
|
|
106
|
+
*/
|
|
107
|
+
export interface OnPageApi {
|
|
88
108
|
session: EditorSession;
|
|
89
|
-
snap: SessionSnapshot;
|
|
90
109
|
renderer: Renderer;
|
|
91
|
-
media?: MediaLibrary;
|
|
110
|
+
media?: MediaLibrary | undefined;
|
|
92
111
|
editors: EditorRegistry;
|
|
93
|
-
targets: TargetIndex;
|
|
94
112
|
links: Links;
|
|
95
113
|
t: Translate;
|
|
96
|
-
panel: Panel;
|
|
97
114
|
setPanel: (p: Panel) => void;
|
|
98
|
-
editing: EditingState | null;
|
|
99
115
|
setEditing: (e: EditingState | null) => void;
|
|
100
|
-
selected: Selection | null;
|
|
101
116
|
setSelected: (s: Selection | null) => void;
|
|
102
|
-
/** Documents shown on the current page (the session may hold others from earlier pages). */
|
|
103
|
-
docKeys: string[];
|
|
104
117
|
/** Is this document rendered from session state (client mode)? */
|
|
105
|
-
isLive: (key:
|
|
118
|
+
isLive: (key: RefKey) => boolean;
|
|
106
119
|
/** Client-mode documents register here (they don't need a server refresh). */
|
|
107
|
-
registerClientDoc: (key:
|
|
108
|
-
/** The page is re-rendering after a save (refresh mode). */
|
|
109
|
-
rendering: boolean;
|
|
120
|
+
registerClientDoc: (key: RefKey) => () => void;
|
|
110
121
|
/** Open the right editor for a field (registry resolution); false if none applies. */
|
|
111
|
-
edit: (key:
|
|
122
|
+
edit: (key: RefKey, path: string, opts?: {
|
|
112
123
|
point?: {
|
|
113
124
|
x: number;
|
|
114
125
|
y: number;
|
|
115
|
-
};
|
|
116
|
-
kind?: TargetKind;
|
|
117
|
-
anchor?: Element;
|
|
126
|
+
} | undefined;
|
|
127
|
+
kind?: TargetKind | undefined;
|
|
128
|
+
anchor?: Element | undefined;
|
|
118
129
|
}) => boolean;
|
|
119
130
|
/** Re-render documents after an operation outside autosave (publish, reload). */
|
|
120
131
|
rerender: (refs: DocRef[]) => Promise<void>;
|
|
121
|
-
/** Show a short message in the dock. */
|
|
122
|
-
notify: (
|
|
123
|
-
addGhost: (g: {
|
|
124
|
-
key:
|
|
132
|
+
/** Show a short message in the dock: translated text (`notify(t('notify.published'))`), or an error's text. */
|
|
133
|
+
notify: (text: string, bad?: boolean) => void;
|
|
134
|
+
addGhost: (g: GhostInput & {
|
|
135
|
+
key: RefKey;
|
|
125
136
|
path: string;
|
|
126
|
-
html: string;
|
|
127
|
-
className?: string;
|
|
128
|
-
style?: Partial<CSSStyleDeclaration>;
|
|
129
137
|
}) => void;
|
|
130
138
|
}
|
|
139
|
+
/** What changes as people edit: the documents, what's on the page and what's open. */
|
|
140
|
+
export interface OnPageState {
|
|
141
|
+
snap: SessionSnapshot;
|
|
142
|
+
targets: TargetIndex;
|
|
143
|
+
panel: Panel;
|
|
144
|
+
editing: EditingState | null;
|
|
145
|
+
selected: Selection | null;
|
|
146
|
+
/** Documents shown on the current page (the session may hold others from earlier pages). */
|
|
147
|
+
docKeys: RefKey[];
|
|
148
|
+
/** The page is re-rendering after a save (refresh mode). */
|
|
149
|
+
rendering: boolean;
|
|
150
|
+
/** The dock's current message. */
|
|
151
|
+
flash: Flash | null;
|
|
152
|
+
}
|
|
153
|
+
/** Everything inside the editor (`useOnPage()`): its API and its state. */
|
|
154
|
+
export type OnPageContextValue = OnPageApi & OnPageState;
|
|
155
|
+
export type PanelKind = NonNullable<Panel>['kind'];
|
|
131
156
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAC1C,OAAO,KAAK,EACV,MAAM,EACN,aAAa,EACb,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,eAAe,EACf,MAAM,EACN,UAAU,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BlockPicker.d.ts","sourceRoot":"","sources":["../../src/ui/BlockPicker.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"BlockPicker.d.ts","sourceRoot":"","sources":["../../src/ui/BlockPicker.tsx"],"names":[],"mappings":"AAOA,qEAAqE;AACrE,wBAAgB,WAAW,uCAuC1B"}
|
package/dist/ui/BlockPicker.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import { fieldAtPath,
|
|
3
|
+
import { fieldAtPath, isReady, newBlockRow } from '@payload-onpage/core';
|
|
4
|
+
import { insertRow } from "../rowOps.js";
|
|
4
5
|
import { useOnPage } from "../context.js";
|
|
5
6
|
import { Dialog } from "./Dialog.js";
|
|
6
7
|
/** Choose a block type to insert at a position in a blocks field. */
|
|
@@ -9,18 +10,18 @@ export function BlockPicker() {
|
|
|
9
10
|
if (panel?.kind !== 'blocks')
|
|
10
11
|
return null;
|
|
11
12
|
const state = snap.docs[panel.key];
|
|
12
|
-
if (!state
|
|
13
|
+
if (!isReady(state))
|
|
13
14
|
return null;
|
|
14
15
|
const { key, listPath, index } = panel;
|
|
15
16
|
const field = fieldAtPath(state.schema.fields, state.doc, listPath)?.field;
|
|
16
|
-
const blocks = field?.type === 'blocks' ?
|
|
17
|
+
const blocks = field?.type === 'blocks' ? field.blocks : [];
|
|
17
18
|
const choose = (slug) => {
|
|
18
19
|
const block = blocks.find((b) => b.slug === slug);
|
|
19
20
|
if (!block)
|
|
20
21
|
return;
|
|
21
|
-
|
|
22
|
+
const next = insertRow(session, key, listPath, index, newBlockRow(block));
|
|
22
23
|
setPanel(null);
|
|
23
|
-
setSelected(
|
|
24
|
+
setSelected(next);
|
|
24
25
|
};
|
|
25
26
|
return (_jsx(Dialog, { title: t('blocks.title'), onClose: () => setPanel(null), t: t, width: 640, testId: "onpage-block-picker", children: _jsx("div", { className: "po-blocks", children: blocks.map((b) => (_jsx("button", { type: "button", onClick: () => choose(b.slug), "data-testid": `onpage-block-${b.slug}`, children: b.labels.singular }, b.slug))) }) }));
|
|
26
27
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BlockPicker.js","sourceRoot":"","sources":["../../src/ui/BlockPicker.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"BlockPicker.js","sourceRoot":"","sources":["../../src/ui/BlockPicker.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AACxE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,eAAgB,CAAA;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAc,CAAA;AAErC,qEAAqE;AACrE,MAAM,UAAU,WAAW;IACzB,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,EAAE,GAAG,SAAS,EAAE,CAAA;IACtE,IAAI,KAAK,EAAE,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAA;IACzC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAClC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAChC,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,KAAK,CAAA;IACtC,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,KAAK,CAAA;IAC1E,MAAM,MAAM,GAAG,KAAK,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAA;IAE3D,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,EAAE;QAC9B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;QACjD,IAAI,CAAC,KAAK;YAAE,OAAM;QAClB,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,CAAA;QACzE,QAAQ,CAAC,IAAI,CAAC,CAAA;QACd,WAAW,CAAC,IAAI,CAAC,CAAA;IACnB,CAAC,CAAA;IAED,OAAO,CACL,KAAC,MAAM,IACL,KAAK,EAAE,CAAC,CAAC,cAAc,CAAC,EACxB,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAC7B,CAAC,EAAE,CAAC,EACJ,KAAK,EAAE,GAAG,EACV,MAAM,EAAC,qBAAqB,YAE5B,cAAK,SAAS,EAAC,WAAW,YACvB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CACjB,iBAEE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,iBAChB,gBAAgB,CAAC,CAAC,IAAI,EAAE,YAEpC,CAAC,CAAC,MAAM,CAAC,QAAQ,IALb,CAAC,CAAC,IAAI,CAMJ,CACV,CAAC,GACE,GACC,CACV,CAAA;AACH,CAAC"}
|
package/dist/ui/Dialog.d.ts
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The one dialog primitive: labelled, focus moves in on open and back on
|
|
3
|
-
* close, Tab stays inside (modal), Escape closes. `variant="popover"` is
|
|
4
|
-
* anchored next to an element and closes on an outside click.
|
|
5
|
-
*/
|
|
6
1
|
import { type ReactNode } from 'react';
|
|
7
2
|
import type { Translate } from '../messages.ts';
|
|
8
3
|
export interface DialogProps {
|
package/dist/ui/Dialog.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dialog.d.ts","sourceRoot":"","sources":["../../src/ui/Dialog.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Dialog.d.ts","sourceRoot":"","sources":["../../src/ui/Dialog.tsx"],"names":[],"mappings":"AAQA,OAAO,EAA0D,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAG9F,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE/C,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,QAAQ,EAAE,SAAS,CAAA;IACnB,CAAC,EAAE,SAAS,CAAA;IACZ,2FAA2F;IAC3F,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,CAAA;IACvC,MAAM,CAAC,EAAE,MAAM,OAAO,GAAG,IAAI,CAAA;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,kDAAkD;IAClD,OAAO,CAAC,EAAE,SAAS,CAAA;CACpB;AAED,wBAAgB,MAAM,CAAC,EACrB,KAAK,EACL,OAAO,EACP,QAAQ,EACR,CAAC,EACD,OAAiB,EACjB,MAAM,EACN,KAAK,EACL,MAAM,EACN,OAAO,GACR,EAAE,WAAW,+BA6Hb"}
|
package/dist/ui/Dialog.js
CHANGED
|
@@ -5,6 +5,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
5
5
|
* close, Tab stays inside (modal), Escape closes. `variant="popover"` is
|
|
6
6
|
* anchored next to an element and closes on an outside click.
|
|
7
7
|
*/
|
|
8
|
+
import { useEvent } from "../useEvent.js";
|
|
8
9
|
import { useEffect, useId, useRef, useState } from 'react';
|
|
9
10
|
import { focusableIn, popoverPosition } from "../dom.js";
|
|
10
11
|
import { useLayoutTick } from "../layout.js";
|
|
@@ -32,20 +33,23 @@ export function Dialog({ title, onClose, children, t, variant = 'modal', anchor,
|
|
|
32
33
|
ro.observe(el);
|
|
33
34
|
return () => ro.disconnect();
|
|
34
35
|
}, [variant]);
|
|
36
|
+
// Stable, so the listeners below aren't re-bound on every render (callers pass inline
|
|
37
|
+
// closures); a re-bind would also re-open the deferral gap where an outside click is lost.
|
|
38
|
+
const close = useEvent(onClose);
|
|
35
39
|
useEffect(() => {
|
|
36
40
|
const onKey = (e) => {
|
|
37
41
|
if (e.key === 'Escape') {
|
|
38
42
|
e.stopPropagation();
|
|
39
|
-
|
|
43
|
+
close();
|
|
40
44
|
return;
|
|
41
45
|
}
|
|
42
46
|
if (e.key !== 'Tab' || variant !== 'modal' || !box.current)
|
|
43
47
|
return;
|
|
44
48
|
const items = focusableIn(box.current);
|
|
45
|
-
if (!items.length)
|
|
46
|
-
return;
|
|
47
49
|
const first = items[0];
|
|
48
|
-
const last = items
|
|
50
|
+
const last = items.at(-1);
|
|
51
|
+
if (!first || !last)
|
|
52
|
+
return;
|
|
49
53
|
if (e.shiftKey && document.activeElement === first) {
|
|
50
54
|
e.preventDefault();
|
|
51
55
|
last.focus();
|
|
@@ -57,7 +61,7 @@ export function Dialog({ title, onClose, children, t, variant = 'modal', anchor,
|
|
|
57
61
|
};
|
|
58
62
|
const onDown = (e) => {
|
|
59
63
|
if (variant === 'popover' && box.current && !box.current.contains(e.target))
|
|
60
|
-
|
|
64
|
+
close();
|
|
61
65
|
};
|
|
62
66
|
document.addEventListener('keydown', onKey, true);
|
|
63
67
|
// Deferred, so the click that opened a popover doesn't close it.
|
|
@@ -67,7 +71,7 @@ export function Dialog({ title, onClose, children, t, variant = 'modal', anchor,
|
|
|
67
71
|
document.removeEventListener('keydown', onKey, true);
|
|
68
72
|
document.removeEventListener('pointerdown', onDown, true);
|
|
69
73
|
};
|
|
70
|
-
}, [
|
|
74
|
+
}, [close, variant]);
|
|
71
75
|
const header = (_jsxs("header", { className: "po-dialog-head", children: [_jsx("h2", { className: "po-h3", id: titleId, children: title }), actions, _jsx("button", { type: "button", className: "po-btn po-close", onClick: onClose, "aria-label": t('common.close'), children: "\u2715" })] }));
|
|
72
76
|
if (variant === 'modal') {
|
|
73
77
|
return (_jsx("div", { className: "po-modal-bg", onPointerDown: (e) => e.target === e.currentTarget && onClose(), "data-testid": testId, children: _jsxs("div", { ref: box, className: "po-modal", role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, tabIndex: -1, style: width ? { width: `min(${width}px, 100%)` } : undefined, children: [header, _jsx("div", { className: "po-body", children: children })] }) }));
|
package/dist/ui/Dialog.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dialog.js","sourceRoot":"","sources":["../../src/ui/Dialog.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ;;;;GAIG;AACH,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAsC,MAAM,OAAO,CAAA;AAC9F,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAiB5C,MAAM,UAAU,MAAM,CAAC,EACrB,KAAK,EACL,OAAO,EACP,QAAQ,EACR,CAAC,EACD,OAAO,GAAG,OAAO,EACjB,MAAM,EACN,KAAK,EACL,MAAM,EACN,OAAO,GACK;IACZ,MAAM,GAAG,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAA;IACxC,MAAM,OAAO,GAAG,KAAK,EAAE,CAAA;IACvB,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAA;IACzC,aAAa,EAAE,CAAA,CAAC,+BAA+B;IAE/C,mCAAmC;IACnC,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAmC,CAAA;QAC7D,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAA;QACtB,IAAI,EAAE;YACJ,CACE,EAAE,CAAC,aAAa,CAAc,8BAA8B,CAAC;gBAC7D,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;gBAClB,EAAE,CACH,CAAC,KAAK,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAA;QAClC,OAAO,GAAG,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAA;IACzD,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,mFAAmF;IACnF,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAA;QACtB,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,EAAE;YAAE,OAAM;QACxC,MAAM,EAAE,GAAG,IAAI,cAAc,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAA;QAC/D,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QACd,OAAO,GAAG,EAAE,CAAC,EAAE,CAAC,UAAU,EAAE,CAAA;IAC9B,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAA;IAEb,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,KAAK,GAAG,CAAC,CAAgB,EAAE,EAAE;YACjC,IAAI,CAAC,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;gBACvB,CAAC,CAAC,eAAe,EAAE,CAAA;gBACnB,
|
|
1
|
+
{"version":3,"file":"Dialog.js","sourceRoot":"","sources":["../../src/ui/Dialog.tsx"],"names":[],"mappings":"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"}
|
package/dist/ui/Dock.d.ts
CHANGED
package/dist/ui/Dock.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dock.d.ts","sourceRoot":"","sources":["../../src/ui/Dock.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Dock.d.ts","sourceRoot":"","sources":["../../src/ui/Dock.tsx"],"names":[],"mappings":"AA0DA,wBAAgB,IAAI,gCAsMnB"}
|
package/dist/ui/Dock.js
CHANGED
|
@@ -1,10 +1,43 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* The bottom bar: save status across the page's documents (with per-document
|
|
5
|
+
* recovery: reload after a conflict, retry after an error), undo/redo, locale,
|
|
6
|
+
* share link, preview, discard, admin, exit and publish.
|
|
7
|
+
*/
|
|
8
|
+
import { errorText } from '@payload-onpage/core';
|
|
3
9
|
import { useEffect, useState } from 'react';
|
|
4
10
|
import { useOnPage } from "../context.js";
|
|
5
11
|
import { relativeTime } from "../messages.js";
|
|
6
12
|
import { PostButton } from "./PostButton.js";
|
|
13
|
+
import { ToolbarButton } from "./ToolbarButton.js";
|
|
7
14
|
const title = (d) => d.schema?.labels.singular ?? d.ref.slug;
|
|
15
|
+
/** What the dock says, most urgent first. */
|
|
16
|
+
function dockStatus(s, t) {
|
|
17
|
+
if (s.failed)
|
|
18
|
+
return {
|
|
19
|
+
text: t('dock.unavailable', { doc: title(s.failed), error: s.failed.error ?? '' }),
|
|
20
|
+
bad: true,
|
|
21
|
+
};
|
|
22
|
+
if (!s.docs.length)
|
|
23
|
+
return { text: t('dock.nothing') };
|
|
24
|
+
if (!s.ready.length)
|
|
25
|
+
return { text: t('dock.loading') };
|
|
26
|
+
if (s.conflict)
|
|
27
|
+
return { text: t('dock.conflict', { doc: title(s.conflict) }), bad: true };
|
|
28
|
+
if (s.error)
|
|
29
|
+
return {
|
|
30
|
+
text: t('dock.saveFailed', { doc: title(s.error), message: s.error.save.message ?? '' }),
|
|
31
|
+
bad: true,
|
|
32
|
+
};
|
|
33
|
+
if (s.saving)
|
|
34
|
+
return { text: t('dock.saving') };
|
|
35
|
+
if (s.rendering)
|
|
36
|
+
return { text: t('dock.updating') };
|
|
37
|
+
if (s.lastSaved)
|
|
38
|
+
return { text: t('dock.saved', { ago: relativeTime(s.lastSaved) }) };
|
|
39
|
+
return { text: t('dock.editing') };
|
|
40
|
+
}
|
|
8
41
|
function useTicker(ms) {
|
|
9
42
|
const [, setN] = useState(0);
|
|
10
43
|
useEffect(() => {
|
|
@@ -12,8 +45,8 @@ function useTicker(ms) {
|
|
|
12
45
|
return () => clearInterval(id);
|
|
13
46
|
}, [ms]);
|
|
14
47
|
}
|
|
15
|
-
export function Dock(
|
|
16
|
-
const { session, snap, links, rendering, notify, rerender, docKeys, t } = useOnPage();
|
|
48
|
+
export function Dock() {
|
|
49
|
+
const { session, snap, links, rendering, notify, rerender, docKeys, flash, t } = useOnPage();
|
|
17
50
|
const [confirmDiscard, setConfirmDiscard] = useState(false);
|
|
18
51
|
useTicker(5000);
|
|
19
52
|
useEffect(() => {
|
|
@@ -31,23 +64,8 @@ export function Dock({ flash }) {
|
|
|
31
64
|
const lastSaved = Math.max(0, ...docs.map((d) => d.save.lastSavedAt ?? 0));
|
|
32
65
|
const primary = docs[0];
|
|
33
66
|
const busy = snap.busy;
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
: !docs.length
|
|
37
|
-
? { text: t('dock.nothing') }
|
|
38
|
-
: !ready.length
|
|
39
|
-
? { text: t('dock.loading') }
|
|
40
|
-
: conflict
|
|
41
|
-
? { text: t('dock.conflict', { doc: title(conflict) }), bad: true }
|
|
42
|
-
: error
|
|
43
|
-
? { text: `${title(error)}: ${error.save.message ?? ''}`, bad: true }
|
|
44
|
-
: saving
|
|
45
|
-
? { text: t('dock.saving') }
|
|
46
|
-
: rendering
|
|
47
|
-
? { text: t('dock.updating') }
|
|
48
|
-
: lastSaved
|
|
49
|
-
? { text: t('dock.saved', { ago: relativeTime(lastSaved) }) }
|
|
50
|
-
: { text: t('dock.editing') };
|
|
67
|
+
const retryable = failed ?? error;
|
|
68
|
+
const status = dockStatus({ docs, ready, failed, conflict, error, saving, rendering, lastSaved }, t);
|
|
51
69
|
const schema = ready[0]?.schema;
|
|
52
70
|
const nonDefaultLocale = schema?.defaultLocale && session.locale && session.locale !== schema.defaultLocale;
|
|
53
71
|
const publish = async () => {
|
|
@@ -56,12 +74,12 @@ export function Dock({ flash }) {
|
|
|
56
74
|
if (res.published.length)
|
|
57
75
|
await rerender(res.published);
|
|
58
76
|
if (res.ok)
|
|
59
|
-
notify(res.published.length ? 'notify.published' : 'notify.nothingToPublish');
|
|
77
|
+
notify(t(res.published.length ? 'notify.published' : 'notify.nothingToPublish'));
|
|
60
78
|
else
|
|
61
|
-
notify('notify.publishFailed', { message: res.message ?? '' }, true);
|
|
79
|
+
notify(t('notify.publishFailed', { message: res.message ?? '' }), true);
|
|
62
80
|
}
|
|
63
81
|
catch (e) {
|
|
64
|
-
notify('notify.publishFailed', { message: e
|
|
82
|
+
notify(t('notify.publishFailed', { message: errorText(e) }), true);
|
|
65
83
|
}
|
|
66
84
|
};
|
|
67
85
|
const discard = async () => {
|
|
@@ -71,10 +89,10 @@ export function Dock({ flash }) {
|
|
|
71
89
|
setConfirmDiscard(false);
|
|
72
90
|
try {
|
|
73
91
|
await session.discard({ keys: docKeys });
|
|
74
|
-
notify('notify.discarded');
|
|
92
|
+
notify(t('notify.discarded'));
|
|
75
93
|
}
|
|
76
94
|
catch (e) {
|
|
77
|
-
notify(e
|
|
95
|
+
notify(errorText(e), true);
|
|
78
96
|
}
|
|
79
97
|
};
|
|
80
98
|
const reload = async (d) => {
|
|
@@ -83,7 +101,7 @@ export function Dock({ flash }) {
|
|
|
83
101
|
await rerender([d.ref]);
|
|
84
102
|
}
|
|
85
103
|
catch (e) {
|
|
86
|
-
notify(e
|
|
104
|
+
notify(errorText(e), true);
|
|
87
105
|
}
|
|
88
106
|
};
|
|
89
107
|
const createLink = session.dataSource.createPreviewLink?.bind(session.dataSource);
|
|
@@ -93,12 +111,12 @@ export function Dock({ flash }) {
|
|
|
93
111
|
try {
|
|
94
112
|
const { url, expiresAt } = await createLink(primary.ref, { locale: session.locale });
|
|
95
113
|
await navigator.clipboard.writeText(url);
|
|
96
|
-
notify('notify.linkCopied', { date: new Date(expiresAt).toLocaleString() });
|
|
114
|
+
notify(t('notify.linkCopied', { date: new Date(expiresAt).toLocaleString() }));
|
|
97
115
|
}
|
|
98
116
|
catch (e) {
|
|
99
|
-
notify('notify.linkFailed', { message: e
|
|
117
|
+
notify(t('notify.linkFailed', { message: errorText(e) }), true);
|
|
100
118
|
}
|
|
101
119
|
};
|
|
102
|
-
return (_jsxs(_Fragment, { children: [nonDefaultLocale && (_jsx("div", { className: "po-notice", role: "note", "data-testid": "onpage-locale-notice", children: t('dock.localeNotice', { locale: session.locale ?? '' }) })), _jsxs("div", { className: "po-dock", role: "toolbar", "aria-label": t('dock.label'), "data-testid": "onpage-dock", children: [_jsx("span", { className: `po-status${(flash?.bad ?? status.bad) ? ' is-bad' : ''}`, role: "status", "aria-live": "polite", "data-testid": "onpage-status", children: flash?.text ?? status.text }), conflict && (_jsx("button", { type: "button", className: "po-btn", disabled: busy, onClick: () => void reload(conflict), "data-testid": "onpage-reload", children: t('dock.reload') })),
|
|
120
|
+
return (_jsxs(_Fragment, { children: [nonDefaultLocale && (_jsx("div", { className: "po-notice", role: "note", "data-testid": "onpage-locale-notice", children: t('dock.localeNotice', { locale: session.locale ?? '' }) })), _jsxs("div", { className: "po-dock", role: "toolbar", "aria-label": t('dock.label'), "data-testid": "onpage-dock", children: [_jsx("span", { className: `po-status${(flash?.bad ?? status.bad) ? ' is-bad' : ''}`, role: "status", "aria-live": "polite", "data-testid": "onpage-status", children: flash?.text ?? status.text }), conflict && (_jsx("button", { type: "button", className: "po-btn", disabled: busy, onClick: () => void reload(conflict), "data-testid": "onpage-reload", children: t('dock.reload') })), retryable && (_jsx("button", { type: "button", className: "po-btn", onClick: () => void session.retry(retryable.key), "data-testid": "onpage-retry", children: t('dock.retry') })), docs.length > 1 && (_jsx("span", { className: "po-docs", title: docs.map(title).join(', '), "data-testid": "onpage-doc-count", children: t('dock.documents', { count: docs.length }) })), session.locale && _jsx("span", { className: "po-chip-locale", children: session.locale }), _jsx("span", { className: "po-sep" }), _jsx(ToolbarButton, { label: t('dock.undo'), hint: `${t('dock.undo')} (⌘Z)`, icon: "\u21B6", disabled: !snap.canUndo, onClick: () => session.undo(), testId: "onpage-undo" }), _jsx(ToolbarButton, { label: t('dock.redo'), hint: `${t('dock.redo')} (⇧⌘Z)`, icon: "\u21B7", disabled: !snap.canRedo, onClick: () => session.redo(), testId: "onpage-redo" }), _jsx("span", { className: "po-sep" }), links.mode && (_jsx(PostButton, { action: links.mode('view'), title: t('dock.previewHint'), testId: "onpage-preview", children: t('dock.preview') })), createLink && primary && (_jsx("button", { type: "button", className: "po-btn", onClick: () => void share(), title: t('dock.shareHint'), "data-testid": "onpage-share", children: t('dock.share') })), _jsx("button", { type: "button", className: `po-btn${confirmDiscard ? ' is-danger' : ''}`, disabled: !ready.length || busy, onClick: () => void discard(), onBlur: () => setConfirmDiscard(false), title: t('dock.discardHint'), "data-testid": "onpage-discard", children: t(confirmDiscard ? 'dock.discardConfirm' : 'dock.discard') }), links.admin && primary && (_jsx("a", { className: "po-btn", href: links.admin(primary.ref), target: "_blank", rel: "noopener noreferrer", "data-testid": "onpage-open-admin", children: t('dock.admin') })), _jsx(PostButton, { action: links.exit, testId: "onpage-exit", children: t('dock.exit') }), _jsx("button", { type: "button", className: "po-btn po-primary", disabled: !ready.length || busy || !!conflict, onClick: () => void publish(), "data-testid": "onpage-publish", children: t(busy ? 'dock.publishing' : 'dock.publish') })] })] }));
|
|
103
121
|
}
|
|
104
122
|
//# sourceMappingURL=Dock.js.map
|