@payloadcms/richtext-lexical 3.0.0-alpha.49 → 3.0.0-alpha.51

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/field/Field.d.ts +2 -0
  2. package/dist/field/Field.d.ts.map +1 -1
  3. package/dist/field/Field.js +17 -4
  4. package/dist/field/Field.js.map +1 -1
  5. package/dist/field/features/blocks/component/BlockContent.d.ts +2 -0
  6. package/dist/field/features/blocks/component/BlockContent.d.ts.map +1 -1
  7. package/dist/field/features/blocks/component/BlockContent.js +5 -5
  8. package/dist/field/features/blocks/component/BlockContent.js.map +1 -1
  9. package/dist/field/features/blocks/component/FormSavePlugin.d.ts.map +1 -1
  10. package/dist/field/features/blocks/component/FormSavePlugin.js +5 -1
  11. package/dist/field/features/blocks/component/FormSavePlugin.js.map +1 -1
  12. package/dist/field/features/blocks/component/index.d.ts.map +1 -1
  13. package/dist/field/features/blocks/component/index.js +10 -5
  14. package/dist/field/features/blocks/component/index.js.map +1 -1
  15. package/dist/field/features/blocks/component/removeEmptyArrayValues.d.ts +11 -0
  16. package/dist/field/features/blocks/component/removeEmptyArrayValues.d.ts.map +1 -0
  17. package/dist/field/features/blocks/component/removeEmptyArrayValues.js +16 -0
  18. package/dist/field/features/blocks/component/removeEmptyArrayValues.js.map +1 -0
  19. package/dist/field/features/blocks/feature.server.d.ts.map +1 -1
  20. package/dist/field/features/blocks/feature.server.js +29 -1
  21. package/dist/field/features/blocks/feature.server.js.map +1 -1
  22. package/dist/field/features/converters/html/field/index.d.ts +1 -1
  23. package/dist/field/features/converters/html/field/index.d.ts.map +1 -1
  24. package/dist/field/features/converters/html/field/index.js.map +1 -1
  25. package/dist/field/features/link/drawer/index.d.ts.map +1 -1
  26. package/dist/field/features/link/drawer/index.js +4 -0
  27. package/dist/field/features/link/drawer/index.js.map +1 -1
  28. package/dist/field/features/lists/htmlConverter.js +1 -1
  29. package/dist/field/features/lists/htmlConverter.js.map +1 -1
  30. package/dist/field/features/relationship/utils/EnabledRelationshipsCondition.d.ts.map +1 -1
  31. package/dist/field/features/relationship/utils/EnabledRelationshipsCondition.js +6 -5
  32. package/dist/field/features/relationship/utils/EnabledRelationshipsCondition.js.map +1 -1
  33. package/dist/field/features/upload/component/ExtraFieldsDrawer/index.d.ts.map +1 -1
  34. package/dist/field/features/upload/component/ExtraFieldsDrawer/index.js +4 -0
  35. package/dist/field/features/upload/component/ExtraFieldsDrawer/index.js.map +1 -1
  36. package/dist/field/features/upload/component/index.d.ts.map +1 -1
  37. package/dist/field/features/upload/component/index.js +1 -2
  38. package/dist/field/features/upload/component/index.js.map +1 -1
  39. package/dist/field/features/upload/nodes/UploadNode.js +2 -2
  40. package/dist/field/features/upload/nodes/UploadNode.js.map +1 -1
  41. package/dist/field/lexical/plugins/handles/AddBlockHandlePlugin/index.scss +1 -3
  42. package/dist/field/lexical/plugins/handles/DraggableBlockPlugin/index.scss +1 -1
  43. package/dist/field/lexical/ui/icons/Add/index.svg +4 -4
  44. package/dist/field/lexical/ui/icons/DraggableBlock/index.svg +8 -8
  45. package/dist/index.d.ts +3 -17
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +1 -2
  48. package/dist/index.js.map +1 -1
  49. package/dist/types.d.ts +12 -1
  50. package/dist/types.d.ts.map +1 -1
  51. package/dist/types.js.map +1 -1
  52. package/package.json +15 -11
  53. package/src/index.ts +419 -0
@@ -1,9 +1,11 @@
1
1
  import type { FormFieldBase } from '@payloadcms/ui/fields/shared';
2
+ import type { FieldBase } from 'payload/types';
2
3
  import React from 'react';
3
4
  import type { SanitizedClientEditorConfig } from './lexical/config/types.js';
4
5
  import './index.scss';
