payload-better-editor 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +57 -0
- package/dist/admin/ErrorBoundary.d.ts +17 -0
- package/dist/admin/ErrorBoundary.js +62 -0
- package/dist/admin/ErrorBoundary.js.map +1 -0
- package/dist/admin/LiveEditorOverlay.d.ts +12 -0
- package/dist/admin/LiveEditorOverlay.js +160 -0
- package/dist/admin/LiveEditorOverlay.js.map +1 -0
- package/dist/admin/LiveEditorToggle.d.ts +7 -0
- package/dist/admin/LiveEditorToggle.js +84 -0
- package/dist/admin/LiveEditorToggle.js.map +1 -0
- package/dist/admin/PreviewFrame.d.ts +22 -0
- package/dist/admin/PreviewFrame.js +137 -0
- package/dist/admin/PreviewFrame.js.map +1 -0
- package/dist/admin/PreviewToolbar.d.ts +16 -0
- package/dist/admin/PreviewToolbar.js +90 -0
- package/dist/admin/PreviewToolbar.js.map +1 -0
- package/dist/admin/SettingsBanner.d.ts +3 -0
- package/dist/admin/SettingsBanner.js +105 -0
- package/dist/admin/SettingsBanner.js.map +1 -0
- package/dist/admin/ViewportToggle.d.ts +7 -0
- package/dist/admin/ViewportToggle.js +79 -0
- package/dist/admin/ViewportToggle.js.map +1 -0
- package/dist/admin/blocks/AddBlockDrawer.d.ts +9 -0
- package/dist/admin/blocks/AddBlockDrawer.js +16 -0
- package/dist/admin/blocks/AddBlockDrawer.js.map +1 -0
- package/dist/admin/blocks/BlockActionsToolbar.d.ts +15 -0
- package/dist/admin/blocks/BlockActionsToolbar.js +102 -0
- package/dist/admin/blocks/BlockActionsToolbar.js.map +1 -0
- package/dist/admin/blocks/BlockEmptyState.d.ts +6 -0
- package/dist/admin/blocks/BlockEmptyState.js +26 -0
- package/dist/admin/blocks/BlockEmptyState.js.map +1 -0
- package/dist/admin/blocks/BlockHeader.d.ts +7 -0
- package/dist/admin/blocks/BlockHeader.js +32 -0
- package/dist/admin/blocks/BlockHeader.js.map +1 -0
- package/dist/admin/blocks/schema.d.ts +19 -0
- package/dist/admin/blocks/schema.js +80 -0
- package/dist/admin/blocks/schema.js.map +1 -0
- package/dist/admin/blocks/useBlockActions.d.ts +24 -0
- package/dist/admin/blocks/useBlockActions.js +100 -0
- package/dist/admin/blocks/useBlockActions.js.map +1 -0
- package/dist/admin/icons.d.ts +24 -0
- package/dist/admin/icons.js +36 -0
- package/dist/admin/icons.js.map +1 -0
- package/dist/admin/sidebar/BlockSettingsTab.d.ts +10 -0
- package/dist/admin/sidebar/BlockSettingsTab.js +153 -0
- package/dist/admin/sidebar/BlockSettingsTab.js.map +1 -0
- package/dist/admin/sidebar/DocumentFieldsTab.d.ts +8 -0
- package/dist/admin/sidebar/DocumentFieldsTab.js +38 -0
- package/dist/admin/sidebar/DocumentFieldsTab.js.map +1 -0
- package/dist/admin/sidebar/DocumentMetaTab.d.ts +2 -0
- package/dist/admin/sidebar/DocumentMetaTab.js +11 -0
- package/dist/admin/sidebar/DocumentMetaTab.js.map +1 -0
- package/dist/admin/sidebar/DocumentSettingsTab.d.ts +2 -0
- package/dist/admin/sidebar/DocumentSettingsTab.js +48 -0
- package/dist/admin/sidebar/DocumentSettingsTab.js.map +1 -0
- package/dist/admin/sidebar/Sidebar.d.ts +10 -0
- package/dist/admin/sidebar/Sidebar.js +92 -0
- package/dist/admin/sidebar/Sidebar.js.map +1 -0
- package/dist/client.d.ts +34 -0
- package/dist/client.js +30 -0
- package/dist/client.js.map +1 -0
- package/dist/global.d.ts +4 -0
- package/dist/global.js +200 -0
- package/dist/global.js.map +1 -0
- package/dist/hooks/useAddBlockDrawer.d.ts +14 -0
- package/dist/hooks/useAddBlockDrawer.js +26 -0
- package/dist/hooks/useAddBlockDrawer.js.map +1 -0
- package/dist/hooks/useBlockActionMessages.d.ts +8 -0
- package/dist/hooks/useBlockActionMessages.js +107 -0
- package/dist/hooks/useBlockActionMessages.js.map +1 -0
- package/dist/hooks/useDocConfig.d.ts +6 -0
- package/dist/hooks/useDocConfig.js +18 -0
- package/dist/hooks/useDocConfig.js.map +1 -0
- package/dist/hooks/useFocusTrap.d.ts +2 -0
- package/dist/hooks/useFocusTrap.js +84 -0
- package/dist/hooks/useFocusTrap.js.map +1 -0
- package/dist/hooks/useFullscreenOverlay.d.ts +2 -0
- package/dist/hooks/useFullscreenOverlay.js +30 -0
- package/dist/hooks/useFullscreenOverlay.js.map +1 -0
- package/dist/hooks/useIframeResizeObserver.d.ts +2 -0
- package/dist/hooks/useIframeResizeObserver.js +20 -0
- package/dist/hooks/useIframeResizeObserver.js.map +1 -0
- package/dist/hooks/useLatestRef.d.ts +6 -0
- package/dist/hooks/useLatestRef.js +12 -0
- package/dist/hooks/useLatestRef.js.map +1 -0
- package/dist/hooks/useMainWrapperPortal.d.ts +1 -0
- package/dist/hooks/useMainWrapperPortal.js +64 -0
- package/dist/hooks/useMainWrapperPortal.js.map +1 -0
- package/dist/hooks/useOverlayKeyboard.d.ts +6 -0
- package/dist/hooks/useOverlayKeyboard.js +43 -0
- package/dist/hooks/useOverlayKeyboard.js.map +1 -0
- package/dist/hooks/usePreviewBinding.d.ts +28 -0
- package/dist/hooks/usePreviewBinding.js +108 -0
- package/dist/hooks/usePreviewBinding.js.map +1 -0
- package/dist/hooks/usePreviewHandleDrag.d.ts +11 -0
- package/dist/hooks/usePreviewHandleDrag.js +53 -0
- package/dist/hooks/usePreviewHandleDrag.js.map +1 -0
- package/dist/hooks/usePreviewSelectionSync.d.ts +15 -0
- package/dist/hooks/usePreviewSelectionSync.js +80 -0
- package/dist/hooks/usePreviewSelectionSync.js.map +1 -0
- package/dist/hooks/usePreviewSettingsSync.d.ts +17 -0
- package/dist/hooks/usePreviewSettingsSync.js +55 -0
- package/dist/hooks/usePreviewSettingsSync.js.map +1 -0
- package/dist/hooks/useSidebarResize.d.ts +8 -0
- package/dist/hooks/useSidebarResize.js +101 -0
- package/dist/hooks/useSidebarResize.js.map +1 -0
- package/dist/hooks/useViewportState.d.ts +10 -0
- package/dist/hooks/useViewportState.js +44 -0
- package/dist/hooks/useViewportState.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +104 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/constants.d.ts +22 -0
- package/dist/internal/constants.js +38 -0
- package/dist/internal/constants.js.map +1 -0
- package/dist/internal/dom.d.ts +4 -0
- package/dist/internal/dom.js +6 -0
- package/dist/internal/dom.js.map +1 -0
- package/dist/internal/iframe.d.ts +5 -0
- package/dist/internal/iframe.js +12 -0
- package/dist/internal/iframe.js.map +1 -0
- package/dist/internal/limits.d.ts +9 -0
- package/dist/internal/limits.js +11 -0
- package/dist/internal/limits.js.map +1 -0
- package/dist/internal/path.d.ts +5 -0
- package/dist/internal/path.js +12 -0
- package/dist/internal/path.js.map +1 -0
- package/dist/internal/postmessage.d.ts +3 -0
- package/dist/internal/postmessage.js +21 -0
- package/dist/internal/postmessage.js.map +1 -0
- package/dist/internal/storage-keys.d.ts +8 -0
- package/dist/internal/storage-keys.js +9 -0
- package/dist/internal/storage-keys.js.map +1 -0
- package/dist/internal/storage.d.ts +2 -0
- package/dist/internal/storage.js +20 -0
- package/dist/internal/storage.js.map +1 -0
- package/dist/preview/HoverToolbar.d.ts +8 -0
- package/dist/preview/HoverToolbar.js +48 -0
- package/dist/preview/HoverToolbar.js.map +1 -0
- package/dist/preview/HoverToolbarController.d.ts +31 -0
- package/dist/preview/HoverToolbarController.js +160 -0
- package/dist/preview/HoverToolbarController.js.map +1 -0
- package/dist/preview/hover-css.d.ts +11 -0
- package/dist/preview/hover-css.js +94 -0
- package/dist/preview/hover-css.js.map +1 -0
- package/dist/preview/installClickToFocus.d.ts +6 -0
- package/dist/preview/installClickToFocus.js +21 -0
- package/dist/preview/installClickToFocus.js.map +1 -0
- package/dist/preview/installHoverStyles.d.ts +2 -0
- package/dist/preview/installHoverStyles.js +15 -0
- package/dist/preview/installHoverStyles.js.map +1 -0
- package/dist/preview/protocol.d.ts +11 -0
- package/dist/preview/protocol.js +19 -0
- package/dist/preview/protocol.js.map +1 -0
- package/dist/preview/toolbar-position.d.ts +20 -0
- package/dist/preview/toolbar-position.js +22 -0
- package/dist/preview/toolbar-position.js.map +1 -0
- package/dist/providers/BetterEditorConfigProvider.d.ts +14 -0
- package/dist/providers/BetterEditorConfigProvider.js +26 -0
- package/dist/providers/BetterEditorConfigProvider.js.map +1 -0
- package/dist/providers/OverlayProviders.d.ts +8 -0
- package/dist/providers/OverlayProviders.js +22 -0
- package/dist/providers/OverlayProviders.js.map +1 -0
- package/dist/state/useBetterEditorSettings.d.ts +18 -0
- package/dist/state/useBetterEditorSettings.js +65 -0
- package/dist/state/useBetterEditorSettings.js.map +1 -0
- package/dist/state/useEditorHistory.d.ts +16 -0
- package/dist/state/useEditorHistory.js +157 -0
- package/dist/state/useEditorHistory.js.map +1 -0
- package/dist/styles/blocks-tab.css +163 -0
- package/dist/styles/overlay.css +133 -0
- package/dist/styles/preview.css +211 -0
- package/dist/styles/settings-banner.css +73 -0
- package/dist/styles/sidebar.css +88 -0
- package/dist/types.d.ts +41 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +6 -0
- package/dist/version.js.map +1 -0
- package/package.json +117 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/* Blocks tab — header (kicker / heading / path / Deselect),
|
|
2
|
+
action toolbar, dividers, Block Name input, empty-state CTA. */
|
|
3
|
+
|
|
4
|
+
.better-editor-tab__header {
|
|
5
|
+
display: flex;
|
|
6
|
+
align-items: flex-start;
|
|
7
|
+
justify-content: space-between;
|
|
8
|
+
gap: 12px;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.better-editor-tab__kicker {
|
|
12
|
+
display: block;
|
|
13
|
+
font-size: 11px;
|
|
14
|
+
font-weight: 600;
|
|
15
|
+
text-transform: uppercase;
|
|
16
|
+
letter-spacing: 0.06em;
|
|
17
|
+
color: var(--theme-elevation-500);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.better-editor-tab__heading {
|
|
21
|
+
margin: 2px 0 4px;
|
|
22
|
+
font-size: 16px;
|
|
23
|
+
font-weight: 600;
|
|
24
|
+
line-height: 1.2;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.better-editor-tab__path {
|
|
28
|
+
font-family: var(--font-mono, ui-monospace, monospace);
|
|
29
|
+
font-size: 11px;
|
|
30
|
+
color: var(--theme-elevation-500);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.better-editor-tab__clear {
|
|
34
|
+
flex-shrink: 0;
|
|
35
|
+
padding: 6px 10px;
|
|
36
|
+
border: 1px solid var(--theme-elevation-150);
|
|
37
|
+
border-radius: 4px;
|
|
38
|
+
background: transparent;
|
|
39
|
+
color: inherit;
|
|
40
|
+
font: inherit;
|
|
41
|
+
font-size: 12px;
|
|
42
|
+
cursor: pointer;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.better-editor-tab__clear:hover {
|
|
46
|
+
background: var(--theme-elevation-100);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/* Visual break between the block-tab header (kicker / heading / actions /
|
|
50
|
+
block-name) and the block's own field tabs (Content / Row Settings / …)
|
|
51
|
+
so the structural shift is obvious. Symmetric vertical margin — the
|
|
52
|
+
render-fields rule (in sidebar.css) has its own 16px margin-top, which
|
|
53
|
+
collapses into the divider's 20px so the gap looks the same on both sides. */
|
|
54
|
+
.better-editor-tab__divider {
|
|
55
|
+
margin: 20px 0;
|
|
56
|
+
border: 0;
|
|
57
|
+
border-top: 1px solid var(--theme-elevation-150);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* Block Name input */
|
|
61
|
+
|
|
62
|
+
.better-editor-tab__block-name {
|
|
63
|
+
display: flex;
|
|
64
|
+
flex-direction: column;
|
|
65
|
+
gap: 4px;
|
|
66
|
+
margin-top: 12px;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.better-editor-tab__block-name-label {
|
|
70
|
+
font-size: 11px;
|
|
71
|
+
font-weight: 600;
|
|
72
|
+
text-transform: uppercase;
|
|
73
|
+
letter-spacing: 0.06em;
|
|
74
|
+
color: var(--theme-elevation-500);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.better-editor-tab__block-name-input {
|
|
78
|
+
padding: 8px 10px;
|
|
79
|
+
border: 1px solid var(--theme-elevation-150);
|
|
80
|
+
border-radius: 4px;
|
|
81
|
+
background: var(--theme-input-bg, transparent);
|
|
82
|
+
color: inherit;
|
|
83
|
+
font: inherit;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.better-editor-tab__block-name-input:focus {
|
|
87
|
+
outline: 2px solid var(--theme-text);
|
|
88
|
+
outline-offset: 1px;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/* Action toolbar (move / duplicate / add / delete) */
|
|
92
|
+
|
|
93
|
+
.better-editor-tab__actions {
|
|
94
|
+
display: flex;
|
|
95
|
+
gap: 6px;
|
|
96
|
+
margin-top: 12px;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.better-editor-tab__action {
|
|
100
|
+
display: inline-flex;
|
|
101
|
+
align-items: center;
|
|
102
|
+
justify-content: center;
|
|
103
|
+
width: 32px;
|
|
104
|
+
height: 32px;
|
|
105
|
+
padding: 0;
|
|
106
|
+
border: 1px solid var(--theme-elevation-150);
|
|
107
|
+
border-radius: 4px;
|
|
108
|
+
background: transparent;
|
|
109
|
+
color: inherit;
|
|
110
|
+
cursor: pointer;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.better-editor-tab__action:hover:not(:disabled) {
|
|
114
|
+
background: var(--theme-elevation-100);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.better-editor-tab__action:disabled {
|
|
118
|
+
opacity: 0.4;
|
|
119
|
+
cursor: not-allowed;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.better-editor-tab__action--danger:hover:not(:disabled) {
|
|
123
|
+
background: var(--theme-error-100, #fee2e2);
|
|
124
|
+
color: var(--theme-error-700, #b91c1c);
|
|
125
|
+
border-color: var(--theme-error-500, #ef4444);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/* Empty-state with "Add Block" CTA */
|
|
129
|
+
|
|
130
|
+
.better-editor-tab--empty {
|
|
131
|
+
display: flex;
|
|
132
|
+
flex-direction: column;
|
|
133
|
+
align-items: stretch;
|
|
134
|
+
gap: 16px;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.better-editor-tab__empty-text {
|
|
138
|
+
margin: 0;
|
|
139
|
+
color: var(--theme-elevation-500);
|
|
140
|
+
font-size: 13px;
|
|
141
|
+
line-height: 1.4;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.better-editor-tab__add-block {
|
|
145
|
+
display: inline-flex;
|
|
146
|
+
align-items: center;
|
|
147
|
+
justify-content: center;
|
|
148
|
+
gap: 8px;
|
|
149
|
+
padding: 10px 14px;
|
|
150
|
+
border: 1px dashed var(--theme-elevation-200);
|
|
151
|
+
border-radius: 4px;
|
|
152
|
+
background: transparent;
|
|
153
|
+
color: inherit;
|
|
154
|
+
font: inherit;
|
|
155
|
+
font-weight: 500;
|
|
156
|
+
cursor: pointer;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.better-editor-tab__add-block:hover {
|
|
160
|
+
background: var(--theme-elevation-100);
|
|
161
|
+
border-color: var(--theme-elevation-400);
|
|
162
|
+
border-style: solid;
|
|
163
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/* Overlay shell — root, body grid, fullscreen, sidebar resize handle,
|
|
2
|
+
error boundary, history (undo/redo) buttons. */
|
|
3
|
+
|
|
4
|
+
.better-editor {
|
|
5
|
+
position: absolute;
|
|
6
|
+
inset: 0;
|
|
7
|
+
z-index: var(--better-editor-z-overlay, 50);
|
|
8
|
+
background: var(--theme-bg, #fff);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/* While fullscreen the overlay covers the whole screen via the
|
|
12
|
+
Fullscreen API. Make sure the body fills it (sidebar is not rendered). */
|
|
13
|
+
.better-editor--fullscreen,
|
|
14
|
+
.better-editor--fullscreen .better-editor__body {
|
|
15
|
+
background: var(--theme-bg, #fff);
|
|
16
|
+
}
|
|
17
|
+
.better-editor--fullscreen .better-editor__body {
|
|
18
|
+
height: 100vh;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.better-editor__body {
|
|
22
|
+
display: grid;
|
|
23
|
+
/* grid-template-columns is set inline by LiveEditorOverlay (preview |
|
|
24
|
+
handle | sidebar) so the live drag-resize stays the source of truth. */
|
|
25
|
+
height: 100%;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/* Drag handle: sits between preview + sidebar, 6px wide. Subtle until
|
|
29
|
+
hover. No transition — transitions on bg cause a perceived flicker
|
|
30
|
+
when the cursor crosses the column boundary repeatedly. */
|
|
31
|
+
.better-editor__resize-handle {
|
|
32
|
+
cursor: col-resize;
|
|
33
|
+
background: transparent;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.better-editor__resize-handle:hover,
|
|
37
|
+
.better-editor--resizing .better-editor__resize-handle {
|
|
38
|
+
background: var(--theme-elevation-200);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/* While resizing, the cursor inevitably crosses over the iframe (when
|
|
42
|
+
making the sidebar bigger on the right, or smaller on the left). The
|
|
43
|
+
iframe would normally swallow mousemove events and the drag would
|
|
44
|
+
stall. Disabling pointer-events on it lets the parent window keep
|
|
45
|
+
receiving the events. */
|
|
46
|
+
.better-editor--resizing .better-editor-frame {
|
|
47
|
+
pointer-events: none;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/* History buttons (undo / redo) in the preview toolbar -------------------- */
|
|
51
|
+
|
|
52
|
+
.better-editor__history {
|
|
53
|
+
display: inline-flex;
|
|
54
|
+
gap: 2px;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.better-editor__history-btn {
|
|
58
|
+
display: inline-flex;
|
|
59
|
+
align-items: center;
|
|
60
|
+
justify-content: center;
|
|
61
|
+
width: 32px;
|
|
62
|
+
height: 28px;
|
|
63
|
+
padding: 0;
|
|
64
|
+
border: 1px solid var(--theme-elevation-150);
|
|
65
|
+
border-radius: 4px;
|
|
66
|
+
background: var(--theme-bg, #fff);
|
|
67
|
+
color: var(--theme-elevation-500);
|
|
68
|
+
cursor: pointer;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.better-editor__history-btn:first-child { border-top-right-radius: 0; border-bottom-right-radius: 0; }
|
|
72
|
+
.better-editor__history-btn:last-child { border-top-left-radius: 0; border-bottom-left-radius: 0; margin-left: -1px; }
|
|
73
|
+
|
|
74
|
+
.better-editor__history-btn:hover:not(:disabled) {
|
|
75
|
+
color: var(--theme-text);
|
|
76
|
+
background: var(--theme-elevation-100);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.better-editor__history-btn:disabled {
|
|
80
|
+
opacity: 0.4;
|
|
81
|
+
cursor: not-allowed;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/* Error boundary ----------------------------------------------------------- */
|
|
85
|
+
|
|
86
|
+
.better-editor--errored {
|
|
87
|
+
background: var(--theme-bg, #fff);
|
|
88
|
+
display: flex;
|
|
89
|
+
align-items: center;
|
|
90
|
+
justify-content: center;
|
|
91
|
+
padding: 32px;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.better-editor__error {
|
|
95
|
+
max-width: 720px;
|
|
96
|
+
text-align: left;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.better-editor__error h3 {
|
|
100
|
+
margin: 0 0 8px;
|
|
101
|
+
font-size: 18px;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.better-editor__error pre {
|
|
105
|
+
max-height: 240px;
|
|
106
|
+
overflow: auto;
|
|
107
|
+
padding: 12px;
|
|
108
|
+
border: 1px solid var(--theme-elevation-150);
|
|
109
|
+
border-radius: 4px;
|
|
110
|
+
background: var(--theme-elevation-50);
|
|
111
|
+
font-size: 12px;
|
|
112
|
+
white-space: pre-wrap;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.better-editor__error-actions {
|
|
116
|
+
display: flex;
|
|
117
|
+
gap: 8px;
|
|
118
|
+
margin-top: 16px;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.better-editor__error-actions button {
|
|
122
|
+
padding: 8px 14px;
|
|
123
|
+
border: 1px solid var(--theme-elevation-200);
|
|
124
|
+
border-radius: 4px;
|
|
125
|
+
background: transparent;
|
|
126
|
+
color: inherit;
|
|
127
|
+
font: inherit;
|
|
128
|
+
cursor: pointer;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.better-editor__error-actions button:hover {
|
|
132
|
+
background: var(--theme-elevation-100);
|
|
133
|
+
}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/* Preview pane — toolbar header, iframe wrapper, viewport modes,
|
|
2
|
+
responsive drag handles, width chip, viewport toggle. */
|
|
3
|
+
|
|
4
|
+
.better-editor__preview {
|
|
5
|
+
position: relative;
|
|
6
|
+
overflow: hidden;
|
|
7
|
+
display: flex;
|
|
8
|
+
flex-direction: column;
|
|
9
|
+
min-height: 0;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.better-editor__preview-toolbar {
|
|
13
|
+
display: flex;
|
|
14
|
+
align-items: center;
|
|
15
|
+
justify-content: space-between;
|
|
16
|
+
gap: 12px;
|
|
17
|
+
padding: 8px;
|
|
18
|
+
border-bottom: 1px solid var(--theme-elevation-150);
|
|
19
|
+
background: var(--theme-elevation-50);
|
|
20
|
+
flex-shrink: 0;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.better-editor__preview-toolbar-right {
|
|
24
|
+
display: inline-flex;
|
|
25
|
+
align-items: center;
|
|
26
|
+
gap: 8px;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.better-editor__preview-stage {
|
|
30
|
+
flex: 1;
|
|
31
|
+
min-height: 0;
|
|
32
|
+
position: relative;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.better-editor-frame {
|
|
36
|
+
width: 100%;
|
|
37
|
+
height: 100%;
|
|
38
|
+
border: 0;
|
|
39
|
+
background: #fff;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* Wrapper is always rendered (even at full width) so React doesn't remount
|
|
43
|
+
the iframe when the user switches viewports. The constrained modifier
|
|
44
|
+
applies the device-frame look. */
|
|
45
|
+
.better-editor-frame__viewport {
|
|
46
|
+
width: 100%;
|
|
47
|
+
height: 100%;
|
|
48
|
+
display: flex;
|
|
49
|
+
align-items: stretch;
|
|
50
|
+
justify-content: center;
|
|
51
|
+
overflow: hidden;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.better-editor-frame__viewport--constrained {
|
|
55
|
+
padding: 16px;
|
|
56
|
+
background: var(--theme-elevation-100);
|
|
57
|
+
overflow: auto;
|
|
58
|
+
align-items: center;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.better-editor-frame__viewport--constrained > .better-editor-frame {
|
|
62
|
+
height: 100%;
|
|
63
|
+
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/* Cap the iframe height in device modes only while the overlay is
|
|
67
|
+
fullscreen, where the available height is otherwise so tall that a
|
|
68
|
+
400px-wide mobile view stretches into a thin tower. In the normal
|
|
69
|
+
docked overlay the wrapper height is already constrained by the
|
|
70
|
+
admin shell, so the cap would just shrink the iframe unnecessarily. */
|
|
71
|
+
.better-editor--fullscreen .better-editor-frame__viewport--tablet > .better-editor-frame {
|
|
72
|
+
max-height: 90%;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.better-editor--fullscreen .better-editor-frame__viewport--mobile > .better-editor-frame {
|
|
76
|
+
max-height: 80%;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/* Responsive mode: drag handles on each side. */
|
|
80
|
+
.better-editor-frame__viewport--resizable {
|
|
81
|
+
position: relative;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.better-editor-frame__handle {
|
|
85
|
+
align-self: center;
|
|
86
|
+
width: 6px;
|
|
87
|
+
height: 64px;
|
|
88
|
+
margin: 0 6px;
|
|
89
|
+
border-radius: 3px;
|
|
90
|
+
background: var(--theme-elevation-300);
|
|
91
|
+
cursor: ew-resize;
|
|
92
|
+
flex-shrink: 0;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.better-editor-frame__handle:hover,
|
|
96
|
+
.better-editor-frame__handle:active,
|
|
97
|
+
.better-editor-frame__viewport--resizing .better-editor-frame__handle {
|
|
98
|
+
background: var(--theme-elevation-500);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/* Mirror of the sidebar fix: while dragging the responsive handles, the
|
|
102
|
+
cursor crosses over the iframe and would lose mousemove events. */
|
|
103
|
+
.better-editor-frame__viewport--resizing .better-editor-frame {
|
|
104
|
+
pointer-events: none;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/* Loading skeleton — overlays the iframe while it boots. Subtle pulsing
|
|
108
|
+
bars + a content block, all neutral grays so it works on light/dark. */
|
|
109
|
+
.better-editor-frame__skeleton {
|
|
110
|
+
position: absolute;
|
|
111
|
+
inset: 0;
|
|
112
|
+
display: flex;
|
|
113
|
+
flex-direction: column;
|
|
114
|
+
gap: 12px;
|
|
115
|
+
padding: 32px;
|
|
116
|
+
background: var(--theme-bg, #fff);
|
|
117
|
+
pointer-events: none;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.better-editor-frame__skeleton-bar,
|
|
121
|
+
.better-editor-frame__skeleton-block {
|
|
122
|
+
background: var(--theme-elevation-100);
|
|
123
|
+
border-radius: 4px;
|
|
124
|
+
animation: better-editor-skeleton-pulse 1.4s ease-in-out infinite;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.better-editor-frame__skeleton-bar {
|
|
128
|
+
height: 14px;
|
|
129
|
+
width: 60%;
|
|
130
|
+
}
|
|
131
|
+
.better-editor-frame__skeleton-bar--lg {
|
|
132
|
+
height: 28px;
|
|
133
|
+
width: 40%;
|
|
134
|
+
margin-bottom: 4px;
|
|
135
|
+
}
|
|
136
|
+
.better-editor-frame__skeleton-bar--sm {
|
|
137
|
+
width: 30%;
|
|
138
|
+
}
|
|
139
|
+
.better-editor-frame__skeleton-block {
|
|
140
|
+
flex: 1;
|
|
141
|
+
margin-top: 8px;
|
|
142
|
+
min-height: 120px;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
@keyframes better-editor-skeleton-pulse {
|
|
146
|
+
0%, 100% { opacity: 1; }
|
|
147
|
+
50% { opacity: 0.55; }
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/* Width chip in the preview toolbar (live iframe pixel width) */
|
|
151
|
+
|
|
152
|
+
.better-editor__width-chip {
|
|
153
|
+
display: inline-flex;
|
|
154
|
+
align-items: baseline;
|
|
155
|
+
gap: 3px;
|
|
156
|
+
padding: 4px 10px;
|
|
157
|
+
border: 1px solid var(--theme-elevation-150);
|
|
158
|
+
border-radius: 999px;
|
|
159
|
+
background: var(--theme-bg, #fff);
|
|
160
|
+
color: var(--theme-text);
|
|
161
|
+
font-size: 12px;
|
|
162
|
+
font-weight: 500;
|
|
163
|
+
font-variant-numeric: tabular-nums;
|
|
164
|
+
font-family: var(--font-mono, ui-monospace, SFMono-Regular, monospace);
|
|
165
|
+
user-select: none;
|
|
166
|
+
min-width: 60px;
|
|
167
|
+
justify-content: center;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.better-editor__width-chip-unit {
|
|
171
|
+
color: var(--theme-elevation-500);
|
|
172
|
+
font-size: 10px;
|
|
173
|
+
font-weight: 400;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/* Viewport toggle (desktop / tablet / mobile / responsive / fullscreen) */
|
|
177
|
+
|
|
178
|
+
.better-editor-viewport {
|
|
179
|
+
display: inline-flex;
|
|
180
|
+
gap: 2px;
|
|
181
|
+
padding: 2px;
|
|
182
|
+
border: 1px solid var(--theme-elevation-150);
|
|
183
|
+
border-radius: 6px;
|
|
184
|
+
background: var(--theme-bg, #fff);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.better-editor-viewport__btn {
|
|
188
|
+
display: inline-flex;
|
|
189
|
+
align-items: center;
|
|
190
|
+
justify-content: center;
|
|
191
|
+
width: 32px;
|
|
192
|
+
height: 28px;
|
|
193
|
+
padding: 0;
|
|
194
|
+
border: 0;
|
|
195
|
+
border-radius: 4px;
|
|
196
|
+
background: transparent;
|
|
197
|
+
color: var(--theme-elevation-500);
|
|
198
|
+
cursor: pointer;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.better-editor-viewport__btn:hover {
|
|
202
|
+
color: var(--theme-text);
|
|
203
|
+
background: var(--theme-elevation-100);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
.better-editor-viewport__btn--active,
|
|
207
|
+
.better-editor-viewport__btn--active:hover {
|
|
208
|
+
color: var(--theme-text);
|
|
209
|
+
background: var(--theme-elevation-150);
|
|
210
|
+
}
|
|
211
|
+
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
.better-editor-banner {
|
|
2
|
+
margin-bottom: 24px;
|
|
3
|
+
border: 1px solid var(--theme-elevation-150);
|
|
4
|
+
border-radius: 8px;
|
|
5
|
+
background: var(--theme-elevation-50);
|
|
6
|
+
overflow: hidden;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.better-editor-banner__header {
|
|
10
|
+
display: flex;
|
|
11
|
+
align-items: center;
|
|
12
|
+
gap: 12px;
|
|
13
|
+
padding: 14px 18px;
|
|
14
|
+
border-bottom: 1px solid var(--theme-elevation-150);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.better-editor-banner__heading {
|
|
18
|
+
display: flex;
|
|
19
|
+
flex-direction: column;
|
|
20
|
+
gap: 2px;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.better-editor-banner__title {
|
|
24
|
+
margin: 0;
|
|
25
|
+
font-size: 14px;
|
|
26
|
+
font-weight: 600;
|
|
27
|
+
color: var(--theme-text);
|
|
28
|
+
display: flex;
|
|
29
|
+
align-items: center;
|
|
30
|
+
gap: 8px;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.better-editor-banner__version {
|
|
34
|
+
font-size: 11px;
|
|
35
|
+
font-weight: 500;
|
|
36
|
+
color: var(--theme-elevation-500);
|
|
37
|
+
padding: 2px 6px;
|
|
38
|
+
border: 1px solid var(--theme-elevation-200);
|
|
39
|
+
border-radius: 4px;
|
|
40
|
+
font-family: var(--font-mono, ui-monospace, monospace);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.better-editor-banner__subtitle {
|
|
44
|
+
margin: 0;
|
|
45
|
+
font-size: 12px;
|
|
46
|
+
color: var(--theme-elevation-500);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.better-editor-banner__actions {
|
|
50
|
+
display: flex;
|
|
51
|
+
flex-wrap: wrap;
|
|
52
|
+
gap: 8px;
|
|
53
|
+
padding: 12px 18px;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.better-editor-banner__link {
|
|
57
|
+
display: inline-flex;
|
|
58
|
+
align-items: center;
|
|
59
|
+
gap: 6px;
|
|
60
|
+
padding: 6px 10px;
|
|
61
|
+
border: 1px solid var(--theme-elevation-200);
|
|
62
|
+
border-radius: 6px;
|
|
63
|
+
background: var(--theme-input-bg, var(--theme-elevation-0));
|
|
64
|
+
color: var(--theme-text);
|
|
65
|
+
font-size: 13px;
|
|
66
|
+
font-weight: 500;
|
|
67
|
+
text-decoration: none;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.better-editor-banner__star-badge {
|
|
71
|
+
height: 16px;
|
|
72
|
+
display: block;
|
|
73
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/* Sidebar shell — column wrapper, scrolling content area, tab nav,
|
|
2
|
+
force-full-width-fields override. */
|
|
3
|
+
|
|
4
|
+
.better-editor__sidebar {
|
|
5
|
+
overflow: hidden;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.better-editor-sidebar {
|
|
9
|
+
display: flex;
|
|
10
|
+
flex-direction: column;
|
|
11
|
+
height: 100%;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.better-editor-sidebar__content {
|
|
15
|
+
flex: 1;
|
|
16
|
+
min-height: 0;
|
|
17
|
+
overflow-y: auto;
|
|
18
|
+
overflow-x: hidden;
|
|
19
|
+
overscroll-behavior: contain;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.better-editor-tab {
|
|
23
|
+
margin: 20px;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/* Force every field inside the sidebar to span the full row, regardless
|
|
27
|
+
of the `admin.width` set on the field config. Payload exposes that
|
|
28
|
+
width as an inline `--field-width` custom property; overriding it
|
|
29
|
+
here (with !important to beat the inline style) collapses
|
|
30
|
+
side-by-side fields like 4×25% selects into a vertical stack so they
|
|
31
|
+
stay readable in the narrow sidebar.
|
|
32
|
+
Toggleable via BetterEditorSettings → Layout → forceFullWidthFields.
|
|
33
|
+
NOTE: the `--field-width` variable is a Payload-internal CSS var; if
|
|
34
|
+
Payload renames it the sidebar silently reverts to honoring admin.width. */
|
|
35
|
+
.better-editor-sidebar--force-full-width .better-editor-sidebar__content .field-type {
|
|
36
|
+
--field-width: 100% !important;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.better-editor-sidebar__content .render-fields {
|
|
40
|
+
margin-top: 16px;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* Page / Blocks / Settings tab switcher */
|
|
44
|
+
|
|
45
|
+
.better-editor-sidebar__tabs {
|
|
46
|
+
display: flex;
|
|
47
|
+
border-bottom: 1px solid var(--theme-elevation-150);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.better-editor-sidebar__tab {
|
|
51
|
+
flex: 1;
|
|
52
|
+
padding: 12px 16px;
|
|
53
|
+
border: 0;
|
|
54
|
+
background: transparent;
|
|
55
|
+
color: var(--theme-elevation-500);
|
|
56
|
+
font: inherit;
|
|
57
|
+
font-weight: 500;
|
|
58
|
+
cursor: pointer;
|
|
59
|
+
border-bottom: 2px solid transparent;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.better-editor-sidebar__tab:hover:not(:disabled) {
|
|
63
|
+
color: var(--theme-text);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.better-editor-sidebar__tab:disabled {
|
|
67
|
+
color: var(--theme-elevation-300);
|
|
68
|
+
cursor: not-allowed;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.better-editor-sidebar__tab--active {
|
|
72
|
+
color: var(--theme-text);
|
|
73
|
+
border-bottom-color: var(--theme-text);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* Visually hidden but available to assistive technology — used by the
|
|
77
|
+
selection live region. Standard SR-only recipe. */
|
|
78
|
+
.better-editor-sr-only {
|
|
79
|
+
position: absolute;
|
|
80
|
+
width: 1px;
|
|
81
|
+
height: 1px;
|
|
82
|
+
padding: 0;
|
|
83
|
+
margin: -1px;
|
|
84
|
+
overflow: hidden;
|
|
85
|
+
clip: rect(0, 0, 0, 0);
|
|
86
|
+
white-space: nowrap;
|
|
87
|
+
border: 0;
|
|
88
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export type BetterEditorConfig = {
|
|
2
|
+
/** Skip plugin installation entirely (e.g. behind a feature flag). */
|
|
3
|
+
disabled?: boolean;
|
|
4
|
+
/**
|
|
5
|
+
* Collection slugs that should get the "Open Better Editor" toggle in
|
|
6
|
+
* their `beforeDocumentControls`. Each collection must have an
|
|
7
|
+
* `admin.livePreview.url` configured for the preview to render.
|
|
8
|
+
*/
|
|
9
|
+
collections?: string[];
|
|
10
|
+
/**
|
|
11
|
+
* Global slugs that should get the "Open Better Editor" toggle in
|
|
12
|
+
* their `beforeDocumentControls`. Each global must have an
|
|
13
|
+
* `admin.livePreview.url` configured for the preview to render.
|
|
14
|
+
*/
|
|
15
|
+
globals?: string[];
|
|
16
|
+
/**
|
|
17
|
+
* Name of the `blocks` field inside the configured collections/globals
|
|
18
|
+
* that the sidebar should target. Top-level only for now; nested paths
|
|
19
|
+
* (e.g. `content.layout`) are not supported. Defaults to `'layout'`.
|
|
20
|
+
*/
|
|
21
|
+
blocksField?: string;
|
|
22
|
+
/**
|
|
23
|
+
* CSS selector for the Payload admin element the overlay portals into.
|
|
24
|
+
* Override only if the default selector breaks against a future Payload
|
|
25
|
+
* version. The plugin falls back to `<main>` and finally `<body>`.
|
|
26
|
+
*/
|
|
27
|
+
adminPortalSelector?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Prefix for all `localStorage` keys the editor writes (sidebar width,
|
|
30
|
+
* responsive viewport width, …). Set this if multiple Better Editor
|
|
31
|
+
* instances share the same origin and would otherwise collide.
|
|
32
|
+
* Defaults to `'better-editor'`.
|
|
33
|
+
*/
|
|
34
|
+
storageNamespace?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Show the plugin info banner (version, GitHub links, "Report a bug")
|
|
37
|
+
* at the top of the `BetterEditorSettings` global. Set to `false` to
|
|
38
|
+
* hide it for end users. Defaults to `true`.
|
|
39
|
+
*/
|
|
40
|
+
showSettingsBanner?: boolean;
|
|
41
|
+
};
|
package/dist/types.js
ADDED