@payloadcms/richtext-lexical 3.0.0-beta.39 → 3.0.0-beta.40
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/cell/index.d.ts +2 -1
- package/dist/cell/index.d.ts.map +1 -1
- package/dist/cell/index.js +19 -11
- package/dist/cell/index.js.map +1 -1
- package/dist/exports/components.d.ts +0 -1
- package/dist/exports/components.d.ts.map +1 -1
- package/dist/exports/components.js +0 -1
- package/dist/exports/components.js.map +1 -1
- package/dist/field/features/createFeaturePropComponent.d.ts.map +1 -1
- package/dist/field/features/createFeaturePropComponent.js +6 -1
- package/dist/field/features/createFeaturePropComponent.js.map +1 -1
- package/dist/field/features/toolbars/fixed/Toolbar/index.d.ts +2 -1
- package/dist/field/features/toolbars/fixed/Toolbar/index.d.ts.map +1 -1
- package/dist/field/features/toolbars/fixed/Toolbar/index.js +72 -18
- package/dist/field/features/toolbars/fixed/Toolbar/index.js.map +1 -1
- package/dist/field/features/toolbars/fixed/Toolbar/index.scss +8 -1
- package/dist/field/features/toolbars/fixed/feature.client.d.ts +2 -1
- package/dist/field/features/toolbars/fixed/feature.client.d.ts.map +1 -1
- package/dist/field/features/toolbars/fixed/feature.client.js.map +1 -1
- package/dist/field/features/toolbars/fixed/feature.server.d.ts +17 -1
- package/dist/field/features/toolbars/fixed/feature.server.d.ts.map +1 -1
- package/dist/field/features/toolbars/fixed/feature.server.js +6 -1
- package/dist/field/features/toolbars/fixed/feature.server.js.map +1 -1
- package/dist/field/features/toolbars/shared/ToolbarButton/index.js +5 -5
- package/dist/field/features/toolbars/shared/ToolbarButton/index.js.map +1 -1
- package/dist/field/features/toolbars/shared/ToolbarDropdown/index.js +5 -5
- package/dist/field/features/toolbars/shared/ToolbarDropdown/index.js.map +1 -1
- package/dist/field/features/toolbars/types.d.ts +5 -5
- package/dist/field/features/toolbars/types.d.ts.map +1 -1
- package/dist/field/features/toolbars/types.js.map +1 -1
- package/dist/field/index.d.ts.map +1 -1
- package/dist/field/index.js +10 -5
- package/dist/field/index.js.map +1 -1
- package/dist/field/lexical/LexicalEditor.d.ts +3 -1
- package/dist/field/lexical/LexicalEditor.d.ts.map +1 -1
- package/dist/field/lexical/LexicalEditor.js +27 -12
- package/dist/field/lexical/LexicalEditor.js.map +1 -1
- package/dist/field/lexical/LexicalProvider.d.ts.map +1 -1
- package/dist/field/lexical/LexicalProvider.js +42 -35
- package/dist/field/lexical/LexicalProvider.js.map +1 -1
- package/dist/field/lexical/config/client/EditorConfigProvider.d.ts +13 -1
- package/dist/field/lexical/config/client/EditorConfigProvider.d.ts.map +1 -1
- package/dist/field/lexical/config/client/EditorConfigProvider.js +56 -8
- package/dist/field/lexical/config/client/EditorConfigProvider.js.map +1 -1
- package/dist/field/lexical/ui/ContentEditable.scss +2 -2
- package/dist/field/lexical/ui/icons/Link/index.d.ts.map +1 -1
- package/dist/field/lexical/ui/icons/Link/index.js +8 -25
- package/dist/field/lexical/ui/icons/Link/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/useLexicalFeature.d.ts.map +1 -1
- package/dist/useLexicalFeature.js +6 -1
- package/dist/useLexicalFeature.js.map +1 -1
- package/package.json +11 -9
- package/dist/field/lexical/EditorFocusProvider.d.ts +0 -19
- package/dist/field/lexical/EditorFocusProvider.d.ts.map +0 -1
- package/dist/field/lexical/EditorFocusProvider.js +0 -80
- package/dist/field/lexical/EditorFocusProvider.js.map +0 -1
package/dist/cell/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { EditorConfig as LexicalEditorConfig } from 'lexical';
|
|
2
|
+
import type { CellComponentProps } from 'payload/types';
|
|
2
3
|
import React from 'react';
|
|
3
4
|
import type { LexicalFieldAdminProps } from '../types.js';
|
|
4
|
-
export declare const RichTextCell: React.FC<{
|
|
5
|
+
export declare const RichTextCell: React.FC<CellComponentProps & {
|
|
5
6
|
admin?: LexicalFieldAdminProps;
|
|
6
7
|
lexicalEditorConfig: LexicalEditorConfig;
|
|
7
8
|
}>;
|
package/dist/cell/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cell/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,IAAI,mBAAmB,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cell/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,IAAI,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAClE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAMvD,OAAO,KAA8B,MAAM,OAAO,CAAA;AAIlD,OAAO,KAAK,EAAqC,sBAAsB,EAAE,MAAM,aAAa,CAAA;AAO5F,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CACjC,kBAAkB,GAAG;IACnB,KAAK,CAAC,EAAE,sBAAsB,CAAA;IAC9B,mBAAmB,EAAE,mBAAmB,CAAA;CACzC,CAwKF,CAAA"}
|
package/dist/cell/index.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { createHeadlessEditor } from '@lexical/headless';
|
|
4
4
|
import { useTableCell } from '@payloadcms/ui/elements/Table';
|
|
5
|
-
import { useFieldProps } from '@payloadcms/ui/forms/FieldPropsProvider';
|
|
6
5
|
import { useClientFunctions } from '@payloadcms/ui/providers/ClientFunction';
|
|
7
6
|
import { $getRoot } from 'lexical';
|
|
8
7
|
import React, { useEffect, useState } from 'react';
|
|
@@ -11,23 +10,27 @@ import { loadClientFeatures } from '../field/lexical/config/client/loader.js';
|
|
|
11
10
|
import { sanitizeClientEditorConfig } from '../field/lexical/config/client/sanitize.js';
|
|
12
11
|
import { getEnabledNodes } from '../field/lexical/nodes/index.js';
|
|
13
12
|
export const RichTextCell = (props)=>{
|
|
14
|
-
const { admin, lexicalEditorConfig } = props;
|
|
13
|
+
const { admin, lexicalEditorConfig, richTextComponentMap } = props;
|
|
15
14
|
const [preview, setPreview] = React.useState('Loading...');
|
|
16
|
-
const { schemaPath } =
|
|
17
|
-
const { cellData, richTextComponentMap } = useTableCell();
|
|
15
|
+
const { cellData, cellProps: { schemaPath } } = useTableCell();
|
|
18
16
|
const clientFunctions = useClientFunctions();
|
|
19
17
|
const [hasLoadedFeatures, setHasLoadedFeatures] = useState(false);
|
|
20
18
|
const [featureProviders, setFeatureProviders] = useState([]);
|
|
21
19
|
const [finalSanitizedEditorConfig, setFinalSanitizedEditorConfig] = useState(null);
|
|
22
|
-
|
|
20
|
+
const featureProviderComponents = richTextComponentMap.get('features').sort((a, b)=>a.order - b.order) // order by order
|
|
23
21
|
;
|
|
24
|
-
//
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
let featureProvidersAndComponentsToLoad = 0 // feature providers and components
|
|
23
|
+
;
|
|
24
|
+
for (const featureProvider of featureProviderComponents){
|
|
25
|
+
const featureComponentKeys = Array.from(richTextComponentMap.keys()).filter((key)=>key.startsWith(`feature.${featureProvider.key}.components.`));
|
|
26
|
+
featureProvidersAndComponentsToLoad += 1;
|
|
27
|
+
featureProvidersAndComponentsToLoad += featureComponentKeys.length;
|
|
28
|
+
}
|
|
27
29
|
useEffect(()=>{
|
|
28
30
|
if (!hasLoadedFeatures) {
|
|
29
31
|
const featureProvidersLocal = [];
|
|
30
|
-
let featureProvidersAndComponentsLoaded = 0
|
|
32
|
+
let featureProvidersAndComponentsLoaded = 0 // feature providers and components only
|
|
33
|
+
;
|
|
31
34
|
Object.entries(clientFunctions).forEach(([key, plugin])=>{
|
|
32
35
|
if (key.startsWith(`lexicalFeature.${schemaPath}.`)) {
|
|
33
36
|
if (!key.includes('.components.')) {
|
|
@@ -36,7 +39,7 @@ export const RichTextCell = (props)=>{
|
|
|
36
39
|
featureProvidersAndComponentsLoaded++;
|
|
37
40
|
}
|
|
38
41
|
});
|
|
39
|
-
if (featureProvidersAndComponentsLoaded ===
|
|
42
|
+
if (featureProvidersAndComponentsLoaded === featureProvidersAndComponentsToLoad) {
|
|
40
43
|
setFeatureProviders(featureProvidersLocal);
|
|
41
44
|
setHasLoadedFeatures(true);
|
|
42
45
|
/**
|
|
@@ -54,6 +57,7 @@ export const RichTextCell = (props)=>{
|
|
|
54
57
|
}
|
|
55
58
|
}, [
|
|
56
59
|
admin,
|
|
60
|
+
featureProviderComponents,
|
|
57
61
|
hasLoadedFeatures,
|
|
58
62
|
clientFunctions,
|
|
59
63
|
schemaPath,
|
|
@@ -61,9 +65,13 @@ export const RichTextCell = (props)=>{
|
|
|
61
65
|
featureProviders,
|
|
62
66
|
finalSanitizedEditorConfig,
|
|
63
67
|
lexicalEditorConfig,
|
|
64
|
-
|
|
68
|
+
richTextComponentMap,
|
|
69
|
+
featureProvidersAndComponentsToLoad
|
|
65
70
|
]);
|
|
66
71
|
useEffect(()=>{
|
|
72
|
+
if (!hasLoadedFeatures) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
67
75
|
let dataToUse = cellData;
|
|
68
76
|
if (dataToUse == null || !hasLoadedFeatures || !finalSanitizedEditorConfig) {
|
|
69
77
|
setPreview('');
|
package/dist/cell/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cell/index.tsx"],"sourcesContent":["'use client'\nimport type { EditorConfig as LexicalEditorConfig } from 'lexical'\n\nimport { createHeadlessEditor } from '@lexical/headless'\nimport { useTableCell } from '@payloadcms/ui/elements/Table'\nimport { useFieldProps } from '@payloadcms/ui/forms/FieldPropsProvider'\nimport { useClientFunctions } from '@payloadcms/ui/providers/ClientFunction'\nimport { $getRoot } from 'lexical'\nimport React, { useEffect, useState } from 'react'\n\nimport type { FeatureProviderClient } from '../field/features/types.js'\nimport type { SanitizedClientEditorConfig } from '../field/lexical/config/types.js'\nimport type { GeneratedFeatureProviderComponent, LexicalFieldAdminProps } from '../types.js'\n\nimport { defaultEditorLexicalConfig } from '../field/lexical/config/client/default.js'\nimport { loadClientFeatures } from '../field/lexical/config/client/loader.js'\nimport { sanitizeClientEditorConfig } from '../field/lexical/config/client/sanitize.js'\nimport { getEnabledNodes } from '../field/lexical/nodes/index.js'\n\nexport const RichTextCell: React.FC<{\n admin?: LexicalFieldAdminProps\n lexicalEditorConfig: LexicalEditorConfig\n}> = (props) => {\n const { admin, lexicalEditorConfig } = props\n\n const [preview, setPreview] = React.useState('Loading...')\n const { schemaPath } = useFieldProps()\n\n const { cellData, richTextComponentMap } = useTableCell()\n\n const clientFunctions = useClientFunctions()\n const [hasLoadedFeatures, setHasLoadedFeatures] = useState(false)\n\n const [featureProviders, setFeatureProviders] = useState<FeatureProviderClient<unknown>[]>([])\n\n const [finalSanitizedEditorConfig, setFinalSanitizedEditorConfig] =\n useState<SanitizedClientEditorConfig>(null)\n\n let featureProviderComponents: GeneratedFeatureProviderComponent[] = richTextComponentMap.get(\n 'features',\n ) as GeneratedFeatureProviderComponent[] // TODO: Type better\n // order by order\n featureProviderComponents = featureProviderComponents.sort((a, b) => a.order - b.order)\n\n const featureComponentsWithFeaturesLength =\n Array.from(richTextComponentMap.keys()).filter(\n (key) => key.startsWith(`feature.`) && !key.includes('.fields.'),\n ).length + featureProviderComponents.length\n\n useEffect(() => {\n if (!hasLoadedFeatures) {\n const featureProvidersLocal: FeatureProviderClient<unknown>[] = []\n let featureProvidersAndComponentsLoaded = 0\n\n Object.entries(clientFunctions).forEach(([key, plugin]) => {\n if (key.startsWith(`lexicalFeature.${schemaPath}.`)) {\n if (!key.includes('.components.')) {\n featureProvidersLocal.push(plugin)\n }\n featureProvidersAndComponentsLoaded++\n }\n })\n\n if (featureProvidersAndComponentsLoaded === featureComponentsWithFeaturesLength) {\n setFeatureProviders(featureProvidersLocal)\n setHasLoadedFeatures(true)\n\n /**\n * Loaded feature provided => create the final sanitized editor config\n */\n\n const resolvedClientFeatures = loadClientFeatures({\n clientFunctions,\n schemaPath,\n unSanitizedEditorConfig: {\n features: featureProvidersLocal,\n lexical: lexicalEditorConfig,\n },\n })\n\n setFinalSanitizedEditorConfig(\n sanitizeClientEditorConfig(\n lexicalEditorConfig ? lexicalEditorConfig : defaultEditorLexicalConfig,\n resolvedClientFeatures,\n admin,\n ),\n )\n }\n }\n }, [\n admin,\n hasLoadedFeatures,\n clientFunctions,\n schemaPath,\n featureProviderComponents.length,\n featureProviders,\n finalSanitizedEditorConfig,\n lexicalEditorConfig,\n featureComponentsWithFeaturesLength,\n ])\n\n useEffect(() => {\n let dataToUse = cellData\n if (dataToUse == null || !hasLoadedFeatures || !finalSanitizedEditorConfig) {\n setPreview('')\n return\n }\n\n // Transform data through load hooks\n if (finalSanitizedEditorConfig?.features?.hooks?.load?.length) {\n finalSanitizedEditorConfig.features.hooks.load.forEach((hook) => {\n dataToUse = hook({ incomingEditorState: dataToUse })\n })\n }\n\n if (!dataToUse || typeof dataToUse !== 'object') {\n setPreview('')\n return\n }\n\n // If data is from Slate and not Lexical\n if (Array.isArray(dataToUse) && !('root' in dataToUse)) {\n setPreview('')\n return\n }\n\n // If data is from payload-plugin-lexical\n if ('jsonContent' in dataToUse) {\n setPreview('')\n return\n }\n\n // initialize headless editor\n const headlessEditor = createHeadlessEditor({\n namespace: finalSanitizedEditorConfig.lexical.namespace,\n nodes: getEnabledNodes({ editorConfig: finalSanitizedEditorConfig }),\n theme: finalSanitizedEditorConfig.lexical.theme,\n })\n headlessEditor.setEditorState(headlessEditor.parseEditorState(dataToUse))\n\n const textContent =\n headlessEditor.getEditorState().read(() => {\n return $getRoot().getTextContent()\n }) || ''\n\n // Limiting the number of characters shown is done in a CSS rule\n setPreview(textContent)\n }, [cellData, lexicalEditorConfig, hasLoadedFeatures, finalSanitizedEditorConfig])\n\n if (!hasLoadedFeatures) {\n return (\n <React.Fragment>\n {Array.isArray(featureProviderComponents) &&\n featureProviderComponents.map((featureProvider) => {\n // get all components starting with key feature.${FeatureProvider.key}.components.{featureComponentKey}\n const featureComponentKeys = Array.from(richTextComponentMap.keys()).filter((key) =>\n key.startsWith(`feature.${featureProvider.key}.components.`),\n )\n const featureComponents: React.ReactNode[] = featureComponentKeys.map((key) => {\n return richTextComponentMap.get(key)\n })\n\n return (\n <React.Fragment key={featureProvider.key}>\n {featureComponents?.length\n ? featureComponents.map((FeatureComponent) => {\n return FeatureComponent\n })\n : null}\n {featureProvider.ClientComponent}\n </React.Fragment>\n )\n })}\n </React.Fragment>\n )\n }\n\n return <span>{preview}</span>\n}\n"],"names":["createHeadlessEditor","useTableCell","useFieldProps","useClientFunctions","$getRoot","React","useEffect","useState","defaultEditorLexicalConfig","loadClientFeatures","sanitizeClientEditorConfig","getEnabledNodes","RichTextCell","props","admin","lexicalEditorConfig","preview","setPreview","schemaPath","cellData","richTextComponentMap","clientFunctions","hasLoadedFeatures","setHasLoadedFeatures","featureProviders","setFeatureProviders","finalSanitizedEditorConfig","setFinalSanitizedEditorConfig","featureProviderComponents","get","sort","a","b","order","featureComponentsWithFeaturesLength","Array","from","keys","filter","key","startsWith","includes","length","featureProvidersLocal","featureProvidersAndComponentsLoaded","Object","entries","forEach","plugin","push","resolvedClientFeatures","unSanitizedEditorConfig","features","lexical","dataToUse","hooks","load","hook","incomingEditorState","isArray","headlessEditor","namespace","nodes","editorConfig","theme","setEditorState","parseEditorState","textContent","getEditorState","read","getTextContent","Fragment","map","featureProvider","featureComponentKeys","featureComponents","FeatureComponent","ClientComponent","span"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/cell/index.tsx"],"sourcesContent":["'use client'\nimport type { EditorConfig as LexicalEditorConfig } from 'lexical'\nimport type { CellComponentProps } from 'payload/types'\n\nimport { createHeadlessEditor } from '@lexical/headless'\nimport { useTableCell } from '@payloadcms/ui/elements/Table'\nimport { useClientFunctions } from '@payloadcms/ui/providers/ClientFunction'\nimport { $getRoot } from 'lexical'\nimport React, { useEffect, useState } from 'react'\n\nimport type { FeatureProviderClient } from '../field/features/types.js'\nimport type { SanitizedClientEditorConfig } from '../field/lexical/config/types.js'\nimport type { GeneratedFeatureProviderComponent, LexicalFieldAdminProps } from '../types.js'\n\nimport { defaultEditorLexicalConfig } from '../field/lexical/config/client/default.js'\nimport { loadClientFeatures } from '../field/lexical/config/client/loader.js'\nimport { sanitizeClientEditorConfig } from '../field/lexical/config/client/sanitize.js'\nimport { getEnabledNodes } from '../field/lexical/nodes/index.js'\n\nexport const RichTextCell: React.FC<\n CellComponentProps & {\n admin?: LexicalFieldAdminProps\n lexicalEditorConfig: LexicalEditorConfig\n }\n> = (props) => {\n const { admin, lexicalEditorConfig, richTextComponentMap } = props\n\n const [preview, setPreview] = React.useState('Loading...')\n\n const {\n cellData,\n cellProps: { schemaPath },\n } = useTableCell()\n\n const clientFunctions = useClientFunctions()\n const [hasLoadedFeatures, setHasLoadedFeatures] = useState(false)\n\n const [featureProviders, setFeatureProviders] = useState<FeatureProviderClient<unknown>[]>([])\n\n const [finalSanitizedEditorConfig, setFinalSanitizedEditorConfig] =\n useState<SanitizedClientEditorConfig>(null)\n\n const featureProviderComponents: GeneratedFeatureProviderComponent[] = (\n richTextComponentMap.get('features') as GeneratedFeatureProviderComponent[]\n ).sort((a, b) => a.order - b.order) // order by order\n\n let featureProvidersAndComponentsToLoad = 0 // feature providers and components\n for (const featureProvider of featureProviderComponents) {\n const featureComponentKeys = Array.from(richTextComponentMap.keys()).filter((key) =>\n key.startsWith(`feature.${featureProvider.key}.components.`),\n )\n\n featureProvidersAndComponentsToLoad += 1\n featureProvidersAndComponentsToLoad += featureComponentKeys.length\n }\n\n useEffect(() => {\n if (!hasLoadedFeatures) {\n const featureProvidersLocal: FeatureProviderClient<unknown>[] = []\n let featureProvidersAndComponentsLoaded = 0 // feature providers and components only\n\n Object.entries(clientFunctions).forEach(([key, plugin]) => {\n if (key.startsWith(`lexicalFeature.${schemaPath}.`)) {\n if (!key.includes('.components.')) {\n featureProvidersLocal.push(plugin)\n }\n featureProvidersAndComponentsLoaded++\n }\n })\n\n if (featureProvidersAndComponentsLoaded === featureProvidersAndComponentsToLoad) {\n setFeatureProviders(featureProvidersLocal)\n setHasLoadedFeatures(true)\n\n /**\n * Loaded feature provided => create the final sanitized editor config\n */\n\n const resolvedClientFeatures = loadClientFeatures({\n clientFunctions,\n schemaPath,\n unSanitizedEditorConfig: {\n features: featureProvidersLocal,\n lexical: lexicalEditorConfig,\n },\n })\n\n setFinalSanitizedEditorConfig(\n sanitizeClientEditorConfig(\n lexicalEditorConfig ? lexicalEditorConfig : defaultEditorLexicalConfig,\n resolvedClientFeatures,\n admin,\n ),\n )\n }\n }\n }, [\n admin,\n featureProviderComponents,\n hasLoadedFeatures,\n clientFunctions,\n schemaPath,\n featureProviderComponents.length,\n featureProviders,\n finalSanitizedEditorConfig,\n lexicalEditorConfig,\n richTextComponentMap,\n featureProvidersAndComponentsToLoad,\n ])\n\n useEffect(() => {\n if (!hasLoadedFeatures) {\n return\n }\n let dataToUse = cellData\n if (dataToUse == null || !hasLoadedFeatures || !finalSanitizedEditorConfig) {\n setPreview('')\n return\n }\n\n // Transform data through load hooks\n if (finalSanitizedEditorConfig?.features?.hooks?.load?.length) {\n finalSanitizedEditorConfig.features.hooks.load.forEach((hook) => {\n dataToUse = hook({ incomingEditorState: dataToUse })\n })\n }\n\n if (!dataToUse || typeof dataToUse !== 'object') {\n setPreview('')\n return\n }\n\n // If data is from Slate and not Lexical\n if (Array.isArray(dataToUse) && !('root' in dataToUse)) {\n setPreview('')\n return\n }\n\n // If data is from payload-plugin-lexical\n if ('jsonContent' in dataToUse) {\n setPreview('')\n return\n }\n\n // initialize headless editor\n const headlessEditor = createHeadlessEditor({\n namespace: finalSanitizedEditorConfig.lexical.namespace,\n nodes: getEnabledNodes({ editorConfig: finalSanitizedEditorConfig }),\n theme: finalSanitizedEditorConfig.lexical.theme,\n })\n headlessEditor.setEditorState(headlessEditor.parseEditorState(dataToUse))\n\n const textContent =\n headlessEditor.getEditorState().read(() => {\n return $getRoot().getTextContent()\n }) || ''\n\n // Limiting the number of characters shown is done in a CSS rule\n setPreview(textContent)\n }, [cellData, lexicalEditorConfig, hasLoadedFeatures, finalSanitizedEditorConfig])\n\n if (!hasLoadedFeatures) {\n return (\n <React.Fragment>\n {Array.isArray(featureProviderComponents) &&\n featureProviderComponents.map((featureProvider) => {\n // get all components starting with key feature.${FeatureProvider.key}.components.{featureComponentKey}\n const featureComponentKeys = Array.from(richTextComponentMap.keys()).filter((key) =>\n key.startsWith(`feature.${featureProvider.key}.components.`),\n )\n\n const featureComponents: React.ReactNode[] = featureComponentKeys.map((key) => {\n return richTextComponentMap.get(key)\n })\n\n return (\n <React.Fragment key={featureProvider.key}>\n {featureComponents?.length\n ? featureComponents.map((FeatureComponent) => {\n return FeatureComponent\n })\n : null}\n {featureProvider.ClientComponent}\n </React.Fragment>\n )\n })}\n </React.Fragment>\n )\n }\n\n return <span>{preview}</span>\n}\n"],"names":["createHeadlessEditor","useTableCell","useClientFunctions","$getRoot","React","useEffect","useState","defaultEditorLexicalConfig","loadClientFeatures","sanitizeClientEditorConfig","getEnabledNodes","RichTextCell","props","admin","lexicalEditorConfig","richTextComponentMap","preview","setPreview","cellData","cellProps","schemaPath","clientFunctions","hasLoadedFeatures","setHasLoadedFeatures","featureProviders","setFeatureProviders","finalSanitizedEditorConfig","setFinalSanitizedEditorConfig","featureProviderComponents","get","sort","a","b","order","featureProvidersAndComponentsToLoad","featureProvider","featureComponentKeys","Array","from","keys","filter","key","startsWith","length","featureProvidersLocal","featureProvidersAndComponentsLoaded","Object","entries","forEach","plugin","includes","push","resolvedClientFeatures","unSanitizedEditorConfig","features","lexical","dataToUse","hooks","load","hook","incomingEditorState","isArray","headlessEditor","namespace","nodes","editorConfig","theme","setEditorState","parseEditorState","textContent","getEditorState","read","getTextContent","Fragment","map","featureComponents","FeatureComponent","ClientComponent","span"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
@@ -7,6 +7,5 @@ export { toolbarTextDropdownGroupWithItems } from '../field/features/shared/tool
|
|
|
7
7
|
export { ToolbarButton } from '../field/features/toolbars/shared/ToolbarButton/index.js';
|
|
8
8
|
export { ToolbarDropdown } from '../field/features/toolbars/shared/ToolbarDropdown/index.js';
|
|
9
9
|
export { RichTextField } from '../field/index.js';
|
|
10
|
-
export { type EditorFocusContextType, EditorFocusProvider, useEditorFocus, } from '../field/lexical/EditorFocusProvider.js';
|
|
11
10
|
export { defaultEditorLexicalConfig } from '../field/lexical/config/client/default.js';
|
|
12
11
|
//# sourceMappingURL=components.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../src/exports/components.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,4CAA4C,CAAA;AAElF,OAAO,EAAE,2BAA2B,EAAE,MAAM,uDAAuD,CAAA;AACnG,OAAO,EAAE,gCAAgC,EAAE,MAAM,sDAAsD,CAAA;AACvG,OAAO,EAAE,mCAAmC,EAAE,MAAM,yDAAyD,CAAA;AAC7G,OAAO,EAAE,iCAAiC,EAAE,MAAM,uDAAuD,CAAA;AACzG,OAAO,EAAE,aAAa,EAAE,MAAM,0DAA0D,CAAA;AACxF,OAAO,EAAE,eAAe,EAAE,MAAM,4DAA4D,CAAA;AAE5F,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../src/exports/components.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,4CAA4C,CAAA;AAElF,OAAO,EAAE,2BAA2B,EAAE,MAAM,uDAAuD,CAAA;AACnG,OAAO,EAAE,gCAAgC,EAAE,MAAM,sDAAsD,CAAA;AACvG,OAAO,EAAE,mCAAmC,EAAE,MAAM,yDAAyD,CAAA;AAC7G,OAAO,EAAE,iCAAiC,EAAE,MAAM,uDAAuD,CAAA;AACzG,OAAO,EAAE,aAAa,EAAE,MAAM,0DAA0D,CAAA;AACxF,OAAO,EAAE,eAAe,EAAE,MAAM,4DAA4D,CAAA;AAE5F,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEjD,OAAO,EAAE,0BAA0B,EAAE,MAAM,2CAA2C,CAAA"}
|
|
@@ -7,7 +7,6 @@ export { toolbarTextDropdownGroupWithItems } from '../field/features/shared/tool
|
|
|
7
7
|
export { ToolbarButton } from '../field/features/toolbars/shared/ToolbarButton/index.js';
|
|
8
8
|
export { ToolbarDropdown } from '../field/features/toolbars/shared/ToolbarDropdown/index.js';
|
|
9
9
|
export { RichTextField } from '../field/index.js';
|
|
10
|
-
export { EditorFocusProvider, useEditorFocus } from '../field/lexical/EditorFocusProvider.js';
|
|
11
10
|
export { defaultEditorLexicalConfig } from '../field/lexical/config/client/default.js';
|
|
12
11
|
|
|
13
12
|
//# sourceMappingURL=components.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/exports/components.ts"],"sourcesContent":["export { RichTextCell } from '../cell/index.js'\nexport { createClientComponent } from '../field/features/createClientComponent.js'\n\nexport { toolbarFormatGroupWithItems } from '../field/features/format/shared/toolbarFormatGroup.js'\nexport { toolbarAddDropdownGroupWithItems } from '../field/features/shared/toolbar/addDropdownGroup.js'\nexport { toolbarFeatureButtonsGroupWithItems } from '../field/features/shared/toolbar/featureButtonsGroup.js'\nexport { toolbarTextDropdownGroupWithItems } from '../field/features/shared/toolbar/textDropdownGroup.js'\nexport { ToolbarButton } from '../field/features/toolbars/shared/ToolbarButton/index.js'\nexport { ToolbarDropdown } from '../field/features/toolbars/shared/ToolbarDropdown/index.js'\n\nexport { RichTextField } from '../field/index.js'\
|
|
1
|
+
{"version":3,"sources":["../../src/exports/components.ts"],"sourcesContent":["export { RichTextCell } from '../cell/index.js'\nexport { createClientComponent } from '../field/features/createClientComponent.js'\n\nexport { toolbarFormatGroupWithItems } from '../field/features/format/shared/toolbarFormatGroup.js'\nexport { toolbarAddDropdownGroupWithItems } from '../field/features/shared/toolbar/addDropdownGroup.js'\nexport { toolbarFeatureButtonsGroupWithItems } from '../field/features/shared/toolbar/featureButtonsGroup.js'\nexport { toolbarTextDropdownGroupWithItems } from '../field/features/shared/toolbar/textDropdownGroup.js'\nexport { ToolbarButton } from '../field/features/toolbars/shared/ToolbarButton/index.js'\nexport { ToolbarDropdown } from '../field/features/toolbars/shared/ToolbarDropdown/index.js'\n\nexport { RichTextField } from '../field/index.js'\n\nexport { defaultEditorLexicalConfig } from '../field/lexical/config/client/default.js'\n"],"names":["RichTextCell","createClientComponent","toolbarFormatGroupWithItems","toolbarAddDropdownGroupWithItems","toolbarFeatureButtonsGroupWithItems","toolbarTextDropdownGroupWithItems","ToolbarButton","ToolbarDropdown","RichTextField","defaultEditorLexicalConfig"],"rangeMappings":";;;;;;;;;","mappings":"AAAA,SAASA,YAAY,QAAQ,mBAAkB;AAC/C,SAASC,qBAAqB,QAAQ,6CAA4C;AAElF,SAASC,2BAA2B,QAAQ,wDAAuD;AACnG,SAASC,gCAAgC,QAAQ,uDAAsD;AACvG,SAASC,mCAAmC,QAAQ,0DAAyD;AAC7G,SAASC,iCAAiC,QAAQ,wDAAuD;AACzG,SAASC,aAAa,QAAQ,2DAA0D;AACxF,SAASC,eAAe,QAAQ,6DAA4D;AAE5F,SAASC,aAAa,QAAQ,oBAAmB;AAEjD,SAASC,0BAA0B,QAAQ,4CAA2C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createFeaturePropComponent.d.ts","sourceRoot":"","sources":["../../../src/field/features/createFeaturePropComponent.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"createFeaturePropComponent.d.ts","sourceRoot":"","sources":["../../../src/field/features/createFeaturePropComponent.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAoB9B,eAAO,MAAM,0BAA0B,sBAC/B,CAAC,KACN,MAAM,EAAE,CAAC;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAKvD,CAAA"}
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
'use client';
|
|
2
|
+
import { useTableCell } from '@payloadcms/ui/elements/Table';
|
|
2
3
|
import { useFieldProps } from '@payloadcms/ui/forms/FieldPropsProvider';
|
|
3
4
|
import { useAddClientFunction } from '@payloadcms/ui/providers/ClientFunction';
|
|
4
5
|
const useLexicalFeatureProp = (featureKey, componentKey, prop)=>{
|
|
5
|
-
const { schemaPath } = useFieldProps();
|
|
6
|
+
const { schemaPath: schemaPathFromFieldProps } = useFieldProps();
|
|
7
|
+
const tableCell = useTableCell();
|
|
8
|
+
const schemaPathFromCellProps = tableCell?.cellProps?.schemaPath;
|
|
9
|
+
const schemaPath = schemaPathFromCellProps || schemaPathFromFieldProps // schemaPathFromCellProps needs to have priority, as there can be cells within fields (e.g. list drawers) and the cell schemaPath needs to be used there - not the parent field schemaPath. There cannot be fields within cells.
|
|
10
|
+
;
|
|
6
11
|
useAddClientFunction(`lexicalFeature.${schemaPath}.${featureKey}.components.${componentKey}`, prop);
|
|
7
12
|
};
|
|
8
13
|
export const createFeaturePropComponent = (prop)=>{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/field/features/createFeaturePropComponent.tsx"],"sourcesContent":["'use client'\n\nimport type React from 'react'\n\nimport { useFieldProps } from '@payloadcms/ui/forms/FieldPropsProvider'\nimport { useAddClientFunction } from '@payloadcms/ui/providers/ClientFunction'\n\nconst useLexicalFeatureProp = <T,>(featureKey: string, componentKey: string, prop: T) => {\n const { schemaPath } = useFieldProps()\n\n useAddClientFunction(\n `lexicalFeature.${schemaPath}.${featureKey}.components.${componentKey}`,\n prop,\n )\n}\n\nexport const createFeaturePropComponent = <T = unknown,>(\n prop: T,\n): React.FC<{ componentKey: string; featureKey: string }> => {\n return (props) => {\n useLexicalFeatureProp(props.featureKey, props.componentKey, prop)\n return null\n }\n}\n"],"names":["useFieldProps","useAddClientFunction","useLexicalFeatureProp","featureKey","componentKey","prop","schemaPath","createFeaturePropComponent","props"],"rangeMappings":"
|
|
1
|
+
{"version":3,"sources":["../../../src/field/features/createFeaturePropComponent.tsx"],"sourcesContent":["'use client'\n\nimport type React from 'react'\n\nimport { useTableCell } from '@payloadcms/ui/elements/Table'\nimport { useFieldProps } from '@payloadcms/ui/forms/FieldPropsProvider'\nimport { useAddClientFunction } from '@payloadcms/ui/providers/ClientFunction'\n\nconst useLexicalFeatureProp = <T,>(featureKey: string, componentKey: string, prop: T) => {\n const { schemaPath: schemaPathFromFieldProps } = useFieldProps()\n const tableCell = useTableCell()\n\n const schemaPathFromCellProps = tableCell?.cellProps?.schemaPath\n\n const schemaPath = schemaPathFromCellProps || schemaPathFromFieldProps // schemaPathFromCellProps needs to have priority, as there can be cells within fields (e.g. list drawers) and the cell schemaPath needs to be used there - not the parent field schemaPath. There cannot be fields within cells.\n\n useAddClientFunction(\n `lexicalFeature.${schemaPath}.${featureKey}.components.${componentKey}`,\n prop,\n )\n}\n\nexport const createFeaturePropComponent = <T = unknown,>(\n prop: T,\n): React.FC<{ componentKey: string; featureKey: string }> => {\n return (props) => {\n useLexicalFeatureProp(props.featureKey, props.componentKey, prop)\n return null\n }\n}\n"],"names":["useTableCell","useFieldProps","useAddClientFunction","useLexicalFeatureProp","featureKey","componentKey","prop","schemaPath","schemaPathFromFieldProps","tableCell","schemaPathFromCellProps","cellProps","createFeaturePropComponent","props"],"rangeMappings":";;;;;;;;;;;;;;;;;","mappings":"AAAA;AAIA,SAASA,YAAY,QAAQ,gCAA+B;AAC5D,SAASC,aAAa,QAAQ,0CAAyC;AACvE,SAASC,oBAAoB,QAAQ,0CAAyC;AAE9E,MAAMC,wBAAwB,CAAKC,YAAoBC,cAAsBC;IAC3E,MAAM,EAAEC,YAAYC,wBAAwB,EAAE,GAAGP;IACjD,MAAMQ,YAAYT;IAElB,MAAMU,0BAA0BD,WAAWE,WAAWJ;IAEtD,MAAMA,aAAaG,2BAA2BF,yBAAyB,iOAAiO;;IAExSN,qBACE,CAAC,eAAe,EAAEK,WAAW,CAAC,EAAEH,WAAW,YAAY,EAAEC,aAAa,CAAC,EACvEC;AAEJ;AAEA,OAAO,MAAMM,6BAA6B,CACxCN;IAEA,OAAO,CAACO;QACNV,sBAAsBU,MAAMT,UAAU,EAAES,MAAMR,YAAY,EAAEC;QAC5D,OAAO;IACT;AACF,EAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { PluginComponentWithAnchor } from '../../../types.js';
|
|
2
|
+
import type { FixedToolbarFeatureProps } from '../feature.server.js';
|
|
2
3
|
import './index.scss';
|
|
3
|
-
export declare const FixedToolbarPlugin: PluginComponentWithAnchor<
|
|
4
|
+
export declare const FixedToolbarPlugin: PluginComponentWithAnchor<FixedToolbarFeatureProps>;
|
|
4
5
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/field/features/toolbars/fixed/Toolbar/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/field/features/toolbars/fixed/Toolbar/index.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAA;AAElE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAA;AAKpE,OAAO,cAAc,CAAA;AAyOrB,eAAO,MAAM,kBAAkB,EAAE,yBAAyB,CAAC,wBAAwB,CAqClF,CAAA"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as scrollInfoImport from '@faceless-ui/scroll-info';
|
|
3
4
|
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js';
|
|
5
|
+
import useThrottledEffect from '@payloadcms/ui/hooks/useThrottledEffect';
|
|
4
6
|
import { useTranslation } from '@payloadcms/ui/providers/Translation';
|
|
5
7
|
import * as React from 'react';
|
|
6
|
-
import {
|
|
8
|
+
import { useMemo } from 'react';
|
|
7
9
|
import { useEditorConfigContext } from '../../../../lexical/config/client/EditorConfigProvider.js';
|
|
8
10
|
import { ToolbarButton } from '../../shared/ToolbarButton/index.js';
|
|
9
11
|
import { ToolbarDropdown } from '../../shared/ToolbarDropdown/index.js';
|
|
@@ -100,7 +102,56 @@ function ToolbarGroupComponent({ anchorElem, editor, editorConfig, group, index
|
|
|
100
102
|
]
|
|
101
103
|
}, group.key);
|
|
102
104
|
}
|
|
103
|
-
function FixedToolbar({ anchorElem, editor, editorConfig }) {
|
|
105
|
+
function FixedToolbar({ anchorElem, clientProps, editor, editorConfig, parentWithFixedToolbar }) {
|
|
106
|
+
const { useScrollInfo } = scrollInfoImport;
|
|
107
|
+
const currentToolbarRef = React.useRef(null);
|
|
108
|
+
const { y } = useScrollInfo();
|
|
109
|
+
// Memoize the parent toolbar element
|
|
110
|
+
const parentToolbarElem = useMemo(()=>{
|
|
111
|
+
if (!parentWithFixedToolbar || clientProps?.disableIfParentHasFixedToolbar) {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
const parentEditorElem = parentWithFixedToolbar.editorContainerRef.current;
|
|
115
|
+
let sibling = parentEditorElem.previousElementSibling;
|
|
116
|
+
while(sibling){
|
|
117
|
+
if (sibling.classList.contains('fixed-toolbar')) {
|
|
118
|
+
return sibling;
|
|
119
|
+
}
|
|
120
|
+
sibling = sibling.previousElementSibling;
|
|
121
|
+
}
|
|
122
|
+
return null;
|
|
123
|
+
}, [
|
|
124
|
+
clientProps?.disableIfParentHasFixedToolbar,
|
|
125
|
+
parentWithFixedToolbar
|
|
126
|
+
]);
|
|
127
|
+
useThrottledEffect(()=>{
|
|
128
|
+
if (!parentToolbarElem) {
|
|
129
|
+
// this also checks for clientProps?.disableIfParentHasFixedToolbar indirectly, see the parentToolbarElem useMemo
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
const currentToolbarElem = currentToolbarRef.current;
|
|
133
|
+
if (!currentToolbarElem) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const currentRect = currentToolbarElem.getBoundingClientRect();
|
|
137
|
+
const parentRect = parentToolbarElem.getBoundingClientRect();
|
|
138
|
+
// we only need to check for vertical overlap
|
|
139
|
+
const overlapping = !(currentRect.bottom < parentRect.top || currentRect.top > parentRect.bottom);
|
|
140
|
+
if (overlapping) {
|
|
141
|
+
currentToolbarRef.current.className = 'fixed-toolbar fixed-toolbar--overlapping';
|
|
142
|
+
parentToolbarElem.className = 'fixed-toolbar fixed-toolbar--hide';
|
|
143
|
+
} else {
|
|
144
|
+
if (!currentToolbarRef.current.classList.contains('fixed-toolbar--overlapping')) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
currentToolbarRef.current.className = 'fixed-toolbar';
|
|
148
|
+
parentToolbarElem.className = 'fixed-toolbar';
|
|
149
|
+
}
|
|
150
|
+
}, 50, [
|
|
151
|
+
currentToolbarRef,
|
|
152
|
+
parentToolbarElem,
|
|
153
|
+
y
|
|
154
|
+
]);
|
|
104
155
|
return /*#__PURE__*/ _jsx("div", {
|
|
105
156
|
className: "fixed-toolbar",
|
|
106
157
|
onFocus: (event)=>{
|
|
@@ -108,6 +159,7 @@ function FixedToolbar({ anchorElem, editor, editorConfig }) {
|
|
|
108
159
|
// the parent editor will be focused, and the child editor will lose focus.
|
|
109
160
|
event.stopPropagation();
|
|
110
161
|
},
|
|
162
|
+
ref: currentToolbarRef,
|
|
111
163
|
children: editor.isEditable() && /*#__PURE__*/ _jsx(React.Fragment, {
|
|
112
164
|
children: editorConfig?.features && editorConfig.features?.toolbarFixed?.groups.map((group, i)=>{
|
|
113
165
|
return /*#__PURE__*/ _jsx(ToolbarGroupComponent, {
|
|
@@ -121,28 +173,29 @@ function FixedToolbar({ anchorElem, editor, editorConfig }) {
|
|
|
121
173
|
})
|
|
122
174
|
});
|
|
123
175
|
}
|
|
124
|
-
const
|
|
125
|
-
if (
|
|
126
|
-
if (
|
|
127
|
-
return
|
|
176
|
+
const getParentEditorWithFixedToolbar = (editorConfigContext)=>{
|
|
177
|
+
if (editorConfigContext.parentEditor?.editorConfig) {
|
|
178
|
+
if (editorConfigContext.parentEditor?.editorConfig.resolvedFeatureMap.has('toolbarFixed')) {
|
|
179
|
+
return editorConfigContext.parentEditor;
|
|
128
180
|
} else {
|
|
129
|
-
if (
|
|
130
|
-
return
|
|
181
|
+
if (editorConfigContext.parentEditor) {
|
|
182
|
+
return getParentEditorWithFixedToolbar(editorConfigContext.parentEditor);
|
|
131
183
|
}
|
|
132
184
|
}
|
|
133
185
|
}
|
|
134
186
|
return false;
|
|
135
187
|
};
|
|
136
|
-
export const FixedToolbarPlugin = ({ anchorElem })=>{
|
|
188
|
+
export const FixedToolbarPlugin = ({ anchorElem, clientProps })=>{
|
|
137
189
|
const [currentEditor] = useLexicalComposerContext();
|
|
138
|
-
const
|
|
139
|
-
const
|
|
140
|
-
const editor =
|
|
141
|
-
const editorConfig =
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
190
|
+
const editorConfigContext = useEditorConfigContext();
|
|
191
|
+
const { editorConfig: currentEditorConfig } = editorConfigContext;
|
|
192
|
+
const editor = clientProps.applyToFocusedEditor ? editorConfigContext.focusedEditor?.editor || currentEditor : currentEditor;
|
|
193
|
+
const editorConfig = clientProps.applyToFocusedEditor ? editorConfigContext.focusedEditor?.editorConfig || currentEditorConfig : currentEditorConfig;
|
|
194
|
+
const parentWithFixedToolbar = getParentEditorWithFixedToolbar(editorConfigContext);
|
|
195
|
+
if (clientProps?.disableIfParentHasFixedToolbar) {
|
|
196
|
+
if (parentWithFixedToolbar) {
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
146
199
|
}
|
|
147
200
|
if (!editorConfig?.features?.toolbarFixed?.groups?.length) {
|
|
148
201
|
return null;
|
|
@@ -150,7 +203,8 @@ export const FixedToolbarPlugin = ({ anchorElem })=>{
|
|
|
150
203
|
return /*#__PURE__*/ _jsx(FixedToolbar, {
|
|
151
204
|
anchorElem: anchorElem,
|
|
152
205
|
editor: editor,
|
|
153
|
-
editorConfig: editorConfig
|
|
206
|
+
editorConfig: editorConfig,
|
|
207
|
+
parentWithFixedToolbar: parentWithFixedToolbar
|
|
154
208
|
});
|
|
155
209
|
};
|
|
156
210
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../src/field/features/toolbars/fixed/Toolbar/index.tsx"],"sourcesContent":["'use client'\nimport type { LexicalEditor } from 'lexical'\n\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js'\nimport { useTranslation } from '@payloadcms/ui/providers/Translation'\nimport * as React from 'react'\n\nimport type { EditorFocusContextType } from '../../../../lexical/EditorFocusProvider.js'\nimport type { SanitizedClientEditorConfig } from '../../../../lexical/config/types.js'\nimport type { PluginComponentWithAnchor } from '../../../types.js'\nimport type { ToolbarGroup, ToolbarGroupItem } from '../../types.js'\n\nimport { useEditorFocus } from '../../../../lexical/EditorFocusProvider.js'\nimport { useEditorConfigContext } from '../../../../lexical/config/client/EditorConfigProvider.js'\nimport { ToolbarButton } from '../../shared/ToolbarButton/index.js'\nimport { ToolbarDropdown } from '../../shared/ToolbarDropdown/index.js'\nimport './index.scss'\n\nfunction ButtonGroupItem({\n anchorElem,\n editor,\n item,\n}: {\n anchorElem: HTMLElement\n editor: LexicalEditor\n item: ToolbarGroupItem\n}): React.ReactNode {\n if (item.Component) {\n return (\n item?.Component && (\n <item.Component anchorElem={anchorElem} editor={editor} item={item} key={item.key} />\n )\n )\n }\n\n return (\n <ToolbarButton editor={editor} item={item} key={item.key}>\n {item?.ChildComponent && <item.ChildComponent />}\n </ToolbarButton>\n )\n}\n\nfunction ToolbarGroupComponent({\n anchorElem,\n editor,\n editorConfig,\n group,\n index,\n}: {\n anchorElem: HTMLElement\n editor: LexicalEditor\n editorConfig: SanitizedClientEditorConfig\n group: ToolbarGroup\n index: number\n}): React.ReactNode {\n const { i18n } = useTranslation()\n\n const [dropdownLabel, setDropdownLabel] = React.useState<null | string>(null)\n const [DropdownIcon, setDropdownIcon] = React.useState<React.FC | null>(null)\n\n React.useEffect(() => {\n if (group?.type === 'dropdown' && group.items.length && group.ChildComponent) {\n setDropdownIcon(() => group.ChildComponent)\n } else {\n setDropdownIcon(null)\n }\n }, [group])\n\n const onActiveChange = ({ activeItems }: { activeItems: ToolbarGroupItem[] }) => {\n if (!activeItems.length) {\n if (group?.type === 'dropdown' && group.items.length && group.ChildComponent) {\n setDropdownIcon(() => group.ChildComponent)\n setDropdownLabel(null)\n } else {\n setDropdownIcon(null)\n setDropdownLabel(null)\n }\n return\n }\n const item = activeItems[0]\n\n let label = item.key\n if (item.label) {\n label = typeof item.label === 'function' ? item.label({ i18n }) : item.label\n }\n // Crop title to max. 25 characters\n if (label.length > 25) {\n label = label.substring(0, 25) + '...'\n }\n setDropdownLabel(label)\n setDropdownIcon(() => item.ChildComponent)\n }\n\n return (\n <div className={`fixed-toolbar__group fixed-toolbar__group-${group.key}`} key={group.key}>\n {group.type === 'dropdown' &&\n group.items.length &&\n (DropdownIcon ? (\n <ToolbarDropdown\n Icon={DropdownIcon}\n anchorElem={anchorElem}\n editor={editor}\n groupKey={group.key}\n items={group.items}\n itemsContainerClassNames={['fixed-toolbar__dropdown-items']}\n label={dropdownLabel}\n maxActiveItems={1}\n onActiveChange={onActiveChange}\n />\n ) : (\n <ToolbarDropdown\n anchorElem={anchorElem}\n editor={editor}\n groupKey={group.key}\n items={group.items}\n itemsContainerClassNames={['fixed-toolbar__dropdown-items']}\n label={dropdownLabel}\n maxActiveItems={1}\n onActiveChange={onActiveChange}\n />\n ))}\n {group.type === 'buttons' &&\n group.items.length &&\n group.items.map((item) => {\n return (\n <ButtonGroupItem anchorElem={anchorElem} editor={editor} item={item} key={item.key} />\n )\n })}\n {index < editorConfig.features.toolbarFixed?.groups.length - 1 && <div className=\"divider\" />}\n </div>\n )\n}\n\nfunction FixedToolbar({\n anchorElem,\n editor,\n editorConfig,\n}: {\n anchorElem: HTMLElement\n editor: LexicalEditor\n editorConfig: SanitizedClientEditorConfig\n}): React.ReactNode {\n return (\n <div\n className=\"fixed-toolbar\"\n onFocus={(event) => {\n // Prevent other focus events being triggered. Otherwise, if this was to be clicked while in a child editor,\n // the parent editor will be focused, and the child editor will lose focus.\n event.stopPropagation()\n }}\n >\n {editor.isEditable() && (\n <React.Fragment>\n {editorConfig?.features &&\n editorConfig.features?.toolbarFixed?.groups.map((group, i) => {\n return (\n <ToolbarGroupComponent\n anchorElem={anchorElem}\n editor={editor}\n editorConfig={editorConfig}\n group={group}\n index={i}\n key={group.key}\n />\n )\n })}\n </React.Fragment>\n )}\n </div>\n )\n}\n\nconst checkParentEditor = (editorFocus: EditorFocusContextType): boolean => {\n if (editorFocus.parentEditorConfigContext?.editorConfig) {\n if (\n editorFocus.parentEditorConfigContext?.editorConfig.resolvedFeatureMap.has('toolbarFixed')\n ) {\n return true\n } else {\n if (editorFocus.parentEditorFocus) {\n return checkParentEditor(editorFocus.parentEditorFocus)\n }\n }\n }\n return false\n}\n\nexport const FixedToolbarPlugin: PluginComponentWithAnchor<undefined> = ({ anchorElem }) => {\n const [currentEditor] = useLexicalComposerContext()\n const { editorConfig: currentEditorConfig, uuid } = useEditorConfigContext()\n\n const editorFocus = useEditorFocus()\n const editor = editorFocus.focusedEditor || currentEditor\n\n const editorConfig = editorFocus.focusedEditorConfigContext?.editorConfig || currentEditorConfig\n\n // Check if there is a parent editor with a fixed toolbar already\n const hasParentWithFixedToolbar = checkParentEditor(editorFocus)\n\n if (hasParentWithFixedToolbar) {\n return null\n }\n\n if (!editorConfig?.features?.toolbarFixed?.groups?.length) {\n return null\n }\n\n return <FixedToolbar anchorElem={anchorElem} editor={editor} editorConfig={editorConfig} />\n}\n"],"names":["useLexicalComposerContext","useTranslation","React","useEditorFocus","useEditorConfigContext","ToolbarButton","ToolbarDropdown","ButtonGroupItem","anchorElem","editor","item","Component","key","ChildComponent","ToolbarGroupComponent","editorConfig","group","index","i18n","dropdownLabel","setDropdownLabel","useState","DropdownIcon","setDropdownIcon","useEffect","type","items","length","onActiveChange","activeItems","label","substring","div","className","Icon","groupKey","itemsContainerClassNames","maxActiveItems","map","features","toolbarFixed","groups","FixedToolbar","onFocus","event","stopPropagation","isEditable","Fragment","i","checkParentEditor","editorFocus","parentEditorConfigContext","resolvedFeatureMap","has","parentEditorFocus","FixedToolbarPlugin","currentEditor","currentEditorConfig","uuid","focusedEditor","focusedEditorConfigContext","hasParentWithFixedToolbar"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/field/features/toolbars/fixed/Toolbar/index.tsx"],"sourcesContent":["'use client'\nimport type { LexicalEditor } from 'lexical'\n\nimport * as scrollInfoImport from '@faceless-ui/scroll-info'\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js'\nimport useThrottledEffect from '@payloadcms/ui/hooks/useThrottledEffect'\nimport { useTranslation } from '@payloadcms/ui/providers/Translation'\nimport * as React from 'react'\nimport { useMemo } from 'react'\n\nimport type { EditorConfigContextType } from '../../../../lexical/config/client/EditorConfigProvider.js'\nimport type { SanitizedClientEditorConfig } from '../../../../lexical/config/types.js'\nimport type { PluginComponentWithAnchor } from '../../../types.js'\nimport type { ToolbarGroup, ToolbarGroupItem } from '../../types.js'\nimport type { FixedToolbarFeatureProps } from '../feature.server.js'\n\nimport { useEditorConfigContext } from '../../../../lexical/config/client/EditorConfigProvider.js'\nimport { ToolbarButton } from '../../shared/ToolbarButton/index.js'\nimport { ToolbarDropdown } from '../../shared/ToolbarDropdown/index.js'\nimport './index.scss'\n\nfunction ButtonGroupItem({\n anchorElem,\n editor,\n item,\n}: {\n anchorElem: HTMLElement\n editor: LexicalEditor\n item: ToolbarGroupItem\n}): React.ReactNode {\n if (item.Component) {\n return (\n item?.Component && (\n <item.Component anchorElem={anchorElem} editor={editor} item={item} key={item.key} />\n )\n )\n }\n\n return (\n <ToolbarButton editor={editor} item={item} key={item.key}>\n {item?.ChildComponent && <item.ChildComponent />}\n </ToolbarButton>\n )\n}\n\nfunction ToolbarGroupComponent({\n anchorElem,\n editor,\n editorConfig,\n group,\n index,\n}: {\n anchorElem: HTMLElement\n editor: LexicalEditor\n editorConfig: SanitizedClientEditorConfig\n group: ToolbarGroup\n index: number\n}): React.ReactNode {\n const { i18n } = useTranslation()\n\n const [dropdownLabel, setDropdownLabel] = React.useState<null | string>(null)\n const [DropdownIcon, setDropdownIcon] = React.useState<React.FC | null>(null)\n\n React.useEffect(() => {\n if (group?.type === 'dropdown' && group.items.length && group.ChildComponent) {\n setDropdownIcon(() => group.ChildComponent)\n } else {\n setDropdownIcon(null)\n }\n }, [group])\n\n const onActiveChange = ({ activeItems }: { activeItems: ToolbarGroupItem[] }) => {\n if (!activeItems.length) {\n if (group?.type === 'dropdown' && group.items.length && group.ChildComponent) {\n setDropdownIcon(() => group.ChildComponent)\n setDropdownLabel(null)\n } else {\n setDropdownIcon(null)\n setDropdownLabel(null)\n }\n return\n }\n const item = activeItems[0]\n\n let label = item.key\n if (item.label) {\n label = typeof item.label === 'function' ? item.label({ i18n }) : item.label\n }\n // Crop title to max. 25 characters\n if (label.length > 25) {\n label = label.substring(0, 25) + '...'\n }\n setDropdownLabel(label)\n setDropdownIcon(() => item.ChildComponent)\n }\n\n return (\n <div className={`fixed-toolbar__group fixed-toolbar__group-${group.key}`} key={group.key}>\n {group.type === 'dropdown' &&\n group.items.length &&\n (DropdownIcon ? (\n <ToolbarDropdown\n Icon={DropdownIcon}\n anchorElem={anchorElem}\n editor={editor}\n groupKey={group.key}\n items={group.items}\n itemsContainerClassNames={['fixed-toolbar__dropdown-items']}\n label={dropdownLabel}\n maxActiveItems={1}\n onActiveChange={onActiveChange}\n />\n ) : (\n <ToolbarDropdown\n anchorElem={anchorElem}\n editor={editor}\n groupKey={group.key}\n items={group.items}\n itemsContainerClassNames={['fixed-toolbar__dropdown-items']}\n label={dropdownLabel}\n maxActiveItems={1}\n onActiveChange={onActiveChange}\n />\n ))}\n {group.type === 'buttons' &&\n group.items.length &&\n group.items.map((item) => {\n return (\n <ButtonGroupItem anchorElem={anchorElem} editor={editor} item={item} key={item.key} />\n )\n })}\n {index < editorConfig.features.toolbarFixed?.groups.length - 1 && <div className=\"divider\" />}\n </div>\n )\n}\n\nfunction FixedToolbar({\n anchorElem,\n clientProps,\n editor,\n editorConfig,\n parentWithFixedToolbar,\n}: {\n anchorElem: HTMLElement\n clientProps?: FixedToolbarFeatureProps\n editor: LexicalEditor\n editorConfig: SanitizedClientEditorConfig\n parentWithFixedToolbar: EditorConfigContextType | false\n}): React.ReactNode {\n const { useScrollInfo } = scrollInfoImport\n\n const currentToolbarRef = React.useRef<HTMLDivElement>(null)\n\n const { y } = useScrollInfo()\n\n // Memoize the parent toolbar element\n const parentToolbarElem = useMemo(() => {\n if (!parentWithFixedToolbar || clientProps?.disableIfParentHasFixedToolbar) {\n return null\n }\n\n const parentEditorElem = parentWithFixedToolbar.editorContainerRef.current\n let sibling = parentEditorElem.previousElementSibling\n while (sibling) {\n if (sibling.classList.contains('fixed-toolbar')) {\n return sibling\n }\n sibling = sibling.previousElementSibling\n }\n return null\n }, [clientProps?.disableIfParentHasFixedToolbar, parentWithFixedToolbar])\n\n useThrottledEffect(\n () => {\n if (!parentToolbarElem) {\n // this also checks for clientProps?.disableIfParentHasFixedToolbar indirectly, see the parentToolbarElem useMemo\n return\n }\n const currentToolbarElem = currentToolbarRef.current\n if (!currentToolbarElem) {\n return\n }\n\n const currentRect = currentToolbarElem.getBoundingClientRect()\n const parentRect = parentToolbarElem.getBoundingClientRect()\n\n // we only need to check for vertical overlap\n const overlapping = !(\n currentRect.bottom < parentRect.top || currentRect.top > parentRect.bottom\n )\n\n if (overlapping) {\n currentToolbarRef.current.className = 'fixed-toolbar fixed-toolbar--overlapping'\n parentToolbarElem.className = 'fixed-toolbar fixed-toolbar--hide'\n } else {\n if (!currentToolbarRef.current.classList.contains('fixed-toolbar--overlapping')) {\n return\n }\n currentToolbarRef.current.className = 'fixed-toolbar'\n parentToolbarElem.className = 'fixed-toolbar'\n }\n },\n 50,\n [currentToolbarRef, parentToolbarElem, y],\n )\n\n return (\n <div\n className=\"fixed-toolbar\"\n onFocus={(event) => {\n // Prevent other focus events being triggered. Otherwise, if this was to be clicked while in a child editor,\n // the parent editor will be focused, and the child editor will lose focus.\n event.stopPropagation()\n }}\n ref={currentToolbarRef}\n >\n {editor.isEditable() && (\n <React.Fragment>\n {editorConfig?.features &&\n editorConfig.features?.toolbarFixed?.groups.map((group, i) => {\n return (\n <ToolbarGroupComponent\n anchorElem={anchorElem}\n editor={editor}\n editorConfig={editorConfig}\n group={group}\n index={i}\n key={group.key}\n />\n )\n })}\n </React.Fragment>\n )}\n </div>\n )\n}\n\nconst getParentEditorWithFixedToolbar = (\n editorConfigContext: EditorConfigContextType,\n): EditorConfigContextType | false => {\n if (editorConfigContext.parentEditor?.editorConfig) {\n if (editorConfigContext.parentEditor?.editorConfig.resolvedFeatureMap.has('toolbarFixed')) {\n return editorConfigContext.parentEditor\n } else {\n if (editorConfigContext.parentEditor) {\n return getParentEditorWithFixedToolbar(editorConfigContext.parentEditor)\n }\n }\n }\n return false\n}\n\nexport const FixedToolbarPlugin: PluginComponentWithAnchor<FixedToolbarFeatureProps> = ({\n anchorElem,\n clientProps,\n}) => {\n const [currentEditor] = useLexicalComposerContext()\n const editorConfigContext = useEditorConfigContext()\n\n const { editorConfig: currentEditorConfig } = editorConfigContext\n\n const editor = clientProps.applyToFocusedEditor\n ? editorConfigContext.focusedEditor?.editor || currentEditor\n : currentEditor\n\n const editorConfig = clientProps.applyToFocusedEditor\n ? editorConfigContext.focusedEditor?.editorConfig || currentEditorConfig\n : currentEditorConfig\n\n const parentWithFixedToolbar = getParentEditorWithFixedToolbar(editorConfigContext)\n\n if (clientProps?.disableIfParentHasFixedToolbar) {\n if (parentWithFixedToolbar) {\n return null\n }\n }\n\n if (!editorConfig?.features?.toolbarFixed?.groups?.length) {\n return null\n }\n\n return (\n <FixedToolbar\n anchorElem={anchorElem}\n editor={editor}\n editorConfig={editorConfig}\n parentWithFixedToolbar={parentWithFixedToolbar}\n />\n )\n}\n"],"names":["scrollInfoImport","useLexicalComposerContext","useThrottledEffect","useTranslation","React","useMemo","useEditorConfigContext","ToolbarButton","ToolbarDropdown","ButtonGroupItem","anchorElem","editor","item","Component","key","ChildComponent","ToolbarGroupComponent","editorConfig","group","index","i18n","dropdownLabel","setDropdownLabel","useState","DropdownIcon","setDropdownIcon","useEffect","type","items","length","onActiveChange","activeItems","label","substring","div","className","Icon","groupKey","itemsContainerClassNames","maxActiveItems","map","features","toolbarFixed","groups","FixedToolbar","clientProps","parentWithFixedToolbar","useScrollInfo","currentToolbarRef","useRef","y","parentToolbarElem","disableIfParentHasFixedToolbar","parentEditorElem","editorContainerRef","current","sibling","previousElementSibling","classList","contains","currentToolbarElem","currentRect","getBoundingClientRect","parentRect","overlapping","bottom","top","onFocus","event","stopPropagation","ref","isEditable","Fragment","i","getParentEditorWithFixedToolbar","editorConfigContext","parentEditor","resolvedFeatureMap","has","FixedToolbarPlugin","currentEditor","currentEditorConfig","applyToFocusedEditor","focusedEditor"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
@@ -44,6 +44,13 @@ html[data-theme='dark'] {
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
.fixed-toolbar.fixed-toolbar--hide {
|
|
48
|
+
visibility: hidden; // Still needs to take up space so content does not jump, thus we cannot use display: none
|
|
49
|
+
// make sure you cant interact with it
|
|
50
|
+
pointer-events: none;
|
|
51
|
+
user-select: none;
|
|
52
|
+
}
|
|
53
|
+
|
|
47
54
|
.fixed-toolbar {
|
|
48
55
|
@include blur-bg(var(--theme-elevation-0));
|
|
49
56
|
display: flex;
|
|
@@ -72,7 +79,7 @@ html[data-theme='dark'] {
|
|
|
72
79
|
.divider {
|
|
73
80
|
width: 1px;
|
|
74
81
|
height: 15px;
|
|
75
|
-
background-color: var(--
|
|
82
|
+
background-color: var(--theme-elevation-100);
|
|
76
83
|
margin: 0 6.25px;
|
|
77
84
|
}
|
|
78
85
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/// <reference types="react" resolution-mode="require"/>
|
|
2
|
+
import type { FixedToolbarFeatureProps } from './feature.server.js';
|
|
2
3
|
export declare const FixedToolbarFeatureClientComponent: import("react").FC<{
|
|
3
4
|
featureKey: string;
|
|
4
5
|
order: number;
|
|
5
|
-
}>;
|
|
6
|
+
} & FixedToolbarFeatureProps>;
|
|
6
7
|
//# sourceMappingURL=feature.client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature.client.d.ts","sourceRoot":"","sources":["../../../../../src/field/features/toolbars/fixed/feature.client.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"feature.client.d.ts","sourceRoot":"","sources":["../../../../../src/field/features/toolbars/fixed/feature.client.tsx"],"names":[],"mappings":";AAGA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;AAsBnE,eAAO,MAAM,kCAAkC;;;6BAAmD,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/field/features/toolbars/fixed/feature.client.tsx"],"sourcesContent":["'use client'\n\nimport type { FeatureProviderProviderClient } from '../../types.js'\n\nimport { createClientComponent } from '../../createClientComponent.js'\nimport { FixedToolbarPlugin } from './Toolbar/index.js'\n\nconst FixedToolbarFeatureClient: FeatureProviderProviderClient<
|
|
1
|
+
{"version":3,"sources":["../../../../../src/field/features/toolbars/fixed/feature.client.tsx"],"sourcesContent":["'use client'\n\nimport type { FeatureProviderProviderClient } from '../../types.js'\nimport type { FixedToolbarFeatureProps } from './feature.server.js'\n\nimport { createClientComponent } from '../../createClientComponent.js'\nimport { FixedToolbarPlugin } from './Toolbar/index.js'\n\nconst FixedToolbarFeatureClient: FeatureProviderProviderClient<FixedToolbarFeatureProps> = (\n props,\n) => {\n return {\n clientFeatureProps: props,\n feature: () => ({\n clientFeatureProps: props,\n plugins: [\n {\n Component: FixedToolbarPlugin,\n position: 'aboveContainer',\n },\n ],\n }),\n }\n}\n\nexport const FixedToolbarFeatureClientComponent = createClientComponent(FixedToolbarFeatureClient)\n"],"names":["createClientComponent","FixedToolbarPlugin","FixedToolbarFeatureClient","props","clientFeatureProps","feature","plugins","Component","position","FixedToolbarFeatureClientComponent"],"rangeMappings":";;;;;;;;;;;;;;;;;","mappings":"AAAA;AAKA,SAASA,qBAAqB,QAAQ,iCAAgC;AACtE,SAASC,kBAAkB,QAAQ,qBAAoB;AAEvD,MAAMC,4BAAqF,CACzFC;IAEA,OAAO;QACLC,oBAAoBD;QACpBE,SAAS,IAAO,CAAA;gBACdD,oBAAoBD;gBACpBG,SAAS;oBACP;wBACEC,WAAWN;wBACXO,UAAU;oBACZ;iBACD;YACH,CAAA;IACF;AACF;AAEA,OAAO,MAAMC,qCAAqCT,sBAAsBE,2BAA0B"}
|
|
@@ -1,3 +1,19 @@
|
|
|
1
1
|
import type { FeatureProviderProviderServer } from '../../types.js';
|
|
2
|
-
export
|
|
2
|
+
export type FixedToolbarFeatureProps = {
|
|
3
|
+
/**
|
|
4
|
+
* @default false
|
|
5
|
+
*
|
|
6
|
+
* If this is enabled, the toolbar will apply to the focused editor, not the editor with the FixedToolbarFeature.
|
|
7
|
+
*
|
|
8
|
+
* This means that if the editor has a child-editor, and the child-editor is focused, the toolbar will apply to the child-editor, not the parent editor with this feature added.
|
|
9
|
+
*/
|
|
10
|
+
applyToFocusedEditor?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* @default false
|
|
13
|
+
*
|
|
14
|
+
* If there is a parent editor with a fixed toolbar, this will disable the toolbar for this editor.
|
|
15
|
+
*/
|
|
16
|
+
disableIfParentHasFixedToolbar?: boolean;
|
|
17
|
+
};
|
|
18
|
+
export declare const FixedToolbarFeature: FeatureProviderProviderServer<FixedToolbarFeatureProps, FixedToolbarFeatureProps>;
|
|
3
19
|
//# sourceMappingURL=feature.server.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature.server.d.ts","sourceRoot":"","sources":["../../../../../src/field/features/toolbars/fixed/feature.server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,gBAAgB,CAAA;AAInE,eAAO,MAAM,mBAAmB,EAAE,6BAA6B,
|
|
1
|
+
{"version":3,"file":"feature.server.d.ts","sourceRoot":"","sources":["../../../../../src/field/features/toolbars/fixed/feature.server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,gBAAgB,CAAA;AAInE,MAAM,MAAM,wBAAwB,GAAG;IACrC;;;;;;OAMG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B;;;;OAIG;IACH,8BAA8B,CAAC,EAAE,OAAO,CAAA;CACzC,CAAA;AAED,eAAO,MAAM,mBAAmB,EAAE,6BAA6B,CAC7D,wBAAwB,EACxB,wBAAwB,CAsBzB,CAAA"}
|
|
@@ -2,9 +2,14 @@ import { FixedToolbarFeatureClientComponent } from './feature.client.js';
|
|
|
2
2
|
export const FixedToolbarFeature = (props)=>{
|
|
3
3
|
return {
|
|
4
4
|
feature: ()=>{
|
|
5
|
+
const sanitizedProps = {
|
|
6
|
+
applyToFocusedEditor: props?.applyToFocusedEditor === undefined ? false : props.applyToFocusedEditor,
|
|
7
|
+
disableIfParentHasFixedToolbar: props?.disableIfParentHasFixedToolbar === undefined ? false : props.disableIfParentHasFixedToolbar
|
|
8
|
+
};
|
|
5
9
|
return {
|
|
6
10
|
ClientComponent: FixedToolbarFeatureClientComponent,
|
|
7
|
-
|
|
11
|
+
clientFeatureProps: sanitizedProps,
|
|
12
|
+
serverFeatureProps: sanitizedProps
|
|
8
13
|
};
|
|
9
14
|
},
|
|
10
15
|
key: 'toolbarFixed',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/field/features/toolbars/fixed/feature.server.ts"],"sourcesContent":["import type { FeatureProviderProviderServer } from '../../types.js'\n\nimport { FixedToolbarFeatureClientComponent } from './feature.client.js'\n\nexport const FixedToolbarFeature: FeatureProviderProviderServer
|
|
1
|
+
{"version":3,"sources":["../../../../../src/field/features/toolbars/fixed/feature.server.ts"],"sourcesContent":["import type { FeatureProviderProviderServer } from '../../types.js'\n\nimport { FixedToolbarFeatureClientComponent } from './feature.client.js'\n\nexport type FixedToolbarFeatureProps = {\n /**\n * @default false\n *\n * If this is enabled, the toolbar will apply to the focused editor, not the editor with the FixedToolbarFeature.\n *\n * This means that if the editor has a child-editor, and the child-editor is focused, the toolbar will apply to the child-editor, not the parent editor with this feature added.\n */\n applyToFocusedEditor?: boolean\n /**\n * @default false\n *\n * If there is a parent editor with a fixed toolbar, this will disable the toolbar for this editor.\n */\n disableIfParentHasFixedToolbar?: boolean\n}\n\nexport const FixedToolbarFeature: FeatureProviderProviderServer<\n FixedToolbarFeatureProps,\n FixedToolbarFeatureProps\n> = (props) => {\n return {\n feature: () => {\n const sanitizedProps: FixedToolbarFeatureProps = {\n applyToFocusedEditor:\n props?.applyToFocusedEditor === undefined ? false : props.applyToFocusedEditor,\n disableIfParentHasFixedToolbar:\n props?.disableIfParentHasFixedToolbar === undefined\n ? false\n : props.disableIfParentHasFixedToolbar,\n }\n\n return {\n ClientComponent: FixedToolbarFeatureClientComponent,\n clientFeatureProps: sanitizedProps,\n serverFeatureProps: sanitizedProps,\n }\n },\n key: 'toolbarFixed',\n serverFeatureProps: props,\n }\n}\n"],"names":["FixedToolbarFeatureClientComponent","FixedToolbarFeature","props","feature","sanitizedProps","applyToFocusedEditor","undefined","disableIfParentHasFixedToolbar","ClientComponent","clientFeatureProps","serverFeatureProps","key"],"rangeMappings":";;;;;;;;;;;;;;;;;","mappings":"AAEA,SAASA,kCAAkC,QAAQ,sBAAqB;AAmBxE,OAAO,MAAMC,sBAGT,CAACC;IACH,OAAO;QACLC,SAAS;YACP,MAAMC,iBAA2C;gBAC/CC,sBACEH,OAAOG,yBAAyBC,YAAY,QAAQJ,MAAMG,oBAAoB;gBAChFE,gCACEL,OAAOK,mCAAmCD,YACtC,QACAJ,MAAMK,8BAA8B;YAC5C;YAEA,OAAO;gBACLC,iBAAiBR;gBACjBS,oBAAoBL;gBACpBM,oBAAoBN;YACtB;QACF;QACAO,KAAK;QACLD,oBAAoBR;IACtB;AACF,EAAC"}
|
|
@@ -3,21 +3,21 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { mergeRegister } from '@lexical/utils';
|
|
4
4
|
import { $getSelection } from 'lexical';
|
|
5
5
|
import React, { useCallback, useEffect, useState } from 'react';
|
|
6
|
-
import {
|
|
6
|
+
import { useEditorConfigContext } from '../../../../lexical/config/client/EditorConfigProvider.js';
|
|
7
7
|
import './index.scss';
|
|
8
8
|
const baseClass = 'toolbar-popup__button';
|
|
9
9
|
export const ToolbarButton = ({ children, editor, item })=>{
|
|
10
10
|
const [enabled, setEnabled] = useState(true);
|
|
11
11
|
const [active, setActive] = useState(false);
|
|
12
12
|
const [className, setClassName] = useState(baseClass);
|
|
13
|
-
const
|
|
13
|
+
const editorConfigContext = useEditorConfigContext();
|
|
14
14
|
const updateStates = useCallback(()=>{
|
|
15
15
|
editor.getEditorState().read(()=>{
|
|
16
16
|
const selection = $getSelection();
|
|
17
17
|
if (item.isActive) {
|
|
18
18
|
const isActive = item.isActive({
|
|
19
19
|
editor,
|
|
20
|
-
|
|
20
|
+
editorConfigContext,
|
|
21
21
|
selection
|
|
22
22
|
});
|
|
23
23
|
if (active !== isActive) {
|
|
@@ -27,7 +27,7 @@ export const ToolbarButton = ({ children, editor, item })=>{
|
|
|
27
27
|
if (item.isEnabled) {
|
|
28
28
|
const isEnabled = item.isEnabled({
|
|
29
29
|
editor,
|
|
30
|
-
|
|
30
|
+
editorConfigContext,
|
|
31
31
|
selection
|
|
32
32
|
});
|
|
33
33
|
if (enabled !== isEnabled) {
|
|
@@ -38,7 +38,7 @@ export const ToolbarButton = ({ children, editor, item })=>{
|
|
|
38
38
|
}, [
|
|
39
39
|
active,
|
|
40
40
|
editor,
|
|
41
|
-
|
|
41
|
+
editorConfigContext,
|
|
42
42
|
enabled,
|
|
43
43
|
item
|
|
44
44
|
]);
|