5
6
  export declare const RichText: React.FC<FormFieldBase & {
6
7
  editorConfig: SanitizedClientEditorConfig;
8
+ label?: FieldBase['label'];
7
9
  name: string;
8
10
  richTextComponentMap: Map<string, React.ReactNode>;
9
11
  width?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"Field.d.ts","sourceRoot":"","sources":["../../src/field/Field.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAA;AAOjE,OAAO,KAAsB,MAAM,OAAO,CAAA;AAG1C,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAA;AAE5E,OAAO,cAAc,CAAA;AAKrB,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAC7B,aAAa,GAAG;IACd,YAAY,EAAE,2BAA2B,CAAA;IACzC,IAAI,EAAE,MAAM,CAAA;IACZ,oBAAoB,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,SAAS,CAAC,CAAA;IAClD,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CA2FF,CAAA"}
1
+ {"version":3,"file":"Field.d.ts","sourceRoot":"","sources":["../../src/field/Field.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAA;AAEjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAQ9C,OAAO,KAAsB,MAAM,OAAO,CAAA;AAG1C,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAA;AAE5E,OAAO,cAAc,CAAA;AA2HrB,eAAO,MAAM,QAAQ;kBApHH,2BAA2B;YACjC,SAAS,CAAC,OAAO,CAAC;UACpB,MAAM;0BACU,IAAI,MAAM,EAAE,MAAM,SAAS,CAAC;YAC1C,MAAM;EAgH8B,CAAA"}
@@ -2,14 +2,16 @@
2
2
  import { FieldDescription } from '@payloadcms/ui/forms/FieldDescription';
3
3
  import { FieldError } from '@payloadcms/ui/forms/FieldError';
4
4
  import { FieldLabel } from '@payloadcms/ui/forms/FieldLabel';
5
+ import { useFieldProps } from '@payloadcms/ui/forms/FieldPropsProvider';
5
6
  import { useField } from '@payloadcms/ui/forms/useField';
7
+ import { withCondition } from '@payloadcms/ui/forms/withCondition';
6
8
  import React, { useCallback } from 'react';
7
9
  import { ErrorBoundary } from 'react-error-boundary';
8
10
  import './index.scss';
9
11
  import { LexicalProvider } from './lexical/LexicalProvider.js';
10
12
  const baseClass = 'rich-text-lexical';
11
- export const RichText = (props)=>{
12
- const { name, CustomDescription, CustomError, CustomLabel, className, descriptionProps, editorConfig, errorProps, labelProps, path: pathFromProps, readOnly, required, style, validate, width } = props;
13
+ const _RichText = (props)=>{
14
+ const { name, CustomDescription, CustomError, CustomLabel, className, descriptionProps, editorConfig, errorProps, label, labelProps, path: pathFromProps, readOnly, required, style, validate, width } = props;
13
15
  const memoizedValidate = useCallback((value, validationOptions)=>{
14
16
  if (typeof validate === 'function') {
15
17
  return validate(value, {
@@ -25,8 +27,9 @@ export const RichText = (props)=>{
25
27
  validate,
26
28
  required
27
29
  ]);
30
+ const { path: pathFromContext } = useFieldProps();
28
31
  const fieldType = useField({
29
- path: pathFromProps || name,
32
+ path: pathFromContext || pathFromProps || name,
30
33
  validate: memoizedValidate
31
34
  });
32
35
  const { errorMessage, initialValue, path, schemaPath, setValue, showError, value } = fieldType;
@@ -46,7 +49,16 @@ export const RichText = (props)=>{
46
49
  }
47
50
  }, /*#__PURE__*/ React.createElement("div", {
48
51
  className: `${baseClass}__wrap`
49
- }, CustomError !== undefined ? CustomError : /*#__PURE__*/ React.createElement(FieldError, errorProps || {}), CustomLabel !== undefined ? CustomLabel : /*#__PURE__*/ React.createElement(FieldLabel, labelProps || {}), /*#__PURE__*/ React.createElement(ErrorBoundary, {
52
+ }, /*#__PURE__*/ React.createElement(FieldError, {
53
+ CustomError: CustomError,
54
+ path: path,
55
+ ...errorProps || {}
56
+ }), /*#__PURE__*/ React.createElement(FieldLabel, {
57
+ CustomLabel: CustomLabel,
58
+ label: label,
59
+ required: required,
60
+ ...labelProps || {}
61
+ }), /*#__PURE__*/ React.createElement(ErrorBoundary, {
50
62
  fallbackRender: fallbackRender,
51
63
  onReset: ()=>{}
52
64
  }, /*#__PURE__*/ React.createElement(LexicalProvider, {
@@ -84,5 +96,6 @@ function fallbackRender({ error }) {
84
96
  }
85
97
  }, error.message));
86
98
  }
99
+ export const RichText = withCondition(_RichText);
87
100
 
88
101
  //# sourceMappingURL=Field.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/field/Field.tsx"],"sourcesContent":["'use client'\nimport type { FormFieldBase } from '@payloadcms/ui/fields/shared'\nimport type { SerializedEditorState } from 'lexical'\n\nimport { FieldDescription } from '@payloadcms/ui/forms/FieldDescription'\nimport { FieldError } from '@payloadcms/ui/forms/FieldError'\nimport { FieldLabel } from '@payloadcms/ui/forms/FieldLabel'\nimport { useField } from '@payloadcms/ui/forms/useField'\nimport React, { useCallback } from 'react'\nimport { ErrorBoundary } from 'react-error-boundary'\n\nimport type { SanitizedClientEditorConfig } from './lexical/config/types.js'\n\nimport './index.scss'\nimport { LexicalProvider } from './lexical/LexicalProvider.js'\n\nconst baseClass = 'rich-text-lexical'\n\nexport const RichText: React.FC<\n FormFieldBase & {\n editorConfig: SanitizedClientEditorConfig // With rendered features n stuff\n name: string\n richTextComponentMap: Map<string, React.ReactNode>\n width?: string\n }\n> = (props) => {\n const {\n name,\n CustomDescription,\n CustomError,\n CustomLabel,\n className,\n descriptionProps,\n editorConfig,\n errorProps,\n labelProps,\n path: pathFromProps,\n readOnly,\n required,\n style,\n validate, // Users can pass in client side validation if they WANT to, but it's not required anymore\n width,\n } = props\n\n const memoizedValidate = useCallback(\n (value, validationOptions) => {\n if (typeof validate === 'function') {\n return validate(value, { ...validationOptions, props, required })\n }\n },\n // Important: do not add props to the dependencies array.\n // This would cause an infinite loop and endless re-rendering.\n // Removing props from the dependencies array fixed this issue: https://github.com/payloadcms/payload/issues/3709\n [validate, required],\n )\n\n const fieldType = useField<SerializedEditorState>({\n path: pathFromProps || name,\n validate: memoizedValidate,\n })\n\n const { errorMessage, initialValue, path, schemaPath, setValue, showError, value } = fieldType\n\n const classes = [\n baseClass,\n 'field-type',\n className,\n showError && 'error',\n readOnly && `${baseClass}--read-only`,\n ]\n .filter(Boolean)\n .join(' ')\n\n return (\n <div\n className={classes}\n key={path}\n style={{\n ...style,\n width,\n }}\n >\n <div className={`${baseClass}__wrap`}>\n {CustomError !== undefined ? CustomError : <FieldError {...(errorProps || {})} />}\n {CustomLabel !== undefined ? CustomLabel : <FieldLabel {...(labelProps || {})} />}\n <ErrorBoundary fallbackRender={fallbackRender} onReset={() => {}}>\n <LexicalProvider\n editorConfig={editorConfig}\n fieldProps={props}\n key={JSON.stringify({ initialValue, path })} // makes sure lexical is completely re-rendered when initialValue changes, bypassing the lexical-internal value memoization. That way, external changes to the form will update the editor. More infos in PR description (https://github.com/payloadcms/payload/pull/5010)\n onChange={(editorState) => {\n let serializedEditorState = editorState.toJSON()\n\n // Transform state through save hooks\n if (editorConfig?.features?.hooks?.save?.length) {\n editorConfig.features.hooks.save.forEach((hook) => {\n serializedEditorState = hook({ incomingEditorState: serializedEditorState })\n })\n }\n\n setValue(serializedEditorState)\n }}\n path={path}\n readOnly={readOnly}\n value={value}\n />\n </ErrorBoundary>\n {CustomDescription !== undefined ? (\n CustomDescription\n ) : (\n <FieldDescription {...(descriptionProps || {})} />\n )}\n </div>\n </div>\n )\n}\n\nfunction fallbackRender({ error }): React.ReactElement {\n // Call resetErrorBoundary() to reset the error boundary and retry the render.\n\n return (\n <div className=\"errorBoundary\" role=\"alert\">\n <p>Something went wrong:</p>\n <pre style={{ color: 'red' }}>{error.message}</pre>\n </div>\n )\n}\n"],"names":["FieldDescription","FieldError","FieldLabel","useField","React","useCallback","ErrorBoundary","LexicalProvider","baseClass","RichText","props","name","CustomDescription","CustomError","CustomLabel","className","descriptionProps","editorConfig","errorProps","labelProps","path","pathFromProps","readOnly","required","style","validate","width","memoizedValidate","value","validationOptions","fieldType","errorMessage","initialValue","schemaPath","setValue","showError","classes","filter","Boolean","join","div","key","undefined","fallbackRender","onReset","fieldProps","JSON","stringify","onChange","editorState","serializedEditorState","toJSON","features","hooks","save","length","forEach","hook","incomingEditorState","error","role","p","pre","color","message"],"mappings":"AAAA;AAIA,SAASA,gBAAgB,QAAQ,wCAAuC;AACxE,SAASC,UAAU,QAAQ,kCAAiC;AAC5D,SAASC,UAAU,QAAQ,kCAAiC;AAC5D,SAASC,QAAQ,QAAQ,gCAA+B;AACxD,OAAOC,SAASC,WAAW,QAAQ,QAAO;AAC1C,SAASC,aAAa,QAAQ,uBAAsB;AAIpD,OAAO,eAAc;AACrB,SAASC,eAAe,QAAQ,+BAA8B;AAE9D,MAAMC,YAAY;AAElB,OAAO,MAAMC,WAOT,CAACC;IACH,MAAM,EACJC,IAAI,EACJC,iBAAiB,EACjBC,WAAW,EACXC,WAAW,EACXC,SAAS,EACTC,gBAAgB,EAChBC,YAAY,EACZC,UAAU,EACVC,UAAU,EACVC,MAAMC,aAAa,EACnBC,QAAQ,EACRC,QAAQ,EACRC,KAAK,EACLC,QAAQ,EACRC,KAAK,EACN,GAAGhB;IAEJ,MAAMiB,mBAAmBtB,YACvB,CAACuB,OAAOC;QACN,IAAI,OAAOJ,aAAa,YAAY;YAClC,OAAOA,SAASG,OAAO;gBAAE,GAAGC,iBAAiB;gBAAEnB;gBAAOa;YAAS;QACjE;IACF,GACA,yDAAyD;IACzD,8DAA8D;IAC9D,iHAAiH;IACjH;QAACE;QAAUF;KAAS;IAGtB,MAAMO,YAAY3B,SAAgC;QAChDiB,MAAMC,iBAAiBV;QACvBc,UAAUE;IACZ;IAEA,MAAM,EAAEI,YAAY,EAAEC,YAAY,EAAEZ,IAAI,EAAEa,UAAU,EAAEC,QAAQ,EAAEC,SAAS,EAAEP,KAAK,EAAE,GAAGE;IAErF,MAAMM,UAAU;QACd5B;QACA;QACAO;QACAoB,aAAa;QACbb,YAAY,CAAC,EAAEd,UAAU,WAAW,CAAC;KACtC,CACE6B,MAAM,CAACC,SACPC,IAAI,CAAC;IAER,qBACE,oBAACC;QACCzB,WAAWqB;QACXK,KAAKrB;QACLI,OAAO;YACL,GAAGA,KAAK;YACRE;QACF;qBAEA,oBAACc;QAAIzB,WAAW,CAAC,EAAEP,UAAU,MAAM,CAAC;OACjCK,gBAAgB6B,YAAY7B,4BAAc,oBAACZ,YAAgBiB,cAAc,CAAC,IAC1EJ,gBAAgB4B,YAAY5B,4BAAc,oBAACZ,YAAgBiB,cAAc,CAAC,kBAC3E,oBAACb;QAAcqC,gBAAgBA;QAAgBC,SAAS,KAAO;qBAC7D,oBAACrC;QACCU,cAAcA;QACd4B,YAAYnC;QACZ+B,KAAKK,KAAKC,SAAS,CAAC;YAAEf;YAAcZ;QAAK;QACzC4B,UAAU,CAACC;YACT,IAAIC,wBAAwBD,YAAYE,MAAM;YAE9C,qCAAqC;YACrC,IAAIlC,cAAcmC,UAAUC,OAAOC,MAAMC,QAAQ;gBAC/CtC,aAAamC,QAAQ,CAACC,KAAK,CAACC,IAAI,CAACE,OAAO,CAAC,CAACC;oBACxCP,wBAAwBO,KAAK;wBAAEC,qBAAqBR;oBAAsB;gBAC5E;YACF;YAEAhB,SAASgB;QACX;QACA9B,MAAMA;QACNE,UAAUA;QACVM,OAAOA;SAGVhB,sBAAsB8B,YACrB9B,kCAEA,oBAACZ,kBAAsBgB,oBAAoB,CAAC;AAKtD,EAAC;AAED,SAAS2B,eAAe,EAAEgB,KAAK,EAAE;IAC/B,8EAA8E;IAE9E,qBACE,oBAACnB;QAAIzB,WAAU;QAAgB6C,MAAK;qBAClC,oBAACC,WAAE,wCACH,oBAACC;QAAItC,OAAO;YAAEuC,OAAO;QAAM;OAAIJ,MAAMK,OAAO;AAGlD"}
1
+ {"version":3,"sources":["../../src/field/Field.tsx"],"sourcesContent":["'use client'\nimport type { FormFieldBase } from '@payloadcms/ui/fields/shared'\nimport type { SerializedEditorState } from 'lexical'\nimport type { FieldBase } from 'payload/types'\n\nimport { FieldDescription } from '@payloadcms/ui/forms/FieldDescription'\nimport { FieldError } from '@payloadcms/ui/forms/FieldError'\nimport { FieldLabel } from '@payloadcms/ui/forms/FieldLabel'\nimport { useFieldProps } from '@payloadcms/ui/forms/FieldPropsProvider'\nimport { useField } from '@payloadcms/ui/forms/useField'\nimport { withCondition } from '@payloadcms/ui/forms/withCondition'\nimport React, { useCallback } from 'react'\nimport { ErrorBoundary } from 'react-error-boundary'\n\nimport type { SanitizedClientEditorConfig } from './lexical/config/types.js'\n\nimport './index.scss'\nimport { LexicalProvider } from './lexical/LexicalProvider.js'\n\nconst baseClass = 'rich-text-lexical'\n\nconst _RichText: React.FC<\n FormFieldBase & {\n editorConfig: SanitizedClientEditorConfig // With rendered features n stuff\n label?: FieldBase['label']\n name: string\n richTextComponentMap: Map<string, React.ReactNode>\n width?: string\n }\n> = (props) => {\n const {\n name,\n CustomDescription,\n CustomError,\n CustomLabel,\n className,\n descriptionProps,\n editorConfig,\n errorProps,\n label,\n labelProps,\n path: pathFromProps,\n readOnly,\n required,\n style,\n validate, // Users can pass in client side validation if they WANT to, but it's not required anymore\n width,\n } = props\n\n const memoizedValidate = useCallback(\n (value, validationOptions) => {\n if (typeof validate === 'function') {\n return validate(value, { ...validationOptions, props, required })\n }\n },\n // Important: do not add props to the dependencies array.\n // This would cause an infinite loop and endless re-rendering.\n // Removing props from the dependencies array fixed this issue: https://github.com/payloadcms/payload/issues/3709\n [validate, required],\n )\n const { path: pathFromContext } = useFieldProps()\n\n const fieldType = useField<SerializedEditorState>({\n path: pathFromContext || pathFromProps || name,\n validate: memoizedValidate,\n })\n\n const { errorMessage, initialValue, path, schemaPath, setValue, showError, value } = fieldType\n\n const classes = [\n baseClass,\n 'field-type',\n className,\n showError && 'error',\n readOnly && `${baseClass}--read-only`,\n ]\n .filter(Boolean)\n .join(' ')\n\n return (\n <div\n className={classes}\n key={path}\n style={{\n ...style,\n width,\n }}\n >\n <div className={`${baseClass}__wrap`}>\n <FieldError CustomError={CustomError} path={path} {...(errorProps || {})} />\n <FieldLabel\n CustomLabel={CustomLabel}\n label={label}\n required={required}\n {...(labelProps || {})}\n />\n <ErrorBoundary fallbackRender={fallbackRender} onReset={() => {}}>\n <LexicalProvider\n editorConfig={editorConfig}\n fieldProps={props}\n key={JSON.stringify({ initialValue, path })} // makes sure lexical is completely re-rendered when initialValue changes, bypassing the lexical-internal value memoization. That way, external changes to the form will update the editor. More infos in PR description (https://github.com/payloadcms/payload/pull/5010)\n onChange={(editorState) => {\n let serializedEditorState = editorState.toJSON()\n\n // Transform state through save hooks\n if (editorConfig?.features?.hooks?.save?.length) {\n editorConfig.features.hooks.save.forEach((hook) => {\n serializedEditorState = hook({ incomingEditorState: serializedEditorState })\n })\n }\n\n setValue(serializedEditorState)\n }}\n path={path}\n readOnly={readOnly}\n value={value}\n />\n </ErrorBoundary>\n {CustomDescription !== undefined ? (\n CustomDescription\n ) : (\n <FieldDescription {...(descriptionProps || {})} />\n )}\n </div>\n </div>\n )\n}\n\nfunction fallbackRender({ error }): React.ReactElement {\n // Call resetErrorBoundary() to reset the error boundary and retry the render.\n\n return (\n <div className=\"errorBoundary\" role=\"alert\">\n <p>Something went wrong:</p>\n <pre style={{ color: 'red' }}>{error.message}</pre>\n </div>\n )\n}\n\nexport const RichText = withCondition(_RichText)\n"],"names":["FieldDescription","FieldError","FieldLabel","useFieldProps","useField","withCondition","React","useCallback","ErrorBoundary","LexicalProvider","baseClass","_RichText","props","name","CustomDescription","CustomError","CustomLabel","className","descriptionProps","editorConfig","errorProps","label","labelProps","path","pathFromProps","readOnly","required","style","validate","width","memoizedValidate","value","validationOptions","pathFromContext","fieldType","errorMessage","initialValue","schemaPath","setValue","showError","classes","filter","Boolean","join","div","key","fallbackRender","onReset","fieldProps","JSON","stringify","onChange","editorState","serializedEditorState","toJSON","features","hooks","save","length","forEach","hook","incomingEditorState","undefined","error","role","p","pre","color","message","RichText"],"mappings":"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"}
@@ -13,7 +13,9 @@ type Props = {
13
13
  formData: BlockFields;
14
14
  formSchema: FieldMap;
15
15
  nodeKey: string;
16
+ path: string;
16
17
  reducedBlock: ReducedBlock;
18
+ schemaPath: string;
17
19
  };
18
20
  /**
19
21
  * The actual content of the Block. This should be INSIDE a Form component,
@@ -1 +1 @@
1
- {"version":3,"file":"BlockContent.d.ts","sourceRoot":"","sources":["../../../../../src/field/features/blocks/component/BlockContent.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAA;AACjE,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,4CAA4C,CAAA;AAYxF,OAAO,KAAsB,MAAM,OAAO,CAAA;AAE1C,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAA;AACnF,OAAO,KAAK,EAAE,WAAW,EAAa,MAAM,wBAAwB,CAAA;AAIpE,KAAK,KAAK,GAAG;IACX,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,aAAa,GAAG;QACrB,YAAY,EAAE,2BAA2B,CAAA;QACzC,IAAI,EAAE,MAAM,CAAA;QACZ,oBAAoB,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,SAAS,CAAC,CAAA;KACnD,CAAA;IACD,QAAQ,EAAE,WAAW,CAAA;IACrB,UAAU,EAAE,QAAQ,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,YAAY,CAAA;CAC3B,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAwMxC,CAAA"}
1
+ {"version":3,"file":"BlockContent.d.ts","sourceRoot":"","sources":["../../../../../src/field/features/blocks/component/BlockContent.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAA;AACjE,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,4CAA4C,CAAA;AAYxF,OAAO,KAAsB,MAAM,OAAO,CAAA;AAE1C,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAA;AACnF,OAAO,KAAK,EAAE,WAAW,EAAa,MAAM,wBAAwB,CAAA;AAIpE,KAAK,KAAK,GAAG;IACX,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,aAAa,GAAG;QACrB,YAAY,EAAE,2BAA2B,CAAA;QACzC,IAAI,EAAE,MAAM,CAAA;QACZ,oBAAoB,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,SAAS,CAAC,CAAA;KACnD,CAAA;IACD,QAAQ,EAAE,WAAW,CAAA;IACrB,UAAU,EAAE,QAAQ,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,EAAE,YAAY,CAAA;IAC1B,UAAU,EAAE,MAAM,CAAA;CACnB,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAyMxC,CAAA"}
@@ -20,7 +20,7 @@ import { FormSavePlugin } from './FormSavePlugin.js';
20
20
  * scoped to the block. All format operations in here are thus scoped to the block's form, and
21
21
  * not the whole document.
22
22
  */ export const BlockContent = (props)=>{
23
- const { baseClass, field, formData, formSchema, nodeKey, reducedBlock: { labels } } = props;
23
+ const { baseClass, field, formData, formSchema, nodeKey, path, reducedBlock: { labels }, schemaPath } = props;
24
24
  const { i18n } = useTranslation();
25
25
  const [editor] = useLexicalComposerContext();
26
26
  // Used for saving collapsed to preferences (and gettin' it from there again)
@@ -50,7 +50,6 @@ import { FormSavePlugin } from './FormSavePlugin.js';
50
50
  newFormData = {
51
51
  ...newFormData,
52
52
  id: formData.id,
53
- blockName: newFormData.blockName2,
54
53
  blockType: formData.blockType
55
54
  };
56
55
  // Recursively remove all undefined values from even being present in formData, as they will
@@ -144,7 +143,7 @@ import { FormSavePlugin } from './FormSavePlugin.js';
144
143
  className: `${baseClass}__block-pill ${baseClass}__block-pill-${formData?.blockType}`,
145
144
  pillStyle: "white"
146
145
  }, typeof labels.singular === 'string' ? getTranslation(labels.singular, i18n) : '[Singular Label]'), /*#__PURE__*/ React.createElement(SectionTitle, {
147
- path: "blockName2",
146
+ path: "blockName",
148
147
  readOnly: field?.readOnly
149
148
  }), fieldHasErrors && /*#__PURE__*/ React.createElement(ErrorPill, {
150
149
  count: errorCount,
@@ -172,9 +171,10 @@ import { FormSavePlugin } from './FormSavePlugin.js';
172
171
  fieldMap: Array.isArray(formSchema) ? formSchema : [],
173
172
  forceRender: true,
174
173
  margins: "small",
175
- path: "",
174
+ path: "" // Leaving path empty makes it so field values are not prefixed / scoped by the entire schemaPath. e.g. we can access "myField" instead of "someLexicalField.feature.blocks.someArrayB" // TODO: Could there be any implications leaving path different than schemaPath?
175
+ ,
176
176
  readOnly: false,
177
- schemaPath: ""
177
+ schemaPath: schemaPath
178
178
  })), /*#__PURE__*/ React.createElement(FormSavePlugin, {
179
179
  onChange: onFormChange
180
180
  }));
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/field/features/blocks/component/BlockContent.tsx"],"sourcesContent":["import type { FormState } from 'payload/types'\nimport type { Data } from 'payload/types'\n\nimport lexicalComposerContextImport from '@lexical/react/LexicalComposerContext.js'\nconst { useLexicalComposerContext } = lexicalComposerContextImport\nimport { getTranslation } from '@payloadcms/translations'\nimport isDeepEqual from 'deep-equal'\nimport lexicalImport from 'lexical'\nconst { $getNodeByKey } = lexicalImport\nimport type { FormFieldBase } from '@payloadcms/ui/fields/shared'\nimport type { FieldMap, ReducedBlock } from '@payloadcms/ui/utilities/buildComponentMap'\nimport type { CollapsedPreferences } from 'payload/types'\n\nimport { Button } from '@payloadcms/ui/elements/Button'\nimport { Collapsible } from '@payloadcms/ui/elements/Collapsible'\nimport { ErrorPill } from '@payloadcms/ui/elements/ErrorPill'\nimport { Pill } from '@payloadcms/ui/elements/Pill'\nimport { SectionTitle } from '@payloadcms/ui/fields/Blocks/SectionTitle'\nimport { useFormSubmitted } from '@payloadcms/ui/forms/Form'\nimport { RenderFields } from '@payloadcms/ui/forms/RenderFields'\nimport { useDocumentInfo } from '@payloadcms/ui/providers/DocumentInfo'\nimport { useTranslation } from '@payloadcms/ui/providers/Translation'\nimport React, { useCallback } from 'react'\n\nimport type { SanitizedClientEditorConfig } from '../../../lexical/config/types.js'\nimport type { BlockFields, BlockNode } from '../nodes/BlocksNode.js'\n\nimport { FormSavePlugin } from './FormSavePlugin.js'\n\ntype Props = {\n baseClass: string\n field: FormFieldBase & {\n editorConfig: SanitizedClientEditorConfig // With rendered features n stuff\n name: string\n richTextComponentMap: Map<string, React.ReactNode>\n }\n formData: BlockFields\n formSchema: FieldMap\n nodeKey: string\n reducedBlock: ReducedBlock\n}\n\n/**\n * The actual content of the Block. This should be INSIDE a Form component,\n * scoped to the block. All format operations in here are thus scoped to the block's form, and\n * not the whole document.\n */\nexport const BlockContent: React.FC<Props> = (props) => {\n const {\n baseClass,\n field,\n formData,\n formSchema,\n nodeKey,\n reducedBlock: { labels },\n } = props\n\n const { i18n } = useTranslation()\n const [editor] = useLexicalComposerContext()\n // Used for saving collapsed to preferences (and gettin' it from there again)\n // Remember, these preferences are scoped to the whole document, not just this form. This\n // is important to consider for the data path used in setDocFieldPreferences\n const { getDocPreferences, setDocFieldPreferences } = useDocumentInfo()\n\n const [collapsed, setCollapsed] = React.useState<boolean>(() => {\n let initialState = false\n\n void getDocPreferences().then((currentDocPreferences) => {\n const currentFieldPreferences = currentDocPreferences?.fields[field.name]\n\n const collapsedArray = currentFieldPreferences?.collapsed\n\n if (collapsedArray && collapsedArray.includes(formData.id)) {\n initialState = true\n setCollapsed(true)\n }\n })\n return initialState\n })\n\n const hasSubmitted = useFormSubmitted()\n\n const [errorCount, setErrorCount] = React.useState(0)\n\n const fieldHasErrors = hasSubmitted && errorCount > 0\n\n const classNames = [\n `${baseClass}__row`,\n fieldHasErrors ? `${baseClass}__row--has-errors` : `${baseClass}__row--no-errors`,\n ]\n .filter(Boolean)\n .join(' ')\n\n const onFormChange = useCallback(\n ({\n fullFieldsWithValues,\n newFormData,\n }: {\n fullFieldsWithValues: FormState\n newFormData: Data\n }) => {\n newFormData = {\n ...newFormData,\n id: formData.id,\n blockName: newFormData.blockName2, // TODO: Find a better solution for this. We have to wrap it in blockName2 when using it here, as blockName does not accept or provide any updated values for some reason.\n blockType: formData.blockType,\n }\n\n // Recursively remove all undefined values from even being present in formData, as they will\n // cause isDeepEqual to return false if, for example, formData has a key that fields.data\n // does not have, even if it's undefined.\n // Currently, this happens if a block has another sub-blocks field. Inside formData, that sub-blocks field has an undefined blockName property.\n // Inside of fields.data however, that sub-blocks blockName property does not exist at all.\n function removeUndefinedAndNullRecursively(obj: object) {\n Object.keys(obj).forEach((key) => {\n if (obj[key] && typeof obj[key] === 'object') {\n removeUndefinedAndNullRecursively(obj[key])\n } else if (obj[key] === undefined || obj[key] === null) {\n delete obj[key]\n }\n })\n }\n removeUndefinedAndNullRecursively(newFormData)\n removeUndefinedAndNullRecursively(formData)\n\n // Only update if the data has actually changed. Otherwise, we may be triggering an unnecessary value change,\n // which would trigger the \"Leave without saving\" dialog unnecessarily\n if (!isDeepEqual(formData, newFormData)) {\n // Running this in the next tick in the meantime fixes this issue: https://github.com/payloadcms/payload/issues/4108\n // I don't know why. When this is called immediately, it might focus out of a nested lexical editor field if an update is made there.\n // My hypothesis is that the nested editor might not have fully finished its update cycle yet. By updating in the next tick, we\n // ensure that the nested editor has finished its update cycle before we update the block node.\n setTimeout(() => {\n editor.update(() => {\n const node: BlockNode = $getNodeByKey(nodeKey)\n if (node) {\n node.setFields(newFormData as BlockFields)\n }\n })\n }, 0)\n }\n\n // update error count\n if (hasSubmitted) {\n let rowErrorCount = 0\n for (const formField of Object.values(fullFieldsWithValues)) {\n if (formField?.valid === false) {\n rowErrorCount++\n }\n }\n setErrorCount(rowErrorCount)\n }\n },\n [editor, nodeKey, hasSubmitted, formData],\n )\n\n const onCollapsedChange = useCallback(\n (changedCollapsed: boolean) => {\n void getDocPreferences().then((currentDocPreferences) => {\n const currentFieldPreferences = currentDocPreferences?.fields[field.name]\n\n const collapsedArray = currentFieldPreferences?.collapsed\n\n const newCollapsed: CollapsedPreferences =\n collapsedArray && collapsedArray?.length ? collapsedArray : []\n\n if (changedCollapsed) {\n if (!newCollapsed.includes(formData.id)) {\n newCollapsed.push(formData.id)\n }\n } else {\n if (newCollapsed.includes(formData.id)) {\n newCollapsed.splice(newCollapsed.indexOf(formData.id), 1)\n }\n }\n\n setDocFieldPreferences(field.name, {\n collapsed: newCollapsed,\n hello: 'hi',\n })\n })\n },\n [getDocPreferences, field.name, setDocFieldPreferences, formData.id],\n )\n\n const removeBlock = useCallback(() => {\n editor.update(() => {\n $getNodeByKey(nodeKey).remove()\n })\n }, [editor, nodeKey])\n\n return (\n <React.Fragment>\n <Collapsible\n className={classNames}\n collapsed={collapsed}\n collapsibleStyle={fieldHasErrors ? 'error' : 'default'}\n header={\n <div className={`${baseClass}__block-header`}>\n <div>\n <Pill\n className={`${baseClass}__block-pill ${baseClass}__block-pill-${formData?.blockType}`}\n pillStyle=\"white\"\n >\n {typeof labels.singular === 'string'\n ? getTranslation(labels.singular, i18n)\n : '[Singular Label]'}\n </Pill>\n <SectionTitle path=\"blockName2\" readOnly={field?.readOnly} />\n {fieldHasErrors && <ErrorPill count={errorCount} i18n={i18n} withMessage />}\n </div>\n {editor.isEditable() && (\n <Button\n buttonStyle=\"icon-label\"\n className={`${baseClass}__removeButton`}\n disabled={field?.readOnly}\n icon=\"x\"\n onClick={(e) => {\n e.preventDefault()\n removeBlock()\n }}\n round\n tooltip=\"Remove Block\"\n />\n )}\n </div>\n }\n key={0}\n onToggle={(collapsed) => {\n onCollapsedChange(collapsed)\n setCollapsed(collapsed)\n }}\n >\n <RenderFields\n className={`${baseClass}__fields`}\n fieldMap={Array.isArray(formSchema) ? formSchema : []}\n forceRender\n margins=\"small\"\n path=\"\"\n readOnly={false}\n schemaPath=\"\"\n />\n </Collapsible>\n\n <FormSavePlugin onChange={onFormChange} />\n </React.Fragment>\n )\n}\n"],"names":["lexicalComposerContextImport","useLexicalComposerContext","getTranslation","isDeepEqual","lexicalImport","$getNodeByKey","Button","Collapsible","ErrorPill","Pill","SectionTitle","useFormSubmitted","RenderFields","useDocumentInfo","useTranslation","React","useCallback","FormSavePlugin","BlockContent","props","baseClass","field","formData","formSchema","nodeKey","reducedBlock","labels","i18n","editor","getDocPreferences","setDocFieldPreferences","collapsed","setCollapsed","useState","initialState","then","currentDocPreferences","currentFieldPreferences","fields","name","collapsedArray","includes","id","hasSubmitted","errorCount","setErrorCount","fieldHasErrors","classNames","filter","Boolean","join","onFormChange","fullFieldsWithValues","newFormData","blockName","blockName2","blockType","removeUndefinedAndNullRecursively","obj","Object","keys","forEach","key","undefined","setTimeout","update","node","setFields","rowErrorCount","formField","values","valid","onCollapsedChange","changedCollapsed","newCollapsed","length","push","splice","indexOf","hello","removeBlock","remove","Fragment","className","collapsibleStyle","header","div","pillStyle","singular","path","readOnly","count","withMessage","isEditable","buttonStyle","disabled","icon","onClick","e","preventDefault","round","tooltip","onToggle","fieldMap","Array","isArray","forceRender","margins","schemaPath","onChange"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../src/field/features/blocks/component/BlockContent.tsx"],"sourcesContent":["import type { FormState } from 'payload/types'\nimport type { Data } from 'payload/types'\n\nimport lexicalComposerContextImport from '@lexical/react/LexicalComposerContext.js'\nconst { useLexicalComposerContext } = lexicalComposerContextImport\nimport { getTranslation } from '@payloadcms/translations'\nimport isDeepEqual from 'deep-equal'\nimport lexicalImport from 'lexical'\nconst { $getNodeByKey } = lexicalImport\nimport type { FormFieldBase } from '@payloadcms/ui/fields/shared'\nimport type { FieldMap, ReducedBlock } from '@payloadcms/ui/utilities/buildComponentMap'\nimport type { CollapsedPreferences } from 'payload/types'\n\nimport { Button } from '@payloadcms/ui/elements/Button'\nimport { Collapsible } from '@payloadcms/ui/elements/Collapsible'\nimport { ErrorPill } from '@payloadcms/ui/elements/ErrorPill'\nimport { Pill } from '@payloadcms/ui/elements/Pill'\nimport { SectionTitle } from '@payloadcms/ui/fields/Blocks/SectionTitle'\nimport { useFormSubmitted } from '@payloadcms/ui/forms/Form'\nimport { RenderFields } from '@payloadcms/ui/forms/RenderFields'\nimport { useDocumentInfo } from '@payloadcms/ui/providers/DocumentInfo'\nimport { useTranslation } from '@payloadcms/ui/providers/Translation'\nimport React, { useCallback } from 'react'\n\nimport type { SanitizedClientEditorConfig } from '../../../lexical/config/types.js'\nimport type { BlockFields, BlockNode } from '../nodes/BlocksNode.js'\n\nimport { FormSavePlugin } from './FormSavePlugin.js'\n\ntype Props = {\n baseClass: string\n field: FormFieldBase & {\n editorConfig: SanitizedClientEditorConfig // With rendered features n stuff\n name: string\n richTextComponentMap: Map<string, React.ReactNode>\n }\n formData: BlockFields\n formSchema: FieldMap\n nodeKey: string\n path: string\n reducedBlock: ReducedBlock\n schemaPath: string\n}\n\n/**\n * The actual content of the Block. This should be INSIDE a Form component,\n * scoped to the block. All format operations in here are thus scoped to the block's form, and\n * not the whole document.\n */\nexport const BlockContent: React.FC<Props> = (props) => {\n const {\n baseClass,\n field,\n formData,\n formSchema,\n nodeKey,\n path,\n reducedBlock: { labels },\n schemaPath,\n } = props\n\n const { i18n } = useTranslation()\n const [editor] = useLexicalComposerContext()\n // Used for saving collapsed to preferences (and gettin' it from there again)\n // Remember, these preferences are scoped to the whole document, not just this form. This\n // is important to consider for the data path used in setDocFieldPreferences\n const { getDocPreferences, setDocFieldPreferences } = useDocumentInfo()\n\n const [collapsed, setCollapsed] = React.useState<boolean>(() => {\n let initialState = false\n\n void getDocPreferences().then((currentDocPreferences) => {\n const currentFieldPreferences = currentDocPreferences?.fields[field.name]\n\n const collapsedArray = currentFieldPreferences?.collapsed\n\n if (collapsedArray && collapsedArray.includes(formData.id)) {\n initialState = true\n setCollapsed(true)\n }\n })\n return initialState\n })\n\n const hasSubmitted = useFormSubmitted()\n\n const [errorCount, setErrorCount] = React.useState(0)\n\n const fieldHasErrors = hasSubmitted && errorCount > 0\n\n const classNames = [\n `${baseClass}__row`,\n fieldHasErrors ? `${baseClass}__row--has-errors` : `${baseClass}__row--no-errors`,\n ]\n .filter(Boolean)\n .join(' ')\n\n const onFormChange = useCallback(\n ({\n fullFieldsWithValues,\n newFormData,\n }: {\n fullFieldsWithValues: FormState\n newFormData: Data\n }) => {\n newFormData = {\n ...newFormData,\n id: formData.id,\n blockType: formData.blockType,\n }\n\n // Recursively remove all undefined values from even being present in formData, as they will\n // cause isDeepEqual to return false if, for example, formData has a key that fields.data\n // does not have, even if it's undefined.\n // Currently, this happens if a block has another sub-blocks field. Inside formData, that sub-blocks field has an undefined blockName property.\n // Inside of fields.data however, that sub-blocks blockName property does not exist at all.\n function removeUndefinedAndNullRecursively(obj: object) {\n Object.keys(obj).forEach((key) => {\n if (obj[key] && typeof obj[key] === 'object') {\n removeUndefinedAndNullRecursively(obj[key])\n } else if (obj[key] === undefined || obj[key] === null) {\n delete obj[key]\n }\n })\n }\n removeUndefinedAndNullRecursively(newFormData)\n removeUndefinedAndNullRecursively(formData)\n\n // Only update if the data has actually changed. Otherwise, we may be triggering an unnecessary value change,\n // which would trigger the \"Leave without saving\" dialog unnecessarily\n if (!isDeepEqual(formData, newFormData)) {\n // Running this in the next tick in the meantime fixes this issue: https://github.com/payloadcms/payload/issues/4108\n // I don't know why. When this is called immediately, it might focus out of a nested lexical editor field if an update is made there.\n // My hypothesis is that the nested editor might not have fully finished its update cycle yet. By updating in the next tick, we\n // ensure that the nested editor has finished its update cycle before we update the block node.\n setTimeout(() => {\n editor.update(() => {\n const node: BlockNode = $getNodeByKey(nodeKey)\n if (node) {\n node.setFields(newFormData as BlockFields)\n }\n })\n }, 0)\n }\n\n // update error count\n if (hasSubmitted) {\n let rowErrorCount = 0\n for (const formField of Object.values(fullFieldsWithValues)) {\n if (formField?.valid === false) {\n rowErrorCount++\n }\n }\n setErrorCount(rowErrorCount)\n }\n },\n [editor, nodeKey, hasSubmitted, formData],\n )\n\n const onCollapsedChange = useCallback(\n (changedCollapsed: boolean) => {\n void getDocPreferences().then((currentDocPreferences) => {\n const currentFieldPreferences = currentDocPreferences?.fields[field.name]\n\n const collapsedArray = currentFieldPreferences?.collapsed\n\n const newCollapsed: CollapsedPreferences =\n collapsedArray && collapsedArray?.length ? collapsedArray : []\n\n if (changedCollapsed) {\n if (!newCollapsed.includes(formData.id)) {\n newCollapsed.push(formData.id)\n }\n } else {\n if (newCollapsed.includes(formData.id)) {\n newCollapsed.splice(newCollapsed.indexOf(formData.id), 1)\n }\n }\n\n setDocFieldPreferences(field.name, {\n collapsed: newCollapsed,\n hello: 'hi',\n })\n })\n },\n [getDocPreferences, field.name, setDocFieldPreferences, formData.id],\n )\n\n const removeBlock = useCallback(() => {\n editor.update(() => {\n $getNodeByKey(nodeKey).remove()\n })\n }, [editor, nodeKey])\n\n return (\n <React.Fragment>\n <Collapsible\n className={classNames}\n collapsed={collapsed}\n collapsibleStyle={fieldHasErrors ? 'error' : 'default'}\n header={\n <div className={`${baseClass}__block-header`}>\n <div>\n <Pill\n className={`${baseClass}__block-pill ${baseClass}__block-pill-${formData?.blockType}`}\n pillStyle=\"white\"\n >\n {typeof labels.singular === 'string'\n ? getTranslation(labels.singular, i18n)\n : '[Singular Label]'}\n </Pill>\n <SectionTitle path=\"blockName\" readOnly={field?.readOnly} />\n {fieldHasErrors && <ErrorPill count={errorCount} i18n={i18n} withMessage />}\n </div>\n {editor.isEditable() && (\n <Button\n buttonStyle=\"icon-label\"\n className={`${baseClass}__removeButton`}\n disabled={field?.readOnly}\n icon=\"x\"\n onClick={(e) => {\n e.preventDefault()\n removeBlock()\n }}\n round\n tooltip=\"Remove Block\"\n />\n )}\n </div>\n }\n key={0}\n onToggle={(collapsed) => {\n onCollapsedChange(collapsed)\n setCollapsed(collapsed)\n }}\n >\n <RenderFields\n className={`${baseClass}__fields`}\n fieldMap={Array.isArray(formSchema) ? formSchema : []}\n forceRender\n margins=\"small\"\n path=\"\" // Leaving path empty makes it so field values are not prefixed / scoped by the entire schemaPath. e.g. we can access \"myField\" instead of \"someLexicalField.feature.blocks.someArrayB\" // TODO: Could there be any implications leaving path different than schemaPath?\n readOnly={false}\n schemaPath={schemaPath} // Having the correct schemaPath here allows sub-fields (like array > addRow) to run correct form-state calls and retrieve their needed form state from the server\n />\n </Collapsible>\n\n <FormSavePlugin onChange={onFormChange} />\n </React.Fragment>\n )\n}\n"],"names":["lexicalComposerContextImport","useLexicalComposerContext","getTranslation","isDeepEqual","lexicalImport","$getNodeByKey","Button","Collapsible","ErrorPill","Pill","SectionTitle","useFormSubmitted","RenderFields","useDocumentInfo","useTranslation","React","useCallback","FormSavePlugin","BlockContent","props","baseClass","field","formData","formSchema","nodeKey","path","reducedBlock","labels","schemaPath","i18n","editor","getDocPreferences","setDocFieldPreferences","collapsed","setCollapsed","useState","initialState","then","currentDocPreferences","currentFieldPreferences","fields","name","collapsedArray","includes","id","hasSubmitted","errorCount","setErrorCount","fieldHasErrors","classNames","filter","Boolean","join","onFormChange","fullFieldsWithValues","newFormData","blockType","removeUndefinedAndNullRecursively","obj","Object","keys","forEach","key","undefined","setTimeout","update","node","setFields","rowErrorCount","formField","values","valid","onCollapsedChange","changedCollapsed","newCollapsed","length","push","splice","indexOf","hello","removeBlock","remove","Fragment","className","collapsibleStyle","header","div","pillStyle","singular","readOnly","count","withMessage","isEditable","buttonStyle","disabled","icon","onClick","e","preventDefault","round","tooltip","onToggle","fieldMap","Array","isArray","forceRender","margins","onChange"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"FormSavePlugin.d.ts","sourceRoot":"","sources":["../../../../../src/field/features/blocks/component/FormSavePlugin.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAM9B,KAAK,KAAK,GAAG;IACX,QAAQ,CAAC,EAAE,CAAC,EACV,oBAAoB,EACpB,WAAW,GACZ,EAAE;QACD,oBAAoB,EAAE,SAAS,CAAA;QAC/B,WAAW,EAAE,IAAI,CAAA;KAClB,KAAK,IAAI,CAAA;CACX,CAAA;AAED,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAgB1C,CAAA"}
1
+ {"version":3,"file":"FormSavePlugin.d.ts","sourceRoot":"","sources":["../../../../../src/field/features/blocks/component/FormSavePlugin.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAQ9B,KAAK,KAAK,GAAG;IACX,QAAQ,CAAC,EAAE,CAAC,EACV,oBAAoB,EACpB,WAAW,GACZ,EAAE;QACD,oBAAoB,EAAE,SAAS,CAAA;QAC/B,WAAW,EAAE,IAAI,CAAA;KAClB,KAAK,IAAI,CAAA;CACX,CAAA;AAED,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAkB1C,CAAA"}
@@ -1,9 +1,13 @@
1
1
  import { useAllFormFields } from '@payloadcms/ui/forms/Form';
2
2
  import { reduceFieldsToValues } from '@payloadcms/ui/utilities/reduceFieldsToValues';
3
3
  import { useEffect } from 'react';
4
+ import { removeEmptyArrayValues } from './removeEmptyArrayValues.js';
4
5
  export const FormSavePlugin = (props)=>{
5
6
  const { onChange } = props;
6
- const [fields, dispatchFields] = useAllFormFields();
7
+ const [_fields] = useAllFormFields();
8
+ const fields = removeEmptyArrayValues({
9
+ fields: _fields
10
+ });
7
11
  // Pass in fields, and indicate if you'd like to "unflatten" field data.
8
12
  // The result below will reflect the data stored in the form at the given time
9
13
  const newFormData = reduceFieldsToValues(fields, true);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/field/features/blocks/component/FormSavePlugin.tsx"],"sourcesContent":["import type { FormState } from 'payload/types'\nimport type { Data } from 'payload/types'\nimport type React from 'react'\n\nimport { useAllFormFields } from '@payloadcms/ui/forms/Form'\nimport { reduceFieldsToValues } from '@payloadcms/ui/utilities/reduceFieldsToValues'\nimport { useEffect } from 'react'\n\ntype Props = {\n onChange?: ({\n fullFieldsWithValues,\n newFormData,\n }: {\n fullFieldsWithValues: FormState\n newFormData: Data\n }) => void\n}\n\nexport const FormSavePlugin: React.FC<Props> = (props) => {\n const { onChange } = props\n\n const [fields, dispatchFields] = useAllFormFields()\n\n // Pass in fields, and indicate if you'd like to \"unflatten\" field data.\n // The result below will reflect the data stored in the form at the given time\n const newFormData = reduceFieldsToValues(fields, true)\n\n useEffect(() => {\n if (onChange) {\n onChange({ fullFieldsWithValues: fields, newFormData })\n }\n }, [newFormData, onChange, fields])\n\n return null\n}\n"],"names":["useAllFormFields","reduceFieldsToValues","useEffect","FormSavePlugin","props","onChange","fields","dispatchFields","newFormData","fullFieldsWithValues"],"mappings":"AAIA,SAASA,gBAAgB,QAAQ,4BAA2B;AAC5D,SAASC,oBAAoB,QAAQ,gDAA+C;AACpF,SAASC,SAAS,QAAQ,QAAO;AAYjC,OAAO,MAAMC,iBAAkC,CAACC;IAC9C,MAAM,EAAEC,QAAQ,EAAE,GAAGD;IAErB,MAAM,CAACE,QAAQC,eAAe,GAAGP;IAEjC,wEAAwE;IACxE,8EAA8E;IAC9E,MAAMQ,cAAcP,qBAAqBK,QAAQ;IAEjDJ,UAAU;QACR,IAAIG,UAAU;YACZA,SAAS;gBAAEI,sBAAsBH;gBAAQE;YAAY;QACvD;IACF,GAAG;QAACA;QAAaH;QAAUC;KAAO;IAElC,OAAO;AACT,EAAC"}
1
+ {"version":3,"sources":["../../../../../src/field/features/blocks/component/FormSavePlugin.tsx"],"sourcesContent":["import type { FormState } from 'payload/types'\nimport type { Data } from 'payload/types'\nimport type React from 'react'\n\nimport { useAllFormFields } from '@payloadcms/ui/forms/Form'\nimport { reduceFieldsToValues } from '@payloadcms/ui/utilities/reduceFieldsToValues'\nimport { useEffect } from 'react'\n\nimport { removeEmptyArrayValues } from './removeEmptyArrayValues.js'\n\ntype Props = {\n onChange?: ({\n fullFieldsWithValues,\n newFormData,\n }: {\n fullFieldsWithValues: FormState\n newFormData: Data\n }) => void\n}\n\nexport const FormSavePlugin: React.FC<Props> = (props) => {\n const { onChange } = props\n\n const [_fields] = useAllFormFields()\n\n const fields = removeEmptyArrayValues({ fields: _fields })\n\n // Pass in fields, and indicate if you'd like to \"unflatten\" field data.\n // The result below will reflect the data stored in the form at the given time\n const newFormData = reduceFieldsToValues(fields, true)\n\n useEffect(() => {\n if (onChange) {\n onChange({ fullFieldsWithValues: fields, newFormData })\n }\n }, [newFormData, onChange, fields])\n\n return null\n}\n"],"names":["useAllFormFields","reduceFieldsToValues","useEffect","removeEmptyArrayValues","FormSavePlugin","props","onChange","_fields","fields","newFormData","fullFieldsWithValues"],"mappings":"AAIA,SAASA,gBAAgB,QAAQ,4BAA2B;AAC5D,SAASC,oBAAoB,QAAQ,gDAA+C;AACpF,SAASC,SAAS,QAAQ,QAAO;AAEjC,SAASC,sBAAsB,QAAQ,8BAA6B;AAYpE,OAAO,MAAMC,iBAAkC,CAACC;IAC9C,MAAM,EAAEC,QAAQ,EAAE,GAAGD;IAErB,MAAM,CAACE,QAAQ,GAAGP;IAElB,MAAMQ,SAASL,uBAAuB;QAAEK,QAAQD;IAAQ;IAExD,wEAAwE;IACxE,8EAA8E;IAC9E,MAAME,cAAcR,qBAAqBO,QAAQ;IAEjDN,UAAU;QACR,IAAII,UAAU;YACZA,SAAS;gBAAEI,sBAAsBF;gBAAQC;YAAY;QACvD;IACF,GAAG;QAACA;QAAaH;QAAUE;KAAO;IAElC,OAAO;AACT,EAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/field/features/blocks/component/index.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAoD,MAAM,OAAO,CAAA;AAExE,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAkBzD,OAAO,cAAc,CAAA;AAErB,KAAK,KAAK,GAAG;IACX,qBAAqB,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAE1B,QAAQ,EAAE,WAAW,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;OAEG;IACH,mBAAmB,EAAE,WAAW,CAAA;CACjC,CAAA;AAED,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAqH1C,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/field/features/blocks/component/index.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAoD,MAAM,OAAO,CAAA;AAExE,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAkBzD,OAAO,cAAc,CAAA;AAGrB,KAAK,KAAK,GAAG;IACX,qBAAqB,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAE1B,QAAQ,EAAE,WAAW,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;OAEG;IACH,mBAAmB,EAAE,WAAW,CAAA;CACjC,CAAA;AAED,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAuH1C,CAAA"}
@@ -11,12 +11,13 @@ import { v4 as uuid } from 'uuid';
11
11
  import { useEditorConfigContext } from '../../../lexical/config/client/EditorConfigProvider.js';
12
12
  import { BlockContent } from './BlockContent.js';
13
13
  import './index.scss';
14
+ import { removeEmptyArrayValues } from './removeEmptyArrayValues.js';
14
15
  export const BlockComponent = (props)=>{
15
16
  const { blockFieldWrapperName, formData, nodeKey } = props;
16
17
  const config = useConfig();
17
18
  const submitted = useFormSubmitted();
18
19
  const { id } = useDocumentInfo();
19
- const { schemaPath } = useFieldProps();
20
+ const { path, schemaPath } = useFieldProps();
20
21
  const { editorConfig, field: parentLexicalRichTextField } = useEditorConfigContext();
21
22
  const [initialState, setInitialState] = useState(false);
22
23
  const { field: { richTextComponentMap } } = useEditorConfigContext();
@@ -40,8 +41,10 @@ export const BlockComponent = (props)=>{
40
41
  ;
41
42
  if (state) {
42
43
  setInitialState({
43
- ...state,
44
- blockName2: {
44
+ ...removeEmptyArrayValues({
45
+ fields: state
46
+ }),
47
+ blockName: {
45
48
  initialValue: '',
46
49
  passesCondition: true,
47
50
  valid: true,
@@ -72,7 +75,7 @@ export const BlockComponent = (props)=>{
72
75
  });
73
76
  return {
74
77
  ...formState,
75
- blockName2: {
78
+ blockName: {
76
79
  initialValue: '',
77
80
  passesCondition: true,
78
81
  valid: true,
@@ -103,7 +106,9 @@ export const BlockComponent = (props)=>{
103
106
  formData: formData,
104
107
  formSchema: Array.isArray(fieldMap) ? fieldMap : [],
105
108
  nodeKey: nodeKey,
106
- reducedBlock: reducedBlock
109
+ path: `${path}.feature.blocks.${formData.blockType}`,
110
+ reducedBlock: reducedBlock,
111
+ schemaPath: schemaFieldsPath
107
112
  }));
108
113
  }, [
109
114
  fieldMap,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/field/features/blocks/component/index.tsx"],"sourcesContent":["'use client'\n\nimport type { FormProps } from '@payloadcms/ui/forms/Form'\n\nimport { Form } from '@payloadcms/ui/forms/Form'\nimport React, { useCallback, useEffect, useMemo, useState } from 'react'\n\nimport { type BlockFields } from '../nodes/BlocksNode.js'\nconst baseClass = 'lexical-block'\n\nimport type { ReducedBlock } from '@payloadcms/ui/utilities/buildComponentMap'\nimport type { FormState } from 'payload/types'\n\nimport { useFieldProps } from '@payloadcms/ui/forms/FieldPropsProvider'\nimport { useFormSubmitted } from '@payloadcms/ui/forms/Form'\nimport { useConfig } from '@payloadcms/ui/providers/Config'\nimport { useDocumentInfo } from '@payloadcms/ui/providers/DocumentInfo'\nimport { getFormState } from '@payloadcms/ui/utilities/getFormState'\nimport { v4 as uuid } from 'uuid'\n\nimport type { ClientComponentProps } from '../../types.js'\nimport type { BlocksFeatureClientProps } from '../feature.client.js'\n\nimport { useEditorConfigContext } from '../../../lexical/config/client/EditorConfigProvider.js'\nimport { BlockContent } from './BlockContent.js'\nimport './index.scss'\n\ntype Props = {\n blockFieldWrapperName: string\n children?: React.ReactNode\n\n formData: BlockFields\n nodeKey?: string\n /**\n * This transformedFormData already comes wrapped in blockFieldWrapperName\n */\n transformedFormData: BlockFields\n}\n\nexport const BlockComponent: React.FC<Props> = (props) => {\n const { blockFieldWrapperName, formData, nodeKey } = props\n const config = useConfig()\n const submitted = useFormSubmitted()\n const { id } = useDocumentInfo()\n const { schemaPath } = useFieldProps()\n const { editorConfig, field: parentLexicalRichTextField } = useEditorConfigContext()\n\n const [initialState, setInitialState] = useState<FormState | false>(false)\n const {\n field: { richTextComponentMap },\n } = useEditorConfigContext()\n\n const componentMapRenderedFieldsPath = `feature.blocks.fields.${formData?.blockType}`\n const schemaFieldsPath = `${schemaPath}.feature.blocks.${formData?.blockType}`\n\n const reducedBlock: ReducedBlock = (\n editorConfig?.resolvedFeatureMap?.get('blocks')\n ?.clientFeatureProps as ClientComponentProps<BlocksFeatureClientProps>\n )?.reducedBlocks?.find((block) => block.slug === formData?.blockType)\n\n const fieldMap = richTextComponentMap.get(componentMapRenderedFieldsPath)\n // Field Schema\n useEffect(() => {\n const awaitInitialState = async () => {\n const state = await getFormState({\n apiRoute: config.routes.api,\n body: {\n id,\n data: JSON.parse(JSON.stringify(formData)),\n operation: 'update',\n schemaPath: schemaFieldsPath,\n },\n serverURL: config.serverURL,\n }) // Form State\n\n if (state) {\n setInitialState({\n ...state,\n blockName2: {\n initialValue: '',\n passesCondition: true,\n valid: true,\n value: formData.blockName,\n },\n })\n }\n }\n\n if (formData) {\n void awaitInitialState()\n }\n }, [config.routes.api, config.serverURL, schemaFieldsPath, id])\n\n const onChange: FormProps['onChange'][0] = useCallback(\n async ({ formState: prevFormState }) => {\n const formState = await getFormState({\n apiRoute: config.routes.api,\n body: {\n id,\n formState: prevFormState,\n operation: 'update',\n schemaPath: schemaFieldsPath,\n },\n serverURL: config.serverURL,\n })\n\n return {\n ...formState,\n blockName2: {\n initialValue: '',\n passesCondition: true,\n valid: true,\n value: formData.blockName,\n },\n }\n },\n\n [config.routes.api, config.serverURL, schemaFieldsPath, id, formData.blockName],\n )\n\n // Memoized Form JSX\n const formContent = useMemo(() => {\n return (\n reducedBlock &&\n initialState !== false && (\n <Form\n // @ts-expect-error TODO: Fix this\n fields={fieldMap}\n initialState={initialState}\n onChange={[onChange]}\n submitted={submitted}\n uuid={uuid()}\n >\n <BlockContent\n baseClass={baseClass}\n field={parentLexicalRichTextField}\n formData={formData}\n formSchema={Array.isArray(fieldMap) ? fieldMap : []}\n nodeKey={nodeKey}\n reducedBlock={reducedBlock}\n />\n </Form>\n )\n )\n }, [\n fieldMap,\n parentLexicalRichTextField,\n nodeKey,\n submitted,\n initialState,\n reducedBlock,\n blockFieldWrapperName,\n onChange,\n ])\n\n return <div className={baseClass}>{formContent}</div>\n}\n"],"names":["Form","React","useCallback","useEffect","useMemo","useState","baseClass","useFieldProps","useFormSubmitted","useConfig","useDocumentInfo","getFormState","v4","uuid","useEditorConfigContext","BlockContent","BlockComponent","props","blockFieldWrapperName","formData","nodeKey","config","submitted","id","schemaPath","editorConfig","field","parentLexicalRichTextField","initialState","setInitialState","richTextComponentMap","componentMapRenderedFieldsPath","blockType","schemaFieldsPath","reducedBlock","resolvedFeatureMap","get","clientFeatureProps","reducedBlocks","find","block","slug","fieldMap","awaitInitialState","state","apiRoute","routes","api","body","data","JSON","parse","stringify","operation","serverURL","blockName2","initialValue","passesCondition","valid","value","blockName","onChange","formState","prevFormState","formContent","fields","formSchema","Array","isArray","div","className"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../src/field/features/blocks/component/index.tsx"],"sourcesContent":["'use client'\n\nimport type { FormProps } from '@payloadcms/ui/forms/Form'\n\nimport { Form } from '@payloadcms/ui/forms/Form'\nimport React, { useCallback, useEffect, useMemo, useState } from 'react'\n\nimport { type BlockFields } from '../nodes/BlocksNode.js'\nconst baseClass = 'lexical-block'\n\nimport type { ReducedBlock } from '@payloadcms/ui/utilities/buildComponentMap'\nimport type { FormState } from 'payload/types'\n\nimport { useFieldProps } from '@payloadcms/ui/forms/FieldPropsProvider'\nimport { useFormSubmitted } from '@payloadcms/ui/forms/Form'\nimport { useConfig } from '@payloadcms/ui/providers/Config'\nimport { useDocumentInfo } from '@payloadcms/ui/providers/DocumentInfo'\nimport { getFormState } from '@payloadcms/ui/utilities/getFormState'\nimport { v4 as uuid } from 'uuid'\n\nimport type { ClientComponentProps } from '../../types.js'\nimport type { BlocksFeatureClientProps } from '../feature.client.js'\n\nimport { useEditorConfigContext } from '../../../lexical/config/client/EditorConfigProvider.js'\nimport { BlockContent } from './BlockContent.js'\nimport './index.scss'\nimport { removeEmptyArrayValues } from './removeEmptyArrayValues.js'\n\ntype Props = {\n blockFieldWrapperName: string\n children?: React.ReactNode\n\n formData: BlockFields\n nodeKey?: string\n /**\n * This transformedFormData already comes wrapped in blockFieldWrapperName\n */\n transformedFormData: BlockFields\n}\n\nexport const BlockComponent: React.FC<Props> = (props) => {\n const { blockFieldWrapperName, formData, nodeKey } = props\n const config = useConfig()\n const submitted = useFormSubmitted()\n const { id } = useDocumentInfo()\n const { path, schemaPath } = useFieldProps()\n const { editorConfig, field: parentLexicalRichTextField } = useEditorConfigContext()\n\n const [initialState, setInitialState] = useState<FormState | false>(false)\n const {\n field: { richTextComponentMap },\n } = useEditorConfigContext()\n\n const componentMapRenderedFieldsPath = `feature.blocks.fields.${formData?.blockType}`\n const schemaFieldsPath = `${schemaPath}.feature.blocks.${formData?.blockType}`\n\n const reducedBlock: ReducedBlock = (\n editorConfig?.resolvedFeatureMap?.get('blocks')\n ?.clientFeatureProps as ClientComponentProps<BlocksFeatureClientProps>\n )?.reducedBlocks?.find((block) => block.slug === formData?.blockType)\n\n const fieldMap = richTextComponentMap.get(componentMapRenderedFieldsPath)\n // Field Schema\n useEffect(() => {\n const awaitInitialState = async () => {\n const state = await getFormState({\n apiRoute: config.routes.api,\n body: {\n id,\n data: JSON.parse(JSON.stringify(formData)),\n operation: 'update',\n schemaPath: schemaFieldsPath,\n },\n serverURL: config.serverURL,\n }) // Form State\n\n if (state) {\n setInitialState({\n ...removeEmptyArrayValues({ fields: state }),\n blockName: {\n initialValue: '',\n passesCondition: true,\n valid: true,\n value: formData.blockName,\n },\n })\n }\n }\n\n if (formData) {\n void awaitInitialState()\n }\n }, [config.routes.api, config.serverURL, schemaFieldsPath, id])\n\n const onChange: FormProps['onChange'][0] = useCallback(\n async ({ formState: prevFormState }) => {\n const formState = await getFormState({\n apiRoute: config.routes.api,\n body: {\n id,\n formState: prevFormState,\n operation: 'update',\n schemaPath: schemaFieldsPath,\n },\n serverURL: config.serverURL,\n })\n\n return {\n ...formState,\n blockName: {\n initialValue: '',\n passesCondition: true,\n valid: true,\n value: formData.blockName,\n },\n }\n },\n\n [config.routes.api, config.serverURL, schemaFieldsPath, id, formData.blockName],\n )\n\n // Memoized Form JSX\n const formContent = useMemo(() => {\n return (\n reducedBlock &&\n initialState !== false && (\n <Form\n // @ts-expect-error TODO: Fix this\n fields={fieldMap}\n initialState={initialState}\n onChange={[onChange]}\n submitted={submitted}\n uuid={uuid()}\n >\n <BlockContent\n baseClass={baseClass}\n field={parentLexicalRichTextField}\n formData={formData}\n formSchema={Array.isArray(fieldMap) ? fieldMap : []}\n nodeKey={nodeKey}\n path={`${path}.feature.blocks.${formData.blockType}`}\n reducedBlock={reducedBlock}\n schemaPath={schemaFieldsPath}\n />\n </Form>\n )\n )\n }, [\n fieldMap,\n parentLexicalRichTextField,\n nodeKey,\n submitted,\n initialState,\n reducedBlock,\n blockFieldWrapperName,\n onChange,\n ])\n\n return <div className={baseClass}>{formContent}</div>\n}\n"],"names":["Form","React","useCallback","useEffect","useMemo","useState","baseClass","useFieldProps","useFormSubmitted","useConfig","useDocumentInfo","getFormState","v4","uuid","useEditorConfigContext","BlockContent","removeEmptyArrayValues","BlockComponent","props","blockFieldWrapperName","formData","nodeKey","config","submitted","id","path","schemaPath","editorConfig","field","parentLexicalRichTextField","initialState","setInitialState","richTextComponentMap","componentMapRenderedFieldsPath","blockType","schemaFieldsPath","reducedBlock","resolvedFeatureMap","get","clientFeatureProps","reducedBlocks","find","block","slug","fieldMap","awaitInitialState","state","apiRoute","routes","api","body","data","JSON","parse","stringify","operation","serverURL","fields","blockName","initialValue","passesCondition","valid","value","onChange","formState","prevFormState","formContent","formSchema","Array","isArray","div","className"],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { FormState } from 'payload/types';
2
+ /**
3
+ * By default, if an array field is empty, it will be included in the form state with a value of 0.
4
+ * We do not need this behavior here, By setting `disableFormData` to true, we can prevent the field from being included in the form state
5
+ * like that.
6
+ * @param fields form state
7
+ */
8
+ export declare function removeEmptyArrayValues({ fields }: {
9
+ fields: FormState;
10
+ }): FormState;
11
+ //# sourceMappingURL=removeEmptyArrayValues.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"removeEmptyArrayValues.d.ts","sourceRoot":"","sources":["../../../../../src/field/features/blocks/component/removeEmptyArrayValues.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAE9C;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GAAG,SAAS,CAQnF"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * By default, if an array field is empty, it will be included in the form state with a value of 0.
3
+ * We do not need this behavior here, By setting `disableFormData` to true, we can prevent the field from being included in the form state
4
+ * like that.
5
+ * @param fields form state
6
+ */ export function removeEmptyArrayValues({ fields }) {
7
+ for(const key in fields){
8
+ const field = fields[key];
9
+ if (Array.isArray(field.rows) && 'value' in field) {
10
+ field.disableFormData = true;
11
+ }
12
+ }
13
+ return fields;
14
+ }
15
+
16
+ //# sourceMappingURL=removeEmptyArrayValues.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/field/features/blocks/component/removeEmptyArrayValues.ts"],"sourcesContent":["import type { FormState } from 'payload/types'\n\n/**\n * By default, if an array field is empty, it will be included in the form state with a value of 0.\n * We do not need this behavior here, By setting `disableFormData` to true, we can prevent the field from being included in the form state\n * like that.\n * @param fields form state\n */\nexport function removeEmptyArrayValues({ fields }: { fields: FormState }): FormState {\n for (const key in fields) {\n const field = fields[key]\n if (Array.isArray(field.rows) && 'value' in field) {\n field.disableFormData = true\n }\n }\n return fields\n}\n"],"names":["removeEmptyArrayValues","fields","key","field","Array","isArray","rows","disableFormData"],"mappings":"AAEA;;;;;CAKC,GACD,OAAO,SAASA,uBAAuB,EAAEC,MAAM,EAAyB;IACtE,IAAK,MAAMC,OAAOD,OAAQ;QACxB,MAAME,QAAQF,MAAM,CAACC,IAAI;QACzB,IAAIE,MAAMC,OAAO,CAACF,MAAMG,IAAI,KAAK,WAAWH,OAAO;YACjDA,MAAMI,eAAe,GAAG;QAC1B;IACF;IACA,OAAON;AACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"feature.server.d.ts","sourceRoot":"","sources":["../../../../src/field/features/blocks/feature.server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAqB,MAAM,eAAe,CAAA;AAK7D,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,aAAa,CAAA;AAChE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;AAQnE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,KAAK,EAAE,CAAA;CAChB,CAAA;AAED,eAAO,MAAM,aAAa,EAAE,6BAA6B,CACvD,kBAAkB,EAClB,wBAAwB,CAyGzB,CAAA"}
1
+ {"version":3,"file":"feature.server.d.ts","sourceRoot":"","sources":["../../../../src/field/features/blocks/feature.server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAqB,MAAM,eAAe,CAAA;AAK7D,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,aAAa,CAAA;AAChE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;AAQnE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,KAAK,EAAE,CAAA;CAChB,CAAA;AAED,eAAO,MAAM,aAAa,EAAE,6BAA6B,CACvD,kBAAkB,EAClB,wBAAwB,CAuIzB,CAAA"}
@@ -37,10 +37,38 @@ export const BlocksFeature = (props)=>{
37
37
  return {
38
38
  ClientComponent: BlocksFeatureClientComponent,
39
39
  clientFeatureProps: clientProps,
40
- generateSchemaMap: ({ props })=>{
40
+ generateSchemaMap: ({ config, props, schemaMap: schemaMapFromProps, schemaPath })=>{
41
41
  const schemaMap = {};
42
+ /**
43
+ * Add sub-fields to the schemaMap. E.g. if you have an array field as part of the block and it runs addRow, it will request these
44
+ * sub-fields from the component map. Thus we need to put them in the component map here.
45
+ */ const handleFields = (parentPath, fields)=>{
46
+ for (const field of fields){
47
+ if ('name' in field && 'fields' in field) {
48
+ schemaMap[parentPath + '.' + field.name] = field.fields;
49
+ handleFields(parentPath + '.' + field.name, field.fields);
50
+ }
51
+ if ('blocks' in field) {
52
+ for (const block of field.blocks){
53
+ schemaMap[parentPath + '.' + field.name + '.' + block.slug] = block.fields || [];
54
+ handleFields(parentPath + '.' + field.name + '.' + block.slug, block.fields);
55
+ }
56
+ }
57
+ if ('tabs' in field) {
58
+ for (const tab of field.tabs){
59
+ if ('name' in tab) {
60
+ schemaMap[parentPath + '.' + tab.name] = tab.fields || [];
61
+ handleFields(parentPath + '.' + tab.name, tab.fields);
62
+ } else {
63
+ handleFields(parentPath, tab.fields);
64
+ }
65
+ }
66
+ }
67
+ }
68
+ };
42
69
  for (const block of props.blocks){
43
70
  schemaMap[block.slug] = block.fields || [];
71
+ handleFields(block.slug, block.fields);
44
72
  }
45
73
  return schemaMap;
46
74
  },
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/field/features/blocks/feature.server.ts"],"sourcesContent":["import type { Block, BlockField, Field } from 'payload/types'\n\nimport { baseBlockFields, sanitizeFields } from 'payload/config'\nimport { fieldsToJSONSchema, formatLabels } from 'payload/utilities'\n\nimport type { FeatureProviderProviderServer } from '../types.js'\nimport type { BlocksFeatureClientProps } from './feature.client.js'\n\nimport { cloneDeep } from '../../lexical/utils/cloneDeep.js'\nimport { BlocksFeatureClientComponent } from './feature.client.js'\nimport { BlockNode } from './nodes/BlocksNode.js'\nimport { blockPopulationPromiseHOC } from './populationPromise.js'\nimport { blockValidationHOC } from './validate.js'\n\nexport type BlocksFeatureProps = {\n blocks: Block[]\n}\n\nexport const BlocksFeature: FeatureProviderProviderServer<\n BlocksFeatureProps,\n BlocksFeatureClientProps\n> = (props) => {\n // Sanitization taken from payload/src/fields/config/sanitize.ts\n\n if (props?.blocks?.length) {\n props.blocks = props.blocks.map((block) => {\n const blockCopy = cloneDeep(block)\n\n return {\n ...blockCopy,\n fields: blockCopy.fields.concat(baseBlockFields),\n labels: !blockCopy.labels ? formatLabels(blockCopy.slug) : blockCopy.labels,\n }\n })\n // unSanitizedBlock.fields are sanitized in the React component and not here.\n // That's because we do not have access to the payload config here.\n }\n\n // Build clientProps\n const clientProps: BlocksFeatureClientProps = {\n reducedBlocks: [],\n }\n for (const block of props.blocks) {\n clientProps.reducedBlocks.push({\n slug: block.slug,\n fieldMap: [],\n imageAltText: block.imageAltText,\n imageURL: block.imageURL,\n labels: block.labels,\n })\n }\n\n return {\n feature: () => {\n return {\n ClientComponent: BlocksFeatureClientComponent,\n clientFeatureProps: clientProps,\n generateSchemaMap: ({ props }) => {\n const schemaMap: {\n [key: string]: Field[]\n } = {}\n\n for (const block of props.blocks) {\n schemaMap[block.slug] = block.fields || []\n }\n\n return schemaMap\n },\n generatedTypes: {\n modifyOutputSchema: ({\n collectionIDFieldTypes,\n config,\n currentSchema,\n field,\n interfaceNameDefinitions,\n }) => {\n if (!props?.blocks?.length) {\n return currentSchema\n }\n\n // sanitize blocks\n const validRelationships = config.collections.map((c) => c.slug) || []\n\n const sanitizedBlocks = props.blocks.map((block) => {\n const blockCopy = cloneDeep(block)\n return {\n ...blockCopy,\n fields: sanitizeFields({\n config,\n fields: blockCopy.fields,\n validRelationships,\n }),\n }\n })\n\n const blocksField: BlockField = {\n name: field?.name + '_lexical_blocks',\n type: 'blocks',\n blocks: sanitizedBlocks,\n }\n // This is only done so that interfaceNameDefinitions sets those block's interfaceNames.\n // we don't actually use the JSON Schema itself in the generated types yet.\n fieldsToJSONSchema(\n collectionIDFieldTypes,\n [blocksField],\n interfaceNameDefinitions,\n config,\n )\n\n return currentSchema\n },\n },\n nodes: [\n {\n node: BlockNode,\n populationPromises: [blockPopulationPromiseHOC(props)],\n validations: [blockValidationHOC(props)],\n },\n ],\n serverFeatureProps: props,\n }\n },\n key: 'blocks',\n serverFeatureProps: props,\n }\n}\n"],"names":["baseBlockFields","sanitizeFields","fieldsToJSONSchema","formatLabels","cloneDeep","BlocksFeatureClientComponent","BlockNode","blockPopulationPromiseHOC","blockValidationHOC","BlocksFeature","props","blocks","length","map","block","blockCopy","fields","concat","labels","slug","clientProps","reducedBlocks","push","fieldMap","imageAltText","imageURL","feature","ClientComponent","clientFeatureProps","generateSchemaMap","schemaMap","generatedTypes","modifyOutputSchema","collectionIDFieldTypes","config","currentSchema","field","interfaceNameDefinitions","validRelationships","collections","c","sanitizedBlocks","blocksField","name","type","nodes","node","populationPromises","validations","serverFeatureProps","key"],"mappings":"AAEA,SAASA,eAAe,EAAEC,cAAc,QAAQ,iBAAgB;AAChE,SAASC,kBAAkB,EAAEC,YAAY,QAAQ,oBAAmB;AAKpE,SAASC,SAAS,QAAQ,mCAAkC;AAC5D,SAASC,4BAA4B,QAAQ,sBAAqB;AAClE,SAASC,SAAS,QAAQ,wBAAuB;AACjD,SAASC,yBAAyB,QAAQ,yBAAwB;AAClE,SAASC,kBAAkB,QAAQ,gBAAe;AAMlD,OAAO,MAAMC,gBAGT,CAACC;IACH,gEAAgE;IAEhE,IAAIA,OAAOC,QAAQC,QAAQ;QACzBF,MAAMC,MAAM,GAAGD,MAAMC,MAAM,CAACE,GAAG,CAAC,CAACC;YAC/B,MAAMC,YAAYX,UAAUU;YAE5B,OAAO;gBACL,GAAGC,SAAS;gBACZC,QAAQD,UAAUC,MAAM,CAACC,MAAM,CAACjB;gBAChCkB,QAAQ,CAACH,UAAUG,MAAM,GAAGf,aAAaY,UAAUI,IAAI,IAAIJ,UAAUG,MAAM;YAC7E;QACF;IACA,8EAA8E;IAC9E,mEAAmE;IACrE;IAEA,oBAAoB;IACpB,MAAME,cAAwC;QAC5CC,eAAe,EAAE;IACnB;IACA,KAAK,MAAMP,SAASJ,MAAMC,MAAM,CAAE;QAChCS,YAAYC,aAAa,CAACC,IAAI,CAAC;YAC7BH,MAAML,MAAMK,IAAI;YAChBI,UAAU,EAAE;YACZC,cAAcV,MAAMU,YAAY;YAChCC,UAAUX,MAAMW,QAAQ;YACxBP,QAAQJ,MAAMI,MAAM;QACtB;IACF;IAEA,OAAO;QACLQ,SAAS;YACP,OAAO;gBACLC,iBAAiBtB;gBACjBuB,oBAAoBR;gBACpBS,mBAAmB,CAAC,EAAEnB,KAAK,EAAE;oBAC3B,MAAMoB,YAEF,CAAC;oBAEL,KAAK,MAAMhB,SAASJ,MAAMC,MAAM,CAAE;wBAChCmB,SAAS,CAAChB,MAAMK,IAAI,CAAC,GAAGL,MAAME,MAAM,IAAI,EAAE;oBAC5C;oBAEA,OAAOc;gBACT;gBACAC,gBAAgB;oBACdC,oBAAoB,CAAC,EACnBC,sBAAsB,EACtBC,MAAM,EACNC,aAAa,EACbC,KAAK,EACLC,wBAAwB,EACzB;wBACC,IAAI,CAAC3B,OAAOC,QAAQC,QAAQ;4BAC1B,OAAOuB;wBACT;wBAEA,kBAAkB;wBAClB,MAAMG,qBAAqBJ,OAAOK,WAAW,CAAC1B,GAAG,CAAC,CAAC2B,IAAMA,EAAErB,IAAI,KAAK,EAAE;wBAEtE,MAAMsB,kBAAkB/B,MAAMC,MAAM,CAACE,GAAG,CAAC,CAACC;4BACxC,MAAMC,YAAYX,UAAUU;4BAC5B,OAAO;gCACL,GAAGC,SAAS;gCACZC,QAAQf,eAAe;oCACrBiC;oCACAlB,QAAQD,UAAUC,MAAM;oCACxBsB;gCACF;4BACF;wBACF;wBAEA,MAAMI,cAA0B;4BAC9BC,MAAMP,OAAOO,OAAO;4BACpBC,MAAM;4BACNjC,QAAQ8B;wBACV;wBACA,wFAAwF;wBACxF,2EAA2E;wBAC3EvC,mBACE+B,wBACA;4BAACS;yBAAY,EACbL,0BACAH;wBAGF,OAAOC;oBACT;gBACF;gBACAU,OAAO;oBACL;wBACEC,MAAMxC;wBACNyC,oBAAoB;4BAACxC,0BAA0BG;yBAAO;wBACtDsC,aAAa;4BAACxC,mBAAmBE;yBAAO;oBAC1C;iBACD;gBACDuC,oBAAoBvC;YACtB;QACF;QACAwC,KAAK;QACLD,oBAAoBvC;IACtB;AACF,EAAC"}
1
+ {"version":3,"sources":["../../../../src/field/features/blocks/feature.server.ts"],"sourcesContent":["import type { Block, BlockField, Field } from 'payload/types'\n\nimport { baseBlockFields, sanitizeFields } from 'payload/config'\nimport { fieldsToJSONSchema, formatLabels } from 'payload/utilities'\n\nimport type { FeatureProviderProviderServer } from '../types.js'\nimport type { BlocksFeatureClientProps } from './feature.client.js'\n\nimport { cloneDeep } from '../../lexical/utils/cloneDeep.js'\nimport { BlocksFeatureClientComponent } from './feature.client.js'\nimport { BlockNode } from './nodes/BlocksNode.js'\nimport { blockPopulationPromiseHOC } from './populationPromise.js'\nimport { blockValidationHOC } from './validate.js'\n\nexport type BlocksFeatureProps = {\n blocks: Block[]\n}\n\nexport const BlocksFeature: FeatureProviderProviderServer<\n BlocksFeatureProps,\n BlocksFeatureClientProps\n> = (props) => {\n // Sanitization taken from payload/src/fields/config/sanitize.ts\n\n if (props?.blocks?.length) {\n props.blocks = props.blocks.map((block) => {\n const blockCopy = cloneDeep(block)\n\n return {\n ...blockCopy,\n fields: blockCopy.fields.concat(baseBlockFields),\n labels: !blockCopy.labels ? formatLabels(blockCopy.slug) : blockCopy.labels,\n }\n })\n // unSanitizedBlock.fields are sanitized in the React component and not here.\n // That's because we do not have access to the payload config here.\n }\n\n // Build clientProps\n const clientProps: BlocksFeatureClientProps = {\n reducedBlocks: [],\n }\n for (const block of props.blocks) {\n clientProps.reducedBlocks.push({\n slug: block.slug,\n fieldMap: [],\n imageAltText: block.imageAltText,\n imageURL: block.imageURL,\n labels: block.labels,\n })\n }\n\n return {\n feature: () => {\n return {\n ClientComponent: BlocksFeatureClientComponent,\n clientFeatureProps: clientProps,\n generateSchemaMap: ({ config, props, schemaMap: schemaMapFromProps, schemaPath }) => {\n const schemaMap: {\n [key: string]: Field[]\n } = {}\n\n /**\n * Add sub-fields to the schemaMap. E.g. if you have an array field as part of the block and it runs addRow, it will request these\n * sub-fields from the component map. Thus we need to put them in the component map here.\n */\n const handleFields = (parentPath: string, fields: Field[]) => {\n for (const field of fields) {\n if ('name' in field && 'fields' in field) {\n schemaMap[parentPath + '.' + field.name] = field.fields\n handleFields(parentPath + '.' + field.name, field.fields)\n }\n if ('blocks' in field) {\n for (const block of field.blocks) {\n schemaMap[parentPath + '.' + field.name + '.' + block.slug] = block.fields || []\n handleFields(parentPath + '.' + field.name + '.' + block.slug, block.fields)\n }\n }\n if ('tabs' in field) {\n for (const tab of field.tabs) {\n if ('name' in tab) {\n schemaMap[parentPath + '.' + tab.name] = tab.fields || []\n handleFields(parentPath + '.' + tab.name, tab.fields)\n } else {\n handleFields(parentPath, tab.fields)\n }\n }\n }\n }\n }\n\n for (const block of props.blocks) {\n schemaMap[block.slug] = block.fields || []\n handleFields(block.slug, block.fields)\n }\n\n return schemaMap\n },\n generatedTypes: {\n modifyOutputSchema: ({\n collectionIDFieldTypes,\n config,\n currentSchema,\n field,\n interfaceNameDefinitions,\n }) => {\n if (!props?.blocks?.length) {\n return currentSchema\n }\n\n // sanitize blocks\n const validRelationships = config.collections.map((c) => c.slug) || []\n\n const sanitizedBlocks = props.blocks.map((block) => {\n const blockCopy = cloneDeep(block)\n return {\n ...blockCopy,\n fields: sanitizeFields({\n config,\n fields: blockCopy.fields,\n validRelationships,\n }),\n }\n })\n\n const blocksField: BlockField = {\n name: field?.name + '_lexical_blocks',\n type: 'blocks',\n blocks: sanitizedBlocks,\n }\n // This is only done so that interfaceNameDefinitions sets those block's interfaceNames.\n // we don't actually use the JSON Schema itself in the generated types yet.\n fieldsToJSONSchema(\n collectionIDFieldTypes,\n [blocksField],\n interfaceNameDefinitions,\n config,\n )\n\n return currentSchema\n },\n },\n nodes: [\n {\n node: BlockNode,\n populationPromises: [blockPopulationPromiseHOC(props)],\n validations: [blockValidationHOC(props)],\n },\n ],\n serverFeatureProps: props,\n }\n },\n key: 'blocks',\n serverFeatureProps: props,\n }\n}\n"],"names":["baseBlockFields","sanitizeFields","fieldsToJSONSchema","formatLabels","cloneDeep","BlocksFeatureClientComponent","BlockNode","blockPopulationPromiseHOC","blockValidationHOC","BlocksFeature","props","blocks","length","map","block","blockCopy","fields","concat","labels","slug","clientProps","reducedBlocks","push","fieldMap","imageAltText","imageURL","feature","ClientComponent","clientFeatureProps","generateSchemaMap","config","schemaMap","schemaMapFromProps","schemaPath","handleFields","parentPath","field","name","tab","tabs","generatedTypes","modifyOutputSchema","collectionIDFieldTypes","currentSchema","interfaceNameDefinitions","validRelationships","collections","c","sanitizedBlocks","blocksField","type","nodes","node","populationPromises","validations","serverFeatureProps","key"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import type { TextField } from 'payload/types';
2
- import type { SanitizedServerEditorConfig } from '../../../../../index.js';
2
+ import type { SanitizedServerEditorConfig } from '../../../../lexical/config/types.js';
3
3
  import type { HTMLConverter } from '../converter/types.js';
4
4
  type Props = {
5
5
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/field/features/converters/html/field/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAwB,SAAS,EAAE,MAAM,eAAe,CAAA;AAEpE,OAAO,KAAK,EAA0B,2BAA2B,EAAE,MAAM,yBAAyB,CAAA;AAElG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAM1D,KAAK,KAAK,GAAG;IACX,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,yBAAyB;kBAGtB,2BAA2B;qBAsB1C,CAAA;AAED,eAAO,MAAM,WAAW,EAAE;AACxB;;;;IAII;AACJ,gBAAgB,EAAE,MAAM,EACxB,KAAK,EAAE,KAAK,KACT,SAsHJ,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/field/features/converters/html/field/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAwB,SAAS,EAAE,MAAM,eAAe,CAAA;AAGpE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAA;AACtF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAM1D,KAAK,KAAK,GAAG;IACX,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,yBAAyB;kBAGtB,2BAA2B;qBAsB1C,CAAA;AAED,eAAO,MAAM,WAAW,EAAE;AACxB;;;;IAII;AACJ,gBAAgB,EAAE,MAAM,EACxB,KAAK,EAAE,KAAK,KACT,SAsHJ,CAAA"}