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.
- package/dist/admin/ErrorBoundary.d.ts +1 -10
- package/dist/admin/ErrorBoundary.js +14 -5
- package/dist/admin/ErrorBoundary.js.map +1 -1
- package/dist/admin/LiveEditorOverlay.js +4 -2
- package/dist/admin/LiveEditorOverlay.js.map +1 -1
- package/dist/admin/LiveEditorToggle.d.ts +2 -0
- package/dist/admin/LiveEditorToggle.js +14 -9
- package/dist/admin/LiveEditorToggle.js.map +1 -1
- package/dist/admin/PreviewFrame.js +6 -4
- package/dist/admin/PreviewFrame.js.map +1 -1
- package/dist/admin/PreviewToolbar.js +20 -13
- package/dist/admin/PreviewToolbar.js.map +1 -1
- package/dist/admin/SettingsBanner.js +10 -5
- package/dist/admin/SettingsBanner.js.map +1 -1
- package/dist/admin/ViewportToggle.js +30 -25
- package/dist/admin/ViewportToggle.js.map +1 -1
- package/dist/admin/blocks/AddBlockDrawer.js +7 -3
- package/dist/admin/blocks/AddBlockDrawer.js.map +1 -1
- package/dist/admin/blocks/BlockActionsToolbar.js +13 -11
- package/dist/admin/blocks/BlockActionsToolbar.js.map +1 -1
- package/dist/admin/blocks/BlockEmptyState.js +7 -3
- package/dist/admin/blocks/BlockEmptyState.js.map +1 -1
- package/dist/admin/blocks/BlockHeader.d.ts +1 -0
- package/dist/admin/blocks/BlockHeader.js +9 -8
- package/dist/admin/blocks/BlockHeader.js.map +1 -1
- package/dist/admin/blocks/schema.js +38 -7
- package/dist/admin/blocks/schema.js.map +1 -1
- package/dist/admin/sidebar/BlockSettingsTab.js +19 -4
- package/dist/admin/sidebar/BlockSettingsTab.js.map +1 -1
- package/dist/admin/sidebar/DocumentMetaTab.js +6 -2
- package/dist/admin/sidebar/DocumentMetaTab.js.map +1 -1
- package/dist/admin/sidebar/DocumentSettingsTab.js +6 -2
- package/dist/admin/sidebar/DocumentSettingsTab.js.map +1 -1
- package/dist/admin/sidebar/Sidebar.js +21 -16
- package/dist/admin/sidebar/Sidebar.js.map +1 -1
- package/dist/admin/sidebar/ValidationSummary.js +5 -2
- package/dist/admin/sidebar/ValidationSummary.js.map +1 -1
- package/dist/global.js +55 -39
- package/dist/global.js.map +1 -1
- package/dist/hooks/usePreviewBinding.js +6 -2
- package/dist/hooks/usePreviewBinding.js.map +1 -1
- package/dist/hooks/usePreviewSettingsSync.js +8 -3
- package/dist/hooks/usePreviewSettingsSync.js.map +1 -1
- package/dist/i18n/de.d.ts +2 -0
- package/dist/i18n/de.js +135 -0
- package/dist/i18n/de.js.map +1 -0
- package/dist/i18n/en.d.ts +2 -0
- package/dist/i18n/en.js +135 -0
- package/dist/i18n/en.js.map +1 -0
- package/dist/i18n/merge.d.ts +8 -0
- package/dist/i18n/merge.js +22 -0
- package/dist/i18n/merge.js.map +1 -0
- package/dist/i18n/types.d.ts +133 -0
- package/dist/i18n/types.js +3 -0
- package/dist/i18n/types.js.map +1 -0
- package/dist/i18n/useBetterEditorT.d.ts +2 -0
- package/dist/i18n/useBetterEditorT.js +10 -0
- package/dist/i18n/useBetterEditorT.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +21 -2
- package/dist/index.js.map +1 -1
- package/dist/preview/HoverToolbar.d.ts +8 -0
- package/dist/preview/HoverToolbar.js +31 -29
- package/dist/preview/HoverToolbar.js.map +1 -1
- package/dist/preview/HoverToolbarController.d.ts +6 -0
- package/dist/preview/HoverToolbarController.js +20 -5
- package/dist/preview/HoverToolbarController.js.map +1 -1
- package/dist/preview/hover-css.d.ts +1 -0
- package/dist/preview/hover-css.js +18 -22
- package/dist/preview/hover-css.js.map +1 -1
- package/dist/styles/blocks-tab.css +1 -7
- package/dist/styles/overlay.css +2 -0
- package/dist/styles/sidebar.css +1 -0
- package/dist/styles/toggle.css +17 -0
- package/dist/types.d.ts +6 -0
- package/dist/types.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +13 -14
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/admin/sidebar/BlockSettingsTab.tsx"],"sourcesContent":["'use client'\n\nimport React, { useMemo } from 'react'\nimport {\n RenderFields,\n useAllFormFields,\n useConfig,\n useDrawerSlug,\n useField,\n useModal,\n} from '@payloadcms/ui'\nimport { useDocConfig } from '../../hooks/useDocConfig'\nimport { useAddBlockDrawer } from '../../hooks/useAddBlockDrawer'\nimport { AddBlockDrawer } from '../blocks/AddBlockDrawer'\nimport { BlockActionsToolbar } from '../blocks/BlockActionsToolbar'\nimport { useBlockActions } from '../blocks/useBlockActions'\nimport { findNamedField, resolveBlockSchema, resolveFieldBlocks } from '../blocks/schema'\nimport type { ClientBlock } from 'payload'\nimport { BlockEmptyState } from '../blocks/BlockEmptyState'\nimport { BlockHeader } from '../blocks/BlockHeader'\n\nexport type BlockSettingsTabProps = {\n selectedBlockPath: string | null\n onClearSelection: () => void\n onSelectPath: (path: string | null) => void\n blocksField: string\n /** Bump to open the add-after drawer externally (iframe `+` button). */\n addBelowRequestId?: number\n}\n\nexport const BlockSettingsTab: React.FC<BlockSettingsTabProps> = ({\n selectedBlockPath,\n onClearSelection,\n onSelectPath,\n blocksField,\n addBelowRequestId = 0,\n}) => {\n const { fields: docFields, slug: docSlug } = useDocConfig()\n const [fields] = useAllFormFields()\n const { config } = useConfig()\n const blocksMap = config.blocksMap\n const { toggleModal } = useModal()\n const addBlockDrawerSlug = useDrawerSlug('better-editor-add-block')\n const addAfterDrawerSlug = useDrawerSlug('better-editor-add-after')\n\n const actions = useBlockActions({\n selectedBlockPath,\n onSelectPath,\n onClearSelection,\n })\n\n useAddBlockDrawer({\n drawerSlug: addAfterDrawerSlug,\n requestId: addBelowRequestId,\n selectedBlockPath,\n })\n\n const blocksFieldInfo = useMemo(() => {\n if (!docFields) return null\n return findNamedField(docFields, blocksField, docSlug || '')\n }, [docFields, blocksField, docSlug])\n\n const blocksFieldField = blocksFieldInfo?.field\n const availableBlocks: ClientBlock[] =\n blocksFieldField && blocksFieldField.type === 'blocks'\n ? resolveFieldBlocks(blocksFieldField, blocksMap)\n : []\n const blocksSchemaPath = blocksFieldInfo?.schemaPath || ''\n const topLevelRows = fields[blocksField]?.rows\n const addRowIndex = Array.isArray(topLevelRows) ? topLevelRows.length : 0\n\n if (!selectedBlockPath) {\n return (\n <>\n <BlockEmptyState\n canAdd={availableBlocks.length > 0}\n onAddClick={() => toggleModal(addBlockDrawerSlug)}\n />\n {availableBlocks.length > 0 ? (\n <AddBlockDrawer\n slug={addBlockDrawerSlug}\n blocks={availableBlocks}\n addRow={(index, blockType) =>\n actions.addAfter({\n blockType,\n schemaPath: blocksSchemaPath,\n containerPath: blocksField,\n index,\n })\n }\n addRowIndex={addRowIndex}\n />\n ) : null}\n </>\n )\n }\n\n const resolved = docFields\n ? resolveBlockSchema(\n { docFields, docSlug: docSlug || '', formFields: fields, blocksMap },\n selectedBlockPath,\n )\n : null\n\n return (\n <div className=\"better-editor-tab better-editor-tab--native\">\n <BlockHeader\n blockType={resolved?.blockType || 'unknown'}\n path={selectedBlockPath}\n onClearSelection={onClearSelection}\n />\n\n <hr className=\"better-editor-tab__divider\" aria-hidden=\"true\" />\n\n <BlockActionsToolbar\n canMoveUp={actions.canMoveUp}\n canMoveDown={actions.canMoveDown}\n canMutate={actions.canMutate}\n canAddBelow={!!resolved}\n onMoveUp={actions.moveUp}\n onMoveDown={actions.moveDown}\n onDuplicate={actions.duplicate}\n onAddBelow={() => toggleModal(addAfterDrawerSlug)}\n onDelete={actions.remove}\n />\n\n {actions.canMutate && resolved && resolved.blocksFieldBlocks.length > 0 ? (\n <AddBlockDrawer\n slug={addAfterDrawerSlug}\n blocks={resolved.blocksFieldBlocks}\n addRow={(index, blockType) =>\n actions.addAfter({\n blockType,\n schemaPath: resolved.blocksFieldSchemaPath,\n containerPath: actions.parentPath,\n index,\n })\n }\n addRowIndex={actions.rowIndex + 1}\n />\n ) : null}\n\n {!resolved ? (\n <div className=\"better-editor-tab__empty\">\n Could not resolve block schema for this path.\n </div>\n ) : (\n <>\n <BlockNameInput path={`${selectedBlockPath}.blockName`} />\n <hr className=\"better-editor-tab__divider\" aria-hidden=\"true\" />\n <RenderFields\n fields={resolved.blockFields}\n parentPath={resolved.parentPath}\n parentIndexPath=\"\"\n parentSchemaPath={resolved.schemaPath}\n // RenderFields' client read-gate is bypassed; the server-side\n // write check still runs on save.\n permissions={true}\n />\n </>\n )}\n </div>\n )\n}\n\nconst BlockNameInput: React.FC<{ path: string }> = ({ path }) => {\n const { value, setValue } = useField<string>({ path })\n const inputId = `be-blockname-${path}`\n return (\n <div className=\"better-editor-tab__block-name\">\n <label className=\"better-editor-tab__block-name-label\" htmlFor={inputId}>\n Block Name\n </label>\n <input\n id={inputId}\n className=\"better-editor-tab__block-name-input\"\n type=\"text\"\n value={value || ''}\n onChange={(e) => setValue(e.target.value)}\n placeholder=\"Optional label for this block\"\n />\n </div>\n )\n}\n"],"names":["React","useMemo","RenderFields","useAllFormFields","useConfig","useDrawerSlug","useField","useModal","useDocConfig","useAddBlockDrawer","AddBlockDrawer","BlockActionsToolbar","useBlockActions","findNamedField","resolveBlockSchema","resolveFieldBlocks","BlockEmptyState","BlockHeader","BlockSettingsTab","selectedBlockPath","onClearSelection","onSelectPath","blocksField","addBelowRequestId","fields","docFields","slug","docSlug","config","blocksMap","toggleModal","addBlockDrawerSlug","addAfterDrawerSlug","actions","drawerSlug","requestId","blocksFieldInfo","blocksFieldField","field","availableBlocks","type","blocksSchemaPath","schemaPath","topLevelRows","rows","addRowIndex","Array","isArray","length","canAdd","onAddClick","blocks","addRow","index","blockType","addAfter","containerPath","resolved","formFields","div","className","path","hr","aria-hidden","canMoveUp","canMoveDown","canMutate","canAddBelow","onMoveUp","moveUp","onMoveDown","moveDown","onDuplicate","duplicate","onAddBelow","onDelete","remove","blocksFieldBlocks","blocksFieldSchemaPath","parentPath","rowIndex","BlockNameInput","blockFields","parentIndexPath","parentSchemaPath","permissions","value","setValue","inputId","label","htmlFor","input","id","onChange","e","target","placeholder"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/admin/sidebar/BlockSettingsTab.tsx"],"sourcesContent":["'use client'\n\nimport React, { useMemo } from 'react'\nimport {\n RenderFields,\n useAllFormFields,\n useConfig,\n useDrawerSlug,\n useField,\n useModal,\n useTranslation,\n} from '@payloadcms/ui'\nimport { useDocConfig } from '../../hooks/useDocConfig'\nimport { useAddBlockDrawer } from '../../hooks/useAddBlockDrawer'\nimport { AddBlockDrawer } from '../blocks/AddBlockDrawer'\nimport { BlockActionsToolbar } from '../blocks/BlockActionsToolbar'\nimport { useBlockActions } from '../blocks/useBlockActions'\nimport { findNamedField, resolveBlockSchema, resolveFieldBlocks } from '../blocks/schema'\nimport type { ClientBlock } from 'payload'\nimport { BlockEmptyState } from '../blocks/BlockEmptyState'\nimport { BlockHeader } from '../blocks/BlockHeader'\nimport { useBetterEditorT } from '../../i18n/useBetterEditorT'\n\nexport type BlockSettingsTabProps = {\n selectedBlockPath: string | null\n onClearSelection: () => void\n onSelectPath: (path: string | null) => void\n blocksField: string\n /** Bump to open the add-after drawer externally (iframe `+` button). */\n addBelowRequestId?: number\n}\n\nexport const BlockSettingsTab: React.FC<BlockSettingsTabProps> = ({\n selectedBlockPath,\n onClearSelection,\n onSelectPath,\n blocksField,\n addBelowRequestId = 0,\n}) => {\n const t = useBetterEditorT()\n const { i18n } = useTranslation()\n const { fields: docFields, slug: docSlug } = useDocConfig()\n const [fields] = useAllFormFields()\n const { config } = useConfig()\n const blocksMap = config.blocksMap\n const { toggleModal } = useModal()\n const addBlockDrawerSlug = useDrawerSlug('better-editor-add-block')\n const addAfterDrawerSlug = useDrawerSlug('better-editor-add-after')\n\n const actions = useBlockActions({\n selectedBlockPath,\n onSelectPath,\n onClearSelection,\n })\n\n useAddBlockDrawer({\n drawerSlug: addAfterDrawerSlug,\n requestId: addBelowRequestId,\n selectedBlockPath,\n })\n\n const blocksFieldInfo = useMemo(() => {\n if (!docFields) return null\n return findNamedField(docFields, blocksField, docSlug || '')\n }, [docFields, blocksField, docSlug])\n\n const blocksFieldField = blocksFieldInfo?.field\n const availableBlocks: ClientBlock[] =\n blocksFieldField && blocksFieldField.type === 'blocks'\n ? resolveFieldBlocks(blocksFieldField, blocksMap)\n : []\n const blocksSchemaPath = blocksFieldInfo?.schemaPath || ''\n const topLevelRows = fields[blocksField]?.rows\n const addRowIndex = Array.isArray(topLevelRows) ? topLevelRows.length : 0\n\n if (!selectedBlockPath) {\n return (\n <>\n <BlockEmptyState\n canAdd={availableBlocks.length > 0}\n onAddClick={() => toggleModal(addBlockDrawerSlug)}\n />\n {availableBlocks.length > 0 ? (\n <AddBlockDrawer\n slug={addBlockDrawerSlug}\n blocks={availableBlocks}\n addRow={(index, blockType) =>\n actions.addAfter({\n blockType,\n schemaPath: blocksSchemaPath,\n containerPath: blocksField,\n index,\n })\n }\n addRowIndex={addRowIndex}\n />\n ) : null}\n </>\n )\n }\n\n const resolved = docFields\n ? resolveBlockSchema(\n { docFields, docSlug: docSlug || '', formFields: fields, blocksMap },\n selectedBlockPath,\n )\n : null\n\n const blockLabel = (() => {\n if (!resolved) return undefined\n const cfg = resolved.blocksFieldBlocks.find((b) => b.slug === resolved.blockType)\n const singular = cfg?.labels?.singular\n if (typeof singular === 'string') return singular\n if (singular && typeof singular === 'object') {\n return (singular as Record<string, string>)[i18n.language] ?? Object.values(singular)[0] as string | undefined\n }\n return undefined\n })()\n\n return (\n <div className=\"better-editor-tab better-editor-tab--native\">\n <BlockHeader\n blockType={resolved?.blockType || 'unknown'}\n blockLabel={blockLabel}\n path={selectedBlockPath}\n onClearSelection={onClearSelection}\n />\n\n <hr className=\"better-editor-tab__divider\" aria-hidden=\"true\" />\n\n <BlockActionsToolbar\n canMoveUp={actions.canMoveUp}\n canMoveDown={actions.canMoveDown}\n canMutate={actions.canMutate}\n canAddBelow={!!resolved}\n onMoveUp={actions.moveUp}\n onMoveDown={actions.moveDown}\n onDuplicate={actions.duplicate}\n onAddBelow={() => toggleModal(addAfterDrawerSlug)}\n onDelete={actions.remove}\n />\n\n {actions.canMutate && resolved && resolved.blocksFieldBlocks.length > 0 ? (\n <AddBlockDrawer\n slug={addAfterDrawerSlug}\n blocks={resolved.blocksFieldBlocks}\n addRow={(index, blockType) =>\n actions.addAfter({\n blockType,\n schemaPath: resolved.blocksFieldSchemaPath,\n containerPath: actions.parentPath,\n index,\n })\n }\n addRowIndex={actions.rowIndex + 1}\n />\n ) : null}\n\n {!resolved ? (\n <div className=\"better-editor-tab__empty\">{t.blocks.schemaError}</div>\n ) : (\n <>\n <BlockNameInput path={`${selectedBlockPath}.blockName`} />\n <hr className=\"better-editor-tab__divider\" aria-hidden=\"true\" />\n <RenderFields\n fields={resolved.blockFields}\n parentPath={resolved.parentPath}\n parentIndexPath=\"\"\n parentSchemaPath={resolved.schemaPath}\n // RenderFields' client read-gate is bypassed; the server-side\n // write check still runs on save.\n permissions={true}\n />\n </>\n )}\n </div>\n )\n}\n\nconst BlockNameInput: React.FC<{ path: string }> = ({ path }) => {\n const { value, setValue } = useField<string>({ path })\n const t = useBetterEditorT()\n const inputId = `be-blockname-${path}`\n return (\n <div className=\"better-editor-tab__block-name\">\n <label className=\"better-editor-tab__block-name-label\" htmlFor={inputId}>\n {t.blocks.blockName}\n </label>\n <input\n id={inputId}\n className=\"better-editor-tab__block-name-input\"\n type=\"text\"\n value={value || ''}\n onChange={(e) => setValue(e.target.value)}\n placeholder={t.blocks.blockNamePlaceholder}\n />\n </div>\n )\n}\n"],"names":["React","useMemo","RenderFields","useAllFormFields","useConfig","useDrawerSlug","useField","useModal","useTranslation","useDocConfig","useAddBlockDrawer","AddBlockDrawer","BlockActionsToolbar","useBlockActions","findNamedField","resolveBlockSchema","resolveFieldBlocks","BlockEmptyState","BlockHeader","useBetterEditorT","BlockSettingsTab","selectedBlockPath","onClearSelection","onSelectPath","blocksField","addBelowRequestId","t","i18n","fields","docFields","slug","docSlug","config","blocksMap","toggleModal","addBlockDrawerSlug","addAfterDrawerSlug","actions","drawerSlug","requestId","blocksFieldInfo","blocksFieldField","field","availableBlocks","type","blocksSchemaPath","schemaPath","topLevelRows","rows","addRowIndex","Array","isArray","length","canAdd","onAddClick","blocks","addRow","index","blockType","addAfter","containerPath","resolved","formFields","blockLabel","undefined","cfg","blocksFieldBlocks","find","b","singular","labels","language","Object","values","div","className","path","hr","aria-hidden","canMoveUp","canMoveDown","canMutate","canAddBelow","onMoveUp","moveUp","onMoveDown","moveDown","onDuplicate","duplicate","onAddBelow","onDelete","remove","blocksFieldSchemaPath","parentPath","rowIndex","schemaError","BlockNameInput","blockFields","parentIndexPath","parentSchemaPath","permissions","value","setValue","inputId","label","htmlFor","blockName","input","id","onChange","e","target","placeholder","blockNamePlaceholder"],"mappings":"AAAA;;AAEA,OAAOA,SAASC,OAAO,QAAQ,QAAO;AACtC,SACEC,YAAY,EACZC,gBAAgB,EAChBC,SAAS,EACTC,aAAa,EACbC,QAAQ,EACRC,QAAQ,EACRC,cAAc,QACT,iBAAgB;AACvB,SAASC,YAAY,QAAQ,2BAA0B;AACvD,SAASC,iBAAiB,QAAQ,gCAA+B;AACjE,SAASC,cAAc,QAAQ,2BAA0B;AACzD,SAASC,mBAAmB,QAAQ,gCAA+B;AACnE,SAASC,eAAe,QAAQ,4BAA2B;AAC3D,SAASC,cAAc,EAAEC,kBAAkB,EAAEC,kBAAkB,QAAQ,mBAAkB;AAEzF,SAASC,eAAe,QAAQ,4BAA2B;AAC3D,SAASC,WAAW,QAAQ,wBAAuB;AACnD,SAASC,gBAAgB,QAAQ,8BAA6B;AAW9D,OAAO,MAAMC,mBAAoD,CAAC,EAChEC,iBAAiB,EACjBC,gBAAgB,EAChBC,YAAY,EACZC,WAAW,EACXC,oBAAoB,CAAC,EACtB;IACC,MAAMC,IAAIP;IACV,MAAM,EAAEQ,IAAI,EAAE,GAAGnB;IACjB,MAAM,EAAEoB,QAAQC,SAAS,EAAEC,MAAMC,OAAO,EAAE,GAAGtB;IAC7C,MAAM,CAACmB,OAAO,GAAGzB;IACjB,MAAM,EAAE6B,MAAM,EAAE,GAAG5B;IACnB,MAAM6B,YAAYD,OAAOC,SAAS;IAClC,MAAM,EAAEC,WAAW,EAAE,GAAG3B;IACxB,MAAM4B,qBAAqB9B,cAAc;IACzC,MAAM+B,qBAAqB/B,cAAc;IAEzC,MAAMgC,UAAUxB,gBAAgB;QAC9BQ;QACAE;QACAD;IACF;IAEAZ,kBAAkB;QAChB4B,YAAYF;QACZG,WAAWd;QACXJ;IACF;IAEA,MAAMmB,kBAAkBvC,QAAQ;QAC9B,IAAI,CAAC4B,WAAW,OAAO;QACvB,OAAOf,eAAee,WAAWL,aAAaO,WAAW;IAC3D,GAAG;QAACF;QAAWL;QAAaO;KAAQ;IAEpC,MAAMU,mBAAmBD,iBAAiBE;IAC1C,MAAMC,kBACJF,oBAAoBA,iBAAiBG,IAAI,KAAK,WAC1C5B,mBAAmByB,kBAAkBR,aACrC,EAAE;IACR,MAAMY,mBAAmBL,iBAAiBM,cAAc;IACxD,MAAMC,eAAenB,MAAM,CAACJ,YAAY,EAAEwB;IAC1C,MAAMC,cAAcC,MAAMC,OAAO,CAACJ,gBAAgBA,aAAaK,MAAM,GAAG;IAExE,IAAI,CAAC/B,mBAAmB;QACtB,qBACE;;8BACE,KAACJ;oBACCoC,QAAQV,gBAAgBS,MAAM,GAAG;oBACjCE,YAAY,IAAMpB,YAAYC;;gBAE/BQ,gBAAgBS,MAAM,GAAG,kBACxB,KAACzC;oBACCmB,MAAMK;oBACNoB,QAAQZ;oBACRa,QAAQ,CAACC,OAAOC,YACdrB,QAAQsB,QAAQ,CAAC;4BACfD;4BACAZ,YAAYD;4BACZe,eAAepC;4BACfiC;wBACF;oBAEFR,aAAaA;qBAEb;;;IAGV;IAEA,MAAMY,WAAWhC,YACbd,mBACE;QAAEc;QAAWE,SAASA,WAAW;QAAI+B,YAAYlC;QAAQK;IAAU,GACnEZ,qBAEF;IAEJ,MAAM0C,aAAa,AAAC,CAAA;QAClB,IAAI,CAACF,UAAU,OAAOG;QACtB,MAAMC,MAAMJ,SAASK,iBAAiB,CAACC,IAAI,CAAC,CAACC,IAAMA,EAAEtC,IAAI,KAAK+B,SAASH,SAAS;QAChF,MAAMW,WAAWJ,KAAKK,QAAQD;QAC9B,IAAI,OAAOA,aAAa,UAAU,OAAOA;QACzC,IAAIA,YAAY,OAAOA,aAAa,UAAU;YAC5C,OAAO,AAACA,QAAmC,CAAC1C,KAAK4C,QAAQ,CAAC,IAAIC,OAAOC,MAAM,CAACJ,SAAS,CAAC,EAAE;QAC1F;QACA,OAAOL;IACT,CAAA;IAEA,qBACE,MAACU;QAAIC,WAAU;;0BACb,KAACzD;gBACCwC,WAAWG,UAAUH,aAAa;gBAClCK,YAAYA;gBACZa,MAAMvD;gBACNC,kBAAkBA;;0BAGpB,KAACuD;gBAAGF,WAAU;gBAA6BG,eAAY;;0BAEvD,KAAClE;gBACCmE,WAAW1C,QAAQ0C,SAAS;gBAC5BC,aAAa3C,QAAQ2C,WAAW;gBAChCC,WAAW5C,QAAQ4C,SAAS;gBAC5BC,aAAa,CAAC,CAACrB;gBACfsB,UAAU9C,QAAQ+C,MAAM;gBACxBC,YAAYhD,QAAQiD,QAAQ;gBAC5BC,aAAalD,QAAQmD,SAAS;gBAC9BC,YAAY,IAAMvD,YAAYE;gBAC9BsD,UAAUrD,QAAQsD,MAAM;;YAGzBtD,QAAQ4C,SAAS,IAAIpB,YAAYA,SAASK,iBAAiB,CAACd,MAAM,GAAG,kBACpE,KAACzC;gBACCmB,MAAMM;gBACNmB,QAAQM,SAASK,iBAAiB;gBAClCV,QAAQ,CAACC,OAAOC,YACdrB,QAAQsB,QAAQ,CAAC;wBACfD;wBACAZ,YAAYe,SAAS+B,qBAAqB;wBAC1ChC,eAAevB,QAAQwD,UAAU;wBACjCpC;oBACF;gBAEFR,aAAaZ,QAAQyD,QAAQ,GAAG;iBAEhC;YAEH,CAACjC,yBACA,KAACa;gBAAIC,WAAU;0BAA4BjD,EAAE6B,MAAM,CAACwC,WAAW;+BAE/D;;kCACE,KAACC;wBAAepB,MAAM,GAAGvD,kBAAkB,UAAU,CAAC;;kCACtD,KAACwD;wBAAGF,WAAU;wBAA6BG,eAAY;;kCACvD,KAAC5E;wBACC0B,QAAQiC,SAASoC,WAAW;wBAC5BJ,YAAYhC,SAASgC,UAAU;wBAC/BK,iBAAgB;wBAChBC,kBAAkBtC,SAASf,UAAU;wBACrC,8DAA8D;wBAC9D,kCAAkC;wBAClCsD,aAAa;;;;;;AAMzB,EAAC;AAED,MAAMJ,iBAA6C,CAAC,EAAEpB,IAAI,EAAE;IAC1D,MAAM,EAAEyB,KAAK,EAAEC,QAAQ,EAAE,GAAGhG,SAAiB;QAAEsE;IAAK;IACpD,MAAMlD,IAAIP;IACV,MAAMoF,UAAU,CAAC,aAAa,EAAE3B,MAAM;IACtC,qBACE,MAACF;QAAIC,WAAU;;0BACb,KAAC6B;gBAAM7B,WAAU;gBAAsC8B,SAASF;0BAC7D7E,EAAE6B,MAAM,CAACmD,SAAS;;0BAErB,KAACC;gBACCC,IAAIL;gBACJ5B,WAAU;gBACV/B,MAAK;gBACLyD,OAAOA,SAAS;gBAChBQ,UAAU,CAACC,IAAMR,SAASQ,EAAEC,MAAM,CAACV,KAAK;gBACxCW,aAAatF,EAAE6B,MAAM,CAAC0D,oBAAoB;;;;AAIlD"}
|
|
@@ -2,10 +2,14 @@
|
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import { DocumentFieldsTab } from './DocumentFieldsTab';
|
|
5
|
+
import { useBetterEditorT } from '../../i18n/useBetterEditorT';
|
|
5
6
|
const isSidebarField = (f)=>'admin' in f && f.admin?.position === 'sidebar';
|
|
6
|
-
export const DocumentMetaTab = ()
|
|
7
|
+
export const DocumentMetaTab = ()=>{
|
|
8
|
+
const t = useBetterEditorT();
|
|
9
|
+
return /*#__PURE__*/ _jsx(DocumentFieldsTab, {
|
|
7
10
|
filter: isSidebarField,
|
|
8
|
-
emptyText:
|
|
11
|
+
emptyText: t.documentFields.noSettings
|
|
9
12
|
});
|
|
13
|
+
};
|
|
10
14
|
|
|
11
15
|
//# sourceMappingURL=DocumentMetaTab.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/admin/sidebar/DocumentMetaTab.tsx"],"sourcesContent":["'use client'\n\nimport React from 'react'\nimport type { ClientField } from 'payload'\nimport { DocumentFieldsTab } from './DocumentFieldsTab'\n\nconst isSidebarField = (f: ClientField): boolean =>\n 'admin' in f && f.admin?.position === 'sidebar'\n\nexport const DocumentMetaTab: React.FC = () => (\n <DocumentFieldsTab
|
|
1
|
+
{"version":3,"sources":["../../../src/admin/sidebar/DocumentMetaTab.tsx"],"sourcesContent":["'use client'\n\nimport React from 'react'\nimport type { ClientField } from 'payload'\nimport { DocumentFieldsTab } from './DocumentFieldsTab'\nimport { useBetterEditorT } from '../../i18n/useBetterEditorT'\n\nconst isSidebarField = (f: ClientField): boolean =>\n 'admin' in f && f.admin?.position === 'sidebar'\n\nexport const DocumentMetaTab: React.FC = () => {\n const t = useBetterEditorT()\n return <DocumentFieldsTab filter={isSidebarField} emptyText={t.documentFields.noSettings} />\n}\n"],"names":["React","DocumentFieldsTab","useBetterEditorT","isSidebarField","f","admin","position","DocumentMetaTab","t","filter","emptyText","documentFields","noSettings"],"mappings":"AAAA;;AAEA,OAAOA,WAAW,QAAO;AAEzB,SAASC,iBAAiB,QAAQ,sBAAqB;AACvD,SAASC,gBAAgB,QAAQ,8BAA6B;AAE9D,MAAMC,iBAAiB,CAACC,IACtB,WAAWA,KAAKA,EAAEC,KAAK,EAAEC,aAAa;AAExC,OAAO,MAAMC,kBAA4B;IACvC,MAAMC,IAAIN;IACV,qBAAO,KAACD;QAAkBQ,QAAQN;QAAgBO,WAAWF,EAAEG,cAAc,CAACC,UAAU;;AAC1F,EAAC"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import { DocumentFieldsTab } from './DocumentFieldsTab';
|
|
5
|
+
import { useBetterEditorT } from '../../i18n/useBetterEditorT';
|
|
5
6
|
const isNotSidebar = (f)=>!('admin' in f) || f.admin?.position !== 'sidebar';
|
|
6
7
|
// The blocks tab owns layout-block editing; stripping `blocks` fields here
|
|
7
8
|
// avoids rendering them twice and keeps this tab focused on document meta.
|
|
@@ -39,10 +40,13 @@ const stripBlocks = (fields)=>{
|
|
|
39
40
|
}
|
|
40
41
|
return result;
|
|
41
42
|
};
|
|
42
|
-
export const DocumentSettingsTab = ()
|
|
43
|
+
export const DocumentSettingsTab = ()=>{
|
|
44
|
+
const t = useBetterEditorT();
|
|
45
|
+
return /*#__PURE__*/ _jsx(DocumentFieldsTab, {
|
|
43
46
|
filter: isNotSidebar,
|
|
44
47
|
transform: stripBlocks,
|
|
45
|
-
emptyText:
|
|
48
|
+
emptyText: t.documentFields.noFields
|
|
46
49
|
});
|
|
50
|
+
};
|
|
47
51
|
|
|
48
52
|
//# sourceMappingURL=DocumentSettingsTab.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/admin/sidebar/DocumentSettingsTab.tsx"],"sourcesContent":["'use client'\n\nimport React from 'react'\nimport type { ClientField, ClientTab } from 'payload'\nimport { DocumentFieldsTab } from './DocumentFieldsTab'\n\nconst isNotSidebar = (f: ClientField): boolean =>\n !('admin' in f) || f.admin?.position !== 'sidebar'\n\n// The blocks tab owns layout-block editing; stripping `blocks` fields here\n// avoids rendering them twice and keeps this tab focused on document meta.\nconst stripBlocks = (fields: ClientField[]): ClientField[] => {\n const result: ClientField[] = []\n for (const field of fields) {\n const type = field.type\n\n if (type === 'blocks') continue\n\n if (type === 'tabs') {\n const newTabs: ClientTab[] = []\n for (const tab of field.tabs) {\n const inner = stripBlocks(tab.fields ?? [])\n if (inner.length > 0) newTabs.push({ ...tab, fields: inner })\n }\n if (newTabs.length === 0) continue\n result.push({ ...field, tabs: newTabs })\n continue\n }\n\n if (type === 'collapsible' || type === 'row' || type === 'group') {\n const inner = stripBlocks(field.fields)\n if (inner.length === 0) continue\n result.push({ ...field, fields: inner })\n continue\n }\n\n result.push(field)\n }\n return result\n}\n\nexport const DocumentSettingsTab: React.FC = () => (\n <DocumentFieldsTab\n
|
|
1
|
+
{"version":3,"sources":["../../../src/admin/sidebar/DocumentSettingsTab.tsx"],"sourcesContent":["'use client'\n\nimport React from 'react'\nimport type { ClientField, ClientTab } from 'payload'\nimport { DocumentFieldsTab } from './DocumentFieldsTab'\nimport { useBetterEditorT } from '../../i18n/useBetterEditorT'\n\nconst isNotSidebar = (f: ClientField): boolean =>\n !('admin' in f) || f.admin?.position !== 'sidebar'\n\n// The blocks tab owns layout-block editing; stripping `blocks` fields here\n// avoids rendering them twice and keeps this tab focused on document meta.\nconst stripBlocks = (fields: ClientField[]): ClientField[] => {\n const result: ClientField[] = []\n for (const field of fields) {\n const type = field.type\n\n if (type === 'blocks') continue\n\n if (type === 'tabs') {\n const newTabs: ClientTab[] = []\n for (const tab of field.tabs) {\n const inner = stripBlocks(tab.fields ?? [])\n if (inner.length > 0) newTabs.push({ ...tab, fields: inner })\n }\n if (newTabs.length === 0) continue\n result.push({ ...field, tabs: newTabs })\n continue\n }\n\n if (type === 'collapsible' || type === 'row' || type === 'group') {\n const inner = stripBlocks(field.fields)\n if (inner.length === 0) continue\n result.push({ ...field, fields: inner })\n continue\n }\n\n result.push(field)\n }\n return result\n}\n\nexport const DocumentSettingsTab: React.FC = () => {\n const t = useBetterEditorT()\n return (\n <DocumentFieldsTab\n filter={isNotSidebar}\n transform={stripBlocks}\n emptyText={t.documentFields.noFields}\n />\n )\n}\n"],"names":["React","DocumentFieldsTab","useBetterEditorT","isNotSidebar","f","admin","position","stripBlocks","fields","result","field","type","newTabs","tab","tabs","inner","length","push","DocumentSettingsTab","t","filter","transform","emptyText","documentFields","noFields"],"mappings":"AAAA;;AAEA,OAAOA,WAAW,QAAO;AAEzB,SAASC,iBAAiB,QAAQ,sBAAqB;AACvD,SAASC,gBAAgB,QAAQ,8BAA6B;AAE9D,MAAMC,eAAe,CAACC,IACpB,CAAE,CAAA,WAAWA,CAAAA,KAAMA,EAAEC,KAAK,EAAEC,aAAa;AAE3C,2EAA2E;AAC3E,2EAA2E;AAC3E,MAAMC,cAAc,CAACC;IACnB,MAAMC,SAAwB,EAAE;IAChC,KAAK,MAAMC,SAASF,OAAQ;QAC1B,MAAMG,OAAOD,MAAMC,IAAI;QAEvB,IAAIA,SAAS,UAAU;QAEvB,IAAIA,SAAS,QAAQ;YACnB,MAAMC,UAAuB,EAAE;YAC/B,KAAK,MAAMC,OAAOH,MAAMI,IAAI,CAAE;gBAC5B,MAAMC,QAAQR,YAAYM,IAAIL,MAAM,IAAI,EAAE;gBAC1C,IAAIO,MAAMC,MAAM,GAAG,GAAGJ,QAAQK,IAAI,CAAC;oBAAE,GAAGJ,GAAG;oBAAEL,QAAQO;gBAAM;YAC7D;YACA,IAAIH,QAAQI,MAAM,KAAK,GAAG;YAC1BP,OAAOQ,IAAI,CAAC;gBAAE,GAAGP,KAAK;gBAAEI,MAAMF;YAAQ;YACtC;QACF;QAEA,IAAID,SAAS,iBAAiBA,SAAS,SAASA,SAAS,SAAS;YAChE,MAAMI,QAAQR,YAAYG,MAAMF,MAAM;YACtC,IAAIO,MAAMC,MAAM,KAAK,GAAG;YACxBP,OAAOQ,IAAI,CAAC;gBAAE,GAAGP,KAAK;gBAAEF,QAAQO;YAAM;YACtC;QACF;QAEAN,OAAOQ,IAAI,CAACP;IACd;IACA,OAAOD;AACT;AAEA,OAAO,MAAMS,sBAAgC;IAC3C,MAAMC,IAAIjB;IACV,qBACE,KAACD;QACCmB,QAAQjB;QACRkB,WAAWd;QACXe,WAAWH,EAAEI,cAAc,CAACC,QAAQ;;AAG1C,EAAC"}
|
|
@@ -5,20 +5,7 @@ import { DocumentSettingsTab } from './DocumentSettingsTab';
|
|
|
5
5
|
import { DocumentMetaTab } from './DocumentMetaTab';
|
|
6
6
|
import { BlockSettingsTab } from './BlockSettingsTab';
|
|
7
7
|
import { ValidationSummary } from './ValidationSummary';
|
|
8
|
-
|
|
9
|
-
{
|
|
10
|
-
key: 'page',
|
|
11
|
-
label: 'Page'
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
key: 'block',
|
|
15
|
-
label: 'Blocks'
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
key: 'settings',
|
|
19
|
-
label: 'Settings'
|
|
20
|
-
}
|
|
21
|
-
];
|
|
8
|
+
import { useBetterEditorT } from '../../i18n/useBetterEditorT';
|
|
22
9
|
const ROOT_CLASS = 'better-editor-sidebar';
|
|
23
10
|
const TAB_CLASS = `${ROOT_CLASS}__tab`;
|
|
24
11
|
const tabId = (key)=>`better-editor-tab-${key}`;
|
|
@@ -36,6 +23,21 @@ const SidebarTab = ({ tabKey, label, active, onSelect })=>/*#__PURE__*/ _jsx("bu
|
|
|
36
23
|
});
|
|
37
24
|
// Memoized so resize-drag re-renders of the overlay skip the field tree.
|
|
38
25
|
export const Sidebar = /*#__PURE__*/ React.memo(function Sidebar({ selectedBlockPath, onClearSelection, onSelectPath, forceFullWidthFields, blocksField, addBelowRequestId = 0 }) {
|
|
26
|
+
const t = useBetterEditorT();
|
|
27
|
+
const TABS = [
|
|
28
|
+
{
|
|
29
|
+
key: 'page',
|
|
30
|
+
label: t.sidebar.tabs.page
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
key: 'block',
|
|
34
|
+
label: t.sidebar.tabs.block
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
key: 'settings',
|
|
38
|
+
label: t.sidebar.tabs.settings
|
|
39
|
+
}
|
|
40
|
+
];
|
|
39
41
|
const [tab, setTab] = useState('page');
|
|
40
42
|
// Auto-jump to the block tab when the iframe selects a new block.
|
|
41
43
|
useEffect(()=>{
|
|
@@ -87,12 +89,15 @@ export const Sidebar = /*#__PURE__*/ React.memo(function Sidebar({ selectedBlock
|
|
|
87
89
|
});
|
|
88
90
|
// Off-screen live region announces block-selection changes to screen
|
|
89
91
|
// readers; visible UI updates handle sighted users via the tab switch.
|
|
90
|
-
const SelectionAnnouncer = ({ selectedBlockPath })
|
|
92
|
+
const SelectionAnnouncer = ({ selectedBlockPath })=>{
|
|
93
|
+
const t = useBetterEditorT();
|
|
94
|
+
return /*#__PURE__*/ _jsx("div", {
|
|
91
95
|
role: "status",
|
|
92
96
|
"aria-live": "polite",
|
|
93
97
|
"aria-atomic": "true",
|
|
94
98
|
className: "better-editor-sr-only",
|
|
95
|
-
children: selectedBlockPath ?
|
|
99
|
+
children: selectedBlockPath ? `${t.sidebar.blockSelected}${selectedBlockPath}` : t.sidebar.noBlockSelected
|
|
96
100
|
});
|
|
101
|
+
};
|
|
97
102
|
|
|
98
103
|
//# sourceMappingURL=Sidebar.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/admin/sidebar/Sidebar.tsx"],"sourcesContent":["'use client'\n\nimport React, { useEffect, useState } from 'react'\nimport { DocumentSettingsTab } from './DocumentSettingsTab'\nimport { DocumentMetaTab } from './DocumentMetaTab'\nimport { BlockSettingsTab } from './BlockSettingsTab'\nimport { ValidationSummary } from './ValidationSummary'\n\nexport type SidebarProps = {\n selectedBlockPath: string | null\n onClearSelection: () => void\n onSelectPath: (path: string | null) => void\n forceFullWidthFields: boolean\n blocksField: string\n addBelowRequestId?: number\n}\n\ntype TabKey = 'page' | 'block' | 'settings'\n\nconst
|
|
1
|
+
{"version":3,"sources":["../../../src/admin/sidebar/Sidebar.tsx"],"sourcesContent":["'use client'\n\nimport React, { useEffect, useState } from 'react'\nimport { DocumentSettingsTab } from './DocumentSettingsTab'\nimport { DocumentMetaTab } from './DocumentMetaTab'\nimport { BlockSettingsTab } from './BlockSettingsTab'\nimport { ValidationSummary } from './ValidationSummary'\nimport { useBetterEditorT } from '../../i18n/useBetterEditorT'\n\nexport type SidebarProps = {\n selectedBlockPath: string | null\n onClearSelection: () => void\n onSelectPath: (path: string | null) => void\n forceFullWidthFields: boolean\n blocksField: string\n addBelowRequestId?: number\n}\n\ntype TabKey = 'page' | 'block' | 'settings'\n\nconst ROOT_CLASS = 'better-editor-sidebar'\nconst TAB_CLASS = `${ROOT_CLASS}__tab`\n\nconst tabId = (key: TabKey) => `better-editor-tab-${key}`\nconst panelId = (key: TabKey) => `better-editor-panel-${key}`\n\ntype SidebarTabProps = {\n tabKey: TabKey\n label: string\n active: boolean\n onSelect: (key: TabKey) => void\n}\n\nconst SidebarTab: React.FC<SidebarTabProps> = ({ tabKey, label, active, onSelect }) => (\n <button\n type=\"button\"\n role=\"tab\"\n id={tabId(tabKey)}\n aria-selected={active}\n aria-controls={panelId(tabKey)}\n tabIndex={active ? 0 : -1}\n className={active ? `${TAB_CLASS} ${TAB_CLASS}--active` : TAB_CLASS}\n onClick={() => onSelect(tabKey)}\n >\n {label}\n </button>\n)\n\n// Memoized so resize-drag re-renders of the overlay skip the field tree.\nexport const Sidebar = React.memo(function Sidebar({\n selectedBlockPath,\n onClearSelection,\n onSelectPath,\n forceFullWidthFields,\n blocksField,\n addBelowRequestId = 0,\n}: SidebarProps) {\n const t = useBetterEditorT()\n const TABS: ReadonlyArray<{ key: TabKey; label: string }> = [\n { key: 'page', label: t.sidebar.tabs.page },\n { key: 'block', label: t.sidebar.tabs.block },\n { key: 'settings', label: t.sidebar.tabs.settings },\n ]\n const [tab, setTab] = useState<TabKey>('page')\n\n // Auto-jump to the block tab when the iframe selects a new block.\n useEffect(() => {\n if (selectedBlockPath) setTab('block')\n }, [selectedBlockPath])\n\n const className = forceFullWidthFields\n ? `${ROOT_CLASS} ${ROOT_CLASS}--force-full-width`\n : ROOT_CLASS\n\n return (\n <div className={className}>\n <div role=\"tablist\" className={`${ROOT_CLASS}__tabs`}>\n {TABS.map((t) => (\n <SidebarTab\n key={t.key}\n tabKey={t.key}\n label={t.label}\n active={tab === t.key}\n onSelect={setTab}\n />\n ))}\n </div>\n\n <ValidationSummary blocksField={blocksField} onSelectPath={onSelectPath} />\n\n <div\n className={`${ROOT_CLASS}__content`}\n role=\"tabpanel\"\n id={panelId(tab)}\n aria-labelledby={tabId(tab)}\n tabIndex={0}\n >\n {tab === 'page' && <DocumentSettingsTab />}\n {tab === 'block' && (\n <BlockSettingsTab\n selectedBlockPath={selectedBlockPath}\n onClearSelection={onClearSelection}\n onSelectPath={onSelectPath}\n blocksField={blocksField}\n addBelowRequestId={addBelowRequestId}\n />\n )}\n {tab === 'settings' && <DocumentMetaTab />}\n </div>\n\n <SelectionAnnouncer selectedBlockPath={selectedBlockPath} />\n </div>\n )\n})\n\n// Off-screen live region announces block-selection changes to screen\n// readers; visible UI updates handle sighted users via the tab switch.\nconst SelectionAnnouncer: React.FC<{ selectedBlockPath: string | null }> = ({\n selectedBlockPath,\n}) => {\n const t = useBetterEditorT()\n return (\n <div role=\"status\" aria-live=\"polite\" aria-atomic=\"true\" className=\"better-editor-sr-only\">\n {selectedBlockPath\n ? `${t.sidebar.blockSelected}${selectedBlockPath}`\n : t.sidebar.noBlockSelected}\n </div>\n )\n}\n"],"names":["React","useEffect","useState","DocumentSettingsTab","DocumentMetaTab","BlockSettingsTab","ValidationSummary","useBetterEditorT","ROOT_CLASS","TAB_CLASS","tabId","key","panelId","SidebarTab","tabKey","label","active","onSelect","button","type","role","id","aria-selected","aria-controls","tabIndex","className","onClick","Sidebar","memo","selectedBlockPath","onClearSelection","onSelectPath","forceFullWidthFields","blocksField","addBelowRequestId","t","TABS","sidebar","tabs","page","block","settings","tab","setTab","div","map","aria-labelledby","SelectionAnnouncer","aria-live","aria-atomic","blockSelected","noBlockSelected"],"mappings":"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"}
|
|
@@ -3,22 +3,25 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import React, { useMemo } from 'react';
|
|
4
4
|
import { useAllFormFields } from '@payloadcms/ui';
|
|
5
5
|
import { collectFieldErrors } from './validation';
|
|
6
|
+
import { useBetterEditorT } from '../../i18n/useBetterEditorT';
|
|
6
7
|
// Sidebar banner listing invalid fields across all blocks.
|
|
7
8
|
export const ValidationSummary = ({ blocksField, onSelectPath })=>{
|
|
9
|
+
const t = useBetterEditorT();
|
|
8
10
|
const [fields] = useAllFormFields();
|
|
9
11
|
const errors = useMemo(()=>collectFieldErrors(fields, blocksField), [
|
|
10
12
|
fields,
|
|
11
13
|
blocksField
|
|
12
14
|
]);
|
|
13
15
|
if (errors.length === 0) return null;
|
|
16
|
+
const countLabel = errors.length === 1 ? t.sidebar.validationSingular : `${errors.length}${t.sidebar.validationPlural}`;
|
|
14
17
|
return /*#__PURE__*/ _jsxs("div", {
|
|
15
18
|
className: "better-editor-sidebar__errors",
|
|
16
19
|
role: "region",
|
|
17
|
-
"aria-label":
|
|
20
|
+
"aria-label": t.sidebar.validationLabel,
|
|
18
21
|
children: [
|
|
19
22
|
/*#__PURE__*/ _jsx("p", {
|
|
20
23
|
className: "better-editor-sidebar__errors-title",
|
|
21
|
-
children:
|
|
24
|
+
children: countLabel
|
|
22
25
|
}),
|
|
23
26
|
/*#__PURE__*/ _jsx("ul", {
|
|
24
27
|
className: "better-editor-sidebar__errors-list",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/admin/sidebar/ValidationSummary.tsx"],"sourcesContent":["'use client'\n\nimport React, { useMemo } from 'react'\nimport { useAllFormFields } from '@payloadcms/ui'\nimport type { FormState } from 'payload'\nimport { collectFieldErrors } from './validation'\n\nexport type ValidationSummaryProps = {\n blocksField: string\n onSelectPath: (path: string | null) => void\n}\n\n// Sidebar banner listing invalid fields across all blocks.\nexport const ValidationSummary: React.FC<ValidationSummaryProps> = ({\n blocksField,\n onSelectPath,\n}) => {\n const [fields] = useAllFormFields()\n const errors = useMemo(\n () => collectFieldErrors(fields as FormState, blocksField),\n [fields, blocksField],\n )\n\n if (errors.length === 0) return null\n\n return (\n <div
|
|
1
|
+
{"version":3,"sources":["../../../src/admin/sidebar/ValidationSummary.tsx"],"sourcesContent":["'use client'\n\nimport React, { useMemo } from 'react'\nimport { useAllFormFields } from '@payloadcms/ui'\nimport type { FormState } from 'payload'\nimport { collectFieldErrors } from './validation'\nimport { useBetterEditorT } from '../../i18n/useBetterEditorT'\n\nexport type ValidationSummaryProps = {\n blocksField: string\n onSelectPath: (path: string | null) => void\n}\n\n// Sidebar banner listing invalid fields across all blocks.\nexport const ValidationSummary: React.FC<ValidationSummaryProps> = ({\n blocksField,\n onSelectPath,\n}) => {\n const t = useBetterEditorT()\n const [fields] = useAllFormFields()\n const errors = useMemo(\n () => collectFieldErrors(fields as FormState, blocksField),\n [fields, blocksField],\n )\n\n if (errors.length === 0) return null\n\n const countLabel =\n errors.length === 1\n ? t.sidebar.validationSingular\n : `${errors.length}${t.sidebar.validationPlural}`\n\n return (\n <div\n className=\"better-editor-sidebar__errors\"\n role=\"region\"\n aria-label={t.sidebar.validationLabel}\n >\n <p className=\"better-editor-sidebar__errors-title\">{countLabel}</p>\n <ul className=\"better-editor-sidebar__errors-list\">\n {errors.map((error) => (\n <li key={error.path} className=\"better-editor-sidebar__errors-item\">\n {error.blockPath ? (\n <button\n type=\"button\"\n className=\"better-editor-sidebar__errors-jump\"\n onClick={() => onSelectPath(error.blockPath)}\n >\n {error.label}\n </button>\n ) : (\n <span className=\"better-editor-sidebar__errors-label\">{error.label}</span>\n )}\n <span className=\"better-editor-sidebar__errors-message\">{error.message}</span>\n </li>\n ))}\n </ul>\n </div>\n )\n}\n"],"names":["React","useMemo","useAllFormFields","collectFieldErrors","useBetterEditorT","ValidationSummary","blocksField","onSelectPath","t","fields","errors","length","countLabel","sidebar","validationSingular","validationPlural","div","className","role","aria-label","validationLabel","p","ul","map","error","li","blockPath","button","type","onClick","label","span","message","path"],"mappings":"AAAA;;AAEA,OAAOA,SAASC,OAAO,QAAQ,QAAO;AACtC,SAASC,gBAAgB,QAAQ,iBAAgB;AAEjD,SAASC,kBAAkB,QAAQ,eAAc;AACjD,SAASC,gBAAgB,QAAQ,8BAA6B;AAO9D,2DAA2D;AAC3D,OAAO,MAAMC,oBAAsD,CAAC,EAClEC,WAAW,EACXC,YAAY,EACb;IACC,MAAMC,IAAIJ;IACV,MAAM,CAACK,OAAO,GAAGP;IACjB,MAAMQ,SAAST,QACb,IAAME,mBAAmBM,QAAqBH,cAC9C;QAACG;QAAQH;KAAY;IAGvB,IAAII,OAAOC,MAAM,KAAK,GAAG,OAAO;IAEhC,MAAMC,aACJF,OAAOC,MAAM,KAAK,IACdH,EAAEK,OAAO,CAACC,kBAAkB,GAC5B,GAAGJ,OAAOC,MAAM,GAAGH,EAAEK,OAAO,CAACE,gBAAgB,EAAE;IAErD,qBACE,MAACC;QACCC,WAAU;QACVC,MAAK;QACLC,cAAYX,EAAEK,OAAO,CAACO,eAAe;;0BAErC,KAACC;gBAAEJ,WAAU;0BAAuCL;;0BACpD,KAACU;gBAAGL,WAAU;0BACXP,OAAOa,GAAG,CAAC,CAACC,sBACX,MAACC;wBAAoBR,WAAU;;4BAC5BO,MAAME,SAAS,iBACd,KAACC;gCACCC,MAAK;gCACLX,WAAU;gCACVY,SAAS,IAAMtB,aAAaiB,MAAME,SAAS;0CAE1CF,MAAMM,KAAK;+CAGd,KAACC;gCAAKd,WAAU;0CAAuCO,MAAMM,KAAK;;0CAEpE,KAACC;gCAAKd,WAAU;0CAAyCO,MAAMQ,OAAO;;;uBAZ/DR,MAAMS,IAAI;;;;AAkB7B,EAAC"}
|
package/dist/global.js
CHANGED
|
@@ -1,33 +1,49 @@
|
|
|
1
1
|
import { DEFAULT_BETTER_EDITOR_SETTINGS as D } from './internal/constants';
|
|
2
2
|
import { HOVER_OUTLINE_MAX, HOVER_OUTLINE_MIN, MOBILE_WIDTH_MAX, MOBILE_WIDTH_MIN, TABLET_WIDTH_MAX, TABLET_WIDTH_MIN } from './internal/limits';
|
|
3
|
+
import { en } from './i18n/en';
|
|
4
|
+
import { de } from './i18n/de';
|
|
3
5
|
export const BETTER_EDITOR_SETTINGS_SLUG = 'better-editor-settings';
|
|
4
6
|
export const BETTER_EDITOR_SETTINGS_BANNER_FIELD = 'betterEditorSettingsBanner';
|
|
5
7
|
// Mirrors the runtime regex in `preview/hover-css.ts` so the admin UI rejects
|
|
6
8
|
// values that would silently be skipped at render time.
|
|
7
9
|
const HOVER_COLOR_RE = /^(?:#[0-9a-fA-F]{3,8}|rgba?\([^()\n\r]*\))$/i;
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
const settingsKey = (path)=>`betterEditor:settings.${path}`;
|
|
11
|
+
// Locales the plugin ships built-in translations for.
|
|
12
|
+
const SETTINGS_TRANSLATIONS = {
|
|
13
|
+
en: en.settings,
|
|
14
|
+
de: de.settings
|
|
15
|
+
};
|
|
16
|
+
const lookupSetting = (settings, path)=>path.split('.').reduce((value, key)=>value?.[key], settings);
|
|
17
|
+
// Entity/field labels and descriptions are serialized into the admin RootLayout
|
|
18
|
+
// (a Client Component), so they must be plain data — a function (e.g. `({ t }) => …`)
|
|
19
|
+
// can't cross that RSC boundary. Return a Payload locale map built from our bundled
|
|
20
|
+
// translations; Payload selects the entry for the admin UI language. (Runtime `t()`
|
|
21
|
+
// stays available for `validate`, which Payload strips before client serialization.)
|
|
22
|
+
const translatedLabel = (path)=>Object.fromEntries(Object.entries(SETTINGS_TRANSLATIONS).map(([locale, settings])=>[
|
|
23
|
+
locale,
|
|
24
|
+
lookupSetting(settings, path)
|
|
25
|
+
]));
|
|
26
|
+
const validateHoverColor = (value, args)=>{
|
|
27
|
+
const t = args?.t ?? ((k)=>k);
|
|
28
|
+
if (typeof value !== 'string' || value.length === 0) return t(settingsKey('validation.colorRequired'));
|
|
29
|
+
if (!HOVER_COLOR_RE.test(value.trim())) return t(settingsKey('validation.colorInvalid'));
|
|
13
30
|
return true;
|
|
14
31
|
};
|
|
15
|
-
const validateHoverOutline = (value)=>{
|
|
16
|
-
|
|
17
|
-
if (value
|
|
18
|
-
|
|
19
|
-
}
|
|
32
|
+
const validateHoverOutline = (value, args)=>{
|
|
33
|
+
const t = args?.t ?? ((k)=>k);
|
|
34
|
+
if (typeof value !== 'number' || !Number.isFinite(value)) return t(settingsKey('validation.mustBeNumber'));
|
|
35
|
+
if (value < HOVER_OUTLINE_MIN || value > HOVER_OUTLINE_MAX) return t(settingsKey('validation.outlineRange'));
|
|
20
36
|
return true;
|
|
21
37
|
};
|
|
22
38
|
export const betterEditorSettingsGlobal = {
|
|
23
39
|
slug: BETTER_EDITOR_SETTINGS_SLUG,
|
|
24
|
-
label: '
|
|
40
|
+
label: translatedLabel('globalLabel'),
|
|
25
41
|
access: {
|
|
26
42
|
read: ()=>true
|
|
27
43
|
},
|
|
28
44
|
admin: {
|
|
29
45
|
group: 'Better Editor',
|
|
30
|
-
description: '
|
|
46
|
+
description: translatedLabel('globalDescription')
|
|
31
47
|
},
|
|
32
48
|
fields: [
|
|
33
49
|
{
|
|
@@ -43,21 +59,21 @@ export const betterEditorSettingsGlobal = {
|
|
|
43
59
|
type: 'tabs',
|
|
44
60
|
tabs: [
|
|
45
61
|
{
|
|
46
|
-
label: '
|
|
47
|
-
description: '
|
|
62
|
+
label: translatedLabel('sidebar.tabLabel'),
|
|
63
|
+
description: translatedLabel('sidebar.tabDescription'),
|
|
48
64
|
fields: [
|
|
49
65
|
{
|
|
50
66
|
name: 'sidebarPosition',
|
|
51
67
|
type: 'select',
|
|
52
|
-
label: '
|
|
68
|
+
label: translatedLabel('sidebar.position'),
|
|
53
69
|
defaultValue: D.sidebarPosition,
|
|
54
70
|
options: [
|
|
55
71
|
{
|
|
56
|
-
label: '
|
|
72
|
+
label: translatedLabel('sidebar.positionRight'),
|
|
57
73
|
value: 'right'
|
|
58
74
|
},
|
|
59
75
|
{
|
|
60
|
-
label: '
|
|
76
|
+
label: translatedLabel('sidebar.positionLeft'),
|
|
61
77
|
value: 'left'
|
|
62
78
|
}
|
|
63
79
|
]
|
|
@@ -65,17 +81,17 @@ export const betterEditorSettingsGlobal = {
|
|
|
65
81
|
{
|
|
66
82
|
name: 'forceFullWidthFields',
|
|
67
83
|
type: 'checkbox',
|
|
68
|
-
label: '
|
|
84
|
+
label: translatedLabel('sidebar.forceFullWidth'),
|
|
69
85
|
defaultValue: D.forceFullWidthFields,
|
|
70
86
|
admin: {
|
|
71
|
-
description: '
|
|
87
|
+
description: translatedLabel('sidebar.forceFullWidthDesc')
|
|
72
88
|
}
|
|
73
89
|
}
|
|
74
90
|
]
|
|
75
91
|
},
|
|
76
92
|
{
|
|
77
|
-
label: '
|
|
78
|
-
description: '
|
|
93
|
+
label: translatedLabel('viewport.tabLabel'),
|
|
94
|
+
description: translatedLabel('viewport.tabDescription'),
|
|
79
95
|
fields: [
|
|
80
96
|
{
|
|
81
97
|
type: 'row',
|
|
@@ -83,7 +99,7 @@ export const betterEditorSettingsGlobal = {
|
|
|
83
99
|
{
|
|
84
100
|
name: 'tabletWidth',
|
|
85
101
|
type: 'number',
|
|
86
|
-
label: '
|
|
102
|
+
label: translatedLabel('viewport.tabletWidth'),
|
|
87
103
|
defaultValue: D.tabletWidth,
|
|
88
104
|
min: TABLET_WIDTH_MIN,
|
|
89
105
|
max: TABLET_WIDTH_MAX,
|
|
@@ -95,7 +111,7 @@ export const betterEditorSettingsGlobal = {
|
|
|
95
111
|
{
|
|
96
112
|
name: 'mobileWidth',
|
|
97
113
|
type: 'number',
|
|
98
|
-
label: '
|
|
114
|
+
label: translatedLabel('viewport.mobileWidth'),
|
|
99
115
|
defaultValue: D.mobileWidth,
|
|
100
116
|
min: MOBILE_WIDTH_MIN,
|
|
101
117
|
max: MOBILE_WIDTH_MAX,
|
|
@@ -109,8 +125,8 @@ export const betterEditorSettingsGlobal = {
|
|
|
109
125
|
]
|
|
110
126
|
},
|
|
111
127
|
{
|
|
112
|
-
label: '
|
|
113
|
-
description: '
|
|
128
|
+
label: translatedLabel('outline.tabLabel'),
|
|
129
|
+
description: translatedLabel('outline.tabDescription'),
|
|
114
130
|
fields: [
|
|
115
131
|
{
|
|
116
132
|
type: 'row',
|
|
@@ -118,25 +134,25 @@ export const betterEditorSettingsGlobal = {
|
|
|
118
134
|
{
|
|
119
135
|
name: 'hoverColorTopLevel',
|
|
120
136
|
type: 'text',
|
|
121
|
-
label: '
|
|
137
|
+
label: translatedLabel('outline.topLevelColor'),
|
|
122
138
|
defaultValue: D.hoverColorTopLevel,
|
|
123
139
|
validate: validateHoverColor,
|
|
124
140
|
admin: {
|
|
125
141
|
width: '50%',
|
|
126
142
|
placeholder: D.hoverColorTopLevel,
|
|
127
|
-
description: '
|
|
143
|
+
description: translatedLabel('outline.topLevelColorDesc')
|
|
128
144
|
}
|
|
129
145
|
},
|
|
130
146
|
{
|
|
131
147
|
name: 'hoverColorNested',
|
|
132
148
|
type: 'text',
|
|
133
|
-
label: '
|
|
149
|
+
label: translatedLabel('outline.nestedColor'),
|
|
134
150
|
defaultValue: D.hoverColorNested,
|
|
135
151
|
validate: validateHoverColor,
|
|
136
152
|
admin: {
|
|
137
153
|
width: '50%',
|
|
138
154
|
placeholder: D.hoverColorNested,
|
|
139
|
-
description: '
|
|
155
|
+
description: translatedLabel('outline.nestedColorDesc')
|
|
140
156
|
}
|
|
141
157
|
}
|
|
142
158
|
]
|
|
@@ -144,48 +160,48 @@ export const betterEditorSettingsGlobal = {
|
|
|
144
160
|
{
|
|
145
161
|
name: 'hoverOutlineWidth',
|
|
146
162
|
type: 'number',
|
|
147
|
-
label: '
|
|
163
|
+
label: translatedLabel('outline.outlineWidth'),
|
|
148
164
|
defaultValue: D.hoverOutlineWidth,
|
|
149
165
|
min: HOVER_OUTLINE_MIN,
|
|
150
166
|
max: HOVER_OUTLINE_MAX,
|
|
151
167
|
validate: validateHoverOutline,
|
|
152
168
|
admin: {
|
|
153
169
|
placeholder: String(D.hoverOutlineWidth),
|
|
154
|
-
description:
|
|
170
|
+
description: translatedLabel('outline.outlineWidthDesc')
|
|
155
171
|
}
|
|
156
172
|
}
|
|
157
173
|
]
|
|
158
174
|
},
|
|
159
175
|
{
|
|
160
|
-
label: '
|
|
161
|
-
description: '
|
|
176
|
+
label: translatedLabel('toolbar.tabLabel'),
|
|
177
|
+
description: translatedLabel('toolbar.tabDescription'),
|
|
162
178
|
fields: [
|
|
163
179
|
{
|
|
164
180
|
name: 'showHoverToolbar',
|
|
165
181
|
type: 'checkbox',
|
|
166
|
-
label: '
|
|
182
|
+
label: translatedLabel('toolbar.enabled'),
|
|
167
183
|
defaultValue: D.showHoverToolbar
|
|
168
184
|
},
|
|
169
185
|
{
|
|
170
186
|
name: 'hoverToolbarPosition',
|
|
171
187
|
type: 'select',
|
|
172
|
-
label: '
|
|
188
|
+
label: translatedLabel('toolbar.anchorCorner'),
|
|
173
189
|
defaultValue: D.hoverToolbarPosition,
|
|
174
190
|
options: [
|
|
175
191
|
{
|
|
176
|
-
label: '
|
|
192
|
+
label: translatedLabel('toolbar.topRight'),
|
|
177
193
|
value: 'top-right'
|
|
178
194
|
},
|
|
179
195
|
{
|
|
180
|
-
label: '
|
|
196
|
+
label: translatedLabel('toolbar.topLeft'),
|
|
181
197
|
value: 'top-left'
|
|
182
198
|
},
|
|
183
199
|
{
|
|
184
|
-
label: '
|
|
200
|
+
label: translatedLabel('toolbar.bottomRight'),
|
|
185
201
|
value: 'bottom-right'
|
|
186
202
|
},
|
|
187
203
|
{
|
|
188
|
-
label: '
|
|
204
|
+
label: translatedLabel('toolbar.bottomLeft'),
|
|
189
205
|
value: 'bottom-left'
|
|
190
206
|
}
|
|
191
207
|
]
|
package/dist/global.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/global.ts"],"sourcesContent":["import type { GlobalConfig } from 'payload'\nimport { DEFAULT_BETTER_EDITOR_SETTINGS as D } from './internal/constants'\nimport {\n HOVER_OUTLINE_MAX,\n HOVER_OUTLINE_MIN,\n MOBILE_WIDTH_MAX,\n MOBILE_WIDTH_MIN,\n TABLET_WIDTH_MAX,\n TABLET_WIDTH_MIN,\n} from './internal/limits'\n\nexport const BETTER_EDITOR_SETTINGS_SLUG = 'better-editor-settings'\n\nexport const BETTER_EDITOR_SETTINGS_BANNER_FIELD = 'betterEditorSettingsBanner'\n\n// Mirrors the runtime regex in `preview/hover-css.ts` so the admin UI rejects\n// values that would silently be skipped at render time.\nconst HOVER_COLOR_RE = /^(?:#[0-9a-fA-F]{3,8}|rgba?\\([^()\\n\\r]*\\))$/i\n\nconst validateHoverColor = (value: unknown): string | true => {\n if (typeof value !== 'string' || value.length === 0) return 'Color is required'\n if (!HOVER_COLOR_RE.test(value.trim())) {\n return 'Must be a hex color (e.g. #3b82f6) or rgb()/rgba()'\n }\n return true\n}\n\nconst validateHoverOutline = (value: unknown): string | true => {\n if (typeof value !== 'number' || !Number.isFinite(value)) return 'Must be a number'\n if (value < HOVER_OUTLINE_MIN || value > HOVER_OUTLINE_MAX) {\n return `Must be between ${HOVER_OUTLINE_MIN} and ${HOVER_OUTLINE_MAX}`\n }\n return true\n}\n\nexport const betterEditorSettingsGlobal: GlobalConfig = {\n slug: BETTER_EDITOR_SETTINGS_SLUG,\n label: 'Settings',\n access: {\n read: () => true,\n },\n admin: {\n group: 'Better Editor',\n description: 'Editor-wide preferences for the Better Editor overlay.',\n },\n\n fields: [\n {\n name: 'betterEditorSettingsBanner',\n type: 'ui',\n admin: {\n components: {\n Field: 'payload-better-editor/client#SettingsBanner',\n },\n },\n },\n {\n type: 'tabs',\n tabs: [\n {\n label: 'Sidebar',\n description: 'Where the sidebar sits and how its fields are stacked.',\n fields: [\n {\n name: 'sidebarPosition',\n type: 'select',\n label: 'Position',\n defaultValue: D.sidebarPosition,\n options: [\n { label: 'Right', value: 'right' },\n { label: 'Left', value: 'left' },\n ],\n },\n {\n name: 'forceFullWidthFields',\n type: 'checkbox',\n label: 'Stack fields full-width',\n defaultValue: D.forceFullWidthFields,\n admin: {\n description:\n 'Override admin.width on sidebar fields so they always span the full row.',\n },\n },\n ],\n },\n {\n label: 'Viewport',\n description: 'Pixel widths for the Tablet and Mobile preview modes.',\n fields: [\n {\n type: 'row',\n fields: [\n {\n name: 'tabletWidth',\n type: 'number',\n label: 'Tablet (px)',\n defaultValue: D.tabletWidth,\n min: TABLET_WIDTH_MIN,\n max: TABLET_WIDTH_MAX,\n admin: { width: '50%', placeholder: String(D.tabletWidth) },\n },\n {\n name: 'mobileWidth',\n type: 'number',\n label: 'Mobile (px)',\n defaultValue: D.mobileWidth,\n min: MOBILE_WIDTH_MIN,\n max: MOBILE_WIDTH_MAX,\n admin: { width: '50%', placeholder: String(D.mobileWidth) },\n },\n ],\n },\n ],\n },\n {\n label: 'Outline',\n description: 'Outline + tint shown on the hovered or selected block.',\n fields: [\n {\n type: 'row',\n fields: [\n {\n name: 'hoverColorTopLevel',\n type: 'text',\n label: 'Top-level color',\n defaultValue: D.hoverColorTopLevel,\n validate: validateHoverColor,\n admin: {\n width: '50%',\n placeholder: D.hoverColorTopLevel,\n description: 'Hex color (e.g. `#3b82f6`).',\n },\n },\n {\n name: 'hoverColorNested',\n type: 'text',\n label: 'Nested color',\n defaultValue: D.hoverColorNested,\n validate: validateHoverColor,\n admin: {\n width: '50%',\n placeholder: D.hoverColorNested,\n description: 'Hex color for blocks nested inside another block.',\n },\n },\n ],\n },\n {\n name: 'hoverOutlineWidth',\n type: 'number',\n label: 'Outline width (px)',\n defaultValue: D.hoverOutlineWidth,\n min: HOVER_OUTLINE_MIN,\n max: HOVER_OUTLINE_MAX,\n validate: validateHoverOutline,\n admin: {\n placeholder: String(D.hoverOutlineWidth),\n description: `Outline thickness in pixels (${HOVER_OUTLINE_MIN}–${HOVER_OUTLINE_MAX}).`,\n },\n },\n ],\n },\n {\n label: 'Toolbar',\n description:\n 'Floating Move / Duplicate / Delete toolbar that appears on the selected block.',\n fields: [\n {\n name: 'showHoverToolbar',\n type: 'checkbox',\n label: 'Enabled',\n defaultValue: D.showHoverToolbar,\n },\n {\n name: 'hoverToolbarPosition',\n type: 'select',\n label: 'Anchor corner',\n defaultValue: D.hoverToolbarPosition,\n options: [\n { label: 'Top right', value: 'top-right' },\n { label: 'Top left', value: 'top-left' },\n { label: 'Bottom right', value: 'bottom-right' },\n { label: 'Bottom left', value: 'bottom-left' },\n ],\n },\n ],\n },\n ],\n },\n ],\n}\n"],"names":["DEFAULT_BETTER_EDITOR_SETTINGS","D","HOVER_OUTLINE_MAX","HOVER_OUTLINE_MIN","MOBILE_WIDTH_MAX","MOBILE_WIDTH_MIN","TABLET_WIDTH_MAX","TABLET_WIDTH_MIN","BETTER_EDITOR_SETTINGS_SLUG","BETTER_EDITOR_SETTINGS_BANNER_FIELD","HOVER_COLOR_RE","validateHoverColor","value","length","test","trim","validateHoverOutline","Number","isFinite","betterEditorSettingsGlobal","slug","label","access","read","admin","group","description","fields","name","type","components","Field","tabs","defaultValue","sidebarPosition","options","forceFullWidthFields","tabletWidth","min","max","width","placeholder","String","mobileWidth","hoverColorTopLevel","validate","hoverColorNested","hoverOutlineWidth","showHoverToolbar","hoverToolbarPosition"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/global.ts"],"sourcesContent":["import type { GlobalConfig } from 'payload'\nimport { DEFAULT_BETTER_EDITOR_SETTINGS as D } from './internal/constants'\nimport {\n HOVER_OUTLINE_MAX,\n HOVER_OUTLINE_MIN,\n MOBILE_WIDTH_MAX,\n MOBILE_WIDTH_MIN,\n TABLET_WIDTH_MAX,\n TABLET_WIDTH_MIN,\n} from './internal/limits'\nimport type { BetterEditorTranslations } from './i18n/types'\nimport { en } from './i18n/en'\nimport { de } from './i18n/de'\n\nexport const BETTER_EDITOR_SETTINGS_SLUG = 'better-editor-settings'\n\nexport const BETTER_EDITOR_SETTINGS_BANNER_FIELD = 'betterEditorSettingsBanner'\n\n// Mirrors the runtime regex in `preview/hover-css.ts` so the admin UI rejects\n// values that would silently be skipped at render time.\nconst HOVER_COLOR_RE = /^(?:#[0-9a-fA-F]{3,8}|rgba?\\([^()\\n\\r]*\\))$/i\n\n// Payload's TFunction is strictly typed to known keys — cast to allow custom plugin keys.\ntype AnyT = (key: string) => string\n\nconst settingsKey = (path: string) => `betterEditor:settings.${path}`\n\n// Locales the plugin ships built-in translations for.\nconst SETTINGS_TRANSLATIONS: Record<string, BetterEditorTranslations['settings']> = {\n en: en.settings,\n de: de.settings,\n}\n\nconst lookupSetting = (settings: BetterEditorTranslations['settings'], path: string): string =>\n path\n .split('.')\n .reduce<unknown>((value, key) => (value as Record<string, unknown> | undefined)?.[key], settings) as string\n\n// Entity/field labels and descriptions are serialized into the admin RootLayout\n// (a Client Component), so they must be plain data — a function (e.g. `({ t }) => …`)\n// can't cross that RSC boundary. Return a Payload locale map built from our bundled\n// translations; Payload selects the entry for the admin UI language. (Runtime `t()`\n// stays available for `validate`, which Payload strips before client serialization.)\nconst translatedLabel = (path: string): Record<string, string> =>\n Object.fromEntries(\n Object.entries(SETTINGS_TRANSLATIONS).map(([locale, settings]) => [locale, lookupSetting(settings, path)]),\n )\n\nconst validateHoverColor = (value: unknown, args: unknown): string | true => {\n const t: AnyT = (args as { t?: AnyT })?.t ?? ((k) => k)\n if (typeof value !== 'string' || value.length === 0) return t(settingsKey('validation.colorRequired'))\n if (!HOVER_COLOR_RE.test(value.trim())) return t(settingsKey('validation.colorInvalid'))\n return true\n}\n\nconst validateHoverOutline = (value: unknown, args: unknown): string | true => {\n const t: AnyT = (args as { t?: AnyT })?.t ?? ((k) => k)\n if (typeof value !== 'number' || !Number.isFinite(value)) return t(settingsKey('validation.mustBeNumber'))\n if (value < HOVER_OUTLINE_MIN || value > HOVER_OUTLINE_MAX) return t(settingsKey('validation.outlineRange'))\n return true\n}\n\nexport const betterEditorSettingsGlobal: GlobalConfig = {\n slug: BETTER_EDITOR_SETTINGS_SLUG,\n label: translatedLabel('globalLabel'),\n access: {\n read: () => true,\n },\n admin: {\n group: 'Better Editor',\n description: translatedLabel('globalDescription'),\n },\n\n fields: [\n {\n name: 'betterEditorSettingsBanner',\n type: 'ui',\n admin: {\n components: {\n Field: 'payload-better-editor/client#SettingsBanner',\n },\n },\n },\n {\n type: 'tabs',\n tabs: [\n {\n label: translatedLabel('sidebar.tabLabel'),\n description: translatedLabel('sidebar.tabDescription'),\n fields: [\n {\n name: 'sidebarPosition',\n type: 'select',\n label: translatedLabel('sidebar.position'),\n defaultValue: D.sidebarPosition,\n options: [\n { label: translatedLabel('sidebar.positionRight'), value: 'right' },\n { label: translatedLabel('sidebar.positionLeft'), value: 'left' },\n ],\n },\n {\n name: 'forceFullWidthFields',\n type: 'checkbox',\n label: translatedLabel('sidebar.forceFullWidth'),\n defaultValue: D.forceFullWidthFields,\n admin: {\n description: translatedLabel('sidebar.forceFullWidthDesc'),\n },\n },\n ],\n },\n {\n label: translatedLabel('viewport.tabLabel'),\n description: translatedLabel('viewport.tabDescription'),\n fields: [\n {\n type: 'row',\n fields: [\n {\n name: 'tabletWidth',\n type: 'number',\n label: translatedLabel('viewport.tabletWidth'),\n defaultValue: D.tabletWidth,\n min: TABLET_WIDTH_MIN,\n max: TABLET_WIDTH_MAX,\n admin: { width: '50%', placeholder: String(D.tabletWidth) },\n },\n {\n name: 'mobileWidth',\n type: 'number',\n label: translatedLabel('viewport.mobileWidth'),\n defaultValue: D.mobileWidth,\n min: MOBILE_WIDTH_MIN,\n max: MOBILE_WIDTH_MAX,\n admin: { width: '50%', placeholder: String(D.mobileWidth) },\n },\n ],\n },\n ],\n },\n {\n label: translatedLabel('outline.tabLabel'),\n description: translatedLabel('outline.tabDescription'),\n fields: [\n {\n type: 'row',\n fields: [\n {\n name: 'hoverColorTopLevel',\n type: 'text',\n label: translatedLabel('outline.topLevelColor'),\n defaultValue: D.hoverColorTopLevel,\n validate: validateHoverColor,\n admin: {\n width: '50%',\n placeholder: D.hoverColorTopLevel,\n description: translatedLabel('outline.topLevelColorDesc'),\n },\n },\n {\n name: 'hoverColorNested',\n type: 'text',\n label: translatedLabel('outline.nestedColor'),\n defaultValue: D.hoverColorNested,\n validate: validateHoverColor,\n admin: {\n width: '50%',\n placeholder: D.hoverColorNested,\n description: translatedLabel('outline.nestedColorDesc'),\n },\n },\n ],\n },\n {\n name: 'hoverOutlineWidth',\n type: 'number',\n label: translatedLabel('outline.outlineWidth'),\n defaultValue: D.hoverOutlineWidth,\n min: HOVER_OUTLINE_MIN,\n max: HOVER_OUTLINE_MAX,\n validate: validateHoverOutline,\n admin: {\n placeholder: String(D.hoverOutlineWidth),\n description: translatedLabel('outline.outlineWidthDesc'),\n },\n },\n ],\n },\n {\n label: translatedLabel('toolbar.tabLabel'),\n description: translatedLabel('toolbar.tabDescription'),\n fields: [\n {\n name: 'showHoverToolbar',\n type: 'checkbox',\n label: translatedLabel('toolbar.enabled'),\n defaultValue: D.showHoverToolbar,\n },\n {\n name: 'hoverToolbarPosition',\n type: 'select',\n label: translatedLabel('toolbar.anchorCorner'),\n defaultValue: D.hoverToolbarPosition,\n options: [\n { label: translatedLabel('toolbar.topRight'), value: 'top-right' },\n { label: translatedLabel('toolbar.topLeft'), value: 'top-left' },\n { label: translatedLabel('toolbar.bottomRight'), value: 'bottom-right' },\n { label: translatedLabel('toolbar.bottomLeft'), value: 'bottom-left' },\n ],\n },\n ],\n },\n ],\n },\n ],\n}\n"],"names":["DEFAULT_BETTER_EDITOR_SETTINGS","D","HOVER_OUTLINE_MAX","HOVER_OUTLINE_MIN","MOBILE_WIDTH_MAX","MOBILE_WIDTH_MIN","TABLET_WIDTH_MAX","TABLET_WIDTH_MIN","en","de","BETTER_EDITOR_SETTINGS_SLUG","BETTER_EDITOR_SETTINGS_BANNER_FIELD","HOVER_COLOR_RE","settingsKey","path","SETTINGS_TRANSLATIONS","settings","lookupSetting","split","reduce","value","key","translatedLabel","Object","fromEntries","entries","map","locale","validateHoverColor","args","t","k","length","test","trim","validateHoverOutline","Number","isFinite","betterEditorSettingsGlobal","slug","label","access","read","admin","group","description","fields","name","type","components","Field","tabs","defaultValue","sidebarPosition","options","forceFullWidthFields","tabletWidth","min","max","width","placeholder","String","mobileWidth","hoverColorTopLevel","validate","hoverColorNested","hoverOutlineWidth","showHoverToolbar","hoverToolbarPosition"],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { useCallback, useEffect, useRef } from 'react';
|
|
3
|
-
import { HoverToolbarController } from '../preview/HoverToolbarController';
|
|
3
|
+
import { HoverToolbarController, toHoverToolbarLabels } from '../preview/HoverToolbarController';
|
|
4
|
+
import { useBetterEditorT } from '../i18n/useBetterEditorT';
|
|
4
5
|
import { installClickToFocus } from '../preview/installClickToFocus';
|
|
5
6
|
import { installHoverStyles } from '../preview/installHoverStyles';
|
|
6
7
|
import { BLOCK_ID_SELECTOR } from '../internal/dom';
|
|
@@ -11,6 +12,8 @@ import { useLatestRef } from './useLatestRef';
|
|
|
11
12
|
* lifecycle. Idempotent: tears down previous bindings before installing
|
|
12
13
|
* new ones, and unbinds on unmount.
|
|
13
14
|
*/ export const usePreviewBinding = ({ iframeRef, settings, interactModeRef, onFocusBlock, onBlockAction, onLoadingChange })=>{
|
|
15
|
+
const t = useBetterEditorT();
|
|
16
|
+
const labelsRef = useLatestRef(t.blocks.actions);
|
|
14
17
|
const teardownRef = useRef(null);
|
|
15
18
|
const controllerRef = useRef(null);
|
|
16
19
|
const isBoundRef = useRef(false);
|
|
@@ -39,7 +42,8 @@ import { useLatestRef } from './useLatestRef';
|
|
|
39
42
|
controllerRef.current = new HoverToolbarController(doc, {
|
|
40
43
|
position: s.hoverToolbarPosition,
|
|
41
44
|
outlineWidth: s.hoverOutlineWidth,
|
|
42
|
-
onAction: (id, action)=>onBlockActionRef.current(id, action)
|
|
45
|
+
onAction: (id, action)=>onBlockActionRef.current(id, action),
|
|
46
|
+
labels: toHoverToolbarLabels(labelsRef.current)
|
|
43
47
|
});
|
|
44
48
|
}
|
|
45
49
|
// Dev-only sanity check: zero [data-better-editor-id] elements means
|