payload-better-editor 1.2.1 → 1.3.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 (80) hide show
  1. package/dist/admin/ErrorBoundary.d.ts +1 -10
  2. package/dist/admin/ErrorBoundary.js +14 -5
  3. package/dist/admin/ErrorBoundary.js.map +1 -1
  4. package/dist/admin/LiveEditorOverlay.js +4 -2
  5. package/dist/admin/LiveEditorOverlay.js.map +1 -1
  6. package/dist/admin/LiveEditorToggle.d.ts +2 -0
  7. package/dist/admin/LiveEditorToggle.js +14 -9
  8. package/dist/admin/LiveEditorToggle.js.map +1 -1
  9. package/dist/admin/PreviewFrame.js +6 -4
  10. package/dist/admin/PreviewFrame.js.map +1 -1
  11. package/dist/admin/PreviewToolbar.js +20 -13
  12. package/dist/admin/PreviewToolbar.js.map +1 -1
  13. package/dist/admin/SettingsBanner.js +10 -5
  14. package/dist/admin/SettingsBanner.js.map +1 -1
  15. package/dist/admin/ViewportToggle.js +30 -25
  16. package/dist/admin/ViewportToggle.js.map +1 -1
  17. package/dist/admin/blocks/AddBlockDrawer.js +7 -3
  18. package/dist/admin/blocks/AddBlockDrawer.js.map +1 -1
  19. package/dist/admin/blocks/BlockActionsToolbar.js +13 -11
  20. package/dist/admin/blocks/BlockActionsToolbar.js.map +1 -1
  21. package/dist/admin/blocks/BlockEmptyState.js +7 -3
  22. package/dist/admin/blocks/BlockEmptyState.js.map +1 -1
  23. package/dist/admin/blocks/BlockHeader.d.ts +1 -0
  24. package/dist/admin/blocks/BlockHeader.js +9 -8
  25. package/dist/admin/blocks/BlockHeader.js.map +1 -1
  26. package/dist/admin/blocks/schema.js +38 -7
  27. package/dist/admin/blocks/schema.js.map +1 -1
  28. package/dist/admin/sidebar/BlockSettingsTab.js +19 -4
  29. package/dist/admin/sidebar/BlockSettingsTab.js.map +1 -1
  30. package/dist/admin/sidebar/DocumentMetaTab.js +6 -2
  31. package/dist/admin/sidebar/DocumentMetaTab.js.map +1 -1
  32. package/dist/admin/sidebar/DocumentSettingsTab.js +6 -2
  33. package/dist/admin/sidebar/DocumentSettingsTab.js.map +1 -1
  34. package/dist/admin/sidebar/Sidebar.js +21 -16
  35. package/dist/admin/sidebar/Sidebar.js.map +1 -1
  36. package/dist/admin/sidebar/ValidationSummary.js +5 -2
  37. package/dist/admin/sidebar/ValidationSummary.js.map +1 -1
  38. package/dist/global.js +55 -39
  39. package/dist/global.js.map +1 -1
  40. package/dist/hooks/usePreviewBinding.js +6 -2
  41. package/dist/hooks/usePreviewBinding.js.map +1 -1
  42. package/dist/hooks/usePreviewSettingsSync.js +8 -3
  43. package/dist/hooks/usePreviewSettingsSync.js.map +1 -1
  44. package/dist/i18n/de.d.ts +2 -0
  45. package/dist/i18n/de.js +135 -0
  46. package/dist/i18n/de.js.map +1 -0
  47. package/dist/i18n/en.d.ts +2 -0
  48. package/dist/i18n/en.js +135 -0
  49. package/dist/i18n/en.js.map +1 -0
  50. package/dist/i18n/merge.d.ts +8 -0
  51. package/dist/i18n/merge.js +22 -0
  52. package/dist/i18n/merge.js.map +1 -0
  53. package/dist/i18n/types.d.ts +133 -0
  54. package/dist/i18n/types.js +3 -0
  55. package/dist/i18n/types.js.map +1 -0
  56. package/dist/i18n/useBetterEditorT.d.ts +2 -0
  57. package/dist/i18n/useBetterEditorT.js +10 -0
  58. package/dist/i18n/useBetterEditorT.js.map +1 -0
  59. package/dist/index.d.ts +2 -1
  60. package/dist/index.js +21 -2
  61. package/dist/index.js.map +1 -1
  62. package/dist/preview/HoverToolbar.d.ts +8 -0
  63. package/dist/preview/HoverToolbar.js +31 -29
  64. package/dist/preview/HoverToolbar.js.map +1 -1
  65. package/dist/preview/HoverToolbarController.d.ts +6 -0
  66. package/dist/preview/HoverToolbarController.js +20 -5
  67. package/dist/preview/HoverToolbarController.js.map +1 -1
  68. package/dist/preview/hover-css.d.ts +1 -0
  69. package/dist/preview/hover-css.js +18 -22
  70. package/dist/preview/hover-css.js.map +1 -1
  71. package/dist/styles/blocks-tab.css +1 -7
  72. package/dist/styles/overlay.css +2 -0
  73. package/dist/styles/sidebar.css +1 -0
  74. package/dist/styles/toggle.css +17 -0
  75. package/dist/types.d.ts +6 -0
  76. package/dist/types.js.map +1 -1
  77. package/dist/version.d.ts +1 -1
  78. package/dist/version.js +1 -1
  79. package/dist/version.js.map +1 -1
  80. package/package.json +13 -14
@@ -4,14 +4,5 @@ type Props = {
4
4
  onReset?: () => void;
5
5
  children: React.ReactNode;
6
6
  };
7
- type State = {
8
- error: Error | null;
9
- };
10
- export declare class OverlayErrorBoundary extends React.Component<Props, State> {
11
- state: State;
12
- static getDerivedStateFromError(error: Error): State;
13
- componentDidCatch(error: Error, info: React.ErrorInfo): void;
14
- private reset;
15
- render(): string | number | bigint | boolean | import("react/jsx-runtime").JSX.Element | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | null | undefined;
16
- }
7
+ export declare const OverlayErrorBoundary: React.FC<Props>;
17
8
  export {};
@@ -1,8 +1,9 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import React from 'react';
4
+ import { useBetterEditorT } from '../i18n/useBetterEditorT';
4
5
  const isDev = process.env.NODE_ENV !== 'production';
