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.
Files changed (182) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +57 -0
  3. package/dist/admin/ErrorBoundary.d.ts +17 -0
  4. package/dist/admin/ErrorBoundary.js +62 -0
  5. package/dist/admin/ErrorBoundary.js.map +1 -0
  6. package/dist/admin/LiveEditorOverlay.d.ts +12 -0
  7. package/dist/admin/LiveEditorOverlay.js +160 -0
  8. package/dist/admin/LiveEditorOverlay.js.map +1 -0
  9. package/dist/admin/LiveEditorToggle.d.ts +7 -0
  10. package/dist/admin/LiveEditorToggle.js +84 -0
  11. package/dist/admin/LiveEditorToggle.js.map +1 -0
  12. package/dist/admin/PreviewFrame.d.ts +22 -0
  13. package/dist/admin/PreviewFrame.js +137 -0
  14. package/dist/admin/PreviewFrame.js.map +1 -0
  15. package/dist/admin/PreviewToolbar.d.ts +16 -0
  16. package/dist/admin/PreviewToolbar.js +90 -0
  17. package/dist/admin/PreviewToolbar.js.map +1 -0
  18. package/dist/admin/SettingsBanner.d.ts +3 -0
  19. package/dist/admin/SettingsBanner.js +105 -0
  20. package/dist/admin/SettingsBanner.js.map +1 -0
  21. package/dist/admin/ViewportToggle.d.ts +7 -0
  22. package/dist/admin/ViewportToggle.js +79 -0
  23. package/dist/admin/ViewportToggle.js.map +1 -0
  24. package/dist/admin/blocks/AddBlockDrawer.d.ts +9 -0
  25. package/dist/admin/blocks/AddBlockDrawer.js +16 -0
  26. package/dist/admin/blocks/AddBlockDrawer.js.map +1 -0
  27. package/dist/admin/blocks/BlockActionsToolbar.d.ts +15 -0
  28. package/dist/admin/blocks/BlockActionsToolbar.js +102 -0
  29. package/dist/admin/blocks/BlockActionsToolbar.js.map +1 -0
  30. package/dist/admin/blocks/BlockEmptyState.d.ts +6 -0
  31. package/dist/admin/blocks/BlockEmptyState.js +26 -0
  32. package/dist/admin/blocks/BlockEmptyState.js.map +1 -0
  33. package/dist/admin/blocks/BlockHeader.d.ts +7 -0
  34. package/dist/admin/blocks/BlockHeader.js +32 -0
  35. package/dist/admin/blocks/BlockHeader.js.map +1 -0
  36. package/dist/admin/blocks/schema.d.ts +19 -0
  37. package/dist/admin/blocks/schema.js +80 -0
  38. package/dist/admin/blocks/schema.js.map +1 -0
  39. package/dist/admin/blocks/useBlockActions.d.ts +24 -0
  40. package/dist/admin/blocks/useBlockActions.js +100 -0
  41. package/dist/admin/blocks/useBlockActions.js.map +1 -0
  42. package/dist/admin/icons.d.ts +24 -0
  43. package/dist/admin/icons.js +36 -0
  44. package/dist/admin/icons.js.map +1 -0
  45. package/dist/admin/sidebar/BlockSettingsTab.d.ts +10 -0
  46. package/dist/admin/sidebar/BlockSettingsTab.js +153 -0
  47. package/dist/admin/sidebar/BlockSettingsTab.js.map +1 -0
  48. package/dist/admin/sidebar/DocumentFieldsTab.d.ts +8 -0
  49. package/dist/admin/sidebar/DocumentFieldsTab.js +38 -0
  50. package/dist/admin/sidebar/DocumentFieldsTab.js.map +1 -0
  51. package/dist/admin/sidebar/DocumentMetaTab.d.ts +2 -0
  52. package/dist/admin/sidebar/DocumentMetaTab.js +11 -0
  53. package/dist/admin/sidebar/DocumentMetaTab.js.map +1 -0
  54. package/dist/admin/sidebar/DocumentSettingsTab.d.ts +2 -0
  55. package/dist/admin/sidebar/DocumentSettingsTab.js +48 -0
  56. package/dist/admin/sidebar/DocumentSettingsTab.js.map +1 -0
  57. package/dist/admin/sidebar/Sidebar.d.ts +10 -0
  58. package/dist/admin/sidebar/Sidebar.js +92 -0
  59. package/dist/admin/sidebar/Sidebar.js.map +1 -0
  60. package/dist/client.d.ts +34 -0
  61. package/dist/client.js +30 -0
  62. package/dist/client.js.map +1 -0
  63. package/dist/global.d.ts +4 -0
  64. package/dist/global.js +200 -0
  65. package/dist/global.js.map +1 -0
  66. package/dist/hooks/useAddBlockDrawer.d.ts +14 -0
  67. package/dist/hooks/useAddBlockDrawer.js +26 -0
  68. package/dist/hooks/useAddBlockDrawer.js.map +1 -0
  69. package/dist/hooks/useBlockActionMessages.d.ts +8 -0
  70. package/dist/hooks/useBlockActionMessages.js +107 -0
  71. package/dist/hooks/useBlockActionMessages.js.map +1 -0
  72. package/dist/hooks/useDocConfig.d.ts +6 -0
  73. package/dist/hooks/useDocConfig.js +18 -0
  74. package/dist/hooks/useDocConfig.js.map +1 -0
  75. package/dist/hooks/useFocusTrap.d.ts +2 -0
  76. package/dist/hooks/useFocusTrap.js +84 -0
  77. package/dist/hooks/useFocusTrap.js.map +1 -0
  78. package/dist/hooks/useFullscreenOverlay.d.ts +2 -0
  79. package/dist/hooks/useFullscreenOverlay.js +30 -0
  80. package/dist/hooks/useFullscreenOverlay.js.map +1 -0
  81. package/dist/hooks/useIframeResizeObserver.d.ts +2 -0
  82. package/dist/hooks/useIframeResizeObserver.js +20 -0
  83. package/dist/hooks/useIframeResizeObserver.js.map +1 -0
  84. package/dist/hooks/useLatestRef.d.ts +6 -0
  85. package/dist/hooks/useLatestRef.js +12 -0
  86. package/dist/hooks/useLatestRef.js.map +1 -0
  87. package/dist/hooks/useMainWrapperPortal.d.ts +1 -0
  88. package/dist/hooks/useMainWrapperPortal.js +64 -0
  89. package/dist/hooks/useMainWrapperPortal.js.map +1 -0
  90. package/dist/hooks/useOverlayKeyboard.d.ts +6 -0
  91. package/dist/hooks/useOverlayKeyboard.js +43 -0
  92. package/dist/hooks/useOverlayKeyboard.js.map +1 -0
  93. package/dist/hooks/usePreviewBinding.d.ts +28 -0
  94. package/dist/hooks/usePreviewBinding.js +108 -0
  95. package/dist/hooks/usePreviewBinding.js.map +1 -0
  96. package/dist/hooks/usePreviewHandleDrag.d.ts +11 -0
  97. package/dist/hooks/usePreviewHandleDrag.js +53 -0
  98. package/dist/hooks/usePreviewHandleDrag.js.map +1 -0
  99. package/dist/hooks/usePreviewSelectionSync.d.ts +15 -0
  100. package/dist/hooks/usePreviewSelectionSync.js +80 -0
  101. package/dist/hooks/usePreviewSelectionSync.js.map +1 -0
  102. package/dist/hooks/usePreviewSettingsSync.d.ts +17 -0
  103. package/dist/hooks/usePreviewSettingsSync.js +55 -0
  104. package/dist/hooks/usePreviewSettingsSync.js.map +1 -0
  105. package/dist/hooks/useSidebarResize.d.ts +8 -0
  106. package/dist/hooks/useSidebarResize.js +101 -0
  107. package/dist/hooks/useSidebarResize.js.map +1 -0
  108. package/dist/hooks/useViewportState.d.ts +10 -0
  109. package/dist/hooks/useViewportState.js +44 -0
  110. package/dist/hooks/useViewportState.js.map +1 -0
  111. package/dist/index.d.ts +25 -0
  112. package/dist/index.js +104 -0
  113. package/dist/index.js.map +1 -0
  114. package/dist/internal/constants.d.ts +22 -0
  115. package/dist/internal/constants.js +38 -0
  116. package/dist/internal/constants.js.map +1 -0
  117. package/dist/internal/dom.d.ts +4 -0
  118. package/dist/internal/dom.js +6 -0
  119. package/dist/internal/dom.js.map +1 -0
  120. package/dist/internal/iframe.d.ts +5 -0
  121. package/dist/internal/iframe.js +12 -0
  122. package/dist/internal/iframe.js.map +1 -0
  123. package/dist/internal/limits.d.ts +9 -0
  124. package/dist/internal/limits.js +11 -0
  125. package/dist/internal/limits.js.map +1 -0
  126. package/dist/internal/path.d.ts +5 -0
  127. package/dist/internal/path.js +12 -0
  128. package/dist/internal/path.js.map +1 -0
  129. package/dist/internal/postmessage.d.ts +3 -0
  130. package/dist/internal/postmessage.js +21 -0
  131. package/dist/internal/postmessage.js.map +1 -0
  132. package/dist/internal/storage-keys.d.ts +8 -0
  133. package/dist/internal/storage-keys.js +9 -0
  134. package/dist/internal/storage-keys.js.map +1 -0
  135. package/dist/internal/storage.d.ts +2 -0
  136. package/dist/internal/storage.js +20 -0
  137. package/dist/internal/storage.js.map +1 -0
  138. package/dist/preview/HoverToolbar.d.ts +8 -0
  139. package/dist/preview/HoverToolbar.js +48 -0
  140. package/dist/preview/HoverToolbar.js.map +1 -0
  141. package/dist/preview/HoverToolbarController.d.ts +31 -0
  142. package/dist/preview/HoverToolbarController.js +160 -0
  143. package/dist/preview/HoverToolbarController.js.map +1 -0
  144. package/dist/preview/hover-css.d.ts +11 -0
  145. package/dist/preview/hover-css.js +94 -0
  146. package/dist/preview/hover-css.js.map +1 -0
  147. package/dist/preview/installClickToFocus.d.ts +6 -0
  148. package/dist/preview/installClickToFocus.js +21 -0
  149. package/dist/preview/installClickToFocus.js.map +1 -0
  150. package/dist/preview/installHoverStyles.d.ts +2 -0
  151. package/dist/preview/installHoverStyles.js +15 -0
  152. package/dist/preview/installHoverStyles.js.map +1 -0
  153. package/dist/preview/protocol.d.ts +11 -0
  154. package/dist/preview/protocol.js +19 -0
  155. package/dist/preview/protocol.js.map +1 -0
  156. package/dist/preview/toolbar-position.d.ts +20 -0
  157. package/dist/preview/toolbar-position.js +22 -0
  158. package/dist/preview/toolbar-position.js.map +1 -0
  159. package/dist/providers/BetterEditorConfigProvider.d.ts +14 -0
  160. package/dist/providers/BetterEditorConfigProvider.js +26 -0
  161. package/dist/providers/BetterEditorConfigProvider.js.map +1 -0
  162. package/dist/providers/OverlayProviders.d.ts +8 -0
  163. package/dist/providers/OverlayProviders.js +22 -0
  164. package/dist/providers/OverlayProviders.js.map +1 -0
  165. package/dist/state/useBetterEditorSettings.d.ts +18 -0
  166. package/dist/state/useBetterEditorSettings.js +65 -0
  167. package/dist/state/useBetterEditorSettings.js.map +1 -0
  168. package/dist/state/useEditorHistory.d.ts +16 -0
  169. package/dist/state/useEditorHistory.js +157 -0
  170. package/dist/state/useEditorHistory.js.map +1 -0
  171. package/dist/styles/blocks-tab.css +163 -0
  172. package/dist/styles/overlay.css +133 -0
  173. package/dist/styles/preview.css +211 -0
  174. package/dist/styles/settings-banner.css +73 -0
  175. package/dist/styles/sidebar.css +88 -0
  176. package/dist/types.d.ts +41 -0
  177. package/dist/types.js +3 -0
  178. package/dist/types.js.map +1 -0
  179. package/dist/version.d.ts +1 -0
  180. package/dist/version.js +6 -0
  181. package/dist/version.js.map +1 -0
  182. package/package.json +117 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/admin/PreviewFrame.tsx"],"sourcesContent":["'use client'\n\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport type { HoverToolbarPosition } from '../internal/constants'\nimport { postToParent } from '../internal/postmessage'\nimport type { BlockActionMessage } from '../preview/protocol'\nimport type { Viewport } from './ViewportToggle'\nimport { useIframeResizeObserver } from '../hooks/useIframeResizeObserver'\nimport { usePreviewHandleDrag } from '../hooks/usePreviewHandleDrag'\nimport { useLatestRef } from '../hooks/useLatestRef'\nimport { usePreviewBinding } from '../hooks/usePreviewBinding'\nimport { usePreviewSettingsSync } from '../hooks/usePreviewSettingsSync'\nimport { usePreviewSelectionSync } from '../hooks/usePreviewSelectionSync'\n\nexport type PreviewFrameProps = {\n previewURL: string | undefined\n hoverColorTopLevel: string\n hoverColorNested: string\n hoverOutlineWidth: number\n showHoverToolbar: boolean\n hoverToolbarPosition: HoverToolbarPosition\n selectedBlockPath: string | null\n /** When true, clicks pass through to the consumer page and the\n * hover/selection affordances are suppressed so users can interact\n * with forms, accordions, links inside the preview. */\n interactMode: boolean\n viewport?: Viewport\n viewportWidth?: number | null\n resizable?: boolean\n onResize?: (next: number) => void\n onIframeWidthChange?: (width: number) => void\n}\n\ntype BlockAction = BlockActionMessage['action']\n\nexport const PreviewFrame: React.FC<PreviewFrameProps> = ({\n previewURL,\n hoverColorTopLevel,\n hoverColorNested,\n hoverOutlineWidth,\n showHoverToolbar,\n hoverToolbarPosition,\n selectedBlockPath,\n interactMode,\n viewport,\n viewportWidth,\n resizable = false,\n onResize,\n onIframeWidthChange,\n}) => {\n const iframeRef = useRef<HTMLIFrameElement | null>(null)\n const [isLoading, setIsLoading] = useState(true)\n const interactModeRef = useLatestRef(interactMode)\n\n const { isResizing, onHandleMouseDown } = usePreviewHandleDrag({\n resizable,\n viewportWidth,\n onResize,\n })\n useIframeResizeObserver(iframeRef, onIframeWidthChange)\n\n useEffect(() => {\n setIsLoading(true)\n }, [previewURL])\n\n const onFocusBlock = useCallback((id: string) => {\n postToParent({ type: 'focus-block', id })\n }, [])\n\n const onBlockAction = useCallback((id: string, action: BlockAction) => {\n postToParent({ type: 'block-action', id, action })\n }, [])\n\n const settings = useMemo(\n () => ({\n hoverColorTopLevel,\n hoverColorNested,\n hoverOutlineWidth,\n showHoverToolbar,\n hoverToolbarPosition,\n }),\n [\n hoverColorTopLevel,\n hoverColorNested,\n hoverOutlineWidth,\n showHoverToolbar,\n hoverToolbarPosition,\n ],\n )\n\n const { controllerRef, isBoundRef } = usePreviewBinding({\n iframeRef,\n settings,\n interactModeRef,\n onFocusBlock,\n onBlockAction,\n onLoadingChange: setIsLoading,\n })\n\n usePreviewSettingsSync({\n iframeRef,\n controllerRef,\n isBoundRef,\n settings,\n onBlockAction,\n })\n\n usePreviewSelectionSync({\n iframeRef,\n controllerRef,\n selectedBlockPath,\n interactMode,\n previewURL,\n })\n\n const constrained = typeof viewportWidth === 'number' && viewportWidth > 0\n const viewportClassName = [\n 'better-editor-frame__viewport',\n constrained && 'better-editor-frame__viewport--constrained',\n constrained && viewport === 'tablet' && 'better-editor-frame__viewport--tablet',\n constrained && viewport === 'mobile' && 'better-editor-frame__viewport--mobile',\n resizable && 'better-editor-frame__viewport--resizable',\n isResizing && 'better-editor-frame__viewport--resizing',\n ]\n .filter(Boolean)\n .join(' ')\n const iframeStyle = constrained\n ? { width: `${viewportWidth}px`, maxWidth: '100%' as const }\n : undefined\n\n // The iframe stays in the same wrapper across viewport modes so React\n // doesn't remount it — that would reload the page and drop the\n // ResizeObserver.\n return (\n <div className={viewportClassName}>\n {resizable ? (\n <div\n className=\"better-editor-frame__handle better-editor-frame__handle--left\"\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-label=\"Resize preview from left\"\n onMouseDown={onHandleMouseDown('left')}\n />\n ) : null}\n <iframe\n ref={iframeRef}\n className=\"better-editor-frame\"\n src={previewURL}\n title=\"Better Editor preview\"\n style={iframeStyle}\n />\n {isLoading ? (\n <div\n className=\"better-editor-frame__skeleton\"\n role=\"status\"\n aria-label=\"Loading preview\"\n >\n <div className=\"better-editor-frame__skeleton-bar better-editor-frame__skeleton-bar--lg\" />\n <div className=\"better-editor-frame__skeleton-bar\" />\n <div className=\"better-editor-frame__skeleton-bar better-editor-frame__skeleton-bar--sm\" />\n <div className=\"better-editor-frame__skeleton-block\" />\n </div>\n ) : null}\n {resizable ? (\n <div\n className=\"better-editor-frame__handle better-editor-frame__handle--right\"\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-label=\"Resize preview from right\"\n onMouseDown={onHandleMouseDown('right')}\n />\n ) : null}\n </div>\n )\n}\n"],"names":["React","useCallback","useEffect","useMemo","useRef","useState","postToParent","useIframeResizeObserver","usePreviewHandleDrag","useLatestRef","usePreviewBinding","usePreviewSettingsSync","usePreviewSelectionSync","PreviewFrame","previewURL","hoverColorTopLevel","hoverColorNested","hoverOutlineWidth","showHoverToolbar","hoverToolbarPosition","selectedBlockPath","interactMode","viewport","viewportWidth","resizable","onResize","onIframeWidthChange","iframeRef","isLoading","setIsLoading","interactModeRef","isResizing","onHandleMouseDown","onFocusBlock","id","type","onBlockAction","action","settings","controllerRef","isBoundRef","onLoadingChange","constrained","viewportClassName","filter","Boolean","join","iframeStyle","width","maxWidth","undefined","div","className","role","aria-orientation","aria-label","onMouseDown","iframe","ref","src","title","style"],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ import { type Viewport } from './ViewportToggle';
3
+ import type { useEditorHistory } from '../state/useEditorHistory';
4
+ export type PreviewToolbarProps = {
5
+ history: ReturnType<typeof useEditorHistory>;
6
+ viewport: Viewport;
7
+ onViewportChange: (viewport: Viewport) => void;
8
+ iframeWidth: number | null;
9
+ isFullscreen: boolean;
10
+ onFullscreenToggle: () => void;
11
+ interactMode: boolean;
12
+ onInteractToggle: () => void;
13
+ sidebarCollapsed: boolean;
14
+ onSidebarToggle: () => void;
15
+ };
16
+ export declare const PreviewToolbar: React.FC<PreviewToolbarProps>;
@@ -0,0 +1,90 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import React from 'react';
4
+ import { ViewportToggle } from './ViewportToggle';
5
+ import { FullscreenExitIcon, FullscreenIcon, InteractIcon, InteractOffIcon, RedoIcon, SidebarHideIcon, SidebarShowIcon, UndoIcon } from './icons';
6
+ export const PreviewToolbar = ({ history, viewport, onViewportChange, iframeWidth, isFullscreen, onFullscreenToggle, interactMode, onInteractToggle, sidebarCollapsed, onSidebarToggle })=>/*#__PURE__*/ _jsxs("div", {
7
+ className: "better-editor__preview-toolbar",
8
+ children: [
9
+ /*#__PURE__*/ _jsx(HistoryButtons, {
10
+ history: history
11
+ }),
12
+ /*#__PURE__*/ _jsxs("div", {
13
+ className: "better-editor__preview-toolbar-right",
14
+ children: [
15
+ iframeWidth ? /*#__PURE__*/ _jsxs("span", {
16
+ className: "better-editor__width-chip",
17
+ "aria-live": "polite",
18
+ children: [
19
+ iframeWidth,
20
+ /*#__PURE__*/ _jsx("span", {
21
+ className: "better-editor__width-chip-unit",
22
+ children: "px"
23
+ })
24
+ ]
25
+ }) : null,
26
+ /*#__PURE__*/ _jsx(ViewportToggle, {
27
+ value: viewport,
28
+ onChange: onViewportChange
29
+ }),
30
+ /*#__PURE__*/ _jsxs("div", {
31
+ className: "better-editor-viewport",
32
+ children: [
33
+ /*#__PURE__*/ _jsx("button", {
34
+ type: "button",
35
+ className: isFullscreen ? 'better-editor-viewport__btn better-editor-viewport__btn--active' : 'better-editor-viewport__btn',
36
+ onClick: onFullscreenToggle,
37
+ "aria-pressed": isFullscreen,
38
+ title: isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen',
39
+ "aria-label": isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen',
40
+ children: isFullscreen ? /*#__PURE__*/ _jsx(FullscreenExitIcon, {}) : /*#__PURE__*/ _jsx(FullscreenIcon, {})
41
+ }),
42
+ /*#__PURE__*/ _jsx("button", {
43
+ type: "button",
44
+ className: interactMode ? 'better-editor-viewport__btn better-editor-viewport__btn--active' : 'better-editor-viewport__btn',
45
+ onClick: onInteractToggle,
46
+ "aria-pressed": interactMode,
47
+ title: interactMode ? 'Switch to edit mode' : 'Switch to interact mode (use forms, accordions, links)',
48
+ "aria-label": interactMode ? 'Switch to edit mode' : 'Switch to interact mode',
49
+ children: interactMode ? /*#__PURE__*/ _jsx(InteractIcon, {}) : /*#__PURE__*/ _jsx(InteractOffIcon, {})
50
+ }),
51
+ /*#__PURE__*/ _jsx("button", {
52
+ type: "button",
53
+ className: "better-editor-viewport__btn",
54
+ onClick: onSidebarToggle,
55
+ "aria-pressed": sidebarCollapsed,
56
+ title: sidebarCollapsed ? 'Show sidebar' : 'Hide sidebar',
57
+ "aria-label": sidebarCollapsed ? 'Show sidebar' : 'Hide sidebar',
58
+ children: sidebarCollapsed ? /*#__PURE__*/ _jsx(SidebarShowIcon, {}) : /*#__PURE__*/ _jsx(SidebarHideIcon, {})
59
+ })
60
+ ]
61
+ })
62
+ ]
63
+ })
64
+ ]
65
+ });
66
+ const HistoryButtons = ({ history })=>/*#__PURE__*/ _jsxs("div", {
67
+ className: "better-editor__history",
68
+ children: [
69
+ /*#__PURE__*/ _jsx("button", {
70
+ type: "button",
71
+ className: "better-editor__history-btn",
72
+ onClick: history.undo,
73
+ disabled: !history.canUndo,
74
+ title: "Undo (Cmd/Ctrl+Z)",
75
+ "aria-label": "Undo",
76
+ children: /*#__PURE__*/ _jsx(UndoIcon, {})
77
+ }),
78
+ /*#__PURE__*/ _jsx("button", {
79
+ type: "button",
80
+ className: "better-editor__history-btn",
81
+ onClick: history.redo,
82
+ disabled: !history.canRedo,
83
+ title: "Redo (Cmd/Ctrl+Shift+Z)",
84
+ "aria-label": "Redo",
85
+ children: /*#__PURE__*/ _jsx(RedoIcon, {})
86
+ })
87
+ ]
88
+ });
89
+
90
+ //# sourceMappingURL=PreviewToolbar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/admin/PreviewToolbar.tsx"],"sourcesContent":["'use client'\n\nimport React from 'react'\nimport { ViewportToggle, type Viewport } from './ViewportToggle'\nimport {\n FullscreenExitIcon,\n FullscreenIcon,\n InteractIcon,\n InteractOffIcon,\n RedoIcon,\n SidebarHideIcon,\n SidebarShowIcon,\n UndoIcon,\n} from './icons'\nimport type { useEditorHistory } from '../state/useEditorHistory'\n\nexport type PreviewToolbarProps = {\n history: ReturnType<typeof useEditorHistory>\n viewport: Viewport\n onViewportChange: (viewport: Viewport) => void\n iframeWidth: number | null\n isFullscreen: boolean\n onFullscreenToggle: () => void\n interactMode: boolean\n onInteractToggle: () => void\n sidebarCollapsed: boolean\n onSidebarToggle: () => void\n}\n\nexport const PreviewToolbar: React.FC<PreviewToolbarProps> = ({\n history,\n viewport,\n onViewportChange,\n iframeWidth,\n isFullscreen,\n onFullscreenToggle,\n interactMode,\n onInteractToggle,\n sidebarCollapsed,\n onSidebarToggle,\n}) => (\n <div className=\"better-editor__preview-toolbar\">\n <HistoryButtons history={history} />\n <div className=\"better-editor__preview-toolbar-right\">\n {iframeWidth ? (\n <span className=\"better-editor__width-chip\" aria-live=\"polite\">\n {iframeWidth}\n <span className=\"better-editor__width-chip-unit\">px</span>\n </span>\n ) : null}\n <ViewportToggle value={viewport} onChange={onViewportChange} />\n <div className=\"better-editor-viewport\">\n <button\n type=\"button\"\n className={\n isFullscreen\n ? 'better-editor-viewport__btn better-editor-viewport__btn--active'\n : 'better-editor-viewport__btn'\n }\n onClick={onFullscreenToggle}\n aria-pressed={isFullscreen}\n title={isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen'}\n aria-label={isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen'}\n >\n {isFullscreen ? <FullscreenExitIcon /> : <FullscreenIcon />}\n </button>\n <button\n type=\"button\"\n className={\n interactMode\n ? 'better-editor-viewport__btn better-editor-viewport__btn--active'\n : 'better-editor-viewport__btn'\n }\n onClick={onInteractToggle}\n aria-pressed={interactMode}\n title={\n interactMode\n ? 'Switch to edit mode'\n : 'Switch to interact mode (use forms, accordions, links)'\n }\n aria-label={interactMode ? 'Switch to edit mode' : 'Switch to interact mode'}\n >\n {interactMode ? <InteractIcon /> : <InteractOffIcon />}\n </button>\n <button\n type=\"button\"\n className=\"better-editor-viewport__btn\"\n onClick={onSidebarToggle}\n aria-pressed={sidebarCollapsed}\n title={sidebarCollapsed ? 'Show sidebar' : 'Hide sidebar'}\n aria-label={sidebarCollapsed ? 'Show sidebar' : 'Hide sidebar'}\n >\n {sidebarCollapsed ? <SidebarShowIcon /> : <SidebarHideIcon />}\n </button>\n </div>\n </div>\n </div>\n)\n\nconst HistoryButtons: React.FC<{ history: ReturnType<typeof useEditorHistory> }> = ({\n history,\n}) => (\n <div className=\"better-editor__history\">\n <button\n type=\"button\"\n className=\"better-editor__history-btn\"\n onClick={history.undo}\n disabled={!history.canUndo}\n title=\"Undo (Cmd/Ctrl+Z)\"\n aria-label=\"Undo\"\n >\n <UndoIcon />\n </button>\n <button\n type=\"button\"\n className=\"better-editor__history-btn\"\n onClick={history.redo}\n disabled={!history.canRedo}\n title=\"Redo (Cmd/Ctrl+Shift+Z)\"\n aria-label=\"Redo\"\n >\n <RedoIcon />\n </button>\n </div>\n)\n"],"names":["React","ViewportToggle","FullscreenExitIcon","FullscreenIcon","InteractIcon","InteractOffIcon","RedoIcon","SidebarHideIcon","SidebarShowIcon","UndoIcon","PreviewToolbar","history","viewport","onViewportChange","iframeWidth","isFullscreen","onFullscreenToggle","interactMode","onInteractToggle","sidebarCollapsed","onSidebarToggle","div","className","HistoryButtons","span","aria-live","value","onChange","button","type","onClick","aria-pressed","title","aria-label","undo","disabled","canUndo","redo","canRedo"],"mappings":"AAAA;;AAEA,OAAOA,WAAW,QAAO;AACzB,SAASC,cAAc,QAAuB,mBAAkB;AAChE,SACEC,kBAAkB,EAClBC,cAAc,EACdC,YAAY,EACZC,eAAe,EACfC,QAAQ,EACRC,eAAe,EACfC,eAAe,EACfC,QAAQ,QACH,UAAS;AAgBhB,OAAO,MAAMC,iBAAgD,CAAC,EAC5DC,OAAO,EACPC,QAAQ,EACRC,gBAAgB,EAChBC,WAAW,EACXC,YAAY,EACZC,kBAAkB,EAClBC,YAAY,EACZC,gBAAgB,EAChBC,gBAAgB,EAChBC,eAAe,EAChB,iBACC,MAACC;QAAIC,WAAU;;0BACb,KAACC;gBAAeZ,SAASA;;0BACzB,MAACU;gBAAIC,WAAU;;oBACZR,4BACC,MAACU;wBAAKF,WAAU;wBAA4BG,aAAU;;4BACnDX;0CACD,KAACU;gCAAKF,WAAU;0CAAiC;;;yBAEjD;kCACJ,KAACrB;wBAAeyB,OAAOd;wBAAUe,UAAUd;;kCAC3C,MAACQ;wBAAIC,WAAU;;0CACb,KAACM;gCACCC,MAAK;gCACLP,WACEP,eACI,oEACA;gCAENe,SAASd;gCACTe,gBAAchB;gCACdiB,OAAOjB,eAAe,oBAAoB;gCAC1CkB,cAAYlB,eAAe,oBAAoB;0CAE9CA,6BAAe,KAACb,wCAAwB,KAACC;;0CAE5C,KAACyB;gCACCC,MAAK;gCACLP,WACEL,eACI,oEACA;gCAENa,SAASZ;gCACTa,gBAAcd;gCACde,OACEf,eACI,wBACA;gCAENgB,cAAYhB,eAAe,wBAAwB;0CAElDA,6BAAe,KAACb,kCAAkB,KAACC;;0CAEtC,KAACuB;gCACCC,MAAK;gCACLP,WAAU;gCACVQ,SAASV;gCACTW,gBAAcZ;gCACda,OAAOb,mBAAmB,iBAAiB;gCAC3Cc,cAAYd,mBAAmB,iBAAiB;0CAE/CA,iCAAmB,KAACX,qCAAqB,KAACD;;;;;;;OAKpD;AAED,MAAMgB,iBAA6E,CAAC,EAClFZ,OAAO,EACR,iBACC,MAACU;QAAIC,WAAU;;0BACb,KAACM;gBACCC,MAAK;gBACLP,WAAU;gBACVQ,SAASnB,QAAQuB,IAAI;gBACrBC,UAAU,CAACxB,QAAQyB,OAAO;gBAC1BJ,OAAM;gBACNC,cAAW;0BAEX,cAAA,KAACxB;;0BAEH,KAACmB;gBACCC,MAAK;gBACLP,WAAU;gBACVQ,SAASnB,QAAQ0B,IAAI;gBACrBF,UAAU,CAACxB,QAAQ2B,OAAO;gBAC1BN,OAAM;gBACNC,cAAW;0BAEX,cAAA,KAAC3B"}
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import '../styles/settings-banner.css';
3
+ export declare const SettingsBanner: React.FC;
@@ -0,0 +1,105 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import React from 'react';
4
+ import { BugIcon, GithubIcon, StarIcon } from './icons';
5
+ import { VERSION } from '../version';
6
+ import '../styles/settings-banner.css';
7
+ const REPO = 'scorpio-99/payload-better-editor';
8
+ const AUTHOR = 'scorpio-99';
9
+ const BANNER = {
10
+ author: AUTHOR,
11
+ repoUrl: `https://github.com/${REPO}`,
12
+ issuesUrl: `https://github.com/${REPO}/issues/new`,
13
+ authorUrl: `https://github.com/${AUTHOR}`,
14
+ starBadgeUrl: `https://img.shields.io/github/stars/${REPO}?style=flat&label=&color=27272a&labelColor=27272a&logo=github&logoColor=white`
15
+ };
16
+ export const SettingsBanner = ()=>/*#__PURE__*/ _jsxs("div", {
17
+ className: "better-editor-banner",
18
+ children: [
19
+ /*#__PURE__*/ _jsx("div", {
20
+ className: "better-editor-banner__header",
21
+ children: /*#__PURE__*/ _jsxs("div", {
22
+ className: "better-editor-banner__heading",
23
+ children: [
24
+ /*#__PURE__*/ _jsxs("div", {
25
+ className: "better-editor-banner__title",
26
+ children: [
27
+ /*#__PURE__*/ _jsx("span", {
28
+ children: "payload-better-editor"
29
+ }),
30
+ /*#__PURE__*/ _jsxs("span", {
31
+ className: "better-editor-banner__version",
32
+ children: [
33
+ "v",
34
+ VERSION
35
+ ]
36
+ })
37
+ ]
38
+ }),
39
+ /*#__PURE__*/ _jsxs("div", {
40
+ className: "better-editor-banner__subtitle",
41
+ children: [
42
+ "Built by",
43
+ ' ',
44
+ /*#__PURE__*/ _jsx("a", {
45
+ href: BANNER.authorUrl,
46
+ target: "_blank",
47
+ rel: "noreferrer noopener",
48
+ children: BANNER.author
49
+ }),
50
+ ". If you find this plugin useful, please leave a star ⭐"
51
+ ]
52
+ })
53
+ ]
54
+ })
55
+ }),
56
+ /*#__PURE__*/ _jsxs("div", {
57
+ className: "better-editor-banner__actions",
58
+ children: [
59
+ /*#__PURE__*/ _jsxs("a", {
60
+ href: BANNER.repoUrl,
61
+ target: "_blank",
62
+ rel: "noreferrer noopener",
63
+ className: "better-editor-banner__link",
64
+ children: [
65
+ /*#__PURE__*/ _jsx(StarIcon, {}),
66
+ /*#__PURE__*/ _jsx("span", {
67
+ children: "Star"
68
+ }),
69
+ /*#__PURE__*/ _jsx("img", {
70
+ src: BANNER.starBadgeUrl,
71
+ alt: "",
72
+ className: "better-editor-banner__star-badge"
73
+ })
74
+ ]
75
+ }),
76
+ /*#__PURE__*/ _jsxs("a", {
77
+ href: BANNER.repoUrl,
78
+ target: "_blank",
79
+ rel: "noreferrer noopener",
80
+ className: "better-editor-banner__link",
81
+ children: [
82
+ /*#__PURE__*/ _jsx(GithubIcon, {}),
83
+ /*#__PURE__*/ _jsx("span", {
84
+ children: "GitHub"
85
+ })
86
+ ]
87
+ }),
88
+ /*#__PURE__*/ _jsxs("a", {
89
+ href: BANNER.issuesUrl,
90
+ target: "_blank",
91
+ rel: "noreferrer noopener",
92
+ className: "better-editor-banner__link",
93
+ children: [
94
+ /*#__PURE__*/ _jsx(BugIcon, {}),
95
+ /*#__PURE__*/ _jsx("span", {
96
+ children: "Report a bug"
97
+ })
98
+ ]
99
+ })
100
+ ]
101
+ })
102
+ ]
103
+ });
104
+
105
+ //# sourceMappingURL=SettingsBanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/admin/SettingsBanner.tsx"],"sourcesContent":["'use client'\n\nimport React from 'react'\nimport { BugIcon, GithubIcon, StarIcon } from './icons'\nimport { VERSION } from '../version'\nimport '../styles/settings-banner.css'\n\nconst REPO = 'scorpio-99/payload-better-editor'\nconst AUTHOR = 'scorpio-99'\n\nconst BANNER = {\n author: AUTHOR,\n repoUrl: `https://github.com/${REPO}`,\n issuesUrl: `https://github.com/${REPO}/issues/new`,\n authorUrl: `https://github.com/${AUTHOR}`,\n starBadgeUrl: `https://img.shields.io/github/stars/${REPO}?style=flat&label=&color=27272a&labelColor=27272a&logo=github&logoColor=white`,\n}\n\nexport const SettingsBanner: React.FC = () => (\n <div className=\"better-editor-banner\">\n <div className=\"better-editor-banner__header\">\n <div className=\"better-editor-banner__heading\">\n <div className=\"better-editor-banner__title\">\n <span>payload-better-editor</span>\n <span className=\"better-editor-banner__version\">v{VERSION}</span>\n </div>\n <div className=\"better-editor-banner__subtitle\">\n Built by{' '}\n <a href={BANNER.authorUrl} target=\"_blank\" rel=\"noreferrer noopener\">\n {BANNER.author}\n </a>\n . If you find this plugin useful, please leave a star ⭐\n </div>\n </div>\n </div>\n <div className=\"better-editor-banner__actions\">\n <a\n href={BANNER.repoUrl}\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n className=\"better-editor-banner__link\"\n >\n <StarIcon />\n <span>Star</span>\n <img\n src={BANNER.starBadgeUrl}\n alt=\"\"\n className=\"better-editor-banner__star-badge\"\n />\n </a>\n <a\n href={BANNER.repoUrl}\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n className=\"better-editor-banner__link\"\n >\n <GithubIcon />\n <span>GitHub</span>\n </a>\n <a\n href={BANNER.issuesUrl}\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n className=\"better-editor-banner__link\"\n >\n <BugIcon />\n <span>Report a bug</span>\n </a>\n </div>\n </div>\n)\n"],"names":["React","BugIcon","GithubIcon","StarIcon","VERSION","REPO","AUTHOR","BANNER","author","repoUrl","issuesUrl","authorUrl","starBadgeUrl","SettingsBanner","div","className","span","a","href","target","rel","img","src","alt"],"mappings":"AAAA;;AAEA,OAAOA,WAAW,QAAO;AACzB,SAASC,OAAO,EAAEC,UAAU,EAAEC,QAAQ,QAAQ,UAAS;AACvD,SAASC,OAAO,QAAQ,aAAY;AACpC,OAAO,gCAA+B;AAEtC,MAAMC,OAAO;AACb,MAAMC,SAAS;AAEf,MAAMC,SAAS;IACbC,QAAQF;IACRG,SAAS,CAAC,mBAAmB,EAAEJ,MAAM;IACrCK,WAAW,CAAC,mBAAmB,EAAEL,KAAK,WAAW,CAAC;IAClDM,WAAW,CAAC,mBAAmB,EAAEL,QAAQ;IACzCM,cAAc,CAAC,oCAAoC,EAAEP,KAAK,6EAA6E,CAAC;AAC1I;AAEA,OAAO,MAAMQ,iBAA2B,kBACtC,MAACC;QAAIC,WAAU;;0BACb,KAACD;gBAAIC,WAAU;0BACb,cAAA,MAACD;oBAAIC,WAAU;;sCACb,MAACD;4BAAIC,WAAU;;8CACb,KAACC;8CAAK;;8CACN,MAACA;oCAAKD,WAAU;;wCAAgC;wCAAEX;;;;;sCAEpD,MAACU;4BAAIC,WAAU;;gCAAiC;gCACrC;8CACT,KAACE;oCAAEC,MAAMX,OAAOI,SAAS;oCAAEQ,QAAO;oCAASC,KAAI;8CAC5Cb,OAAOC,MAAM;;gCACZ;;;;;;0BAKV,MAACM;gBAAIC,WAAU;;kCACb,MAACE;wBACCC,MAAMX,OAAOE,OAAO;wBACpBU,QAAO;wBACPC,KAAI;wBACJL,WAAU;;0CAEV,KAACZ;0CACD,KAACa;0CAAK;;0CACN,KAACK;gCACCC,KAAKf,OAAOK,YAAY;gCACxBW,KAAI;gCACJR,WAAU;;;;kCAGd,MAACE;wBACCC,MAAMX,OAAOE,OAAO;wBACpBU,QAAO;wBACPC,KAAI;wBACJL,WAAU;;0CAEV,KAACb;0CACD,KAACc;0CAAK;;;;kCAER,MAACC;wBACCC,MAAMX,OAAOG,SAAS;wBACtBS,QAAO;wBACPC,KAAI;wBACJL,WAAU;;0CAEV,KAACd;0CACD,KAACe;0CAAK;;;;;;;OAIb"}
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ export type Viewport = 'desktop' | 'tablet' | 'mobile' | 'responsive';
3
+ export type ViewportToggleProps = {
4
+ value: Viewport;
5
+ onChange: (next: Viewport) => void;
6
+ };
7
+ export declare const ViewportToggle: React.FC<ViewportToggleProps>;
@@ -0,0 +1,79 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import React, { useCallback, useRef } from 'react';
4
+ import { DesktopIcon, MobileIcon, ResponsiveIcon, TabletIcon } from './icons';
5
+ const ITEMS = [
6
+ {
7
+ id: 'desktop',
8
+ label: 'Desktop',
9
+ Icon: DesktopIcon
10
+ },
11
+ {
12
+ id: 'tablet',
13
+ label: 'Tablet',
14
+ Icon: TabletIcon
15
+ },
16
+ {
17
+ id: 'mobile',
18
+ label: 'Mobile',
19
+ Icon: MobileIcon
20
+ },
21
+ {
22
+ id: 'responsive',
23
+ label: 'Responsive (drag to resize)',
24
+ Icon: ResponsiveIcon
25
+ }
26
+ ];
27
+ const ROOT_CLASS = 'better-editor-viewport';
28
+ const BTN_CLASS = `${ROOT_CLASS}__btn`;
29
+ const ViewportButton = ({ item, active, onSelect, buttonRef })=>{
30
+ const { id, label, Icon } = item;
31
+ return /*#__PURE__*/ _jsx("button", {
32
+ type: "button",
33
+ ref: buttonRef,
34
+ role: "radio",
35
+ "aria-checked": active,
36
+ tabIndex: active ? 0 : -1,
37
+ className: active ? `${BTN_CLASS} ${BTN_CLASS}--active` : BTN_CLASS,
38
+ onClick: ()=>onSelect(id),
39
+ title: label,
40
+ "aria-label": label,
41
+ children: /*#__PURE__*/ _jsx(Icon, {})
42
+ });
43
+ };
44
+ export const ViewportToggle = ({ value, onChange })=>{
45
+ const btnsRef = useRef([]);
46
+ const onKeyDown = useCallback((e)=>{
47
+ const isPrev = e.key === 'ArrowLeft' || e.key === 'ArrowUp';
48
+ const isNext = e.key === 'ArrowRight' || e.key === 'ArrowDown';
49
+ if (!isPrev && !isNext) return;
50
+ e.preventDefault();
51
+ const idx = ITEMS.findIndex((i)=>i.id === value);
52
+ const start = idx === -1 ? 0 : idx;
53
+ const len = ITEMS.length;
54
+ // Per radiogroup pattern, arrow keys move both selection and focus.
55
+ const nextIdx = isPrev ? (start - 1 + len) % len : (start + 1) % len;
56
+ const next = ITEMS[nextIdx];
57
+ onChange(next.id);
58
+ btnsRef.current[nextIdx]?.focus();
59
+ }, [
60
+ onChange,
61
+ value
62
+ ]);
63
+ return /*#__PURE__*/ _jsx("div", {
64
+ className: ROOT_CLASS,
65
+ role: "radiogroup",
66
+ "aria-label": "Preview viewport",
67
+ onKeyDown: onKeyDown,
68
+ children: ITEMS.map((item, i)=>/*#__PURE__*/ _jsx(ViewportButton, {
69
+ item: item,
70
+ active: value === item.id,
71
+ onSelect: onChange,
72
+ buttonRef: (el)=>{
73
+ btnsRef.current[i] = el;
74
+ }
75
+ }, item.id))
76
+ });
77
+ };
78
+
79
+ //# sourceMappingURL=ViewportToggle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/admin/ViewportToggle.tsx"],"sourcesContent":["'use client'\n\nimport React, { useCallback, useRef } from 'react'\nimport {\n DesktopIcon,\n MobileIcon,\n ResponsiveIcon,\n TabletIcon,\n type LucideProps,\n} from './icons'\n\nexport type Viewport = 'desktop' | 'tablet' | 'mobile' | 'responsive'\n\ntype Item = { id: Viewport; label: string; Icon: React.FC<LucideProps> }\n\nconst ITEMS: ReadonlyArray<Item> = [\n { id: 'desktop', label: 'Desktop', Icon: DesktopIcon },\n { id: 'tablet', label: 'Tablet', Icon: TabletIcon },\n { id: 'mobile', label: 'Mobile', Icon: MobileIcon },\n { id: 'responsive', label: 'Responsive (drag to resize)', Icon: ResponsiveIcon },\n]\n\nconst ROOT_CLASS = 'better-editor-viewport'\nconst BTN_CLASS = `${ROOT_CLASS}__btn`\n\nexport type ViewportToggleProps = {\n value: Viewport\n onChange: (next: Viewport) => void\n}\n\ntype ButtonProps = {\n item: Item\n active: boolean\n onSelect: (id: Viewport) => void\n buttonRef: (el: HTMLButtonElement | null) => void\n}\n\nconst ViewportButton: React.FC<ButtonProps> = ({ item, active, onSelect, buttonRef }) => {\n const { id, label, Icon } = item\n return (\n <button\n type=\"button\"\n ref={buttonRef}\n role=\"radio\"\n aria-checked={active}\n tabIndex={active ? 0 : -1}\n className={active ? `${BTN_CLASS} ${BTN_CLASS}--active` : BTN_CLASS}\n onClick={() => onSelect(id)}\n title={label}\n aria-label={label}\n >\n <Icon />\n </button>\n )\n}\n\nexport const ViewportToggle: React.FC<ViewportToggleProps> = ({ value, onChange }) => {\n const btnsRef = useRef<Array<HTMLButtonElement | null>>([])\n\n const onKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLDivElement>) => {\n const isPrev = e.key === 'ArrowLeft' || e.key === 'ArrowUp'\n const isNext = e.key === 'ArrowRight' || e.key === 'ArrowDown'\n if (!isPrev && !isNext) return\n e.preventDefault()\n const idx = ITEMS.findIndex((i) => i.id === value)\n const start = idx === -1 ? 0 : idx\n const len = ITEMS.length\n // Per radiogroup pattern, arrow keys move both selection and focus.\n const nextIdx = isPrev ? (start - 1 + len) % len : (start + 1) % len\n const next = ITEMS[nextIdx]\n onChange(next.id)\n btnsRef.current[nextIdx]?.focus()\n },\n [onChange, value],\n )\n\n return (\n <div\n className={ROOT_CLASS}\n role=\"radiogroup\"\n aria-label=\"Preview viewport\"\n onKeyDown={onKeyDown}\n >\n {ITEMS.map((item, i) => (\n <ViewportButton\n key={item.id}\n item={item}\n active={value === item.id}\n onSelect={onChange}\n buttonRef={(el) => {\n btnsRef.current[i] = el\n }}\n />\n ))}\n </div>\n )\n}\n"],"names":["React","useCallback","useRef","DesktopIcon","MobileIcon","ResponsiveIcon","TabletIcon","ITEMS","id","label","Icon","ROOT_CLASS","BTN_CLASS","ViewportButton","item","active","onSelect","buttonRef","button","type","ref","role","aria-checked","tabIndex","className","onClick","title","aria-label","ViewportToggle","value","onChange","btnsRef","onKeyDown","e","isPrev","key","isNext","preventDefault","idx","findIndex","i","start","len","length","nextIdx","next","current","focus","div","map","el"],"mappings":"AAAA;;AAEA,OAAOA,SAASC,WAAW,EAAEC,MAAM,QAAQ,QAAO;AAClD,SACEC,WAAW,EACXC,UAAU,EACVC,cAAc,EACdC,UAAU,QAEL,UAAS;AAMhB,MAAMC,QAA6B;IACjC;QAAEC,IAAI;QAAWC,OAAO;QAAWC,MAAMP;IAAY;IACrD;QAAEK,IAAI;QAAUC,OAAO;QAAUC,MAAMJ;IAAW;IAClD;QAAEE,IAAI;QAAUC,OAAO;QAAUC,MAAMN;IAAW;IAClD;QAAEI,IAAI;QAAcC,OAAO;QAA+BC,MAAML;IAAe;CAChF;AAED,MAAMM,aAAa;AACnB,MAAMC,YAAY,GAAGD,WAAW,KAAK,CAAC;AActC,MAAME,iBAAwC,CAAC,EAAEC,IAAI,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,SAAS,EAAE;IAClF,MAAM,EAAET,EAAE,EAAEC,KAAK,EAAEC,IAAI,EAAE,GAAGI;IAC5B,qBACE,KAACI;QACCC,MAAK;QACLC,KAAKH;QACLI,MAAK;QACLC,gBAAcP;QACdQ,UAAUR,SAAS,IAAI,CAAC;QACxBS,WAAWT,SAAS,GAAGH,UAAU,CAAC,EAAEA,UAAU,QAAQ,CAAC,GAAGA;QAC1Da,SAAS,IAAMT,SAASR;QACxBkB,OAAOjB;QACPkB,cAAYlB;kBAEZ,cAAA,KAACC;;AAGP;AAEA,OAAO,MAAMkB,iBAAgD,CAAC,EAAEC,KAAK,EAAEC,QAAQ,EAAE;IAC/E,MAAMC,UAAU7B,OAAwC,EAAE;IAE1D,MAAM8B,YAAY/B,YAChB,CAACgC;QACC,MAAMC,SAASD,EAAEE,GAAG,KAAK,eAAeF,EAAEE,GAAG,KAAK;QAClD,MAAMC,SAASH,EAAEE,GAAG,KAAK,gBAAgBF,EAAEE,GAAG,KAAK;QACnD,IAAI,CAACD,UAAU,CAACE,QAAQ;QACxBH,EAAEI,cAAc;QAChB,MAAMC,MAAM/B,MAAMgC,SAAS,CAAC,CAACC,IAAMA,EAAEhC,EAAE,KAAKqB;QAC5C,MAAMY,QAAQH,QAAQ,CAAC,IAAI,IAAIA;QAC/B,MAAMI,MAAMnC,MAAMoC,MAAM;QACxB,oEAAoE;QACpE,MAAMC,UAAUV,SAAS,AAACO,CAAAA,QAAQ,IAAIC,GAAE,IAAKA,MAAM,AAACD,CAAAA,QAAQ,CAAA,IAAKC;QACjE,MAAMG,OAAOtC,KAAK,CAACqC,QAAQ;QAC3Bd,SAASe,KAAKrC,EAAE;QAChBuB,QAAQe,OAAO,CAACF,QAAQ,EAAEG;IAC5B,GACA;QAACjB;QAAUD;KAAM;IAGnB,qBACE,KAACmB;QACCxB,WAAWb;QACXU,MAAK;QACLM,cAAW;QACXK,WAAWA;kBAEVzB,MAAM0C,GAAG,CAAC,CAACnC,MAAM0B,kBAChB,KAAC3B;gBAECC,MAAMA;gBACNC,QAAQc,UAAUf,KAAKN,EAAE;gBACzBQ,UAAUc;gBACVb,WAAW,CAACiC;oBACVnB,QAAQe,OAAO,CAACN,EAAE,GAAGU;gBACvB;eANKpC,KAAKN,EAAE;;AAWtB,EAAC"}
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import type { ClientBlock } from 'payload';
3
+ export type AddBlockDrawerProps = {
4
+ slug: string;
5
+ blocks: ClientBlock[];
6
+ addRow: (index: number, blockType?: string) => void;
7
+ addRowIndex: number;
8
+ };
9
+ export declare const AddBlockDrawer: React.FC<AddBlockDrawerProps>;
@@ -0,0 +1,16 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import React from 'react';
4
+ import { BlocksDrawer } from '@payloadcms/ui';
5
+ export const AddBlockDrawer = ({ slug, blocks, addRow, addRowIndex })=>/*#__PURE__*/ _jsx(BlocksDrawer, {
6
+ addRow: addRow,
7
+ addRowIndex: addRowIndex,
8
+ blocks: blocks,
9
+ drawerSlug: slug,
10
+ labels: {
11
+ singular: 'Block',
12
+ plural: 'Blocks'
13
+ }
14
+ });
15
+
16
+ //# sourceMappingURL=AddBlockDrawer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/admin/blocks/AddBlockDrawer.tsx"],"sourcesContent":["'use client'\n\nimport React from 'react'\nimport { BlocksDrawer } from '@payloadcms/ui'\nimport type { ClientBlock } from 'payload'\n\nexport type AddBlockDrawerProps = {\n slug: string\n blocks: ClientBlock[]\n addRow: (index: number, blockType?: string) => void\n addRowIndex: number\n}\n\nexport const AddBlockDrawer: React.FC<AddBlockDrawerProps> = ({\n slug,\n blocks,\n addRow,\n addRowIndex,\n}) => (\n <BlocksDrawer\n addRow={addRow}\n addRowIndex={addRowIndex}\n blocks={blocks}\n drawerSlug={slug}\n labels={{ singular: 'Block', plural: 'Blocks' }}\n />\n)\n"],"names":["React","BlocksDrawer","AddBlockDrawer","slug","blocks","addRow","addRowIndex","drawerSlug","labels","singular","plural"],"mappings":"AAAA;;AAEA,OAAOA,WAAW,QAAO;AACzB,SAASC,YAAY,QAAQ,iBAAgB;AAU7C,OAAO,MAAMC,iBAAgD,CAAC,EAC5DC,IAAI,EACJC,MAAM,EACNC,MAAM,EACNC,WAAW,EACZ,iBACC,KAACL;QACCI,QAAQA;QACRC,aAAaA;QACbF,QAAQA;QACRG,YAAYJ;QACZK,QAAQ;YAAEC,UAAU;YAASC,QAAQ;QAAS;OAEjD"}
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ export type BlockActionsToolbarProps = {
3
+ canMoveUp: boolean;
4
+ canMoveDown: boolean;
5
+ /** When false the toolbar renders nothing. */
6
+ canMutate: boolean;
7
+ /** When false the "Add below" button is disabled (no parent blocks list). */
8
+ canAddBelow: boolean;
9
+ onMoveUp: () => void;
10
+ onMoveDown: () => void;
11
+ onDuplicate: () => void;
12
+ onAddBelow: () => void;
13
+ onDelete: () => void;
14
+ };
15
+ export declare const BlockActionsToolbar: React.FC<BlockActionsToolbarProps>;
@@ -0,0 +1,102 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import React, { useCallback, useRef, useState } from 'react';
4
+ import { ChevronDown, ChevronUp, CopyIcon, PlusIcon, TrashIcon } from '../icons';
5
+ export const BlockActionsToolbar = ({ canMoveUp, canMoveDown, canMutate, canAddBelow, onMoveUp, onMoveDown, onDuplicate, onAddBelow, onDelete })=>{
6
+ // Roving tabindex per WAI-ARIA toolbar pattern: only one button is in
7
+ // the tab sequence; arrow keys move focus among siblings.
8
+ const [focusIdx, setFocusIdx] = useState(0);
9
+ const btnsRef = useRef([]);
10
+ const onKeyDown = useCallback((e)=>{
11
+ if (e.key !== 'ArrowLeft' && e.key !== 'ArrowRight' && e.key !== 'Home' && e.key !== 'End') {
12
+ return;
13
+ }
14
+ e.preventDefault();
15
+ const buttons = btnsRef.current.filter((b)=>b !== null);
16
+ if (buttons.length === 0) return;
17
+ const current = buttons.findIndex((b)=>b === document.activeElement);
18
+ const start = current === -1 ? 0 : current;
19
+ let next = start;
20
+ if (e.key === 'ArrowLeft') next = (start - 1 + buttons.length) % buttons.length;
21
+ else if (e.key === 'ArrowRight') next = (start + 1) % buttons.length;
22
+ else if (e.key === 'Home') next = 0;
23
+ else if (e.key === 'End') next = buttons.length - 1;
24
+ buttons[next].focus();
25
+ const idx = btnsRef.current.indexOf(buttons[next]);
26
+ if (idx >= 0) setFocusIdx(idx);
27
+ }, []);
28
+ if (!canMutate) return null;
29
+ const setRef = (i)=>(el)=>{
30
+ btnsRef.current[i] = el;
31
+ };
32
+ const tabIndexFor = (i)=>i === focusIdx ? 0 : -1;
33
+ const onFocus = (i)=>()=>setFocusIdx(i);
34
+ return /*#__PURE__*/ _jsxs("div", {
35
+ className: "better-editor-tab__actions",
36
+ role: "toolbar",
37
+ "aria-label": "Block actions",
38
+ onKeyDown: onKeyDown,
39
+ children: [
40
+ /*#__PURE__*/ _jsx("button", {
41
+ type: "button",
42
+ ref: setRef(0),
43
+ tabIndex: tabIndexFor(0),
44
+ onFocus: onFocus(0),
45
+ className: "better-editor-tab__action",
46
+ onClick: onMoveUp,
47
+ disabled: !canMoveUp,
48
+ title: "Move up",
49
+ "aria-label": "Move block up",
50
+ children: /*#__PURE__*/ _jsx(ChevronUp, {})
51
+ }),
52
+ /*#__PURE__*/ _jsx("button", {
53
+ type: "button",
54
+ ref: setRef(1),
55
+ tabIndex: tabIndexFor(1),
56
+ onFocus: onFocus(1),
57
+ className: "better-editor-tab__action",
58
+ onClick: onMoveDown,
59
+ disabled: !canMoveDown,
60
+ title: "Move down",
61
+ "aria-label": "Move block down",
62
+ children: /*#__PURE__*/ _jsx(ChevronDown, {})
63
+ }),
64
+ /*#__PURE__*/ _jsx("button", {
65
+ type: "button",
66
+ ref: setRef(2),
67
+ tabIndex: tabIndexFor(2),
68
+ onFocus: onFocus(2),
69
+ className: "better-editor-tab__action",
70
+ onClick: onDuplicate,
71
+ title: "Duplicate",
72
+ "aria-label": "Duplicate block",
73
+ children: /*#__PURE__*/ _jsx(CopyIcon, {})
74
+ }),
75
+ /*#__PURE__*/ _jsx("button", {
76
+ type: "button",
77
+ ref: setRef(3),
78
+ tabIndex: tabIndexFor(3),
79
+ onFocus: onFocus(3),
80
+ className: "better-editor-tab__action",
81
+ onClick: onAddBelow,
82
+ disabled: !canAddBelow,
83
+ title: "Add block below",
84
+ "aria-label": "Add block below",
85
+ children: /*#__PURE__*/ _jsx(PlusIcon, {})
86
+ }),
87
+ /*#__PURE__*/ _jsx("button", {
88
+ type: "button",
89
+ ref: setRef(4),
90
+ tabIndex: tabIndexFor(4),
91
+ onFocus: onFocus(4),
92
+ className: "better-editor-tab__action better-editor-tab__action--danger",
93
+ onClick: onDelete,
94
+ title: "Delete",
95
+ "aria-label": "Delete block",
96
+ children: /*#__PURE__*/ _jsx(TrashIcon, {})
97
+ })
98
+ ]
99
+ });
100
+ };
101
+
102
+ //# sourceMappingURL=BlockActionsToolbar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/admin/blocks/BlockActionsToolbar.tsx"],"sourcesContent":["'use client'\n\nimport React, { useCallback, useRef, useState } from 'react'\nimport { ChevronDown, ChevronUp, CopyIcon, PlusIcon, TrashIcon } from '../icons'\n\nexport type BlockActionsToolbarProps = {\n canMoveUp: boolean\n canMoveDown: boolean\n /** When false the toolbar renders nothing. */\n canMutate: boolean\n /** When false the \"Add below\" button is disabled (no parent blocks list). */\n canAddBelow: boolean\n onMoveUp: () => void\n onMoveDown: () => void\n onDuplicate: () => void\n onAddBelow: () => void\n onDelete: () => void\n}\n\nexport const BlockActionsToolbar: React.FC<BlockActionsToolbarProps> = ({\n canMoveUp,\n canMoveDown,\n canMutate,\n canAddBelow,\n onMoveUp,\n onMoveDown,\n onDuplicate,\n onAddBelow,\n onDelete,\n}) => {\n // Roving tabindex per WAI-ARIA toolbar pattern: only one button is in\n // the tab sequence; arrow keys move focus among siblings.\n const [focusIdx, setFocusIdx] = useState(0)\n const btnsRef = useRef<Array<HTMLButtonElement | null>>([])\n\n const onKeyDown = useCallback((e: React.KeyboardEvent<HTMLDivElement>) => {\n if (e.key !== 'ArrowLeft' && e.key !== 'ArrowRight' && e.key !== 'Home' && e.key !== 'End') {\n return\n }\n e.preventDefault()\n const buttons = btnsRef.current.filter((b): b is HTMLButtonElement => b !== null)\n if (buttons.length === 0) return\n const current = buttons.findIndex((b) => b === document.activeElement)\n const start = current === -1 ? 0 : current\n let next = start\n if (e.key === 'ArrowLeft') next = (start - 1 + buttons.length) % buttons.length\n else if (e.key === 'ArrowRight') next = (start + 1) % buttons.length\n else if (e.key === 'Home') next = 0\n else if (e.key === 'End') next = buttons.length - 1\n buttons[next].focus()\n const idx = btnsRef.current.indexOf(buttons[next])\n if (idx >= 0) setFocusIdx(idx)\n }, [])\n\n if (!canMutate) return null\n\n const setRef = (i: number) => (el: HTMLButtonElement | null) => {\n btnsRef.current[i] = el\n }\n const tabIndexFor = (i: number) => (i === focusIdx ? 0 : -1)\n const onFocus = (i: number) => () => setFocusIdx(i)\n\n return (\n <div\n className=\"better-editor-tab__actions\"\n role=\"toolbar\"\n aria-label=\"Block actions\"\n onKeyDown={onKeyDown}\n >\n <button\n type=\"button\"\n ref={setRef(0)}\n tabIndex={tabIndexFor(0)}\n onFocus={onFocus(0)}\n className=\"better-editor-tab__action\"\n onClick={onMoveUp}\n disabled={!canMoveUp}\n title=\"Move up\"\n aria-label=\"Move block up\"\n >\n <ChevronUp />\n </button>\n <button\n type=\"button\"\n ref={setRef(1)}\n tabIndex={tabIndexFor(1)}\n onFocus={onFocus(1)}\n className=\"better-editor-tab__action\"\n onClick={onMoveDown}\n disabled={!canMoveDown}\n title=\"Move down\"\n aria-label=\"Move block down\"\n >\n <ChevronDown />\n </button>\n <button\n type=\"button\"\n ref={setRef(2)}\n tabIndex={tabIndexFor(2)}\n onFocus={onFocus(2)}\n className=\"better-editor-tab__action\"\n onClick={onDuplicate}\n title=\"Duplicate\"\n aria-label=\"Duplicate block\"\n >\n <CopyIcon />\n </button>\n <button\n type=\"button\"\n ref={setRef(3)}\n tabIndex={tabIndexFor(3)}\n onFocus={onFocus(3)}\n className=\"better-editor-tab__action\"\n onClick={onAddBelow}\n disabled={!canAddBelow}\n title=\"Add block below\"\n aria-label=\"Add block below\"\n >\n <PlusIcon />\n </button>\n <button\n type=\"button\"\n ref={setRef(4)}\n tabIndex={tabIndexFor(4)}\n onFocus={onFocus(4)}\n className=\"better-editor-tab__action better-editor-tab__action--danger\"\n onClick={onDelete}\n title=\"Delete\"\n aria-label=\"Delete block\"\n >\n <TrashIcon />\n </button>\n </div>\n )\n}\n"],"names":["React","useCallback","useRef","useState","ChevronDown","ChevronUp","CopyIcon","PlusIcon","TrashIcon","BlockActionsToolbar","canMoveUp","canMoveDown","canMutate","canAddBelow","onMoveUp","onMoveDown","onDuplicate","onAddBelow","onDelete","focusIdx","setFocusIdx","btnsRef","onKeyDown","e","key","preventDefault","buttons","current","filter","b","length","findIndex","document","activeElement","start","next","focus","idx","indexOf","setRef","i","el","tabIndexFor","onFocus","div","className","role","aria-label","button","type","ref","tabIndex","onClick","disabled","title"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ export type BlockEmptyStateProps = {
3
+ canAdd: boolean;
4
+ onAddClick: () => void;
5
+ };
6
+ export declare const BlockEmptyState: React.FC<BlockEmptyStateProps>;
@@ -0,0 +1,26 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import React from 'react';
4
+ import { PlusIcon } from '../icons';
5
+ export const BlockEmptyState = ({ canAdd, onAddClick })=>/*#__PURE__*/ _jsxs("div", {
6
+ className: "better-editor-tab better-editor-tab--empty",
7
+ children: [
8
+ /*#__PURE__*/ _jsx("p", {
9
+ className: "better-editor-tab__empty-text",
10
+ children: "Select a block in the preview to edit its settings."
11
+ }),
12
+ canAdd ? /*#__PURE__*/ _jsxs("button", {
13
+ type: "button",
14
+ className: "better-editor-tab__add-block",
15
+ onClick: onAddClick,
16
+ children: [
17
+ /*#__PURE__*/ _jsx(PlusIcon, {}),
18
+ /*#__PURE__*/ _jsx("span", {
19
+ children: "Add Block"
20
+ })
21
+ ]
22
+ }) : null
23
+ ]
24
+ });
25
+
26
+ //# sourceMappingURL=BlockEmptyState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/admin/blocks/BlockEmptyState.tsx"],"sourcesContent":["'use client'\n\nimport React from 'react'\nimport { PlusIcon } from '../icons'\n\nexport type BlockEmptyStateProps = {\n canAdd: boolean\n onAddClick: () => void\n}\n\nexport const BlockEmptyState: React.FC<BlockEmptyStateProps> = ({ canAdd, onAddClick }) => (\n <div className=\"better-editor-tab better-editor-tab--empty\">\n <p className=\"better-editor-tab__empty-text\">\n Select a block in the preview to edit its settings.\n </p>\n {canAdd ? (\n <button\n type=\"button\"\n className=\"better-editor-tab__add-block\"\n onClick={onAddClick}\n >\n <PlusIcon />\n <span>Add Block</span>\n </button>\n ) : null}\n </div>\n)\n"],"names":["React","PlusIcon","BlockEmptyState","canAdd","onAddClick","div","className","p","button","type","onClick","span"],"mappings":"AAAA;;AAEA,OAAOA,WAAW,QAAO;AACzB,SAASC,QAAQ,QAAQ,WAAU;AAOnC,OAAO,MAAMC,kBAAkD,CAAC,EAAEC,MAAM,EAAEC,UAAU,EAAE,iBACpF,MAACC;QAAIC,WAAU;;0BACb,KAACC;gBAAED,WAAU;0BAAgC;;YAG5CH,uBACC,MAACK;gBACCC,MAAK;gBACLH,WAAU;gBACVI,SAASN;;kCAET,KAACH;kCACD,KAACU;kCAAK;;;iBAEN;;OAEP"}
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ export type BlockHeaderProps = {
3
+ blockType: string;
4
+ path: string;
5
+ onClearSelection: () => void;
6
+ };
7
+ export declare const BlockHeader: React.FC<BlockHeaderProps>;
@@ -0,0 +1,32 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import React from 'react';
4
+ export const BlockHeader = ({ blockType, path, onClearSelection })=>/*#__PURE__*/ _jsxs("div", {
5
+ className: "better-editor-tab__header",
6
+ children: [
7
+ /*#__PURE__*/ _jsxs("div", {
8
+ children: [
9
+ /*#__PURE__*/ _jsx("span", {
10
+ className: "better-editor-tab__kicker",
11
+ children: "Block"
12
+ }),
13
+ /*#__PURE__*/ _jsx("h3", {
14
+ className: "better-editor-tab__heading",
15
+ children: blockType
16
+ }),
17
+ /*#__PURE__*/ _jsx("code", {
18
+ className: "better-editor-tab__path",
19
+ children: path
20
+ })
21
+ ]
22
+ }),
23
+ /*#__PURE__*/ _jsx("button", {
24
+ type: "button",
25
+ className: "better-editor-tab__clear",
26
+ onClick: onClearSelection,
27
+ children: "Deselect"
28
+ })
29
+ ]
30
+ });
31
+
32
+ //# sourceMappingURL=BlockHeader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/admin/blocks/BlockHeader.tsx"],"sourcesContent":["'use client'\n\nimport React from 'react'\n\nexport type BlockHeaderProps = {\n blockType: string\n path: string\n onClearSelection: () => void\n}\n\nexport const BlockHeader: React.FC<BlockHeaderProps> = ({\n blockType,\n path,\n onClearSelection,\n}) => (\n <div className=\"better-editor-tab__header\">\n <div>\n <span className=\"better-editor-tab__kicker\">Block</span>\n <h3 className=\"better-editor-tab__heading\">{blockType}</h3>\n <code className=\"better-editor-tab__path\">{path}</code>\n </div>\n <button\n type=\"button\"\n className=\"better-editor-tab__clear\"\n onClick={onClearSelection}\n >\n Deselect\n </button>\n </div>\n)\n"],"names":["React","BlockHeader","blockType","path","onClearSelection","div","className","span","h3","code","button","type","onClick"],"mappings":"AAAA;;AAEA,OAAOA,WAAW,QAAO;AAQzB,OAAO,MAAMC,cAA0C,CAAC,EACtDC,SAAS,EACTC,IAAI,EACJC,gBAAgB,EACjB,iBACC,MAACC;QAAIC,WAAU;;0BACb,MAACD;;kCACC,KAACE;wBAAKD,WAAU;kCAA4B;;kCAC5C,KAACE;wBAAGF,WAAU;kCAA8BJ;;kCAC5C,KAACO;wBAAKH,WAAU;kCAA2BH;;;;0BAE7C,KAACO;gBACCC,MAAK;gBACLL,WAAU;gBACVM,SAASR;0BACV;;;OAIJ"}