@payloadcms/plugin-seo 3.0.0-canary.f6e77b8 → 3.0.0-canary.fb81f02
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/defaults.js.map +1 -1
- package/dist/exports/fields.d.ts +6 -0
- package/dist/exports/fields.d.ts.map +1 -0
- package/dist/exports/fields.js +7 -0
- package/dist/exports/fields.js.map +1 -0
- package/dist/exports/types.js.map +1 -1
- package/dist/fields/MetaDescription/MetaDescriptionComponent.d.ts +9 -0
- package/dist/fields/MetaDescription/MetaDescriptionComponent.d.ts.map +1 -0
- package/dist/fields/MetaDescription/MetaDescriptionComponent.js +138 -0
- package/dist/fields/MetaDescription/MetaDescriptionComponent.js.map +1 -0
- package/dist/fields/MetaDescription/index.d.ts +12 -0
- package/dist/fields/MetaDescription/index.d.ts.map +1 -0
- package/dist/fields/MetaDescription/index.js +23 -0
- package/dist/fields/MetaDescription/index.js.map +1 -0
- package/dist/fields/MetaImage/MetaImageComponent.d.ts +8 -0
- package/dist/fields/MetaImage/MetaImageComponent.d.ts.map +1 -0
- package/dist/fields/MetaImage/MetaImageComponent.js +142 -0
- package/dist/fields/MetaImage/MetaImageComponent.js.map +1 -0
- package/dist/fields/MetaImage/index.d.ts +13 -0
- package/dist/fields/MetaImage/index.d.ts.map +1 -0
- package/dist/fields/MetaImage/index.js +26 -0
- package/dist/fields/MetaImage/index.js.map +1 -0
- package/dist/fields/MetaTitle/MetaTitleComponent.d.ts +9 -0
- package/dist/fields/MetaTitle/MetaTitleComponent.d.ts.map +1 -0
- package/dist/fields/MetaTitle/MetaTitleComponent.js +140 -0
- package/dist/fields/MetaTitle/MetaTitleComponent.js.map +1 -0
- package/dist/fields/MetaTitle/index.d.ts +12 -0
- package/dist/fields/MetaTitle/index.d.ts.map +1 -0
- package/dist/fields/MetaTitle/index.js +23 -0
- package/dist/fields/MetaTitle/index.js.map +1 -0
- package/dist/fields/Overview/OverviewComponent.d.ts +10 -0
- package/dist/fields/Overview/OverviewComponent.d.ts.map +1 -0
- package/dist/{ui/Overview.js → fields/Overview/OverviewComponent.js} +18 -12
- package/dist/fields/Overview/OverviewComponent.js.map +1 -0
- package/dist/fields/Overview/index.d.ts +26 -0
- package/dist/fields/Overview/index.d.ts.map +1 -0
- package/dist/fields/Overview/index.js +25 -0
- package/dist/fields/Overview/index.js.map +1 -0
- package/dist/fields/Preview/PreviewComponent.d.ts +10 -0
- package/dist/fields/Preview/PreviewComponent.d.ts.map +1 -0
- package/dist/fields/Preview/PreviewComponent.js +101 -0
- package/dist/fields/Preview/PreviewComponent.js.map +1 -0
- package/dist/fields/Preview/index.d.ts +24 -0
- package/dist/fields/Preview/index.d.ts.map +1 -0
- package/dist/fields/Preview/index.js +25 -0
- package/dist/fields/Preview/index.js.map +1 -0
- package/dist/fields/index.scss +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +42 -42
- package/dist/index.js.map +1 -1
- package/dist/translations/index.d.ts +25 -0
- package/dist/translations/index.d.ts.map +1 -1
- package/dist/translations/index.js +22 -0
- package/dist/translations/index.js.map +1 -1
- package/dist/translations/ru.json +22 -0
- package/dist/types.d.ts +10 -10
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/ui/LengthIndicator.d.ts.map +1 -1
- package/dist/ui/LengthIndicator.js +62 -41
- package/dist/ui/LengthIndicator.js.map +1 -1
- package/dist/ui/Pill.js +7 -3
- package/dist/ui/Pill.js.map +1 -1
- package/package.json +30 -19
- package/dist/fields/MetaDescription.d.ts +0 -9
- package/dist/fields/MetaDescription.d.ts.map +0 -1
- package/dist/fields/MetaDescription.js +0 -116
- package/dist/fields/MetaDescription.js.map +0 -1
- package/dist/fields/MetaImage.d.ts +0 -8
- package/dist/fields/MetaImage.d.ts.map +0 -1
- package/dist/fields/MetaImage.js +0 -120
- package/dist/fields/MetaImage.js.map +0 -1
- package/dist/fields/MetaTitle.d.ts +0 -9
- package/dist/fields/MetaTitle.d.ts.map +0 -1
- package/dist/fields/MetaTitle.js +0 -117
- package/dist/fields/MetaTitle.js.map +0 -1
- package/dist/ui/Overview.d.ts +0 -3
- package/dist/ui/Overview.d.ts.map +0 -1
- package/dist/ui/Overview.js.map +0 -1
- package/dist/ui/Preview.d.ts +0 -8
- package/dist/ui/Preview.d.ts.map +0 -1
- package/dist/ui/Preview.js +0 -79
- package/dist/ui/Preview.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/fields/MetaTitle/MetaTitleComponent.tsx"],"sourcesContent":["'use client'\n\nimport type { FieldType, Options } from '@payloadcms/ui'\nimport type { FormFieldBase } from 'payload'\n\nimport {\n FieldLabel,\n TextInput,\n useDocumentInfo,\n useField,\n useFieldProps,\n useForm,\n useLocale,\n useTranslation,\n} from '@payloadcms/ui'\nimport React, { useCallback } from 'react'\n\nimport type { PluginSEOTranslationKeys, PluginSEOTranslations } from '../../translations/index.js'\nimport type { GenerateTitle } from '../../types.js'\n\nimport { defaults } from '../../defaults.js'\nimport { LengthIndicator } from '../../ui/LengthIndicator.js'\nimport '../index.scss'\n\nconst { maxLength, minLength } = defaults.title\n\ntype MetaTitleProps = {\n hasGenerateTitleFn: boolean\n} & FormFieldBase\n\nexport const MetaTitleComponent: React.FC<MetaTitleProps> = (props) => {\n const { CustomLabel, hasGenerateTitleFn, label, labelProps, required } = props || {}\n const { path: pathFromContext } = useFieldProps()\n\n const { t } = useTranslation<PluginSEOTranslations, PluginSEOTranslationKeys>()\n\n const field: FieldType<string> = useField({\n path: pathFromContext,\n } as Options)\n\n const locale = useLocale()\n const { getData } = useForm()\n const docInfo = useDocumentInfo()\n\n const { errorMessage, setValue, showError, value } = field\n\n const regenerateTitle = useCallback(async () => {\n if (!hasGenerateTitleFn) return\n\n const genTitleResponse = await fetch('/api/plugin-seo/generate-title', {\n body: JSON.stringify({\n ...docInfo,\n doc: { ...getData() },\n locale: typeof locale === 'object' ? locale?.code : locale,\n } satisfies Parameters<GenerateTitle>[0]),\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n })\n\n const { result: generatedTitle } = await genTitleResponse.json()\n\n setValue(generatedTitle || '')\n }, [hasGenerateTitleFn, docInfo, getData, locale, setValue])\n\n return (\n <div\n style={{\n marginBottom: '20px',\n }}\n >\n <div\n style={{\n marginBottom: '5px',\n position: 'relative',\n }}\n >\n <div className=\"plugin-seo__field\">\n <FieldLabel CustomLabel={CustomLabel} label={label} {...(labelProps || {})} />\n {hasGenerateTitleFn && (\n <React.Fragment>\n — \n <button\n onClick={() => {\n void regenerateTitle()\n }}\n style={{\n background: 'none',\n backgroundColor: 'transparent',\n border: 'none',\n color: 'currentcolor',\n cursor: 'pointer',\n padding: 0,\n textDecoration: 'underline',\n }}\n type=\"button\"\n >\n {t('plugin-seo:autoGenerate')}\n </button>\n </React.Fragment>\n )}\n </div>\n <div\n style={{\n color: '#9A9A9A',\n }}\n >\n {t('plugin-seo:lengthTipTitle', { maxLength, minLength })}\n <a\n href=\"https://developers.google.com/search/docs/advanced/appearance/title-link#page-titles\"\n rel=\"noopener noreferrer\"\n target=\"_blank\"\n >\n {t('plugin-seo:bestPractices')}\n </a>\n .\n </div>\n </div>\n <div\n style={{\n marginBottom: '10px',\n position: 'relative',\n }}\n >\n <TextInput\n CustomError={errorMessage}\n onChange={setValue}\n path={pathFromContext}\n required={required}\n showError={showError}\n style={{\n marginBottom: 0,\n }}\n value={value}\n />\n </div>\n <div\n style={{\n alignItems: 'center',\n display: 'flex',\n width: '100%',\n }}\n >\n <LengthIndicator maxLength={maxLength} minLength={minLength} text={value} />\n </div>\n </div>\n )\n}\n"],"names":["FieldLabel","TextInput","useDocumentInfo","useField","useFieldProps","useForm","useLocale","useTranslation","React","useCallback","defaults","LengthIndicator","maxLength","minLength","title","MetaTitleComponent","props","CustomLabel","hasGenerateTitleFn","label","labelProps","required","path","pathFromContext","t","field","locale","getData","docInfo","errorMessage","setValue","showError","value","regenerateTitle","genTitleResponse","fetch","body","JSON","stringify","doc","code","credentials","headers","method","result","generatedTitle","json","div","style","marginBottom","position","className","Fragment","button","onClick","background","backgroundColor","border","color","cursor","padding","textDecoration","type","a","href","rel","target","CustomError","onChange","alignItems","display","width","text"],"mappings":"AAAA;;AAKA,SACEA,UAAU,EACVC,SAAS,EACTC,eAAe,EACfC,QAAQ,EACRC,aAAa,EACbC,OAAO,EACPC,SAAS,EACTC,cAAc,QACT,iBAAgB;AACvB,OAAOC,SAASC,WAAW,QAAQ,QAAO;AAK1C,SAASC,QAAQ,QAAQ,oBAAmB;AAC5C,SAASC,eAAe,QAAQ,8BAA6B;AAC7D,OAAO,gBAAe;AAEtB,MAAM,EAAEC,SAAS,EAAEC,SAAS,EAAE,GAAGH,SAASI,KAAK;AAM/C,OAAO,MAAMC,qBAA+C,CAACC;IAC3D,MAAM,EAAEC,WAAW,EAAEC,kBAAkB,EAAEC,KAAK,EAAEC,UAAU,EAAEC,QAAQ,EAAE,GAAGL,SAAS,CAAC;IACnF,MAAM,EAAEM,MAAMC,eAAe,EAAE,GAAGnB;IAElC,MAAM,EAAEoB,CAAC,EAAE,GAAGjB;IAEd,MAAMkB,QAA2BtB,SAAS;QACxCmB,MAAMC;IACR;IAEA,MAAMG,SAASpB;IACf,MAAM,EAAEqB,OAAO,EAAE,GAAGtB;IACpB,MAAMuB,UAAU1B;IAEhB,MAAM,EAAE2B,YAAY,EAAEC,QAAQ,EAAEC,SAAS,EAAEC,KAAK,EAAE,GAAGP;IAErD,MAAMQ,kBAAkBxB,YAAY;QAClC,IAAI,CAACS,oBAAoB;QAEzB,MAAMgB,mBAAmB,MAAMC,MAAM,kCAAkC;YACrEC,MAAMC,KAAKC,SAAS,CAAC;gBACnB,GAAGV,OAAO;gBACVW,KAAK;oBAAE,GAAGZ,SAAS;gBAAC;gBACpBD,QAAQ,OAAOA,WAAW,WAAWA,QAAQc,OAAOd;YACtD;YACAe,aAAa;YACbC,SAAS;gBACP,gBAAgB;YAClB;YACAC,QAAQ;QACV;QAEA,MAAM,EAAEC,QAAQC,cAAc,EAAE,GAAG,MAAMX,iBAAiBY,IAAI;QAE9DhB,SAASe,kBAAkB;IAC7B,GAAG;QAAC3B;QAAoBU;QAASD;QAASD;QAAQI;KAAS;IAE3D,qBACE,MAACiB;QACCC,OAAO;YACLC,cAAc;QAChB;;0BAEA,MAACF;gBACCC,OAAO;oBACLC,cAAc;oBACdC,UAAU;gBACZ;;kCAEA,MAACH;wBAAII,WAAU;;0CACb,KAACnD;gCAAWiB,aAAaA;gCAAaE,OAAOA;gCAAQ,GAAIC,cAAc,CAAC,CAAC;;4BACxEF,oCACC,MAACV,MAAM4C,QAAQ;;oCAAC;kDAEd,KAACC;wCACCC,SAAS;4CACP,KAAKrB;wCACP;wCACAe,OAAO;4CACLO,YAAY;4CACZC,iBAAiB;4CACjBC,QAAQ;4CACRC,OAAO;4CACPC,QAAQ;4CACRC,SAAS;4CACTC,gBAAgB;wCAClB;wCACAC,MAAK;kDAEJtC,EAAE;;;;;;kCAKX,MAACuB;wBACCC,OAAO;4BACLU,OAAO;wBACT;;4BAEClC,EAAE,6BAA6B;gCAAEZ;gCAAWC;4BAAU;0CACvD,KAACkD;gCACCC,MAAK;gCACLC,KAAI;gCACJC,QAAO;0CAEN1C,EAAE;;4BACD;;;;;0BAIR,KAACuB;gBACCC,OAAO;oBACLC,cAAc;oBACdC,UAAU;gBACZ;0BAEA,cAAA,KAACjD;oBACCkE,aAAatC;oBACbuC,UAAUtC;oBACVR,MAAMC;oBACNF,UAAUA;oBACVU,WAAWA;oBACXiB,OAAO;wBACLC,cAAc;oBAChB;oBACAjB,OAAOA;;;0BAGX,KAACe;gBACCC,OAAO;oBACLqB,YAAY;oBACZC,SAAS;oBACTC,OAAO;gBACT;0BAEA,cAAA,KAAC5D;oBAAgBC,WAAWA;oBAAWC,WAAWA;oBAAW2D,MAAMxC;;;;;AAI3E,EAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { TextField } from 'payload';
|
|
2
|
+
interface FieldFunctionProps {
|
|
3
|
+
/**
|
|
4
|
+
* Tell the component if the generate function is available as configured in the plugin config
|
|
5
|
+
*/
|
|
6
|
+
hasGenerateFn?: boolean;
|
|
7
|
+
overrides?: Partial<TextField>;
|
|
8
|
+
}
|
|
9
|
+
type FieldFunction = ({ hasGenerateFn, overrides }: FieldFunctionProps) => TextField;
|
|
10
|
+
export declare const MetaTitleField: FieldFunction;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/fields/MetaTitle/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAMxC,UAAU,kBAAkB;IAC1B;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAA;CAC/B;AAED,KAAK,aAAa,GAAG,CAAC,EAAE,aAAa,EAAE,SAAS,EAAE,EAAE,kBAAkB,KAAK,SAAS,CAAA;AAEpF,eAAO,MAAM,cAAc,EAAE,aAkB5B,CAAA"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { withMergedProps } from '@payloadcms/ui/shared';
|
|
2
|
+
import { MetaTitleComponent } from './MetaTitleComponent.js';
|
|
3
|
+
export const MetaTitleField = ({ hasGenerateFn = false, overrides })=>{
|
|
4
|
+
return {
|
|
5
|
+
name: 'title',
|
|
6
|
+
type: 'text',
|
|
7
|
+
admin: {
|
|
8
|
+
components: {
|
|
9
|
+
Field: withMergedProps({
|
|
10
|
+
Component: MetaTitleComponent,
|
|
11
|
+
sanitizeServerOnlyProps: true,
|
|
12
|
+
toMergeIntoProps: {
|
|
13
|
+
hasGenerateTitleFn: hasGenerateFn
|
|
14
|
+
}
|
|
15
|
+
})
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
localized: true,
|
|
19
|
+
...overrides ?? {}
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/fields/MetaTitle/index.ts"],"sourcesContent":["import type { TextField } from 'payload'\n\nimport { withMergedProps } from '@payloadcms/ui/shared'\n\nimport { MetaTitleComponent } from './MetaTitleComponent.js'\n\ninterface FieldFunctionProps {\n /**\n * Tell the component if the generate function is available as configured in the plugin config\n */\n hasGenerateFn?: boolean\n overrides?: Partial<TextField>\n}\n\ntype FieldFunction = ({ hasGenerateFn, overrides }: FieldFunctionProps) => TextField\n\nexport const MetaTitleField: FieldFunction = ({ hasGenerateFn = false, overrides }) => {\n return {\n name: 'title',\n type: 'text',\n admin: {\n components: {\n Field: withMergedProps({\n Component: MetaTitleComponent,\n sanitizeServerOnlyProps: true,\n toMergeIntoProps: {\n hasGenerateTitleFn: hasGenerateFn,\n },\n }),\n },\n },\n localized: true,\n ...((overrides as unknown as TextField) ?? {}),\n }\n}\n"],"names":["withMergedProps","MetaTitleComponent","MetaTitleField","hasGenerateFn","overrides","name","type","admin","components","Field","Component","sanitizeServerOnlyProps","toMergeIntoProps","hasGenerateTitleFn","localized"],"mappings":"AAEA,SAASA,eAAe,QAAQ,wBAAuB;AAEvD,SAASC,kBAAkB,QAAQ,0BAAyB;AAY5D,OAAO,MAAMC,iBAAgC,CAAC,EAAEC,gBAAgB,KAAK,EAAEC,SAAS,EAAE;IAChF,OAAO;QACLC,MAAM;QACNC,MAAM;QACNC,OAAO;YACLC,YAAY;gBACVC,OAAOT,gBAAgB;oBACrBU,WAAWT;oBACXU,yBAAyB;oBACzBC,kBAAkB;wBAChBC,oBAAoBV;oBACtB;gBACF;YACF;QACF;QACAW,WAAW;QACX,GAAI,AAACV,aAAsC,CAAC,CAAC;IAC/C;AACF,EAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { UIField } from 'payload';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
type OverviewProps = {
|
|
4
|
+
descriptionPath?: string;
|
|
5
|
+
imagePath?: string;
|
|
6
|
+
titlePath?: string;
|
|
7
|
+
} & UIField;
|
|
8
|
+
export declare const OverviewComponent: React.FC<OverviewProps>;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=OverviewComponent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OverviewComponent.d.ts","sourceRoot":"","sources":["../../../src/fields/Overview/OverviewComponent.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAa,OAAO,EAAE,MAAM,SAAS,CAAA;AAGjD,OAAO,KAA2C,MAAM,OAAO,CAAA;AAW/D,KAAK,aAAa,GAAG;IACnB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,GAAG,OAAO,CAAA;AAEX,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CA4DrD,CAAA"}
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import {
|
|
3
|
-
import { useTranslation } from '@payloadcms/ui
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useAllFormFields, useForm, useTranslation } from '@payloadcms/ui';
|
|
4
4
|
import React, { useCallback, useEffect, useState } from 'react';
|
|
5
|
-
import { defaults } from '
|
|
5
|
+
import { defaults } from '../../defaults.js';
|
|
6
6
|
const { description: { maxLength: maxDesc, minLength: minDesc }, title: { maxLength: maxTitle, minLength: minTitle } } = defaults;
|
|
7
|
-
export const
|
|
7
|
+
export const OverviewComponent = ({ descriptionPath: descriptionPathFromContext, imagePath: imagePathFromContext, titlePath: titlePathFromContext })=>{
|
|
8
8
|
const { // dispatchFields,
|
|
9
9
|
getFields } = useForm();
|
|
10
|
-
const
|
|
10
|
+
const descriptionPath = descriptionPathFromContext || 'meta.description';
|
|
11
|
+
const titlePath = titlePathFromContext || 'meta.title';
|
|
12
|
+
const imagePath = imagePathFromContext || 'meta.image';
|
|
13
|
+
const [{ [descriptionPath]: { value: metaDesc } = {}, [imagePath]: { value: metaImage } = {}, [titlePath]: { value: metaTitle } = {} }] = useAllFormFields();
|
|
11
14
|
const { t } = useTranslation();
|
|
12
15
|
const [titleIsValid, setTitleIsValid] = useState();
|
|
13
16
|
const [descIsValid, setDescIsValid] = useState();
|
|
@@ -38,14 +41,17 @@ export const Overview = ()=>{
|
|
|
38
41
|
imageIsValid
|
|
39
42
|
];
|
|
40
43
|
const numberOfPasses = testResults.filter(Boolean).length;
|
|
41
|
-
return /*#__PURE__*/
|
|
44
|
+
return /*#__PURE__*/ _jsx("div", {
|
|
42
45
|
style: {
|
|
43
46
|
marginBottom: '20px'
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
},
|
|
48
|
+
children: /*#__PURE__*/ _jsx("div", {
|
|
49
|
+
children: t('plugin-seo:checksPassing', {
|
|
50
|
+
current: numberOfPasses,
|
|
51
|
+
max: testResults.length
|
|
52
|
+
})
|
|
53
|
+
})
|
|
54
|
+
});
|
|
49
55
|
};
|
|
50
56
|
|
|
51
|
-
//# sourceMappingURL=
|
|
57
|
+
//# sourceMappingURL=OverviewComponent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/fields/Overview/OverviewComponent.tsx"],"sourcesContent":["'use client'\n\nimport type { FormField, UIField } from 'payload'\n\nimport { useAllFormFields, useForm, useTranslation } from '@payloadcms/ui'\nimport React, { useCallback, useEffect, useState } from 'react'\n\nimport type { PluginSEOTranslationKeys, PluginSEOTranslations } from '../../translations/index.js'\n\nimport { defaults } from '../../defaults.js'\n\nconst {\n description: { maxLength: maxDesc, minLength: minDesc },\n title: { maxLength: maxTitle, minLength: minTitle },\n} = defaults\n\ntype OverviewProps = {\n descriptionPath?: string\n imagePath?: string\n titlePath?: string\n} & UIField\n\nexport const OverviewComponent: React.FC<OverviewProps> = ({\n descriptionPath: descriptionPathFromContext,\n imagePath: imagePathFromContext,\n titlePath: titlePathFromContext,\n}) => {\n const {\n // dispatchFields,\n getFields,\n } = useForm()\n\n const descriptionPath = descriptionPathFromContext || 'meta.description'\n const titlePath = titlePathFromContext || 'meta.title'\n const imagePath = imagePathFromContext || 'meta.image'\n\n const [\n {\n [descriptionPath]: { value: metaDesc } = {} as FormField,\n [imagePath]: { value: metaImage } = {} as FormField,\n [titlePath]: { value: metaTitle } = {} as FormField,\n },\n ] = useAllFormFields()\n const { t } = useTranslation<PluginSEOTranslations, PluginSEOTranslationKeys>()\n\n const [titleIsValid, setTitleIsValid] = useState<boolean | undefined>()\n const [descIsValid, setDescIsValid] = useState<boolean | undefined>()\n const [imageIsValid, setImageIsValid] = useState<boolean | undefined>()\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const resetAll = useCallback(() => {\n const fields = getFields()\n const fieldsWithoutMeta = fields\n fieldsWithoutMeta['meta.title'].value = ''\n fieldsWithoutMeta['meta.description'].value = ''\n fieldsWithoutMeta['meta.image'].value = ''\n // dispatchFields(fieldsWithoutMeta);\n }, [getFields])\n\n useEffect(() => {\n if (typeof metaTitle === 'string')\n setTitleIsValid(metaTitle.length >= minTitle && metaTitle.length <= maxTitle)\n if (typeof metaDesc === 'string')\n setDescIsValid(metaDesc.length >= minDesc && metaDesc.length <= maxDesc)\n setImageIsValid(Boolean(metaImage))\n }, [metaTitle, metaDesc, metaImage])\n\n const testResults = [titleIsValid, descIsValid, imageIsValid]\n\n const numberOfPasses = testResults.filter(Boolean).length\n\n return (\n <div\n style={{\n marginBottom: '20px',\n }}\n >\n <div>\n {t('plugin-seo:checksPassing', { current: numberOfPasses, max: testResults.length })}\n </div>\n </div>\n )\n}\n"],"names":["useAllFormFields","useForm","useTranslation","React","useCallback","useEffect","useState","defaults","description","maxLength","maxDesc","minLength","minDesc","title","maxTitle","minTitle","OverviewComponent","descriptionPath","descriptionPathFromContext","imagePath","imagePathFromContext","titlePath","titlePathFromContext","getFields","value","metaDesc","metaImage","metaTitle","t","titleIsValid","setTitleIsValid","descIsValid","setDescIsValid","imageIsValid","setImageIsValid","resetAll","fields","fieldsWithoutMeta","length","Boolean","testResults","numberOfPasses","filter","div","style","marginBottom","current","max"],"mappings":"AAAA;;AAIA,SAASA,gBAAgB,EAAEC,OAAO,EAAEC,cAAc,QAAQ,iBAAgB;AAC1E,OAAOC,SAASC,WAAW,EAAEC,SAAS,EAAEC,QAAQ,QAAQ,QAAO;AAI/D,SAASC,QAAQ,QAAQ,oBAAmB;AAE5C,MAAM,EACJC,aAAa,EAAEC,WAAWC,OAAO,EAAEC,WAAWC,OAAO,EAAE,EACvDC,OAAO,EAAEJ,WAAWK,QAAQ,EAAEH,WAAWI,QAAQ,EAAE,EACpD,GAAGR;AAQJ,OAAO,MAAMS,oBAA6C,CAAC,EACzDC,iBAAiBC,0BAA0B,EAC3CC,WAAWC,oBAAoB,EAC/BC,WAAWC,oBAAoB,EAChC;IACC,MAAM,EACJ,mBAAmB;IACnBC,SAAS,EACV,GAAGtB;IAEJ,MAAMgB,kBAAkBC,8BAA8B;IACtD,MAAMG,YAAYC,wBAAwB;IAC1C,MAAMH,YAAYC,wBAAwB;IAE1C,MAAM,CACJ,EACE,CAACH,gBAAgB,EAAE,EAAEO,OAAOC,QAAQ,EAAE,GAAG,CAAC,CAAc,EACxD,CAACN,UAAU,EAAE,EAAEK,OAAOE,SAAS,EAAE,GAAG,CAAC,CAAc,EACnD,CAACL,UAAU,EAAE,EAAEG,OAAOG,SAAS,EAAE,GAAG,CAAC,CAAc,EACpD,CACF,GAAG3B;IACJ,MAAM,EAAE4B,CAAC,EAAE,GAAG1B;IAEd,MAAM,CAAC2B,cAAcC,gBAAgB,GAAGxB;IACxC,MAAM,CAACyB,aAAaC,eAAe,GAAG1B;IACtC,MAAM,CAAC2B,cAAcC,gBAAgB,GAAG5B;IAExC,6DAA6D;IAC7D,MAAM6B,WAAW/B,YAAY;QAC3B,MAAMgC,SAASb;QACf,MAAMc,oBAAoBD;QAC1BC,iBAAiB,CAAC,aAAa,CAACb,KAAK,GAAG;QACxCa,iBAAiB,CAAC,mBAAmB,CAACb,KAAK,GAAG;QAC9Ca,iBAAiB,CAAC,aAAa,CAACb,KAAK,GAAG;IACxC,qCAAqC;IACvC,GAAG;QAACD;KAAU;IAEdlB,UAAU;QACR,IAAI,OAAOsB,cAAc,UACvBG,gBAAgBH,UAAUW,MAAM,IAAIvB,YAAYY,UAAUW,MAAM,IAAIxB;QACtE,IAAI,OAAOW,aAAa,UACtBO,eAAeP,SAASa,MAAM,IAAI1B,WAAWa,SAASa,MAAM,IAAI5B;QAClEwB,gBAAgBK,QAAQb;IAC1B,GAAG;QAACC;QAAWF;QAAUC;KAAU;IAEnC,MAAMc,cAAc;QAACX;QAAcE;QAAaE;KAAa;IAE7D,MAAMQ,iBAAiBD,YAAYE,MAAM,CAACH,SAASD,MAAM;IAEzD,qBACE,KAACK;QACCC,OAAO;YACLC,cAAc;QAChB;kBAEA,cAAA,KAACF;sBACEf,EAAE,4BAA4B;gBAAEkB,SAASL;gBAAgBM,KAAKP,YAAYF,MAAM;YAAC;;;AAI1F,EAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { UIField } from 'payload';
|
|
2
|
+
interface FieldFunctionProps {
|
|
3
|
+
/**
|
|
4
|
+
* Path to the description field to use for the preview
|
|
5
|
+
*
|
|
6
|
+
* @default 'meta.description'
|
|
7
|
+
*/
|
|
8
|
+
descriptionPath?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Path to the image field to use for the preview
|
|
11
|
+
*
|
|
12
|
+
* @default 'meta.image'
|
|
13
|
+
*/
|
|
14
|
+
imagePath?: string;
|
|
15
|
+
overrides?: Partial<UIField>;
|
|
16
|
+
/**
|
|
17
|
+
* Path to the title field to use for the preview
|
|
18
|
+
*
|
|
19
|
+
* @default 'meta.title'
|
|
20
|
+
*/
|
|
21
|
+
titlePath?: string;
|
|
22
|
+
}
|
|
23
|
+
type FieldFunction = ({ overrides }: FieldFunctionProps) => UIField;
|
|
24
|
+
export declare const OverviewField: FieldFunction;
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/fields/Overview/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAMtC,UAAU,kBAAkB;IAC1B;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;IAC5B;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,KAAK,aAAa,GAAG,CAAC,EAAE,SAAS,EAAE,EAAE,kBAAkB,KAAK,OAAO,CAAA;AAEnE,eAAO,MAAM,aAAa,EAAE,aAyB3B,CAAA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { withMergedProps } from '@payloadcms/ui/shared';
|
|
2
|
+
import { OverviewComponent } from './OverviewComponent.js';
|
|
3
|
+
export const OverviewField = ({ descriptionPath, imagePath, overrides, titlePath })=>{
|
|
4
|
+
return {
|
|
5
|
+
name: 'overview',
|
|
6
|
+
type: 'ui',
|
|
7
|
+
admin: {
|
|
8
|
+
components: {
|
|
9
|
+
Field: withMergedProps({
|
|
10
|
+
Component: OverviewComponent,
|
|
11
|
+
sanitizeServerOnlyProps: true,
|
|
12
|
+
toMergeIntoProps: {
|
|
13
|
+
descriptionPath,
|
|
14
|
+
imagePath,
|
|
15
|
+
titlePath
|
|
16
|
+
}
|
|
17
|
+
})
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
label: 'Overview',
|
|
21
|
+
...overrides ?? {}
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/fields/Overview/index.tsx"],"sourcesContent":["import type { UIField } from 'payload'\n\nimport { withMergedProps } from '@payloadcms/ui/shared'\n\nimport { OverviewComponent } from './OverviewComponent.js'\n\ninterface FieldFunctionProps {\n /**\n * Path to the description field to use for the preview\n *\n * @default 'meta.description'\n */\n descriptionPath?: string\n /**\n * Path to the image field to use for the preview\n *\n * @default 'meta.image'\n */\n imagePath?: string\n overrides?: Partial<UIField>\n /**\n * Path to the title field to use for the preview\n *\n * @default 'meta.title'\n */\n titlePath?: string\n}\n\ntype FieldFunction = ({ overrides }: FieldFunctionProps) => UIField\n\nexport const OverviewField: FieldFunction = ({\n descriptionPath,\n imagePath,\n overrides,\n titlePath,\n}) => {\n return {\n name: 'overview',\n type: 'ui',\n admin: {\n components: {\n Field: withMergedProps({\n Component: OverviewComponent,\n sanitizeServerOnlyProps: true,\n toMergeIntoProps: {\n descriptionPath,\n imagePath,\n titlePath,\n },\n }),\n },\n },\n label: 'Overview',\n ...((overrides as unknown as UIField) ?? {}),\n }\n}\n"],"names":["withMergedProps","OverviewComponent","OverviewField","descriptionPath","imagePath","overrides","titlePath","name","type","admin","components","Field","Component","sanitizeServerOnlyProps","toMergeIntoProps","label"],"mappings":"AAEA,SAASA,eAAe,QAAQ,wBAAuB;AAEvD,SAASC,iBAAiB,QAAQ,yBAAwB;AA0B1D,OAAO,MAAMC,gBAA+B,CAAC,EAC3CC,eAAe,EACfC,SAAS,EACTC,SAAS,EACTC,SAAS,EACV;IACC,OAAO;QACLC,MAAM;QACNC,MAAM;QACNC,OAAO;YACLC,YAAY;gBACVC,OAAOX,gBAAgB;oBACrBY,WAAWX;oBACXY,yBAAyB;oBACzBC,kBAAkB;wBAChBX;wBACAC;wBACAE;oBACF;gBACF;YACF;QACF;QACAS,OAAO;QACP,GAAI,AAACV,aAAoC,CAAC,CAAC;IAC7C;AACF,EAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { UIField } from 'payload';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
type PreviewProps = {
|
|
4
|
+
descriptionPath?: string;
|
|
5
|
+
hasGenerateURLFn: boolean;
|
|
6
|
+
titlePath?: string;
|
|
7
|
+
} & UIField;
|
|
8
|
+
export declare const PreviewComponent: React.FC<PreviewProps>;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=PreviewComponent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PreviewComponent.d.ts","sourceRoot":"","sources":["../../../src/fields/Preview/PreviewComponent.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAa,OAAO,EAAE,MAAM,SAAS,CAAA;AAUjD,OAAO,KAA8B,MAAM,OAAO,CAAA;AAKlD,KAAK,YAAY,GAAG;IAClB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,gBAAgB,EAAE,OAAO,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,GAAG,OAAO,CAAA;AAEX,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,CAuGnD,CAAA"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useAllFormFields, useDocumentInfo, useForm, useLocale, useTranslation } from '@payloadcms/ui';
|
|
4
|
+
import React, { useEffect, useState } from 'react';
|
|
5
|
+
export const PreviewComponent = ({ descriptionPath: descriptionPathFromContext, hasGenerateURLFn, titlePath: titlePathFromContext })=>{
|
|
6
|
+
const { t } = useTranslation();
|
|
7
|
+
const locale = useLocale();
|
|
8
|
+
const [fields] = useAllFormFields();
|
|
9
|
+
const { getData } = useForm();
|
|
10
|
+
const docInfo = useDocumentInfo();
|
|
11
|
+
const descriptionPath = descriptionPathFromContext || 'meta.description';
|
|
12
|
+
const titlePath = titlePathFromContext || 'meta.title';
|
|
13
|
+
const { [descriptionPath]: { value: metaDescription } = {}, [titlePath]: { value: metaTitle } = {} } = fields;
|
|
14
|
+
const [href, setHref] = useState();
|
|
15
|
+
useEffect(()=>{
|
|
16
|
+
const getHref = async ()=>{
|
|
17
|
+
const genURLResponse = await fetch('/api/plugin-seo/generate-url', {
|
|
18
|
+
body: JSON.stringify({
|
|
19
|
+
...docInfo,
|
|
20
|
+
doc: {
|
|
21
|
+
...getData()
|
|
22
|
+
},
|
|
23
|
+
locale: typeof locale === 'object' ? locale?.code : locale
|
|
24
|
+
}),
|
|
25
|
+
credentials: 'include',
|
|
26
|
+
headers: {
|
|
27
|
+
'Content-Type': 'application/json'
|
|
28
|
+
},
|
|
29
|
+
method: 'POST'
|
|
30
|
+
});
|
|
31
|
+
const { result: newHref } = await genURLResponse.json();
|
|
32
|
+
setHref(newHref);
|
|
33
|
+
};
|
|
34
|
+
if (hasGenerateURLFn && !href) {
|
|
35
|
+
void getHref();
|
|
36
|
+
}
|
|
37
|
+
}, [
|
|
38
|
+
fields,
|
|
39
|
+
href,
|
|
40
|
+
locale,
|
|
41
|
+
docInfo,
|
|
42
|
+
hasGenerateURLFn,
|
|
43
|
+
getData
|
|
44
|
+
]);
|
|
45
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
46
|
+
children: [
|
|
47
|
+
/*#__PURE__*/ _jsx("div", {
|
|
48
|
+
children: t('plugin-seo:preview')
|
|
49
|
+
}),
|
|
50
|
+
/*#__PURE__*/ _jsx("div", {
|
|
51
|
+
style: {
|
|
52
|
+
color: '#9A9A9A',
|
|
53
|
+
marginBottom: '5px'
|
|
54
|
+
},
|
|
55
|
+
children: t('plugin-seo:previewDescription')
|
|
56
|
+
}),
|
|
57
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
58
|
+
style: {
|
|
59
|
+
background: 'var(--theme-elevation-50)',
|
|
60
|
+
borderRadius: '5px',
|
|
61
|
+
boxShadow: '0px 0px 10px rgba(0, 0, 0, 0.1)',
|
|
62
|
+
maxWidth: '600px',
|
|
63
|
+
padding: '20px',
|
|
64
|
+
pointerEvents: 'none',
|
|
65
|
+
width: '100%'
|
|
66
|
+
},
|
|
67
|
+
children: [
|
|
68
|
+
/*#__PURE__*/ _jsx("div", {
|
|
69
|
+
children: /*#__PURE__*/ _jsx("a", {
|
|
70
|
+
href: href,
|
|
71
|
+
style: {
|
|
72
|
+
textDecoration: 'none'
|
|
73
|
+
},
|
|
74
|
+
children: href || 'https://...'
|
|
75
|
+
})
|
|
76
|
+
}),
|
|
77
|
+
/*#__PURE__*/ _jsx("h4", {
|
|
78
|
+
style: {
|
|
79
|
+
margin: 0
|
|
80
|
+
},
|
|
81
|
+
children: /*#__PURE__*/ _jsx("a", {
|
|
82
|
+
href: "/",
|
|
83
|
+
style: {
|
|
84
|
+
textDecoration: 'none'
|
|
85
|
+
},
|
|
86
|
+
children: metaTitle
|
|
87
|
+
})
|
|
88
|
+
}),
|
|
89
|
+
/*#__PURE__*/ _jsx("p", {
|
|
90
|
+
style: {
|
|
91
|
+
margin: 0
|
|
92
|
+
},
|
|
93
|
+
children: metaDescription
|
|
94
|
+
})
|
|
95
|
+
]
|
|
96
|
+
})
|
|
97
|
+
]
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
//# sourceMappingURL=PreviewComponent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/fields/Preview/PreviewComponent.tsx"],"sourcesContent":["'use client'\n\nimport type { FormField, UIField } from 'payload'\n\nimport {\n useAllFormFields,\n useDocumentInfo,\n useForm,\n useLocale,\n useTranslation,\n} from '@payloadcms/ui'\nimport { get } from 'http'\nimport React, { useEffect, useState } from 'react'\n\nimport type { PluginSEOTranslationKeys, PluginSEOTranslations } from '../../translations/index.js'\nimport type { GenerateURL } from '../../types.js'\n\ntype PreviewProps = {\n descriptionPath?: string\n hasGenerateURLFn: boolean\n titlePath?: string\n} & UIField\n\nexport const PreviewComponent: React.FC<PreviewProps> = ({\n descriptionPath: descriptionPathFromContext,\n hasGenerateURLFn,\n titlePath: titlePathFromContext,\n}) => {\n const { t } = useTranslation<PluginSEOTranslations, PluginSEOTranslationKeys>()\n\n const locale = useLocale()\n const [fields] = useAllFormFields()\n const { getData } = useForm()\n const docInfo = useDocumentInfo()\n\n const descriptionPath = descriptionPathFromContext || 'meta.description'\n const titlePath = titlePathFromContext || 'meta.title'\n\n const {\n [descriptionPath]: { value: metaDescription } = {} as FormField,\n [titlePath]: { value: metaTitle } = {} as FormField,\n } = fields\n\n const [href, setHref] = useState<string>()\n\n useEffect(() => {\n const getHref = async () => {\n const genURLResponse = await fetch('/api/plugin-seo/generate-url', {\n body: JSON.stringify({\n ...docInfo,\n doc: { ...getData() },\n locale: typeof locale === 'object' ? locale?.code : locale,\n } satisfies Parameters<GenerateURL>[0]),\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n })\n\n const { result: newHref } = await genURLResponse.json()\n\n setHref(newHref)\n }\n\n if (hasGenerateURLFn && !href) {\n void getHref()\n }\n }, [fields, href, locale, docInfo, hasGenerateURLFn, getData])\n\n return (\n <div>\n <div>{t('plugin-seo:preview')}</div>\n <div\n style={{\n color: '#9A9A9A',\n marginBottom: '5px',\n }}\n >\n {t('plugin-seo:previewDescription')}\n </div>\n <div\n style={{\n background: 'var(--theme-elevation-50)',\n borderRadius: '5px',\n boxShadow: '0px 0px 10px rgba(0, 0, 0, 0.1)',\n maxWidth: '600px',\n padding: '20px',\n pointerEvents: 'none',\n width: '100%',\n }}\n >\n <div>\n <a\n href={href}\n style={{\n textDecoration: 'none',\n }}\n >\n {href || 'https://...'}\n </a>\n </div>\n <h4\n style={{\n margin: 0,\n }}\n >\n <a\n href=\"/\"\n style={{\n textDecoration: 'none',\n }}\n >\n {metaTitle as string}\n </a>\n </h4>\n <p\n style={{\n margin: 0,\n }}\n >\n {metaDescription as string}\n </p>\n </div>\n </div>\n )\n}\n"],"names":["useAllFormFields","useDocumentInfo","useForm","useLocale","useTranslation","React","useEffect","useState","PreviewComponent","descriptionPath","descriptionPathFromContext","hasGenerateURLFn","titlePath","titlePathFromContext","t","locale","fields","getData","docInfo","value","metaDescription","metaTitle","href","setHref","getHref","genURLResponse","fetch","body","JSON","stringify","doc","code","credentials","headers","method","result","newHref","json","div","style","color","marginBottom","background","borderRadius","boxShadow","maxWidth","padding","pointerEvents","width","a","textDecoration","h4","margin","p"],"mappings":"AAAA;;AAIA,SACEA,gBAAgB,EAChBC,eAAe,EACfC,OAAO,EACPC,SAAS,EACTC,cAAc,QACT,iBAAgB;AAEvB,OAAOC,SAASC,SAAS,EAAEC,QAAQ,QAAQ,QAAO;AAWlD,OAAO,MAAMC,mBAA2C,CAAC,EACvDC,iBAAiBC,0BAA0B,EAC3CC,gBAAgB,EAChBC,WAAWC,oBAAoB,EAChC;IACC,MAAM,EAAEC,CAAC,EAAE,GAAGV;IAEd,MAAMW,SAASZ;IACf,MAAM,CAACa,OAAO,GAAGhB;IACjB,MAAM,EAAEiB,OAAO,EAAE,GAAGf;IACpB,MAAMgB,UAAUjB;IAEhB,MAAMQ,kBAAkBC,8BAA8B;IACtD,MAAME,YAAYC,wBAAwB;IAE1C,MAAM,EACJ,CAACJ,gBAAgB,EAAE,EAAEU,OAAOC,eAAe,EAAE,GAAG,CAAC,CAAc,EAC/D,CAACR,UAAU,EAAE,EAAEO,OAAOE,SAAS,EAAE,GAAG,CAAC,CAAc,EACpD,GAAGL;IAEJ,MAAM,CAACM,MAAMC,QAAQ,GAAGhB;IAExBD,UAAU;QACR,MAAMkB,UAAU;YACd,MAAMC,iBAAiB,MAAMC,MAAM,gCAAgC;gBACjEC,MAAMC,KAAKC,SAAS,CAAC;oBACnB,GAAGX,OAAO;oBACVY,KAAK;wBAAE,GAAGb,SAAS;oBAAC;oBACpBF,QAAQ,OAAOA,WAAW,WAAWA,QAAQgB,OAAOhB;gBACtD;gBACAiB,aAAa;gBACbC,SAAS;oBACP,gBAAgB;gBAClB;gBACAC,QAAQ;YACV;YAEA,MAAM,EAAEC,QAAQC,OAAO,EAAE,GAAG,MAAMX,eAAeY,IAAI;YAErDd,QAAQa;QACV;QAEA,IAAIzB,oBAAoB,CAACW,MAAM;YAC7B,KAAKE;QACP;IACF,GAAG;QAACR;QAAQM;QAAMP;QAAQG;QAASP;QAAkBM;KAAQ;IAE7D,qBACE,MAACqB;;0BACC,KAACA;0BAAKxB,EAAE;;0BACR,KAACwB;gBACCC,OAAO;oBACLC,OAAO;oBACPC,cAAc;gBAChB;0BAEC3B,EAAE;;0BAEL,MAACwB;gBACCC,OAAO;oBACLG,YAAY;oBACZC,cAAc;oBACdC,WAAW;oBACXC,UAAU;oBACVC,SAAS;oBACTC,eAAe;oBACfC,OAAO;gBACT;;kCAEA,KAACV;kCACC,cAAA,KAACW;4BACC3B,MAAMA;4BACNiB,OAAO;gCACLW,gBAAgB;4BAClB;sCAEC5B,QAAQ;;;kCAGb,KAAC6B;wBACCZ,OAAO;4BACLa,QAAQ;wBACV;kCAEA,cAAA,KAACH;4BACC3B,MAAK;4BACLiB,OAAO;gCACLW,gBAAgB;4BAClB;sCAEC7B;;;kCAGL,KAACgC;wBACCd,OAAO;4BACLa,QAAQ;wBACV;kCAEChC;;;;;;AAKX,EAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { UIField } from 'payload';
|
|
2
|
+
interface FieldFunctionProps {
|
|
3
|
+
/**
|
|
4
|
+
* Path to the description field to use for the preview
|
|
5
|
+
*
|
|
6
|
+
* @default 'meta.description'
|
|
7
|
+
*/
|
|
8
|
+
descriptionPath?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Tell the component if the generate function is available as configured in the plugin config
|
|
11
|
+
*/
|
|
12
|
+
hasGenerateFn?: boolean;
|
|
13
|
+
overrides?: Partial<UIField>;
|
|
14
|
+
/**
|
|
15
|
+
* Path to the title field to use for the preview
|
|
16
|
+
*
|
|
17
|
+
* @default 'meta.title'
|
|
18
|
+
*/
|
|
19
|
+
titlePath?: string;
|
|
20
|
+
}
|
|
21
|
+
type FieldFunction = ({ hasGenerateFn, overrides }: FieldFunctionProps) => UIField;
|
|
22
|
+
export declare const PreviewField: FieldFunction;
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/fields/Preview/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAMtC,UAAU,kBAAkB;IAC1B;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;IAC5B;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,KAAK,aAAa,GAAG,CAAC,EAAE,aAAa,EAAE,SAAS,EAAE,EAAE,kBAAkB,KAAK,OAAO,CAAA;AAElF,eAAO,MAAM,YAAY,EAAE,aAyB1B,CAAA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { withMergedProps } from '@payloadcms/ui/shared';
|
|
2
|
+
import { PreviewComponent } from './PreviewComponent.js';
|
|
3
|
+
export const PreviewField = ({ descriptionPath, hasGenerateFn = false, overrides, titlePath })=>{
|
|
4
|
+
return {
|
|
5
|
+
name: 'preview',
|
|
6
|
+
type: 'ui',
|
|
7
|
+
admin: {
|
|
8
|
+
components: {
|
|
9
|
+
Field: withMergedProps({
|
|
10
|
+
Component: PreviewComponent,
|
|
11
|
+
sanitizeServerOnlyProps: true,
|
|
12
|
+
toMergeIntoProps: {
|
|
13
|
+
descriptionPath,
|
|
14
|
+
hasGenerateURLFn: hasGenerateFn,
|
|
15
|
+
titlePath
|
|
16
|
+
}
|
|
17
|
+
})
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
label: 'Preview',
|
|
21
|
+
...overrides ?? {}
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/fields/Preview/index.tsx"],"sourcesContent":["import type { UIField } from 'payload'\n\nimport { withMergedProps } from '@payloadcms/ui/shared'\n\nimport { PreviewComponent } from './PreviewComponent.js'\n\ninterface FieldFunctionProps {\n /**\n * Path to the description field to use for the preview\n *\n * @default 'meta.description'\n */\n descriptionPath?: string\n /**\n * Tell the component if the generate function is available as configured in the plugin config\n */\n hasGenerateFn?: boolean\n overrides?: Partial<UIField>\n /**\n * Path to the title field to use for the preview\n *\n * @default 'meta.title'\n */\n titlePath?: string\n}\n\ntype FieldFunction = ({ hasGenerateFn, overrides }: FieldFunctionProps) => UIField\n\nexport const PreviewField: FieldFunction = ({\n descriptionPath,\n hasGenerateFn = false,\n overrides,\n titlePath,\n}) => {\n return {\n name: 'preview',\n type: 'ui',\n admin: {\n components: {\n Field: withMergedProps({\n Component: PreviewComponent,\n sanitizeServerOnlyProps: true,\n toMergeIntoProps: {\n descriptionPath,\n hasGenerateURLFn: hasGenerateFn,\n titlePath,\n },\n }),\n },\n },\n label: 'Preview',\n ...((overrides as unknown as UIField) ?? {}),\n }\n}\n"],"names":["withMergedProps","PreviewComponent","PreviewField","descriptionPath","hasGenerateFn","overrides","titlePath","name","type","admin","components","Field","Component","sanitizeServerOnlyProps","toMergeIntoProps","hasGenerateURLFn","label"],"mappings":"AAEA,SAASA,eAAe,QAAQ,wBAAuB;AAEvD,SAASC,gBAAgB,QAAQ,wBAAuB;AAwBxD,OAAO,MAAMC,eAA8B,CAAC,EAC1CC,eAAe,EACfC,gBAAgB,KAAK,EACrBC,SAAS,EACTC,SAAS,EACV;IACC,OAAO;QACLC,MAAM;QACNC,MAAM;QACNC,OAAO;YACLC,YAAY;gBACVC,OAAOX,gBAAgB;oBACrBY,WAAWX;oBACXY,yBAAyB;oBACzBC,kBAAkB;wBAChBX;wBACAY,kBAAkBX;wBAClBE;oBACF;gBACF;YACF;QACF;QACAU,OAAO;QACP,GAAI,AAACX,aAAoC,CAAC,CAAC;IAC7C;AACF,EAAC"}
|
package/dist/fields/index.scss
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Config } from 'payload
|
|
1
|
+
import type { Config } from 'payload';
|
|
2
2
|
import type { SEOPluginConfig } from './types.js';
|
|
3
3
|
export declare const seoPlugin: (pluginConfig: SEOPluginConfig) => (config: Config) => Config;
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAA2C,MAAM,SAAS,CAAA;AAM9E,OAAO,KAAK,EAKV,eAAe,EAChB,MAAM,YAAY,CAAA;AASnB,eAAO,MAAM,SAAS,iBACL,eAAe,cACrB,MAAM,KAAG,MAyRjB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { addDataAndFileToRequest } from '@payloadcms/next/utilities';
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
2
|
+
import { withMergedProps } from '@payloadcms/ui/shared';
|
|
3
|
+
import { deepMergeSimple } from 'payload/shared';
|
|
4
|
+
import { MetaDescriptionComponent } from './fields/MetaDescription/MetaDescriptionComponent.js';
|
|
5
|
+
import { MetaImageComponent } from './fields/MetaImage/MetaImageComponent.js';
|
|
6
|
+
import { MetaTitleComponent } from './fields/MetaTitle/MetaTitleComponent.js';
|
|
7
|
+
import { OverviewComponent } from './fields/Overview/OverviewComponent.js';
|
|
8
|
+
import { PreviewComponent } from './fields/Preview/PreviewComponent.js';
|
|
7
9
|
import { translations } from './translations/index.js';
|
|
8
|
-
import { Overview } from './ui/Overview.js';
|
|
9
|
-
import { Preview } from './ui/Preview.js';
|
|
10
10
|
export const seoPlugin = (pluginConfig)=>(config)=>{
|
|
11
11
|
const seoFields = [
|
|
12
12
|
{
|
|
@@ -18,7 +18,7 @@ export const seoPlugin = (pluginConfig)=>(config)=>{
|
|
|
18
18
|
type: 'ui',
|
|
19
19
|
admin: {
|
|
20
20
|
components: {
|
|
21
|
-
Field:
|
|
21
|
+
Field: OverviewComponent
|
|
22
22
|
}
|
|
23
23
|
},
|
|
24
24
|
label: 'Overview'
|
|
@@ -28,10 +28,13 @@ export const seoPlugin = (pluginConfig)=>(config)=>{
|
|
|
28
28
|
type: 'text',
|
|
29
29
|
admin: {
|
|
30
30
|
components: {
|
|
31
|
-
Field: ({
|
|
32
|
-
|
|
31
|
+
Field: withMergedProps({
|
|
32
|
+
Component: MetaTitleComponent,
|
|
33
|
+
sanitizeServerOnlyProps: true,
|
|
34
|
+
toMergeIntoProps: {
|
|
33
35
|
hasGenerateTitleFn: typeof pluginConfig?.generateTitle === 'function'
|
|
34
|
-
}
|
|
36
|
+
}
|
|
37
|
+
})
|
|
35
38
|
}
|
|
36
39
|
},
|
|
37
40
|
localized: true,
|
|
@@ -42,26 +45,31 @@ export const seoPlugin = (pluginConfig)=>(config)=>{
|
|
|
42
45
|
type: 'textarea',
|
|
43
46
|
admin: {
|
|
44
47
|
components: {
|
|
45
|
-
Field: ({
|
|
46
|
-
|
|
48
|
+
Field: withMergedProps({
|
|
49
|
+
Component: MetaDescriptionComponent,
|
|
50
|
+
sanitizeServerOnlyProps: true,
|
|
51
|
+
toMergeIntoProps: {
|
|
47
52
|
hasGenerateDescriptionFn: typeof pluginConfig?.generateDescription === 'function'
|
|
48
|
-
}
|
|
53
|
+
}
|
|
54
|
+
})
|
|
49
55
|
}
|
|
50
56
|
},
|
|
51
57
|
localized: true,
|
|
52
58
|
...pluginConfig?.fieldOverrides?.description ?? {}
|
|
53
59
|
},
|
|
54
60
|
...pluginConfig?.uploadsCollection ? [
|
|
55
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
56
61
|
{
|
|
57
62
|
name: 'image',
|
|
58
63
|
type: 'upload',
|
|
59
64
|
admin: {
|
|
60
65
|
components: {
|
|
61
|
-
Field: ({
|
|
62
|
-
|
|
66
|
+
Field: withMergedProps({
|
|
67
|
+
Component: MetaImageComponent,
|
|
68
|
+
sanitizeServerOnlyProps: true,
|
|
69
|
+
toMergeIntoProps: {
|
|
63
70
|
hasGenerateImageFn: typeof pluginConfig?.generateImage === 'function'
|
|
64
|
-
}
|
|
71
|
+
}
|
|
72
|
+
})
|
|
65
73
|
},
|
|
66
74
|
description: 'Maximum upload file size: 12MB. Recommended file size for images is <500KB.'
|
|
67
75
|
},
|
|
@@ -77,10 +85,13 @@ export const seoPlugin = (pluginConfig)=>(config)=>{
|
|
|
77
85
|
type: 'ui',
|
|
78
86
|
admin: {
|
|
79
87
|
components: {
|
|
80
|
-
Field: ({
|
|
81
|
-
|
|
88
|
+
Field: withMergedProps({
|
|
89
|
+
Component: PreviewComponent,
|
|
90
|
+
sanitizeServerOnlyProps: true,
|
|
91
|
+
toMergeIntoProps: {
|
|
82
92
|
hasGenerateURLFn: typeof pluginConfig?.generateURL === 'function'
|
|
83
|
-
}
|
|
93
|
+
}
|
|
94
|
+
})
|
|
84
95
|
}
|
|
85
96
|
},
|
|
86
97
|
label: 'Preview'
|
|
@@ -156,11 +167,9 @@ export const seoPlugin = (pluginConfig)=>(config)=>{
|
|
|
156
167
|
...config.endpoints ?? [],
|
|
157
168
|
{
|
|
158
169
|
handler: async (req)=>{
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
const args = reqWithData.data;
|
|
163
|
-
const result = pluginConfig.generateTitle ? await pluginConfig.generateTitle(args) : '';
|
|
170
|
+
await addDataAndFileToRequest(req);
|
|
171
|
+
req.t;
|
|
172
|
+
const result = pluginConfig.generateTitle ? await pluginConfig.generateTitle(req.data) : '';
|
|
164
173
|
return new Response(JSON.stringify({
|
|
165
174
|
result
|
|
166
175
|
}), {
|
|
@@ -172,11 +181,8 @@ export const seoPlugin = (pluginConfig)=>(config)=>{
|
|
|
172
181
|
},
|
|
173
182
|
{
|
|
174
183
|
handler: async (req)=>{
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
});
|
|
178
|
-
const args = reqWithData.data;
|
|
179
|
-
const result = pluginConfig.generateDescription ? await pluginConfig.generateDescription(args) : '';
|
|
184
|
+
await addDataAndFileToRequest(req);
|
|
185
|
+
const result = pluginConfig.generateDescription ? await pluginConfig.generateDescription(req.data) : '';
|
|
180
186
|
return new Response(JSON.stringify({
|
|
181
187
|
result
|
|
182
188
|
}), {
|
|
@@ -188,11 +194,8 @@ export const seoPlugin = (pluginConfig)=>(config)=>{
|
|
|
188
194
|
},
|
|
189
195
|
{
|
|
190
196
|
handler: async (req)=>{
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
});
|
|
194
|
-
const args = reqWithData.data;
|
|
195
|
-
const result = pluginConfig.generateURL ? await pluginConfig.generateURL(args) : '';
|
|
197
|
+
await addDataAndFileToRequest(req);
|
|
198
|
+
const result = pluginConfig.generateURL ? await pluginConfig.generateURL(req.data) : '';
|
|
196
199
|
return new Response(JSON.stringify({
|
|
197
200
|
result
|
|
198
201
|
}), {
|
|
@@ -204,11 +207,8 @@ export const seoPlugin = (pluginConfig)=>(config)=>{
|
|
|
204
207
|
},
|
|
205
208
|
{
|
|
206
209
|
handler: async (req)=>{
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
});
|
|
210
|
-
const args = reqWithData.data;
|
|
211
|
-
const result = pluginConfig.generateImage ? await pluginConfig.generateImage(args) : '';
|
|
210
|
+
await addDataAndFileToRequest(req);
|
|
211
|
+
const result = pluginConfig.generateImage ? await pluginConfig.generateImage(req.data) : '';
|
|
212
212
|
return new Response(result, {
|
|
213
213
|
status: 200
|
|
214
214
|
});
|
|
@@ -264,7 +264,7 @@ export const seoPlugin = (pluginConfig)=>(config)=>{
|
|
|
264
264
|
i18n: {
|
|
265
265
|
...config.i18n,
|
|
266
266
|
translations: {
|
|
267
|
-
...
|
|
267
|
+
...deepMergeSimple(translations, config.i18n?.translations)
|
|
268
268
|
}
|
|
269
269
|
}
|
|
270
270
|
};
|