5
- export class OverlayErrorBoundary extends React.Component {
6
+ class OverlayErrorBoundaryInner extends React.Component {
6
7
  state = {
7
8
  error: null
8
9
  };
@@ -23,6 +24,7 @@ export class OverlayErrorBoundary extends React.Component {
23
24
  render() {
24
25
  const { error } = this.state;
25
26
  if (!error) return this.props.children;
27
+ const { labels } = this.props;
26
28
  return /*#__PURE__*/ _jsx("div", {
27
29
  className: "better-editor better-editor--errored",
28
30
  role: "alert",
@@ -30,10 +32,10 @@ export class OverlayErrorBoundary extends React.Component {
30
32
  className: "better-editor__error",
31
33
  children: [
32
34
  /*#__PURE__*/ _jsx("h3", {
33
- children: "Better Editor crashed"
35
+ children: labels.heading
34
36
  }),
35
37
  /*#__PURE__*/ _jsx("p", {
36
- children: error.message || 'Unknown error.'
38
+ children: error.message || labels.unknown
37
39
  }),
38
40
  isDev && error.stack ? /*#__PURE__*/ _jsx("pre", {
39
41
  children: error.stack
@@ -44,12 +46,12 @@ export class OverlayErrorBoundary extends React.Component {
44
46
  /*#__PURE__*/ _jsx("button", {
45
47
  type: "button",
46
48
  onClick: this.reset,
47
- children: "Try again"
49
+ children: labels.tryAgain
48
50
  }),
49
51
  /*#__PURE__*/ _jsx("button", {
50
52
  type: "button",
51
53
  onClick: this.props.onClose,
52
- children: "Close editor"
54
+ children: labels.closeEditor
53
55
  })
54
56
  ]
55
57
  })
@@ -58,5 +60,12 @@ export class OverlayErrorBoundary extends React.Component {
58
60
  });
59
61
  }
60
62
  }
63
+ export const OverlayErrorBoundary = (props)=>{
64
+ const t = useBetterEditorT();
65
+ return /*#__PURE__*/ _jsx(OverlayErrorBoundaryInner, {
66
+ ...props,
67
+ labels: t.error
68
+ });
69
+ };
61
70
 
62
71
  //# sourceMappingURL=ErrorBoundary.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/admin/ErrorBoundary.tsx"],"sourcesContent":["'use client'\n\nimport React from 'react'\n\ntype Props = {\n onClose: () => void\n onReset?: () => void\n children: React.ReactNode\n}\n\ntype State = {\n error: Error | null\n}\n\nconst isDev = process.env.NODE_ENV !== 'production'\n\nexport class OverlayErrorBoundary extends React.Component<Props, State> {\n state: State = { error: null }\n\n static getDerivedStateFromError(error: Error): State {\n return { error }\n }\n\n componentDidCatch(error: Error, info: React.ErrorInfo) {\n console.error('[better-editor] overlay crashed', error, info)\n }\n\n private reset = () => {\n this.props.onReset?.()\n this.setState({ error: null })\n }\n\n render() {\n const { error } = this.state\n if (!error) return this.props.children\n\n return (\n <div className=\"better-editor better-editor--errored\" role=\"alert\">\n <div className=\"better-editor__error\">\n <h3>Better Editor crashed</h3>\n <p>{error.message || 'Unknown error.'}</p>\n {isDev && error.stack ? <pre>{error.stack}</pre> : null}\n <div className=\"better-editor__error-actions\">\n <button type=\"button\" onClick={this.reset}>\n Try again\n </button>\n <button type=\"button\" onClick={this.props.onClose}>\n Close editor\n </button>\n </div>\n </div>\n </div>\n )\n }\n}\n"],"names":["React","isDev","process","env","NODE_ENV","OverlayErrorBoundary","Component","state","error","getDerivedStateFromError","componentDidCatch","info","console","reset","props","onReset","setState","render","children","div","className","role","h3","p","message","stack","pre","button","type","onClick","onClose"],"mappings":"AAAA;;AAEA,OAAOA,WAAW,QAAO;AAYzB,MAAMC,QAAQC,QAAQC,GAAG,CAACC,QAAQ,KAAK;AAEvC,OAAO,MAAMC,6BAA6BL,MAAMM,SAAS;IACvDC,QAAe;QAAEC,OAAO;IAAK,EAAC;IAE9B,OAAOC,yBAAyBD,KAAY,EAAS;QACnD,OAAO;YAAEA;QAAM;IACjB;IAEAE,kBAAkBF,KAAY,EAAEG,IAAqB,EAAE;QACrDC,QAAQJ,KAAK,CAAC,mCAAmCA,OAAOG;IAC1D;IAEQE,QAAQ;QACd,IAAI,CAACC,KAAK,CAACC,OAAO;QAClB,IAAI,CAACC,QAAQ,CAAC;YAAER,OAAO;QAAK;IAC9B,EAAC;IAEDS,SAAS;QACP,MAAM,EAAET,KAAK,EAAE,GAAG,IAAI,CAACD,KAAK;QAC5B,IAAI,CAACC,OAAO,OAAO,IAAI,CAACM,KAAK,CAACI,QAAQ;QAEtC,qBACE,KAACC;YAAIC,WAAU;YAAuCC,MAAK;sBACzD,cAAA,MAACF;gBAAIC,WAAU;;kCACb,KAACE;kCAAG;;kCACJ,KAACC;kCAAGf,MAAMgB,OAAO,IAAI;;oBACpBvB,SAASO,MAAMiB,KAAK,iBAAG,KAACC;kCAAKlB,MAAMiB,KAAK;yBAAU;kCACnD,MAACN;wBAAIC,WAAU;;0CACb,KAACO;gCAAOC,MAAK;gCAASC,SAAS,IAAI,CAAChB,KAAK;0CAAE;;0CAG3C,KAACc;gCAAOC,MAAK;gCAASC,SAAS,IAAI,CAACf,KAAK,CAACgB,OAAO;0CAAE;;;;;;;IAO7D;AACF"}
1
+ {"version":3,"sources":["../../src/admin/ErrorBoundary.tsx"],"sourcesContent":["'use client'\n\nimport React from 'react'\nimport { useBetterEditorT } from '../i18n/useBetterEditorT'\nimport type { BetterEditorTranslations } from '../i18n/types'\n\ntype Props = {\n onClose: () => void\n onReset?: () => void\n children: React.ReactNode\n}\n\ntype InnerProps = Props & { labels: BetterEditorTranslations['error'] }\n\ntype State = {\n error: Error | null\n}\n\nconst isDev = process.env.NODE_ENV !== 'production'\n\nclass OverlayErrorBoundaryInner extends React.Component<InnerProps, State> {\n state: State = { error: null }\n\n static getDerivedStateFromError(error: Error): State {\n return { error }\n }\n\n componentDidCatch(error: Error, info: React.ErrorInfo) {\n console.error('[better-editor] overlay crashed', error, info)\n }\n\n private reset = () => {\n this.props.onReset?.()\n this.setState({ error: null })\n }\n\n render() {\n const { error } = this.state\n if (!error) return this.props.children\n\n const { labels } = this.props\n return (\n <div className=\"better-editor better-editor--errored\" role=\"alert\">\n <div className=\"better-editor__error\">\n <h3>{labels.heading}</h3>\n <p>{error.message || labels.unknown}</p>\n {isDev && error.stack ? <pre>{error.stack}</pre> : null}\n <div className=\"better-editor__error-actions\">\n <button type=\"button\" onClick={this.reset}>\n {labels.tryAgain}\n </button>\n <button type=\"button\" onClick={this.props.onClose}>\n {labels.closeEditor}\n </button>\n </div>\n </div>\n </div>\n )\n }\n}\n\nexport const OverlayErrorBoundary: React.FC<Props> = (props) => {\n const t = useBetterEditorT()\n return <OverlayErrorBoundaryInner {...props} labels={t.error} />\n}\n"],"names":["React","useBetterEditorT","isDev","process","env","NODE_ENV","OverlayErrorBoundaryInner","Component","state","error","getDerivedStateFromError","componentDidCatch","info","console","reset","props","onReset","setState","render","children","labels","div","className","role","h3","heading","p","message","unknown","stack","pre","button","type","onClick","tryAgain","onClose","closeEditor","OverlayErrorBoundary","t"],"mappings":"AAAA;;AAEA,OAAOA,WAAW,QAAO;AACzB,SAASC,gBAAgB,QAAQ,2BAA0B;AAe3D,MAAMC,QAAQC,QAAQC,GAAG,CAACC,QAAQ,KAAK;AAEvC,MAAMC,kCAAkCN,MAAMO,SAAS;IACrDC,QAAe;QAAEC,OAAO;IAAK,EAAC;IAE9B,OAAOC,yBAAyBD,KAAY,EAAS;QACnD,OAAO;YAAEA;QAAM;IACjB;IAEAE,kBAAkBF,KAAY,EAAEG,IAAqB,EAAE;QACrDC,QAAQJ,KAAK,CAAC,mCAAmCA,OAAOG;IAC1D;IAEQE,QAAQ;QACd,IAAI,CAACC,KAAK,CAACC,OAAO;QAClB,IAAI,CAACC,QAAQ,CAAC;YAAER,OAAO;QAAK;IAC9B,EAAC;IAEDS,SAAS;QACP,MAAM,EAAET,KAAK,EAAE,GAAG,IAAI,CAACD,KAAK;QAC5B,IAAI,CAACC,OAAO,OAAO,IAAI,CAACM,KAAK,CAACI,QAAQ;QAEtC,MAAM,EAAEC,MAAM,EAAE,GAAG,IAAI,CAACL,KAAK;QAC7B,qBACE,KAACM;YAAIC,WAAU;YAAuCC,MAAK;sBACzD,cAAA,MAACF;gBAAIC,WAAU;;kCACb,KAACE;kCAAIJ,OAAOK,OAAO;;kCACnB,KAACC;kCAAGjB,MAAMkB,OAAO,IAAIP,OAAOQ,OAAO;;oBAClC1B,SAASO,MAAMoB,KAAK,iBAAG,KAACC;kCAAKrB,MAAMoB,KAAK;yBAAU;kCACnD,MAACR;wBAAIC,WAAU;;0CACb,KAACS;gCAAOC,MAAK;gCAASC,SAAS,IAAI,CAACnB,KAAK;0CACtCM,OAAOc,QAAQ;;0CAElB,KAACH;gCAAOC,MAAK;gCAASC,SAAS,IAAI,CAAClB,KAAK,CAACoB,OAAO;0CAC9Cf,OAAOgB,WAAW;;;;;;;IAM/B;AACF;AAEA,OAAO,MAAMC,uBAAwC,CAACtB;IACpD,MAAMuB,IAAIrC;IACV,qBAAO,KAACK;QAA2B,GAAGS,KAAK;QAAEK,QAAQkB,EAAE7B,KAAK;;AAC9D,EAAC"}
@@ -14,6 +14,7 @@ import { useBlockActionMessages } from '../hooks/useBlockActionMessages';
14
14
  import { useOverlayKeyboard } from '../hooks/useOverlayKeyboard';
15
15
  import { useFocusTrap } from '../hooks/useFocusTrap';
16
16
  import { OverlayProviders } from '../providers/OverlayProviders';
17
+ import { useBetterEditorT } from '../i18n/useBetterEditorT';
17
18
  import '../styles/overlay.css';
18
19
  import '../styles/preview.css';
19
20
  import '../styles/sidebar.css';
@@ -38,6 +39,7 @@ export const LiveEditorOverlay = ({ onClose, blocksField, storageNamespace, admi
38
39
  });
39
40
  };
40
41
  const LiveEditorOverlayInner = ({ blocksField, selectedBlockPath, setSelectedBlockPath })=>{
42
+ const t = useBetterEditorT();
41
43
  const settings = useBetterEditorSettings();
42
44
  const history = useEditorHistory();
43
45
  const { previewURL } = useLivePreviewContext();
@@ -72,7 +74,7 @@ const LiveEditorOverlayInner = ({ blocksField, selectedBlockPath, setSelectedBlo
72
74
  className: classes('better-editor', isResizing && 'better-editor--resizing', isFullscreen && 'better-editor--fullscreen'),
73
75
  role: "dialog",
74
76
  "aria-modal": "true",
75
- "aria-label": "Better Editor",
77
+ "aria-label": t.overlay.dialogLabel,
76
78
  tabIndex: -1,
77
79
  children: /*#__PURE__*/ _jsxs("div", {
78
80
  className: "better-editor__body",
@@ -127,7 +129,7 @@ const LiveEditorOverlayInner = ({ blocksField, selectedBlockPath, setSelectedBlo
127
129
  },
128
130
  role: "separator",
129
131
  "aria-orientation": "vertical",
130
- "aria-label": "Resize sidebar (use ← / → arrow keys)",
132
+ "aria-label": t.overlay.resizeSidebar,
131
133
  "aria-valuenow": sidebarWidth,
132
134
  tabIndex: 0,
133
135
  onMouseDown: onResizeStart,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/admin/LiveEditorOverlay.tsx"],"sourcesContent":["'use client'\n\nimport React, { useCallback, useRef, useState } from 'react'\nimport { useLivePreviewContext } from '@payloadcms/ui'\nimport { PreviewFrame } from './PreviewFrame'\nimport { PreviewToolbar } from './PreviewToolbar'\nimport { Sidebar } from './sidebar/Sidebar'\nimport { useBetterEditorSettings } from '../state/useBetterEditorSettings'\nimport { useEditorHistory } from '../state/useEditorHistory'\nimport { useSidebarResize } from '../hooks/useSidebarResize'\nimport { useViewportState } from '../hooks/useViewportState'\nimport { useFullscreenOverlay } from '../hooks/useFullscreenOverlay'\nimport { useBlockActionMessages } from '../hooks/useBlockActionMessages'\nimport { useOverlayKeyboard } from '../hooks/useOverlayKeyboard'\nimport { useFocusTrap } from '../hooks/useFocusTrap'\nimport { OverlayProviders } from '../providers/OverlayProviders'\nimport '../styles/overlay.css'\nimport '../styles/preview.css'\nimport '../styles/sidebar.css'\nimport '../styles/blocks-tab.css'\n\nexport type LiveEditorOverlayProps = {\n onClose: () => void\n blocksField: string\n storageNamespace?: string\n adminPortalSelector?: string\n}\n\nconst RESIZE_HANDLE_PX = 6\n\nconst classes = (...parts: Array<string | false | null | undefined>): string =>\n parts.filter(Boolean).join(' ')\n\nexport const LiveEditorOverlay: React.FC<LiveEditorOverlayProps> = ({\n onClose,\n blocksField,\n storageNamespace,\n adminPortalSelector,\n}) => {\n // Selection state lives outside OverlayProviders so the error boundary's\n // onReset can clear it without remounting providers.\n const [selectedBlockPath, setSelectedBlockPath] = useState<string | null>(null)\n const clearSelection = useCallback(() => setSelectedBlockPath(null), [])\n\n return (\n <OverlayProviders\n onClose={onClose}\n onReset={clearSelection}\n storageNamespace={storageNamespace}\n adminPortalSelector={adminPortalSelector}\n >\n <LiveEditorOverlayInner\n blocksField={blocksField}\n selectedBlockPath={selectedBlockPath}\n setSelectedBlockPath={setSelectedBlockPath}\n />\n </OverlayProviders>\n )\n}\n\ntype InnerProps = Omit<LiveEditorOverlayProps, 'onClose'> & {\n selectedBlockPath: string | null\n setSelectedBlockPath: React.Dispatch<React.SetStateAction<string | null>>\n}\n\nconst LiveEditorOverlayInner: React.FC<InnerProps> = ({\n blocksField,\n selectedBlockPath,\n setSelectedBlockPath,\n}) => {\n const settings = useBetterEditorSettings()\n const history = useEditorHistory()\n const { previewURL } = useLivePreviewContext()\n\n const { sidebarWidth, isResizing, onResizeStart, onResizeKeyDown } = useSidebarResize(\n settings.sidebarPosition,\n )\n const {\n viewport,\n setViewport,\n setResponsiveWidth,\n viewportWidth,\n } = useViewportState(settings)\n // Shared with the toolbar's width chip, which measures the iframe directly.\n const iframeRef = useRef<HTMLIFrameElement | null>(null)\n\n const [isFullscreen, setIsFullscreen] = useState(false)\n const toggleFullscreen = useCallback(() => setIsFullscreen((v) => !v), [])\n const exitFullscreen = useCallback(() => setIsFullscreen(false), [])\n const overlayRef = useFullscreenOverlay(isFullscreen, exitFullscreen)\n useFocusTrap(overlayRef)\n\n const clearSelection = useCallback(\n () => setSelectedBlockPath(null),\n [setSelectedBlockPath],\n )\n\n const { addBelowRequestId } = useBlockActionMessages({\n selectedBlockPath,\n setSelectedBlockPath,\n })\n\n useOverlayKeyboard({ history })\n\n const [sidebarCollapsed, setSidebarCollapsed] = useState(false)\n const toggleSidebar = useCallback(() => setSidebarCollapsed((v) => !v), [])\n\n const [interactMode, setInteractMode] = useState(false)\n const toggleInteractMode = useCallback(() => setInteractMode((v) => !v), [])\n\n const isLeft = settings.sidebarPosition === 'left'\n const showSidebar = !sidebarCollapsed\n const gridTemplateColumns = !showSidebar\n ? '1fr'\n : isLeft\n ? `${sidebarWidth}px ${RESIZE_HANDLE_PX}px 1fr`\n : `1fr ${RESIZE_HANDLE_PX}px ${sidebarWidth}px`\n\n return (\n <div\n ref={overlayRef}\n className={classes(\n 'better-editor',\n isResizing && 'better-editor--resizing',\n isFullscreen && 'better-editor--fullscreen',\n )}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Better Editor\"\n tabIndex={-1}\n >\n <div className=\"better-editor__body\" style={{ gridTemplateColumns }}>\n <div className=\"better-editor__preview\" style={{ order: isLeft ? 2 : 0 }}>\n <PreviewToolbar\n history={history}\n viewport={viewport}\n onViewportChange={setViewport}\n iframeRef={iframeRef}\n isFullscreen={isFullscreen}\n onFullscreenToggle={toggleFullscreen}\n interactMode={interactMode}\n onInteractToggle={toggleInteractMode}\n sidebarCollapsed={sidebarCollapsed}\n onSidebarToggle={toggleSidebar}\n />\n <div className=\"better-editor__preview-stage\">\n <PreviewFrame\n iframeRef={iframeRef}\n previewURL={previewURL}\n hoverColorTopLevel={settings.hoverColorTopLevel}\n hoverColorNested={settings.hoverColorNested}\n hoverOutlineWidth={settings.hoverOutlineWidth}\n showHoverToolbar={settings.showHoverToolbar}\n hoverToolbarPosition={settings.hoverToolbarPosition}\n selectedBlockPath={selectedBlockPath}\n interactMode={interactMode}\n viewport={viewport}\n viewportWidth={viewportWidth}\n resizable={viewport === 'responsive'}\n onResize={setResponsiveWidth}\n />\n </div>\n </div>\n {showSidebar ? (\n <>\n <div\n className=\"better-editor__resize-handle\"\n style={{ order: 1 }}\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-label=\"Resize sidebar (use ← / → arrow keys)\"\n aria-valuenow={sidebarWidth}\n tabIndex={0}\n onMouseDown={onResizeStart}\n onKeyDown={onResizeKeyDown}\n />\n <aside\n className=\"better-editor__sidebar\"\n style={{ order: isLeft ? 0 : 2 }}\n >\n <Sidebar\n selectedBlockPath={selectedBlockPath}\n onClearSelection={clearSelection}\n onSelectPath={setSelectedBlockPath}\n forceFullWidthFields={settings.forceFullWidthFields}\n blocksField={blocksField}\n addBelowRequestId={addBelowRequestId}\n />\n </aside>\n </>\n ) : null}\n </div>\n </div>\n )\n}\n\n"],"names":["React","useCallback","useRef","useState","useLivePreviewContext","PreviewFrame","PreviewToolbar","Sidebar","useBetterEditorSettings","useEditorHistory","useSidebarResize","useViewportState","useFullscreenOverlay","useBlockActionMessages","useOverlayKeyboard","useFocusTrap","OverlayProviders","RESIZE_HANDLE_PX","classes","parts","filter","Boolean","join","LiveEditorOverlay","onClose","blocksField","storageNamespace","adminPortalSelector","selectedBlockPath","setSelectedBlockPath","clearSelection","onReset","LiveEditorOverlayInner","settings","history","previewURL","sidebarWidth","isResizing","onResizeStart","onResizeKeyDown","sidebarPosition","viewport","setViewport","setResponsiveWidth","viewportWidth","iframeRef","isFullscreen","setIsFullscreen","toggleFullscreen","v","exitFullscreen","overlayRef","addBelowRequestId","sidebarCollapsed","setSidebarCollapsed","toggleSidebar","interactMode","setInteractMode","toggleInteractMode","isLeft","showSidebar","gridTemplateColumns","div","ref","className","role","aria-modal","aria-label","tabIndex","style","order","onViewportChange","onFullscreenToggle","onInteractToggle","onSidebarToggle","hoverColorTopLevel","hoverColorNested","hoverOutlineWidth","showHoverToolbar","hoverToolbarPosition","resizable","onResize","aria-orientation","aria-valuenow","onMouseDown","onKeyDown","aside","onClearSelection","onSelectPath","forceFullWidthFields"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/admin/LiveEditorOverlay.tsx"],"sourcesContent":["'use client'\n\nimport React, { useCallback, useRef, useState } from 'react'\nimport { useLivePreviewContext } from '@payloadcms/ui'\nimport { PreviewFrame } from './PreviewFrame'\nimport { PreviewToolbar } from './PreviewToolbar'\nimport { Sidebar } from './sidebar/Sidebar'\nimport { useBetterEditorSettings } from '../state/useBetterEditorSettings'\nimport { useEditorHistory } from '../state/useEditorHistory'\nimport { useSidebarResize } from '../hooks/useSidebarResize'\nimport { useViewportState } from '../hooks/useViewportState'\nimport { useFullscreenOverlay } from '../hooks/useFullscreenOverlay'\nimport { useBlockActionMessages } from '../hooks/useBlockActionMessages'\nimport { useOverlayKeyboard } from '../hooks/useOverlayKeyboard'\nimport { useFocusTrap } from '../hooks/useFocusTrap'\nimport { OverlayProviders } from '../providers/OverlayProviders'\nimport { useBetterEditorT } from '../i18n/useBetterEditorT'\nimport '../styles/overlay.css'\nimport '../styles/preview.css'\nimport '../styles/sidebar.css'\nimport '../styles/blocks-tab.css'\n\nexport type LiveEditorOverlayProps = {\n onClose: () => void\n blocksField: string\n storageNamespace?: string\n adminPortalSelector?: string\n}\n\nconst RESIZE_HANDLE_PX = 6\n\nconst classes = (...parts: Array<string | false | null | undefined>): string =>\n parts.filter(Boolean).join(' ')\n\nexport const LiveEditorOverlay: React.FC<LiveEditorOverlayProps> = ({\n onClose,\n blocksField,\n storageNamespace,\n adminPortalSelector,\n}) => {\n // Selection state lives outside OverlayProviders so the error boundary's\n // onReset can clear it without remounting providers.\n const [selectedBlockPath, setSelectedBlockPath] = useState<string | null>(null)\n const clearSelection = useCallback(() => setSelectedBlockPath(null), [])\n\n return (\n <OverlayProviders\n onClose={onClose}\n onReset={clearSelection}\n storageNamespace={storageNamespace}\n adminPortalSelector={adminPortalSelector}\n >\n <LiveEditorOverlayInner\n blocksField={blocksField}\n selectedBlockPath={selectedBlockPath}\n setSelectedBlockPath={setSelectedBlockPath}\n />\n </OverlayProviders>\n )\n}\n\ntype InnerProps = Omit<LiveEditorOverlayProps, 'onClose'> & {\n selectedBlockPath: string | null\n setSelectedBlockPath: React.Dispatch<React.SetStateAction<string | null>>\n}\n\nconst LiveEditorOverlayInner: React.FC<InnerProps> = ({\n blocksField,\n selectedBlockPath,\n setSelectedBlockPath,\n}) => {\n const t = useBetterEditorT()\n const settings = useBetterEditorSettings()\n const history = useEditorHistory()\n const { previewURL } = useLivePreviewContext()\n\n const { sidebarWidth, isResizing, onResizeStart, onResizeKeyDown } = useSidebarResize(\n settings.sidebarPosition,\n )\n const {\n viewport,\n setViewport,\n setResponsiveWidth,\n viewportWidth,\n } = useViewportState(settings)\n // Shared with the toolbar's width chip, which measures the iframe directly.\n const iframeRef = useRef<HTMLIFrameElement | null>(null)\n\n const [isFullscreen, setIsFullscreen] = useState(false)\n const toggleFullscreen = useCallback(() => setIsFullscreen((v) => !v), [])\n const exitFullscreen = useCallback(() => setIsFullscreen(false), [])\n const overlayRef = useFullscreenOverlay(isFullscreen, exitFullscreen)\n useFocusTrap(overlayRef)\n\n const clearSelection = useCallback(\n () => setSelectedBlockPath(null),\n [setSelectedBlockPath],\n )\n\n const { addBelowRequestId } = useBlockActionMessages({\n selectedBlockPath,\n setSelectedBlockPath,\n })\n\n useOverlayKeyboard({ history })\n\n const [sidebarCollapsed, setSidebarCollapsed] = useState(false)\n const toggleSidebar = useCallback(() => setSidebarCollapsed((v) => !v), [])\n\n const [interactMode, setInteractMode] = useState(false)\n const toggleInteractMode = useCallback(() => setInteractMode((v) => !v), [])\n\n const isLeft = settings.sidebarPosition === 'left'\n const showSidebar = !sidebarCollapsed\n const gridTemplateColumns = !showSidebar\n ? '1fr'\n : isLeft\n ? `${sidebarWidth}px ${RESIZE_HANDLE_PX}px 1fr`\n : `1fr ${RESIZE_HANDLE_PX}px ${sidebarWidth}px`\n\n return (\n <div\n ref={overlayRef}\n className={classes(\n 'better-editor',\n isResizing && 'better-editor--resizing',\n isFullscreen && 'better-editor--fullscreen',\n )}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={t.overlay.dialogLabel}\n tabIndex={-1}\n >\n <div className=\"better-editor__body\" style={{ gridTemplateColumns }}>\n <div className=\"better-editor__preview\" style={{ order: isLeft ? 2 : 0 }}>\n <PreviewToolbar\n history={history}\n viewport={viewport}\n onViewportChange={setViewport}\n iframeRef={iframeRef}\n isFullscreen={isFullscreen}\n onFullscreenToggle={toggleFullscreen}\n interactMode={interactMode}\n onInteractToggle={toggleInteractMode}\n sidebarCollapsed={sidebarCollapsed}\n onSidebarToggle={toggleSidebar}\n />\n <div className=\"better-editor__preview-stage\">\n <PreviewFrame\n iframeRef={iframeRef}\n previewURL={previewURL}\n hoverColorTopLevel={settings.hoverColorTopLevel}\n hoverColorNested={settings.hoverColorNested}\n hoverOutlineWidth={settings.hoverOutlineWidth}\n showHoverToolbar={settings.showHoverToolbar}\n hoverToolbarPosition={settings.hoverToolbarPosition}\n selectedBlockPath={selectedBlockPath}\n interactMode={interactMode}\n viewport={viewport}\n viewportWidth={viewportWidth}\n resizable={viewport === 'responsive'}\n onResize={setResponsiveWidth}\n />\n </div>\n </div>\n {showSidebar ? (\n <>\n <div\n className=\"better-editor__resize-handle\"\n style={{ order: 1 }}\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-label={t.overlay.resizeSidebar}\n aria-valuenow={sidebarWidth}\n tabIndex={0}\n onMouseDown={onResizeStart}\n onKeyDown={onResizeKeyDown}\n />\n <aside\n className=\"better-editor__sidebar\"\n style={{ order: isLeft ? 0 : 2 }}\n >\n <Sidebar\n selectedBlockPath={selectedBlockPath}\n onClearSelection={clearSelection}\n onSelectPath={setSelectedBlockPath}\n forceFullWidthFields={settings.forceFullWidthFields}\n blocksField={blocksField}\n addBelowRequestId={addBelowRequestId}\n />\n </aside>\n </>\n ) : null}\n </div>\n </div>\n )\n}\n\n"],"names":["React","useCallback","useRef","useState","useLivePreviewContext","PreviewFrame","PreviewToolbar","Sidebar","useBetterEditorSettings","useEditorHistory","useSidebarResize","useViewportState","useFullscreenOverlay","useBlockActionMessages","useOverlayKeyboard","useFocusTrap","OverlayProviders","useBetterEditorT","RESIZE_HANDLE_PX","classes","parts","filter","Boolean","join","LiveEditorOverlay","onClose","blocksField","storageNamespace","adminPortalSelector","selectedBlockPath","setSelectedBlockPath","clearSelection","onReset","LiveEditorOverlayInner","t","settings","history","previewURL","sidebarWidth","isResizing","onResizeStart","onResizeKeyDown","sidebarPosition","viewport","setViewport","setResponsiveWidth","viewportWidth","iframeRef","isFullscreen","setIsFullscreen","toggleFullscreen","v","exitFullscreen","overlayRef","addBelowRequestId","sidebarCollapsed","setSidebarCollapsed","toggleSidebar","interactMode","setInteractMode","toggleInteractMode","isLeft","showSidebar","gridTemplateColumns","div","ref","className","role","aria-modal","aria-label","overlay","dialogLabel","tabIndex","style","order","onViewportChange","onFullscreenToggle","onInteractToggle","onSidebarToggle","hoverColorTopLevel","hoverColorNested","hoverOutlineWidth","showHoverToolbar","hoverToolbarPosition","resizable","onResize","aria-orientation","resizeSidebar","aria-valuenow","onMouseDown","onKeyDown","aside","onClearSelection","onSelectPath","forceFullWidthFields"],"mappings":"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"}
@@ -1,7 +1,9 @@
1
1
  import React from 'react';
2
+ import '../styles/toggle.css';
2
3
  export type LiveEditorToggleProps = {
3
4
  blocksField: string;
4
5
  adminPortalSelector?: string;
5
6
  storageNamespace?: string;
7
+ hideToggleLabel?: boolean;
6
8
  };
7
9
  export declare const LiveEditorToggle: React.FC<LiveEditorToggleProps>;
@@ -7,7 +7,9 @@ import { LiveEditorOverlay } from './LiveEditorOverlay';
7
7
  import { useMainWrapperPortal } from '../hooks/useMainWrapperPortal';
8
8
  import { buildStorageKeys } from '../internal/storage-keys';
9
9
  import { LayoutIcon } from './icons';
10
- export const LiveEditorToggle = ({ blocksField, adminPortalSelector, storageNamespace })=>{
10
+ import { useBetterEditorT } from '../i18n/useBetterEditorT';
11
+ import '../styles/toggle.css';
12
+ export const LiveEditorToggle = ({ blocksField, adminPortalSelector, storageNamespace, hideToggleLabel })=>{
11
13
  const [open, setOpen] = useState(false);
12
14
  const { collectionSlug, globalSlug } = useDocumentInfo();
13
15
  const { previewURL } = useLivePreviewContext();
@@ -48,7 +50,8 @@ export const LiveEditorToggle = ({ blocksField, adminPortalSelector, storageName
48
50
  const handleToggle = useCallback(()=>setOpen((v)=>!v), []);
49
51
  const handleClose = useCallback(()=>setOpen(false), []);
50
52
  const mountNode = useMainWrapperPortal(open, adminPortalSelector);
51
- const label = open ? 'Close Better Editor' : 'Open Better Editor';
53
+ const t = useBetterEditorT();
54
+ const label = open ? t.toggle.close : t.toggle.open;
52
55
  // Mirror Payload's official live-preview behaviour: only surface the
53
56
  // toggle once a previewURL is actually resolvable (collection has
54
57
  // `admin.livePreview.url` configured AND the document has the data
@@ -58,18 +61,20 @@ export const LiveEditorToggle = ({ blocksField, adminPortalSelector, storageName
58
61
  if (!previewURL) return null;
59
62
  return /*#__PURE__*/ _jsxs(_Fragment, {
60
63
  children: [
61
- /*#__PURE__*/ _jsx("button", {
64
+ /*#__PURE__*/ _jsxs("button", {
62
65
  "aria-label": label,
63
66
  "aria-pressed": open,
64
- className: "preview-btn",
67
+ className: "preview-btn better-editor-toggle",
65
68
  onClick: handleToggle,
66
69
  title: label,
67
70
  type: "button",
68
- style: open ? {
69
- borderColor: 'var(--theme-elevation-300)',
70
- backgroundColor: 'var(--theme-elevation-100)'
71
- } : undefined,
72
- children: /*#__PURE__*/ _jsx(LayoutIcon, {})
71
+ children: [
72
+ hideToggleLabel ? null : /*#__PURE__*/ _jsx("span", {
73
+ className: "better-editor-toggle__label",
74
+ children: label
75
+ }),
76
+ /*#__PURE__*/ _jsx(LayoutIcon, {})
77
+ ]
73
78
  }),
74
79
  open && mountNode ? /*#__PURE__*/ createPortal(/*#__PURE__*/ _jsx(LiveEditorOverlay, {
75
80
  onClose: handleClose,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/admin/LiveEditorToggle.tsx"],"sourcesContent":["'use client'\n\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\nimport { useDocumentInfo, useLivePreviewContext, usePreferences } from '@payloadcms/ui'\nimport { LiveEditorOverlay } from './LiveEditorOverlay'\nimport { useMainWrapperPortal } from '../hooks/useMainWrapperPortal'\nimport { buildStorageKeys } from '../internal/storage-keys'\nimport { LayoutIcon } from './icons'\n\ntype Pref = { open?: boolean }\n\nexport type LiveEditorToggleProps = {\n blocksField: string\n adminPortalSelector?: string\n storageNamespace?: string\n}\n\nexport const LiveEditorToggle: React.FC<LiveEditorToggleProps> = ({\n blocksField,\n adminPortalSelector,\n storageNamespace,\n}) => {\n const [open, setOpen] = useState(false)\n const { collectionSlug, globalSlug } = useDocumentInfo()\n const { previewURL } = useLivePreviewContext()\n const { getPreference, setPreference } = usePreferences()\n const storageKeys = useMemo(() => buildStorageKeys(storageNamespace), [storageNamespace])\n const prefKey = storageKeys.togglePreference(collectionSlug, globalSlug)\n\n // Tracks the prefKey we've successfully hydrated against so persistence\n // can't fire with the initial `false` before the read resolves, and so\n // switching documents reseeds without clobbering the new doc's pref.\n const hydratedKeyRef = useRef<string | null>(null)\n\n useEffect(() => {\n let cancelled = false\n hydratedKeyRef.current = null\n void getPreference<Pref>(prefKey).then((pref) => {\n if (cancelled) return\n hydratedKeyRef.current = prefKey\n setOpen(Boolean(pref?.open))\n })\n return () => {\n cancelled = true\n }\n }, [prefKey, getPreference])\n\n useEffect(() => {\n if (hydratedKeyRef.current !== prefKey) return\n void setPreference<Pref>(prefKey, { open }, true)\n }, [open, prefKey, setPreference])\n\n const handleToggle = useCallback(() => setOpen((v) => !v), [])\n const handleClose = useCallback(() => setOpen(false), [])\n\n const mountNode = useMainWrapperPortal(open, adminPortalSelector)\n const label = open ? 'Close Better Editor' : 'Open Better Editor'\n\n // Mirror Payload's official live-preview behaviour: only surface the\n // toggle once a previewURL is actually resolvable (collection has\n // `admin.livePreview.url` configured AND the document has the data\n // the URL function depends on, e.g. slug). Hiding the button avoids\n // the misleading \"Loading preview URL…\" / \"not configured\" empty\n // states inside the overlay entirely.\n if (!previewURL) return null\n\n return (\n <>\n <button\n aria-label={label}\n aria-pressed={open}\n className=\"preview-btn\"\n onClick={handleToggle}\n title={label}\n type=\"button\"\n style={\n open\n ? {\n borderColor: 'var(--theme-elevation-300)',\n backgroundColor: 'var(--theme-elevation-100)',\n }\n : undefined\n }\n >\n <LayoutIcon />\n </button>\n\n {open && mountNode\n ? createPortal(\n <LiveEditorOverlay\n onClose={handleClose}\n blocksField={blocksField}\n storageNamespace={storageNamespace}\n adminPortalSelector={adminPortalSelector}\n />,\n mountNode,\n )\n : null}\n </>\n )\n}\n"],"names":["React","useCallback","useEffect","useMemo","useRef","useState","createPortal","useDocumentInfo","useLivePreviewContext","usePreferences","LiveEditorOverlay","useMainWrapperPortal","buildStorageKeys","LayoutIcon","LiveEditorToggle","blocksField","adminPortalSelector","storageNamespace","open","setOpen","collectionSlug","globalSlug","previewURL","getPreference","setPreference","storageKeys","prefKey","togglePreference","hydratedKeyRef","cancelled","current","then","pref","Boolean","handleToggle","v","handleClose","mountNode","label","button","aria-label","aria-pressed","className","onClick","title","type","style","borderColor","backgroundColor","undefined","onClose"],"mappings":"AAAA;;AAEA,OAAOA,SAASC,WAAW,EAAEC,SAAS,EAAEC,OAAO,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,QAAO;AAChF,SAASC,YAAY,QAAQ,YAAW;AACxC,SAASC,eAAe,EAAEC,qBAAqB,EAAEC,cAAc,QAAQ,iBAAgB;AACvF,SAASC,iBAAiB,QAAQ,sBAAqB;AACvD,SAASC,oBAAoB,QAAQ,gCAA+B;AACpE,SAASC,gBAAgB,QAAQ,2BAA0B;AAC3D,SAASC,UAAU,QAAQ,UAAS;AAUpC,OAAO,MAAMC,mBAAoD,CAAC,EAChEC,WAAW,EACXC,mBAAmB,EACnBC,gBAAgB,EACjB;IACC,MAAM,CAACC,MAAMC,QAAQ,GAAGd,SAAS;IACjC,MAAM,EAAEe,cAAc,EAAEC,UAAU,EAAE,GAAGd;IACvC,MAAM,EAAEe,UAAU,EAAE,GAAGd;IACvB,MAAM,EAAEe,aAAa,EAAEC,aAAa,EAAE,GAAGf;IACzC,MAAMgB,cAActB,QAAQ,IAAMS,iBAAiBK,mBAAmB;QAACA;KAAiB;IACxF,MAAMS,UAAUD,YAAYE,gBAAgB,CAACP,gBAAgBC;IAE7D,wEAAwE;IACxE,uEAAuE;IACvE,qEAAqE;IACrE,MAAMO,iBAAiBxB,OAAsB;IAE7CF,UAAU;QACR,IAAI2B,YAAY;QAChBD,eAAeE,OAAO,GAAG;QACzB,KAAKP,cAAoBG,SAASK,IAAI,CAAC,CAACC;YACtC,IAAIH,WAAW;YACfD,eAAeE,OAAO,GAAGJ;YACzBP,QAAQc,QAAQD,MAAMd;QACxB;QACA,OAAO;YACLW,YAAY;QACd;IACF,GAAG;QAACH;QAASH;KAAc;IAE3BrB,UAAU;QACR,IAAI0B,eAAeE,OAAO,KAAKJ,SAAS;QACxC,KAAKF,cAAoBE,SAAS;YAAER;QAAK,GAAG;IAC9C,GAAG;QAACA;QAAMQ;QAASF;KAAc;IAEjC,MAAMU,eAAejC,YAAY,IAAMkB,QAAQ,CAACgB,IAAM,CAACA,IAAI,EAAE;IAC7D,MAAMC,cAAcnC,YAAY,IAAMkB,QAAQ,QAAQ,EAAE;IAExD,MAAMkB,YAAY1B,qBAAqBO,MAAMF;IAC7C,MAAMsB,QAAQpB,OAAO,wBAAwB;IAE7C,qEAAqE;IACrE,kEAAkE;IAClE,mEAAmE;IACnE,oEAAoE;IACpE,iEAAiE;IACjE,sCAAsC;IACtC,IAAI,CAACI,YAAY,OAAO;IAExB,qBACE;;0BACE,KAACiB;gBACCC,cAAYF;gBACZG,gBAAcvB;gBACdwB,WAAU;gBACVC,SAAST;gBACTU,OAAON;gBACPO,MAAK;gBACLC,OACE5B,OACI;oBACE6B,aAAa;oBACbC,iBAAiB;gBACnB,IACAC;0BAGN,cAAA,KAACpC;;YAGFK,QAAQmB,0BACL/B,2BACE,KAACI;gBACCwC,SAASd;gBACTrB,aAAaA;gBACbE,kBAAkBA;gBAClBD,qBAAqBA;gBAEvBqB,aAEF;;;AAGV,EAAC"}
1
+ {"version":3,"sources":["../../src/admin/LiveEditorToggle.tsx"],"sourcesContent":["'use client'\n\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\nimport { useDocumentInfo, useLivePreviewContext, usePreferences } from '@payloadcms/ui'\nimport { LiveEditorOverlay } from './LiveEditorOverlay'\nimport { useMainWrapperPortal } from '../hooks/useMainWrapperPortal'\nimport { buildStorageKeys } from '../internal/storage-keys'\nimport { LayoutIcon } from './icons'\nimport { useBetterEditorT } from '../i18n/useBetterEditorT'\nimport '../styles/toggle.css'\n\ntype Pref = { open?: boolean }\n\nexport type LiveEditorToggleProps = {\n blocksField: string\n adminPortalSelector?: string\n storageNamespace?: string\n hideToggleLabel?: boolean\n}\n\nexport const LiveEditorToggle: React.FC<LiveEditorToggleProps> = ({\n blocksField,\n adminPortalSelector,\n storageNamespace,\n hideToggleLabel,\n}) => {\n const [open, setOpen] = useState(false)\n const { collectionSlug, globalSlug } = useDocumentInfo()\n const { previewURL } = useLivePreviewContext()\n const { getPreference, setPreference } = usePreferences()\n const storageKeys = useMemo(() => buildStorageKeys(storageNamespace), [storageNamespace])\n const prefKey = storageKeys.togglePreference(collectionSlug, globalSlug)\n\n // Tracks the prefKey we've successfully hydrated against so persistence\n // can't fire with the initial `false` before the read resolves, and so\n // switching documents reseeds without clobbering the new doc's pref.\n const hydratedKeyRef = useRef<string | null>(null)\n\n useEffect(() => {\n let cancelled = false\n hydratedKeyRef.current = null\n void getPreference<Pref>(prefKey).then((pref) => {\n if (cancelled) return\n hydratedKeyRef.current = prefKey\n setOpen(Boolean(pref?.open))\n })\n return () => {\n cancelled = true\n }\n }, [prefKey, getPreference])\n\n useEffect(() => {\n if (hydratedKeyRef.current !== prefKey) return\n void setPreference<Pref>(prefKey, { open }, true)\n }, [open, prefKey, setPreference])\n\n const handleToggle = useCallback(() => setOpen((v) => !v), [])\n const handleClose = useCallback(() => setOpen(false), [])\n\n const mountNode = useMainWrapperPortal(open, adminPortalSelector)\n const t = useBetterEditorT()\n const label = open ? t.toggle.close : t.toggle.open\n\n // Mirror Payload's official live-preview behaviour: only surface the\n // toggle once a previewURL is actually resolvable (collection has\n // `admin.livePreview.url` configured AND the document has the data\n // the URL function depends on, e.g. slug). Hiding the button avoids\n // the misleading \"Loading preview URL…\" / \"not configured\" empty\n // states inside the overlay entirely.\n if (!previewURL) return null\n\n return (\n <>\n <button\n aria-label={label}\n aria-pressed={open}\n className=\"preview-btn better-editor-toggle\"\n onClick={handleToggle}\n title={label}\n type=\"button\"\n >\n {hideToggleLabel ? null : (\n <span className=\"better-editor-toggle__label\">{label}</span>\n )}\n <LayoutIcon />\n </button>\n\n {open && mountNode\n ? createPortal(\n <LiveEditorOverlay\n onClose={handleClose}\n blocksField={blocksField}\n storageNamespace={storageNamespace}\n adminPortalSelector={adminPortalSelector}\n />,\n mountNode,\n )\n : null}\n </>\n )\n}\n"],"names":["React","useCallback","useEffect","useMemo","useRef","useState","createPortal","useDocumentInfo","useLivePreviewContext","usePreferences","LiveEditorOverlay","useMainWrapperPortal","buildStorageKeys","LayoutIcon","useBetterEditorT","LiveEditorToggle","blocksField","adminPortalSelector","storageNamespace","hideToggleLabel","open","setOpen","collectionSlug","globalSlug","previewURL","getPreference","setPreference","storageKeys","prefKey","togglePreference","hydratedKeyRef","cancelled","current","then","pref","Boolean","handleToggle","v","handleClose","mountNode","t","label","toggle","close","button","aria-label","aria-pressed","className","onClick","title","type","span","onClose"],"mappings":"AAAA;;AAEA,OAAOA,SAASC,WAAW,EAAEC,SAAS,EAAEC,OAAO,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,QAAO;AAChF,SAASC,YAAY,QAAQ,YAAW;AACxC,SAASC,eAAe,EAAEC,qBAAqB,EAAEC,cAAc,QAAQ,iBAAgB;AACvF,SAASC,iBAAiB,QAAQ,sBAAqB;AACvD,SAASC,oBAAoB,QAAQ,gCAA+B;AACpE,SAASC,gBAAgB,QAAQ,2BAA0B;AAC3D,SAASC,UAAU,QAAQ,UAAS;AACpC,SAASC,gBAAgB,QAAQ,2BAA0B;AAC3D,OAAO,uBAAsB;AAW7B,OAAO,MAAMC,mBAAoD,CAAC,EAChEC,WAAW,EACXC,mBAAmB,EACnBC,gBAAgB,EAChBC,eAAe,EAChB;IACC,MAAM,CAACC,MAAMC,QAAQ,GAAGhB,SAAS;IACjC,MAAM,EAAEiB,cAAc,EAAEC,UAAU,EAAE,GAAGhB;IACvC,MAAM,EAAEiB,UAAU,EAAE,GAAGhB;IACvB,MAAM,EAAEiB,aAAa,EAAEC,aAAa,EAAE,GAAGjB;IACzC,MAAMkB,cAAcxB,QAAQ,IAAMS,iBAAiBM,mBAAmB;QAACA;KAAiB;IACxF,MAAMU,UAAUD,YAAYE,gBAAgB,CAACP,gBAAgBC;IAE7D,wEAAwE;IACxE,uEAAuE;IACvE,qEAAqE;IACrE,MAAMO,iBAAiB1B,OAAsB;IAE7CF,UAAU;QACR,IAAI6B,YAAY;QAChBD,eAAeE,OAAO,GAAG;QACzB,KAAKP,cAAoBG,SAASK,IAAI,CAAC,CAACC;YACtC,IAAIH,WAAW;YACfD,eAAeE,OAAO,GAAGJ;YACzBP,QAAQc,QAAQD,MAAMd;QACxB;QACA,OAAO;YACLW,YAAY;QACd;IACF,GAAG;QAACH;QAASH;KAAc;IAE3BvB,UAAU;QACR,IAAI4B,eAAeE,OAAO,KAAKJ,SAAS;QACxC,KAAKF,cAAoBE,SAAS;YAAER;QAAK,GAAG;IAC9C,GAAG;QAACA;QAAMQ;QAASF;KAAc;IAEjC,MAAMU,eAAenC,YAAY,IAAMoB,QAAQ,CAACgB,IAAM,CAACA,IAAI,EAAE;IAC7D,MAAMC,cAAcrC,YAAY,IAAMoB,QAAQ,QAAQ,EAAE;IAExD,MAAMkB,YAAY5B,qBAAqBS,MAAMH;IAC7C,MAAMuB,IAAI1B;IACV,MAAM2B,QAAQrB,OAAOoB,EAAEE,MAAM,CAACC,KAAK,GAAGH,EAAEE,MAAM,CAACtB,IAAI;IAEnD,qEAAqE;IACrE,kEAAkE;IAClE,mEAAmE;IACnE,oEAAoE;IACpE,iEAAiE;IACjE,sCAAsC;IACtC,IAAI,CAACI,YAAY,OAAO;IAExB,qBACE;;0BACE,MAACoB;gBACCC,cAAYJ;gBACZK,gBAAc1B;gBACd2B,WAAU;gBACVC,SAASZ;gBACTa,OAAOR;gBACPS,MAAK;;oBAEJ/B,kBAAkB,qBACjB,KAACgC;wBAAKJ,WAAU;kCAA+BN;;kCAEjD,KAAC5B;;;YAGFO,QAAQmB,0BACLjC,2BACE,KAACI;gBACC0C,SAASd;gBACTtB,aAAaA;gBACbE,kBAAkBA;gBAClBD,qBAAqBA;gBAEvBsB,aAEF;;;AAGV,EAAC"}
@@ -7,8 +7,10 @@ import { useLatestRef } from '../hooks/useLatestRef';
7
7
  import { usePreviewBinding } from '../hooks/usePreviewBinding';
8
8
  import { usePreviewSettingsSync } from '../hooks/usePreviewSettingsSync';
9
9
  import { usePreviewSelectionSync } from '../hooks/usePreviewSelectionSync';
10
+ import { useBetterEditorT } from '../i18n/useBetterEditorT';
10
11
  // Memoized so resize-drag re-renders of the overlay skip the frame.
11
12
  export const PreviewFrame = /*#__PURE__*/ React.memo(function PreviewFrame({ iframeRef, previewURL, hoverColorTopLevel, hoverColorNested, hoverOutlineWidth, showHoverToolbar, hoverToolbarPosition, selectedBlockPath, interactMode, viewport, viewportWidth, resizable = false, onResize }) {
13
+ const t = useBetterEditorT();
12
14
  const [isLoading, setIsLoading] = useState(true);
13
15
  const interactModeRef = useLatestRef(interactMode);
14
16
  const { isResizing, onHandleMouseDown } = usePreviewHandleDrag({
@@ -92,20 +94,20 @@ export const PreviewFrame = /*#__PURE__*/ React.memo(function PreviewFrame({ ifr
92
94
  className: "better-editor-frame__handle better-editor-frame__handle--left",
93
95
  role: "separator",
94
96
  "aria-orientation": "vertical",
95
- "aria-label": "Resize preview from left",
97
+ "aria-label": t.preview.resizeLeft,
96
98
  onMouseDown: onHandleMouseDown('left')
97
99
  }) : null,
98
100
  /*#__PURE__*/ _jsx("iframe", {
99
101
  ref: iframeRef,
100
102
  className: "better-editor-frame",
101
103
  src: previewURL,
102
- title: "Better Editor preview",
104
+ title: t.preview.title,
103
105
  style: iframeStyle
104
106
  }),
105
107
  isLoading ? /*#__PURE__*/ _jsxs("div", {
106
108
  className: "better-editor-frame__skeleton",
107
109
  role: "status",
108
- "aria-label": "Loading preview",
110
+ "aria-label": t.preview.loading,
109
111
  children: [
110
112
  /*#__PURE__*/ _jsx("div", {
111
113
  className: "better-editor-frame__skeleton-bar better-editor-frame__skeleton-bar--lg"
@@ -125,7 +127,7 @@ export const PreviewFrame = /*#__PURE__*/ React.memo(function PreviewFrame({ ifr
125
127
  className: "better-editor-frame__handle better-editor-frame__handle--right",
126
128
  role: "separator",
127
129
  "aria-orientation": "vertical",
128
- "aria-label": "Resize preview from right",
130
+ "aria-label": t.preview.resizeRight,
129
131
  onMouseDown: onHandleMouseDown('right')
130
132
  }) : null
131
133
  ]
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/admin/PreviewFrame.tsx"],"sourcesContent":["'use client'\n\nimport React, { useCallback, useEffect, useMemo, useState, type RefObject } 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 { 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 iframeRef: RefObject<HTMLIFrameElement | null>\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}\n\ntype BlockAction = BlockActionMessage['action']\n\n// Memoized so resize-drag re-renders of the overlay skip the frame.\nexport const PreviewFrame = React.memo(function PreviewFrame({\n iframeRef,\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}: PreviewFrameProps) {\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\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","useState","postToParent","usePreviewHandleDrag","useLatestRef","usePreviewBinding","usePreviewSettingsSync","usePreviewSelectionSync","PreviewFrame","memo","iframeRef","previewURL","hoverColorTopLevel","hoverColorNested","hoverOutlineWidth","showHoverToolbar","hoverToolbarPosition","selectedBlockPath","interactMode","viewport","viewportWidth","resizable","onResize","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":"AAAA;;AAEA,OAAOA,SAASC,WAAW,EAAEC,SAAS,EAAEC,OAAO,EAAEC,QAAQ,QAAwB,QAAO;AAExF,SAASC,YAAY,QAAQ,0BAAyB;AAGtD,SAASC,oBAAoB,QAAQ,gCAA+B;AACpE,SAASC,YAAY,QAAQ,wBAAuB;AACpD,SAASC,iBAAiB,QAAQ,6BAA4B;AAC9D,SAASC,sBAAsB,QAAQ,kCAAiC;AACxE,SAASC,uBAAuB,QAAQ,mCAAkC;AAuB1E,oEAAoE;AACpE,OAAO,MAAMC,6BAAeX,MAAMY,IAAI,CAAC,SAASD,aAAa,EAC3DE,SAAS,EACTC,UAAU,EACVC,kBAAkB,EAClBC,gBAAgB,EAChBC,iBAAiB,EACjBC,gBAAgB,EAChBC,oBAAoB,EACpBC,iBAAiB,EACjBC,YAAY,EACZC,QAAQ,EACRC,aAAa,EACbC,YAAY,KAAK,EACjBC,QAAQ,EACU;IAClB,MAAM,CAACC,WAAWC,aAAa,GAAGvB,SAAS;IAC3C,MAAMwB,kBAAkBrB,aAAac;IAErC,MAAM,EAAEQ,UAAU,EAAEC,iBAAiB,EAAE,GAAGxB,qBAAqB;QAC7DkB;QACAD;QACAE;IACF;IAEAvB,UAAU;QACRyB,aAAa;IACf,GAAG;QAACb;KAAW;IAEf,MAAMiB,eAAe9B,YAAY,CAAC+B;QAChC3B,aAAa;YAAE4B,MAAM;YAAeD;QAAG;IACzC,GAAG,EAAE;IAEL,MAAME,gBAAgBjC,YAAY,CAAC+B,IAAYG;QAC7C9B,aAAa;YAAE4B,MAAM;YAAgBD;YAAIG;QAAO;IAClD,GAAG,EAAE;IAEL,MAAMC,WAAWjC,QACf,IAAO,CAAA;YACLY;YACAC;YACAC;YACAC;YACAC;QACF,CAAA,GACA;QACEJ;QACAC;QACAC;QACAC;QACAC;KACD;IAGH,MAAM,EAAEkB,aAAa,EAAEC,UAAU,EAAE,GAAG9B,kBAAkB;QACtDK;QACAuB;QACAR;QACAG;QACAG;QACAK,iBAAiBZ;IACnB;IAEAlB,uBAAuB;QACrBI;QACAwB;QACAC;QACAF;QACAF;IACF;IAEAxB,wBAAwB;QACtBG;QACAwB;QACAjB;QACAC;QACAP;IACF;IAEA,MAAM0B,cAAc,OAAOjB,kBAAkB,YAAYA,gBAAgB;IACzE,MAAMkB,oBAAoB;QACxB;QACAD,eAAe;QACfA,eAAelB,aAAa,YAAY;QACxCkB,eAAelB,aAAa,YAAY;QACxCE,aAAa;QACbK,cAAc;KACf,CACEa,MAAM,CAACC,SACPC,IAAI,CAAC;IACR,MAAMC,cAAcL,cAChB;QAAEM,OAAO,GAAGvB,cAAc,EAAE,CAAC;QAAEwB,UAAU;IAAgB,IACzDC;IAEJ,sEAAsE;IACtE,+DAA+D;IAC/D,kBAAkB;IAClB,qBACE,MAACC;QAAIC,WAAWT;;YACbjB,0BACC,KAACyB;gBACCC,WAAU;gBACVC,MAAK;gBACLC,oBAAiB;gBACjBC,cAAW;gBACXC,aAAaxB,kBAAkB;iBAE/B;0BACJ,KAACyB;gBACCC,KAAK3C;gBACLqC,WAAU;gBACVO,KAAK3C;gBACL4C,OAAM;gBACNC,OAAOd;;YAERnB,0BACC,MAACuB;gBACCC,WAAU;gBACVC,MAAK;gBACLE,cAAW;;kCAEX,KAACJ;wBAAIC,WAAU;;kCACf,KAACD;wBAAIC,WAAU;;kCACf,KAACD;wBAAIC,WAAU;;kCACf,KAACD;wBAAIC,WAAU;;;iBAEf;YACH1B,0BACC,KAACyB;gBACCC,WAAU;gBACVC,MAAK;gBACLC,oBAAiB;gBACjBC,cAAW;gBACXC,aAAaxB,kBAAkB;iBAE/B;;;AAGV,GAAE"}
1
+ {"version":3,"sources":["../../src/admin/PreviewFrame.tsx"],"sourcesContent":["'use client'\n\nimport React, { useCallback, useEffect, useMemo, useState, type RefObject } 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 { usePreviewHandleDrag } from '../hooks/usePreviewHandleDrag'\nimport { useLatestRef } from '../hooks/useLatestRef'\nimport { usePreviewBinding } from '../hooks/usePreviewBinding'\nimport { usePreviewSettingsSync } from '../hooks/usePreviewSettingsSync'\nimport { usePreviewSelectionSync } from '../hooks/usePreviewSelectionSync'\nimport { useBetterEditorT } from '../i18n/useBetterEditorT'\n\nexport type PreviewFrameProps = {\n iframeRef: RefObject<HTMLIFrameElement | null>\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}\n\ntype BlockAction = BlockActionMessage['action']\n\n// Memoized so resize-drag re-renders of the overlay skip the frame.\nexport const PreviewFrame = React.memo(function PreviewFrame({\n iframeRef,\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}: PreviewFrameProps) {\n const t = useBetterEditorT()\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\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={t.preview.resizeLeft}\n onMouseDown={onHandleMouseDown('left')}\n />\n ) : null}\n <iframe\n ref={iframeRef}\n className=\"better-editor-frame\"\n src={previewURL}\n title={t.preview.title}\n style={iframeStyle}\n />\n {isLoading ? (\n <div\n className=\"better-editor-frame__skeleton\"\n role=\"status\"\n aria-label={t.preview.loading}\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={t.preview.resizeRight}\n onMouseDown={onHandleMouseDown('right')}\n />\n ) : null}\n </div>\n )\n})\n"],"names":["React","useCallback","useEffect","useMemo","useState","postToParent","usePreviewHandleDrag","useLatestRef","usePreviewBinding","usePreviewSettingsSync","usePreviewSelectionSync","useBetterEditorT","PreviewFrame","memo","iframeRef","previewURL","hoverColorTopLevel","hoverColorNested","hoverOutlineWidth","showHoverToolbar","hoverToolbarPosition","selectedBlockPath","interactMode","viewport","viewportWidth","resizable","onResize","t","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","preview","resizeLeft","onMouseDown","iframe","ref","src","title","style","loading","resizeRight"],"mappings":"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"}
@@ -4,8 +4,11 @@ import React from 'react';
4
4
  import { ViewportToggle } from './ViewportToggle';
5
5
  import { WidthChip } from './WidthChip';
6
6
  import { FullscreenExitIcon, FullscreenIcon, InteractIcon, InteractOffIcon, RedoIcon, SidebarHideIcon, SidebarShowIcon, UndoIcon } from './icons';
7
+ import { useBetterEditorT } from '../i18n/useBetterEditorT';
7
8
  // Memoized so resize-drag re-renders of the overlay skip the toolbar.
8
- export const PreviewToolbar = /*#__PURE__*/ React.memo(({ history, viewport, onViewportChange, iframeRef, isFullscreen, onFullscreenToggle, interactMode, onInteractToggle, sidebarCollapsed, onSidebarToggle })=>/*#__PURE__*/ _jsxs("div", {
9
+ export const PreviewToolbar = /*#__PURE__*/ React.memo(({ history, viewport, onViewportChange, iframeRef, isFullscreen, onFullscreenToggle, interactMode, onInteractToggle, sidebarCollapsed, onSidebarToggle })=>{
10
+ const t = useBetterEditorT();
11
+ return /*#__PURE__*/ _jsxs("div", {
9
12
  className: "better-editor__preview-toolbar",
10
13
  children: [
11
14
  /*#__PURE__*/ _jsx(HistoryButtons, {
@@ -29,8 +32,8 @@ export const PreviewToolbar = /*#__PURE__*/ React.memo(({ history, viewport, onV
29
32
  className: isFullscreen ? 'better-editor-viewport__btn better-editor-viewport__btn--active' : 'better-editor-viewport__btn',
30
33
  onClick: onFullscreenToggle,
31
34
  "aria-pressed": isFullscreen,
32
- title: isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen',
33
- "aria-label": isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen',
35
+ title: isFullscreen ? t.toolbar.exitFullscreen : t.toolbar.enterFullscreen,
36
+ "aria-label": isFullscreen ? t.toolbar.exitFullscreen : t.toolbar.enterFullscreen,
34
37
  children: isFullscreen ? /*#__PURE__*/ _jsx(FullscreenExitIcon, {}) : /*#__PURE__*/ _jsx(FullscreenIcon, {})
35
38
  }),
36
39
  /*#__PURE__*/ _jsx("button", {
@@ -38,8 +41,8 @@ export const PreviewToolbar = /*#__PURE__*/ React.memo(({ history, viewport, onV
38
41
  className: interactMode ? 'better-editor-viewport__btn better-editor-viewport__btn--active' : 'better-editor-viewport__btn',
39
42
  onClick: onInteractToggle,
40
43
  "aria-pressed": interactMode,
41
- title: interactMode ? 'Switch to edit mode' : 'Switch to interact mode (use forms, accordions, links)',
42
- "aria-label": interactMode ? 'Switch to edit mode' : 'Switch to interact mode',
44
+ title: interactMode ? t.toolbar.switchToEdit : t.toolbar.switchToInteract,
45
+ "aria-label": interactMode ? t.toolbar.switchToEdit : t.toolbar.switchToInteractShort,
43
46
  children: interactMode ? /*#__PURE__*/ _jsx(InteractIcon, {}) : /*#__PURE__*/ _jsx(InteractOffIcon, {})
44
47
  }),
45
48
  /*#__PURE__*/ _jsx("button", {
@@ -47,8 +50,8 @@ export const PreviewToolbar = /*#__PURE__*/ React.memo(({ history, viewport, onV
47
50
  className: "better-editor-viewport__btn",
48
51
  onClick: onSidebarToggle,
49
52
  "aria-pressed": sidebarCollapsed,
50
- title: sidebarCollapsed ? 'Show sidebar' : 'Hide sidebar',
51
- "aria-label": sidebarCollapsed ? 'Show sidebar' : 'Hide sidebar',
53
+ title: sidebarCollapsed ? t.toolbar.showSidebar : t.toolbar.hideSidebar,
54
+ "aria-label": sidebarCollapsed ? t.toolbar.showSidebar : t.toolbar.hideSidebar,
52
55
  children: sidebarCollapsed ? /*#__PURE__*/ _jsx(SidebarShowIcon, {}) : /*#__PURE__*/ _jsx(SidebarHideIcon, {})
53
56
  })
54
57
  ]
@@ -56,8 +59,11 @@ export const PreviewToolbar = /*#__PURE__*/ React.memo(({ history, viewport, onV
56
59
  ]
57
60
  })
58
61
  ]
59
- }));
60
- const HistoryButtons = ({ history })=>/*#__PURE__*/ _jsxs("div", {
62
+ });
63
+ });
64
+ const HistoryButtons = ({ history })=>{
65
+ const t = useBetterEditorT();
66
+ return /*#__PURE__*/ _jsxs("div", {
61
67
  className: "better-editor__history",
62
68
  children: [
63
69
  /*#__PURE__*/ _jsx("button", {
@@ -65,8 +71,8 @@ const HistoryButtons = ({ history })=>/*#__PURE__*/ _jsxs("div", {
65
71
  className: "better-editor__history-btn",
66
72
  onClick: history.undo,
67
73
  disabled: !history.canUndo,
68
- title: "Undo (Cmd/Ctrl+Z)",
69
- "aria-label": "Undo",
74
+ title: t.toolbar.undoTitle,
75
+ "aria-label": t.toolbar.undo,
70
76
  children: /*#__PURE__*/ _jsx(UndoIcon, {})
71
77
  }),
72
78
  /*#__PURE__*/ _jsx("button", {
@@ -74,11 +80,12 @@ const HistoryButtons = ({ history })=>/*#__PURE__*/ _jsxs("div", {
74
80
  className: "better-editor__history-btn",
75
81
  onClick: history.redo,
76
82
  disabled: !history.canRedo,
77
- title: "Redo (Cmd/Ctrl+Shift+Z)",
78
- "aria-label": "Redo",
83
+ title: t.toolbar.redoTitle,
84
+ "aria-label": t.toolbar.redo,
79
85
  children: /*#__PURE__*/ _jsx(RedoIcon, {})
80
86
  })
81
87
  ]
82
88
  });
89
+ };
83
90
 
84
91
  //# sourceMappingURL=PreviewToolbar.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/admin/PreviewToolbar.tsx"],"sourcesContent":["'use client'\n\nimport React, { type RefObject } from 'react'\nimport { ViewportToggle, type Viewport } from './ViewportToggle'\nimport { WidthChip } from './WidthChip'\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 iframeRef: RefObject<HTMLIFrameElement | null>\n isFullscreen: boolean\n onFullscreenToggle: () => void\n interactMode: boolean\n onInteractToggle: () => void\n sidebarCollapsed: boolean\n onSidebarToggle: () => void\n}\n\n// Memoized so resize-drag re-renders of the overlay skip the toolbar.\nexport const PreviewToolbar = React.memo<PreviewToolbarProps>(({\n history,\n viewport,\n onViewportChange,\n iframeRef,\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 <WidthChip iframeRef={iframeRef} />\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","WidthChip","FullscreenExitIcon","FullscreenIcon","InteractIcon","InteractOffIcon","RedoIcon","SidebarHideIcon","SidebarShowIcon","UndoIcon","PreviewToolbar","memo","history","viewport","onViewportChange","iframeRef","isFullscreen","onFullscreenToggle","interactMode","onInteractToggle","sidebarCollapsed","onSidebarToggle","div","className","HistoryButtons","value","onChange","button","type","onClick","aria-pressed","title","aria-label","undo","disabled","canUndo","redo","canRedo"],"mappings":"AAAA;;AAEA,OAAOA,WAA+B,QAAO;AAC7C,SAASC,cAAc,QAAuB,mBAAkB;AAChE,SAASC,SAAS,QAAQ,cAAa;AACvC,SACEC,kBAAkB,EAClBC,cAAc,EACdC,YAAY,EACZC,eAAe,EACfC,QAAQ,EACRC,eAAe,EACfC,eAAe,EACfC,QAAQ,QACH,UAAS;AAgBhB,sEAAsE;AACtE,OAAO,MAAMC,+BAAiBX,MAAMY,IAAI,CAAsB,CAAC,EAC7DC,OAAO,EACPC,QAAQ,EACRC,gBAAgB,EAChBC,SAAS,EACTC,YAAY,EACZC,kBAAkB,EAClBC,YAAY,EACZC,gBAAgB,EAChBC,gBAAgB,EAChBC,eAAe,EAChB,iBACC,MAACC;QAAIC,WAAU;;0BACb,KAACC;gBAAeZ,SAASA;;0BACzB,MAACU;gBAAIC,WAAU;;kCACb,KAACtB;wBAAUc,WAAWA;;kCACtB,KAACf;wBAAeyB,OAAOZ;wBAAUa,UAAUZ;;kCAC3C,MAACQ;wBAAIC,WAAU;;0CACb,KAACI;gCACCC,MAAK;gCACLL,WACEP,eACI,oEACA;gCAENa,SAASZ;gCACTa,gBAAcd;gCACde,OAAOf,eAAe,oBAAoB;gCAC1CgB,cAAYhB,eAAe,oBAAoB;0CAE9CA,6BAAe,KAACd,wCAAwB,KAACC;;0CAE5C,KAACwB;gCACCC,MAAK;gCACLL,WACEL,eACI,oEACA;gCAENW,SAASV;gCACTW,gBAAcZ;gCACda,OACEb,eACI,wBACA;gCAENc,cAAYd,eAAe,wBAAwB;0CAElDA,6BAAe,KAACd,kCAAkB,KAACC;;0CAEtC,KAACsB;gCACCC,MAAK;gCACLL,WAAU;gCACVM,SAASR;gCACTS,gBAAcV;gCACdW,OAAOX,mBAAmB,iBAAiB;gCAC3CY,cAAYZ,mBAAmB,iBAAiB;0CAE/CA,iCAAmB,KAACZ,qCAAqB,KAACD;;;;;;;QAKnD;AAEF,MAAMiB,iBAA6E,CAAC,EAClFZ,OAAO,EACR,iBACC,MAACU;QAAIC,WAAU;;0BACb,KAACI;gBACCC,MAAK;gBACLL,WAAU;gBACVM,SAASjB,QAAQqB,IAAI;gBACrBC,UAAU,CAACtB,QAAQuB,OAAO;gBAC1BJ,OAAM;gBACNC,cAAW;0BAEX,cAAA,KAACvB;;0BAEH,KAACkB;gBACCC,MAAK;gBACLL,WAAU;gBACVM,SAASjB,QAAQwB,IAAI;gBACrBF,UAAU,CAACtB,QAAQyB,OAAO;gBAC1BN,OAAM;gBACNC,cAAW;0BAEX,cAAA,KAAC1B"}
1
+ {"version":3,"sources":["../../src/admin/PreviewToolbar.tsx"],"sourcesContent":["'use client'\n\nimport React, { type RefObject } from 'react'\nimport { ViewportToggle, type Viewport } from './ViewportToggle'\nimport { WidthChip } from './WidthChip'\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'\nimport { useBetterEditorT } from '../i18n/useBetterEditorT'\n\nexport type PreviewToolbarProps = {\n history: ReturnType<typeof useEditorHistory>\n viewport: Viewport\n onViewportChange: (viewport: Viewport) => void\n iframeRef: RefObject<HTMLIFrameElement | null>\n isFullscreen: boolean\n onFullscreenToggle: () => void\n interactMode: boolean\n onInteractToggle: () => void\n sidebarCollapsed: boolean\n onSidebarToggle: () => void\n}\n\n// Memoized so resize-drag re-renders of the overlay skip the toolbar.\nexport const PreviewToolbar = React.memo<PreviewToolbarProps>(({\n history,\n viewport,\n onViewportChange,\n iframeRef,\n isFullscreen,\n onFullscreenToggle,\n interactMode,\n onInteractToggle,\n sidebarCollapsed,\n onSidebarToggle,\n}) => {\n const t = useBetterEditorT()\n return (\n <div className=\"better-editor__preview-toolbar\">\n <HistoryButtons history={history} />\n <div className=\"better-editor__preview-toolbar-right\">\n <WidthChip iframeRef={iframeRef} />\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 ? t.toolbar.exitFullscreen : t.toolbar.enterFullscreen}\n aria-label={isFullscreen ? t.toolbar.exitFullscreen : t.toolbar.enterFullscreen}\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={interactMode ? t.toolbar.switchToEdit : t.toolbar.switchToInteract}\n aria-label={interactMode ? t.toolbar.switchToEdit : t.toolbar.switchToInteractShort}\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 ? t.toolbar.showSidebar : t.toolbar.hideSidebar}\n aria-label={sidebarCollapsed ? t.toolbar.showSidebar : t.toolbar.hideSidebar}\n >\n {sidebarCollapsed ? <SidebarShowIcon /> : <SidebarHideIcon />}\n </button>\n </div>\n </div>\n </div>\n )\n})\n\nconst HistoryButtons: React.FC<{ history: ReturnType<typeof useEditorHistory> }> = ({\n history,\n}) => {\n const t = useBetterEditorT()\n return (\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={t.toolbar.undoTitle}\n aria-label={t.toolbar.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={t.toolbar.redoTitle}\n aria-label={t.toolbar.redo}\n >\n <RedoIcon />\n </button>\n </div>\n )\n}\n"],"names":["React","ViewportToggle","WidthChip","FullscreenExitIcon","FullscreenIcon","InteractIcon","InteractOffIcon","RedoIcon","SidebarHideIcon","SidebarShowIcon","UndoIcon","useBetterEditorT","PreviewToolbar","memo","history","viewport","onViewportChange","iframeRef","isFullscreen","onFullscreenToggle","interactMode","onInteractToggle","sidebarCollapsed","onSidebarToggle","t","div","className","HistoryButtons","value","onChange","button","type","onClick","aria-pressed","title","toolbar","exitFullscreen","enterFullscreen","aria-label","switchToEdit","switchToInteract","switchToInteractShort","showSidebar","hideSidebar","undo","disabled","canUndo","undoTitle","redo","canRedo","redoTitle"],"mappings":"AAAA;;AAEA,OAAOA,WAA+B,QAAO;AAC7C,SAASC,cAAc,QAAuB,mBAAkB;AAChE,SAASC,SAAS,QAAQ,cAAa;AACvC,SACEC,kBAAkB,EAClBC,cAAc,EACdC,YAAY,EACZC,eAAe,EACfC,QAAQ,EACRC,eAAe,EACfC,eAAe,EACfC,QAAQ,QACH,UAAS;AAEhB,SAASC,gBAAgB,QAAQ,2BAA0B;AAe3D,sEAAsE;AACtE,OAAO,MAAMC,+BAAiBZ,MAAMa,IAAI,CAAsB,CAAC,EAC7DC,OAAO,EACPC,QAAQ,EACRC,gBAAgB,EAChBC,SAAS,EACTC,YAAY,EACZC,kBAAkB,EAClBC,YAAY,EACZC,gBAAgB,EAChBC,gBAAgB,EAChBC,eAAe,EAChB;IACC,MAAMC,IAAIb;IACV,qBACE,MAACc;QAAIC,WAAU;;0BACb,KAACC;gBAAeb,SAASA;;0BACzB,MAACW;gBAAIC,WAAU;;kCACb,KAACxB;wBAAUe,WAAWA;;kCACtB,KAAChB;wBAAe2B,OAAOb;wBAAUc,UAAUb;;kCAC3C,MAACS;wBAAIC,WAAU;;0CACb,KAACI;gCACCC,MAAK;gCACLL,WACER,eACI,oEACA;gCAENc,SAASb;gCACTc,gBAAcf;gCACdgB,OAAOhB,eAAeM,EAAEW,OAAO,CAACC,cAAc,GAAGZ,EAAEW,OAAO,CAACE,eAAe;gCAC1EC,cAAYpB,eAAeM,EAAEW,OAAO,CAACC,cAAc,GAAGZ,EAAEW,OAAO,CAACE,eAAe;0CAE9EnB,6BAAe,KAACf,wCAAwB,KAACC;;0CAE5C,KAAC0B;gCACCC,MAAK;gCACLL,WACEN,eACI,oEACA;gCAENY,SAASX;gCACTY,gBAAcb;gCACdc,OAAOd,eAAeI,EAAEW,OAAO,CAACI,YAAY,GAAGf,EAAEW,OAAO,CAACK,gBAAgB;gCACzEF,cAAYlB,eAAeI,EAAEW,OAAO,CAACI,YAAY,GAAGf,EAAEW,OAAO,CAACM,qBAAqB;0CAElFrB,6BAAe,KAACf,kCAAkB,KAACC;;0CAEtC,KAACwB;gCACCC,MAAK;gCACLL,WAAU;gCACVM,SAAST;gCACTU,gBAAcX;gCACdY,OAAOZ,mBAAmBE,EAAEW,OAAO,CAACO,WAAW,GAAGlB,EAAEW,OAAO,CAACQ,WAAW;gCACvEL,cAAYhB,mBAAmBE,EAAEW,OAAO,CAACO,WAAW,GAAGlB,EAAEW,OAAO,CAACQ,WAAW;0CAE3ErB,iCAAmB,KAACb,qCAAqB,KAACD;;;;;;;;AAMvD,GAAE;AAEF,MAAMmB,iBAA6E,CAAC,EAClFb,OAAO,EACR;IACC,MAAMU,IAAIb;IACV,qBACE,MAACc;QAAIC,WAAU;;0BACb,KAACI;gBACCC,MAAK;gBACLL,WAAU;gBACVM,SAASlB,QAAQ8B,IAAI;gBACrBC,UAAU,CAAC/B,QAAQgC,OAAO;gBAC1BZ,OAAOV,EAAEW,OAAO,CAACY,SAAS;gBAC1BT,cAAYd,EAAEW,OAAO,CAACS,IAAI;0BAE1B,cAAA,KAAClC;;0BAEH,KAACoB;gBACCC,MAAK;gBACLL,WAAU;gBACVM,SAASlB,QAAQkC,IAAI;gBACrBH,UAAU,CAAC/B,QAAQmC,OAAO;gBAC1Bf,OAAOV,EAAEW,OAAO,CAACe,SAAS;gBAC1BZ,cAAYd,EAAEW,OAAO,CAACa,IAAI;0BAE1B,cAAA,KAACzC;;;;AAIT"}
@@ -3,6 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import React from 'react';
4
4
  import { BugIcon, GithubIcon, StarIcon } from './icons';
5
5
  import { VERSION } from '../version';
6
+ import { useBetterEditorT } from '../i18n/useBetterEditorT';
6
7
  import '../styles/settings-banner.css';
7
8
  const REPO = 'scorpio-99/payload-better-editor';
8
9
  const AUTHOR = 'scorpio-99';
@@ -13,7 +14,9 @@ const BANNER = {
13
14
  authorUrl: `https://github.com/${AUTHOR}`,
14
15
  starBadgeUrl: `https://img.shields.io/github/stars/${REPO}?style=flat&label=&color=27272a&labelColor=27272a&logo=github&logoColor=white`
15
16
  };
16
- export const SettingsBanner = ()=>/*#__PURE__*/ _jsxs("div", {
17
+ export const SettingsBanner = ()=>{
18
+ const t = useBetterEditorT();
19
+ return /*#__PURE__*/ _jsxs("div", {
17
20
  className: "better-editor-banner",
18
21
  children: [
19
22
  /*#__PURE__*/ _jsx("div", {
@@ -47,7 +50,8 @@ export const SettingsBanner = ()=>/*#__PURE__*/ _jsxs("div", {
47
50
  rel: "noreferrer noopener",
48
51
  children: BANNER.author
49
52
  }),
50
- ". If you find this plugin useful, please leave a star ⭐"
53
+ ". ",
54
+ t.banner.builtBy
51
55
  ]
52
56
  })
53
57
  ]
@@ -64,7 +68,7 @@ export const SettingsBanner = ()=>/*#__PURE__*/ _jsxs("div", {
64
68
  children: [
65
69
  /*#__PURE__*/ _jsx(StarIcon, {}),
66
70
  /*#__PURE__*/ _jsx("span", {
67
- children: "Star"
71
+ children: t.banner.star
68
72
  }),
69
73
  /*#__PURE__*/ _jsx("img", {
70
74
  src: BANNER.starBadgeUrl,
@@ -81,7 +85,7 @@ export const SettingsBanner = ()=>/*#__PURE__*/ _jsxs("div", {
81
85
  children: [
82
86
  /*#__PURE__*/ _jsx(GithubIcon, {}),
83
87
  /*#__PURE__*/ _jsx("span", {
84
- children: "GitHub"
88
+ children: t.banner.github
85
89
  })
86
90
  ]
87
91
  }),
@@ -93,7 +97,7 @@ export const SettingsBanner = ()=>/*#__PURE__*/ _jsxs("div", {
93
97
  children: [
94
98
  /*#__PURE__*/ _jsx(BugIcon, {}),
95
99
  /*#__PURE__*/ _jsx("span", {
96
- children: "Report a bug"
100
+ children: t.banner.reportBug
97
101
  })
98
102
  ]
99
103
  })
@@ -101,5 +105,6 @@ export const SettingsBanner = ()=>/*#__PURE__*/ _jsxs("div", {
101
105
  })
102
106
  ]
103
107
  });
108
+ };
104
109
 
105
110
  //# sourceMappingURL=SettingsBanner.js.map