@payloadcms/ui 3.0.0-beta.25 → 3.0.0-beta.27
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/elements/ArrayAction/index.d.ts +1 -0
- package/dist/elements/ArrayAction/index.d.ts.map +1 -1
- package/dist/elements/ArrayAction/index.js +3 -3
- package/dist/elements/ArrayAction/index.js.map +1 -1
- package/dist/elements/Autosave/index.d.ts.map +1 -1
- package/dist/elements/Autosave/index.js +15 -3
- package/dist/elements/Autosave/index.js.map +1 -1
- package/dist/elements/DocumentControls/index.scss +2 -2
- package/dist/elements/EditUpload/index.d.ts +12 -0
- package/dist/elements/EditUpload/index.d.ts.map +1 -1
- package/dist/elements/EditUpload/index.js +25 -25
- package/dist/elements/EditUpload/index.js.map +1 -1
- package/dist/elements/Upload/index.d.ts.map +1 -1
- package/dist/elements/Upload/index.js +37 -1
- package/dist/elements/Upload/index.js.map +1 -1
- package/dist/elements/Upload/index.scss +12 -1
- package/dist/fields/Array/ArrayRow.d.ts +1 -0
- package/dist/fields/Array/ArrayRow.d.ts.map +1 -1
- package/dist/fields/Array/ArrayRow.js +4 -3
- package/dist/fields/Array/ArrayRow.js.map +1 -1
- package/dist/fields/Array/index.d.ts +1 -0
- package/dist/fields/Array/index.d.ts.map +1 -1
- package/dist/fields/Array/index.js +3 -2
- package/dist/fields/Array/index.js.map +1 -1
- package/dist/fields/Blocks/BlockRow.d.ts +1 -0
- package/dist/fields/Blocks/BlockRow.d.ts.map +1 -1
- package/dist/fields/Blocks/BlockRow.js +4 -3
- package/dist/fields/Blocks/BlockRow.js.map +1 -1
- package/dist/fields/Blocks/RowActions.d.ts +1 -0
- package/dist/fields/Blocks/RowActions.d.ts.map +1 -1
- package/dist/fields/Blocks/RowActions.js +2 -1
- package/dist/fields/Blocks/RowActions.js.map +1 -1
- package/dist/fields/Blocks/index.d.ts +1 -0
- package/dist/fields/Blocks/index.d.ts.map +1 -1
- package/dist/fields/Blocks/index.js +3 -2
- package/dist/fields/Blocks/index.js.map +1 -1
- package/dist/providers/ComponentMap/buildComponentMap/fields.d.ts.map +1 -1
- package/dist/providers/ComponentMap/buildComponentMap/fields.js +2 -0
- package/dist/providers/ComponentMap/buildComponentMap/fields.js.map +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/elements/ArrayAction/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAUzB,OAAO,cAAc,CAAA;AAIrB,MAAM,MAAM,KAAK,GAAG;IAClB,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IACrD,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC,UAAU,EAAE,OAAO,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAC3C,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/elements/ArrayAction/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAUzB,OAAO,cAAc,CAAA;AAIrB,MAAM,MAAM,KAAK,GAAG;IAClB,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IACrD,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC,UAAU,EAAE,OAAO,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAC3C,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAyFvC,CAAA"}
|
|
@@ -8,7 +8,7 @@ import { useTranslation } from '../../providers/Translation/index.js';
|
|
|
8
8
|
import { PopupList } from '../Popup/index.js';
|
|
9
9
|
import { Popup } from '../Popup/index.js';
|
|
10
10
|
const baseClass = 'array-actions';
|
|
11
|
-
export const ArrayAction = ({ addRow, duplicateRow, hasMaxRows, index, moveRow, removeRow, rowCount })=>{
|
|
11
|
+
export const ArrayAction = ({ addRow, duplicateRow, hasMaxRows, index, isSortable, moveRow, removeRow, rowCount })=>{
|
|
12
12
|
const { t } = useTranslation();
|
|
13
13
|
return /*#__PURE__*/ React.createElement(Popup, {
|
|
14
14
|
button: /*#__PURE__*/ React.createElement(MoreIcon, null),
|
|
@@ -18,7 +18,7 @@ export const ArrayAction = ({ addRow, duplicateRow, hasMaxRows, index, moveRow,
|
|
|
18
18
|
render: ({ close })=>{
|
|
19
19
|
return /*#__PURE__*/ React.createElement(PopupList.ButtonGroup, {
|
|
20
20
|
buttonSize: "small"
|
|
21
|
-
}, index !== 0 && /*#__PURE__*/ React.createElement(PopupList.Button, {
|
|
21
|
+
}, isSortable && index !== 0 && /*#__PURE__*/ React.createElement(PopupList.Button, {
|
|
22
22
|
className: `${baseClass}__action ${baseClass}__move-up`,
|
|
23
23
|
onClick: ()=>{
|
|
24
24
|
moveRow(index, index - 1);
|
|
@@ -28,7 +28,7 @@ export const ArrayAction = ({ addRow, duplicateRow, hasMaxRows, index, moveRow,
|
|
|
28
28
|
className: `${baseClass}__action-chevron`
|
|
29
29
|
}, /*#__PURE__*/ React.createElement(Chevron, {
|
|
30
30
|
direction: "up"
|
|
31
|
-
})), t('general:moveUp')), index < rowCount - 1 && /*#__PURE__*/ React.createElement(PopupList.Button, {
|
|
31
|
+
})), t('general:moveUp')), isSortable && index < rowCount - 1 && /*#__PURE__*/ React.createElement(PopupList.Button, {
|
|
32
32
|
className: `${baseClass}__action`,
|
|
33
33
|
onClick: ()=>{
|
|
34
34
|
moveRow(index, index + 1);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/elements/ArrayAction/index.tsx"],"sourcesContent":["import React from 'react'\n\nimport { Chevron } from '../../icons/Chevron/index.js'\nimport { Copy } from '../../icons/Copy/index.js'\nimport { MoreIcon } from '../../icons/More/index.js'\nimport { Plus } from '../../icons/Plus/index.js'\nimport { X } from '../../icons/X/index.js'\nimport { useTranslation } from '../../providers/Translation/index.js'\nimport { PopupList } from '../Popup/index.js'\nimport { Popup } from '../Popup/index.js'\nimport './index.scss'\n\nconst baseClass = 'array-actions'\n\nexport type Props = {\n addRow: (current: number, blockType?: string) => void\n duplicateRow: (current: number) => void\n hasMaxRows: boolean\n index: number\n moveRow: (from: number, to: number) => void\n removeRow: (index: number) => void\n rowCount: number\n}\n\nexport const ArrayAction: React.FC<Props> = ({\n addRow,\n duplicateRow,\n hasMaxRows,\n index,\n moveRow,\n removeRow,\n rowCount,\n}) => {\n const { t } = useTranslation()\n\n return (\n <Popup\n button={<MoreIcon />}\n buttonClassName={`${baseClass}__button`}\n className={baseClass}\n horizontalAlign=\"center\"\n render={({ close }) => {\n return (\n <PopupList.ButtonGroup buttonSize=\"small\">\n {index !== 0 && (\n <PopupList.Button\n className={`${baseClass}__action ${baseClass}__move-up`}\n onClick={() => {\n moveRow(index, index - 1)\n close()\n }}\n >\n <div className={`${baseClass}__action-chevron`}>\n <Chevron direction=\"up\" />\n </div>\n {t('general:moveUp')}\n </PopupList.Button>\n )}\n {index < rowCount - 1 && (\n <PopupList.Button\n className={`${baseClass}__action`}\n onClick={() => {\n moveRow(index, index + 1)\n close()\n }}\n >\n <div className={`${baseClass}__action-chevron`}>\n <Chevron />\n </div>\n {t('general:moveDown')}\n </PopupList.Button>\n )}\n {!hasMaxRows && (\n <React.Fragment>\n <PopupList.Button\n className={`${baseClass}__action ${baseClass}__add`}\n onClick={() => {\n addRow(index + 1)\n close()\n }}\n >\n <Plus />\n {t('general:addBelow')}\n </PopupList.Button>\n <PopupList.Button\n className={`${baseClass}__action ${baseClass}__duplicate`}\n onClick={() => {\n duplicateRow(index)\n close()\n }}\n >\n <Copy />\n {t('general:duplicate')}\n </PopupList.Button>\n </React.Fragment>\n )}\n <PopupList.Button\n className={`${baseClass}__action ${baseClass}__remove`}\n onClick={() => {\n removeRow(index)\n close()\n }}\n >\n <X />\n {t('general:remove')}\n </PopupList.Button>\n </PopupList.ButtonGroup>\n )\n }}\n size=\"medium\"\n />\n )\n}\n"],"names":["React","Chevron","Copy","MoreIcon","Plus","X","useTranslation","PopupList","Popup","baseClass","ArrayAction","addRow","duplicateRow","hasMaxRows","index","moveRow","removeRow","rowCount","t","button","buttonClassName","className","horizontalAlign","render","close","ButtonGroup","buttonSize","Button","onClick","div","direction","Fragment","size"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,OAAOA,WAAW,QAAO;AAEzB,SAASC,OAAO,QAAQ,+BAA8B;AACtD,SAASC,IAAI,QAAQ,4BAA2B;AAChD,SAASC,QAAQ,QAAQ,4BAA2B;AACpD,SAASC,IAAI,QAAQ,4BAA2B;AAChD,SAASC,CAAC,QAAQ,yBAAwB;AAC1C,SAASC,cAAc,QAAQ,uCAAsC;AACrE,SAASC,SAAS,QAAQ,oBAAmB;AAC7C,SAASC,KAAK,QAAQ,oBAAmB;AAGzC,MAAMC,YAAY;
|
|
1
|
+
{"version":3,"sources":["../../../src/elements/ArrayAction/index.tsx"],"sourcesContent":["import React from 'react'\n\nimport { Chevron } from '../../icons/Chevron/index.js'\nimport { Copy } from '../../icons/Copy/index.js'\nimport { MoreIcon } from '../../icons/More/index.js'\nimport { Plus } from '../../icons/Plus/index.js'\nimport { X } from '../../icons/X/index.js'\nimport { useTranslation } from '../../providers/Translation/index.js'\nimport { PopupList } from '../Popup/index.js'\nimport { Popup } from '../Popup/index.js'\nimport './index.scss'\n\nconst baseClass = 'array-actions'\n\nexport type Props = {\n addRow: (current: number, blockType?: string) => void\n duplicateRow: (current: number) => void\n hasMaxRows: boolean\n index: number\n isSortable?: boolean\n moveRow: (from: number, to: number) => void\n removeRow: (index: number) => void\n rowCount: number\n}\n\nexport const ArrayAction: React.FC<Props> = ({\n addRow,\n duplicateRow,\n hasMaxRows,\n index,\n isSortable,\n moveRow,\n removeRow,\n rowCount,\n}) => {\n const { t } = useTranslation()\n\n return (\n <Popup\n button={<MoreIcon />}\n buttonClassName={`${baseClass}__button`}\n className={baseClass}\n horizontalAlign=\"center\"\n render={({ close }) => {\n return (\n <PopupList.ButtonGroup buttonSize=\"small\">\n {isSortable && index !== 0 && (\n <PopupList.Button\n className={`${baseClass}__action ${baseClass}__move-up`}\n onClick={() => {\n moveRow(index, index - 1)\n close()\n }}\n >\n <div className={`${baseClass}__action-chevron`}>\n <Chevron direction=\"up\" />\n </div>\n {t('general:moveUp')}\n </PopupList.Button>\n )}\n {isSortable && index < rowCount - 1 && (\n <PopupList.Button\n className={`${baseClass}__action`}\n onClick={() => {\n moveRow(index, index + 1)\n close()\n }}\n >\n <div className={`${baseClass}__action-chevron`}>\n <Chevron />\n </div>\n {t('general:moveDown')}\n </PopupList.Button>\n )}\n {!hasMaxRows && (\n <React.Fragment>\n <PopupList.Button\n className={`${baseClass}__action ${baseClass}__add`}\n onClick={() => {\n addRow(index + 1)\n close()\n }}\n >\n <Plus />\n {t('general:addBelow')}\n </PopupList.Button>\n <PopupList.Button\n className={`${baseClass}__action ${baseClass}__duplicate`}\n onClick={() => {\n duplicateRow(index)\n close()\n }}\n >\n <Copy />\n {t('general:duplicate')}\n </PopupList.Button>\n </React.Fragment>\n )}\n <PopupList.Button\n className={`${baseClass}__action ${baseClass}__remove`}\n onClick={() => {\n removeRow(index)\n close()\n }}\n >\n <X />\n {t('general:remove')}\n </PopupList.Button>\n </PopupList.ButtonGroup>\n )\n }}\n size=\"medium\"\n />\n )\n}\n"],"names":["React","Chevron","Copy","MoreIcon","Plus","X","useTranslation","PopupList","Popup","baseClass","ArrayAction","addRow","duplicateRow","hasMaxRows","index","isSortable","moveRow","removeRow","rowCount","t","button","buttonClassName","className","horizontalAlign","render","close","ButtonGroup","buttonSize","Button","onClick","div","direction","Fragment","size"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,OAAOA,WAAW,QAAO;AAEzB,SAASC,OAAO,QAAQ,+BAA8B;AACtD,SAASC,IAAI,QAAQ,4BAA2B;AAChD,SAASC,QAAQ,QAAQ,4BAA2B;AACpD,SAASC,IAAI,QAAQ,4BAA2B;AAChD,SAASC,CAAC,QAAQ,yBAAwB;AAC1C,SAASC,cAAc,QAAQ,uCAAsC;AACrE,SAASC,SAAS,QAAQ,oBAAmB;AAC7C,SAASC,KAAK,QAAQ,oBAAmB;AAGzC,MAAMC,YAAY;AAalB,OAAO,MAAMC,cAA+B,CAAC,EAC3CC,MAAM,EACNC,YAAY,EACZC,UAAU,EACVC,KAAK,EACLC,UAAU,EACVC,OAAO,EACPC,SAAS,EACTC,QAAQ,EACT;IACC,MAAM,EAAEC,CAAC,EAAE,GAAGb;IAEd,qBACE,oBAACE;QACCY,sBAAQ,oBAACjB;QACTkB,iBAAiB,CAAC,EAAEZ,UAAU,QAAQ,CAAC;QACvCa,WAAWb;QACXc,iBAAgB;QAChBC,QAAQ,CAAC,EAAEC,KAAK,EAAE;YAChB,qBACE,oBAAClB,UAAUmB,WAAW;gBAACC,YAAW;eAC/BZ,cAAcD,UAAU,mBACvB,oBAACP,UAAUqB,MAAM;gBACfN,WAAW,CAAC,EAAEb,UAAU,SAAS,EAAEA,UAAU,SAAS,CAAC;gBACvDoB,SAAS;oBACPb,QAAQF,OAAOA,QAAQ;oBACvBW;gBACF;6BAEA,oBAACK;gBAAIR,WAAW,CAAC,EAAEb,UAAU,gBAAgB,CAAC;6BAC5C,oBAACR;gBAAQ8B,WAAU;iBAEpBZ,EAAE,oBAGNJ,cAAcD,QAAQI,WAAW,mBAChC,oBAACX,UAAUqB,MAAM;gBACfN,WAAW,CAAC,EAAEb,UAAU,QAAQ,CAAC;gBACjCoB,SAAS;oBACPb,QAAQF,OAAOA,QAAQ;oBACvBW;gBACF;6BAEA,oBAACK;gBAAIR,WAAW,CAAC,EAAEb,UAAU,gBAAgB,CAAC;6BAC5C,oBAACR,iBAEFkB,EAAE,sBAGN,CAACN,4BACA,oBAACb,MAAMgC,QAAQ,sBACb,oBAACzB,UAAUqB,MAAM;gBACfN,WAAW,CAAC,EAAEb,UAAU,SAAS,EAAEA,UAAU,KAAK,CAAC;gBACnDoB,SAAS;oBACPlB,OAAOG,QAAQ;oBACfW;gBACF;6BAEA,oBAACrB,aACAe,EAAE,oCAEL,oBAACZ,UAAUqB,MAAM;gBACfN,WAAW,CAAC,EAAEb,UAAU,SAAS,EAAEA,UAAU,WAAW,CAAC;gBACzDoB,SAAS;oBACPjB,aAAaE;oBACbW;gBACF;6BAEA,oBAACvB,aACAiB,EAAE,sCAIT,oBAACZ,UAAUqB,MAAM;gBACfN,WAAW,CAAC,EAAEb,UAAU,SAAS,EAAEA,UAAU,QAAQ,CAAC;gBACtDoB,SAAS;oBACPZ,UAAUH;oBACVW;gBACF;6BAEA,oBAACpB,UACAc,EAAE;QAIX;QACAc,MAAK;;AAGX,EAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/elements/Autosave/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/elements/Autosave/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAG/E,OAAO,KAAsC,MAAM,OAAO,CAAA;AAU1D,OAAO,cAAc,CAAA;AAIrB,MAAM,MAAM,KAAK,GAAG;IAClB,UAAU,CAAC,EAAE,sBAAsB,CAAA;IACnC,MAAM,CAAC,EAAE,kBAAkB,CAAA;IAC3B,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACpB,qBAAqB,EAAE,MAAM,CAAA;CAC9B,CAAA;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAuIpC,CAAA"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
'use client';
|
|
2
|
+
import { useDocumentEvents } from '@payloadcms/ui/providers/DocumentEvents';
|
|
2
3
|
import React, { useEffect, useRef, useState } from 'react';
|
|
3
4
|
import { useAllFormFields, useFormModified } from '../../forms/Form/context.js';
|
|
4
5
|
import { useDebounce } from '../../hooks/useDebounce.js';
|
|
@@ -12,6 +13,7 @@ const baseClass = 'autosave';
|
|
|
12
13
|
export const Autosave = ({ id, collection, global: globalDoc, publishedDocUpdatedAt })=>{
|
|
13
14
|
const { routes: { api }, serverURL } = useConfig();
|
|
14
15
|
const { docConfig, getVersions, versions } = useDocumentInfo();
|
|
16
|
+
const { reportUpdate } = useDocumentEvents();
|
|
15
17
|
const versionsConfig = docConfig?.versions;
|
|
16
18
|
const [fields] = useAllFormFields();
|
|
17
19
|
const modified = useFormModified();
|
|
@@ -43,12 +45,15 @@ export const Autosave = ({ id, collection, global: globalDoc, publishedDocUpdate
|
|
|
43
45
|
setSaving(true);
|
|
44
46
|
let url;
|
|
45
47
|
let method;
|
|
48
|
+
let entitySlug;
|
|
46
49
|
if (collection && id) {
|
|
47
|
-
|
|
50
|
+
entitySlug = collection.slug;
|
|
51
|
+
url = `${serverURL}${api}/${entitySlug}/${id}?draft=true&autosave=true&locale=${localeRef.current}`;
|
|
48
52
|
method = 'PATCH';
|
|
49
53
|
}
|
|
50
54
|
if (globalDoc) {
|
|
51
|
-
|
|
55
|
+
entitySlug = globalDoc.slug;
|
|
56
|
+
url = `${serverURL}${api}/globals/${entitySlug}?draft=true&autosave=true&locale=${localeRef.current}`;
|
|
52
57
|
method = 'POST';
|
|
53
58
|
}
|
|
54
59
|
if (url) {
|
|
@@ -68,7 +73,13 @@ export const Autosave = ({ id, collection, global: globalDoc, publishedDocUpdate
|
|
|
68
73
|
method
|
|
69
74
|
});
|
|
70
75
|
if (res.status === 200) {
|
|
71
|
-
|
|
76
|
+
const newDate = new Date();
|
|
77
|
+
setLastSaved(newDate.getTime());
|
|
78
|
+
reportUpdate({
|
|
79
|
+
id,
|
|
80
|
+
entitySlug,
|
|
81
|
+
updatedAt: newDate.toISOString()
|
|
82
|
+
});
|
|
72
83
|
void getVersions();
|
|
73
84
|
}
|
|
74
85
|
}
|
|
@@ -86,6 +97,7 @@ export const Autosave = ({ id, collection, global: globalDoc, publishedDocUpdate
|
|
|
86
97
|
api,
|
|
87
98
|
collection,
|
|
88
99
|
globalDoc,
|
|
100
|
+
reportUpdate,
|
|
89
101
|
id,
|
|
90
102
|
getVersions
|
|
91
103
|
]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/elements/Autosave/index.tsx"],"sourcesContent":["'use client'\n// TODO: abstract the `next/navigation` dependency out from this component\nimport type { ClientCollectionConfig, ClientGlobalConfig } from 'payload/types'\n\nimport React, { useEffect, useRef, useState } from 'react'\n\nimport { useAllFormFields, useFormModified } from '../../forms/Form/context.js'\nimport { useDebounce } from '../../hooks/useDebounce.js'\nimport { useConfig } from '../../providers/Config/index.js'\nimport { useDocumentInfo } from '../../providers/DocumentInfo/index.js'\nimport { useLocale } from '../../providers/Locale/index.js'\nimport { useTranslation } from '../../providers/Translation/index.js'\nimport { formatTimeToNow } from '../../utilities/formatDate.js'\nimport { reduceFieldsToValues } from '../../utilities/reduceFieldsToValues.js'\nimport './index.scss'\n\nconst baseClass = 'autosave'\n\nexport type Props = {\n collection?: ClientCollectionConfig\n global?: ClientGlobalConfig\n id?: number | string\n publishedDocUpdatedAt: string\n}\n\nexport const Autosave: React.FC<Props> = ({\n id,\n collection,\n global: globalDoc,\n publishedDocUpdatedAt,\n}) => {\n const {\n routes: { api },\n serverURL,\n } = useConfig()\n const { docConfig, getVersions, versions } = useDocumentInfo()\n const versionsConfig = docConfig?.versions\n\n const [fields] = useAllFormFields()\n const modified = useFormModified()\n const { code: locale } = useLocale()\n const { i18n, t } = useTranslation()\n\n let interval = 800\n if (versionsConfig.drafts && versionsConfig?.drafts?.autosave)\n interval = versionsConfig.drafts.autosave.interval\n\n const [saving, setSaving] = useState(false)\n const [lastSaved, setLastSaved] = useState<number>()\n const debouncedFields = useDebounce(fields, interval)\n const fieldRef = useRef(fields)\n const modifiedRef = useRef(modified)\n const localeRef = useRef(locale)\n\n // Store fields in ref so the autosave func\n // can always retrieve the most to date copies\n // after the timeout has executed\n fieldRef.current = fields\n\n // Store modified in ref so the autosave func\n // can bail out if modified becomes false while\n // timing out during autosave\n modifiedRef.current = modified\n\n // Store locale in ref so the autosave func\n // can always retrieve the most to date locale\n localeRef.current = locale\n\n // When debounced fields change, autosave\n useEffect(() => {\n const autosave = () => {\n if (modified) {\n setSaving(true)\n\n let url: string\n let method: string\n\n if (collection && id) {\n url = `${serverURL}${api}/${
|
|
1
|
+
{"version":3,"sources":["../../../src/elements/Autosave/index.tsx"],"sourcesContent":["'use client'\n// TODO: abstract the `next/navigation` dependency out from this component\nimport type { ClientCollectionConfig, ClientGlobalConfig } from 'payload/types'\n\nimport { useDocumentEvents } from '@payloadcms/ui/providers/DocumentEvents'\nimport React, { useEffect, useRef, useState } from 'react'\n\nimport { useAllFormFields, useFormModified } from '../../forms/Form/context.js'\nimport { useDebounce } from '../../hooks/useDebounce.js'\nimport { useConfig } from '../../providers/Config/index.js'\nimport { useDocumentInfo } from '../../providers/DocumentInfo/index.js'\nimport { useLocale } from '../../providers/Locale/index.js'\nimport { useTranslation } from '../../providers/Translation/index.js'\nimport { formatTimeToNow } from '../../utilities/formatDate.js'\nimport { reduceFieldsToValues } from '../../utilities/reduceFieldsToValues.js'\nimport './index.scss'\n\nconst baseClass = 'autosave'\n\nexport type Props = {\n collection?: ClientCollectionConfig\n global?: ClientGlobalConfig\n id?: number | string\n publishedDocUpdatedAt: string\n}\n\nexport const Autosave: React.FC<Props> = ({\n id,\n collection,\n global: globalDoc,\n publishedDocUpdatedAt,\n}) => {\n const {\n routes: { api },\n serverURL,\n } = useConfig()\n const { docConfig, getVersions, versions } = useDocumentInfo()\n const { reportUpdate } = useDocumentEvents()\n const versionsConfig = docConfig?.versions\n\n const [fields] = useAllFormFields()\n const modified = useFormModified()\n const { code: locale } = useLocale()\n const { i18n, t } = useTranslation()\n\n let interval = 800\n if (versionsConfig.drafts && versionsConfig?.drafts?.autosave)\n interval = versionsConfig.drafts.autosave.interval\n\n const [saving, setSaving] = useState(false)\n const [lastSaved, setLastSaved] = useState<number>()\n const debouncedFields = useDebounce(fields, interval)\n const fieldRef = useRef(fields)\n const modifiedRef = useRef(modified)\n const localeRef = useRef(locale)\n\n // Store fields in ref so the autosave func\n // can always retrieve the most to date copies\n // after the timeout has executed\n fieldRef.current = fields\n\n // Store modified in ref so the autosave func\n // can bail out if modified becomes false while\n // timing out during autosave\n modifiedRef.current = modified\n\n // Store locale in ref so the autosave func\n // can always retrieve the most to date locale\n localeRef.current = locale\n\n // When debounced fields change, autosave\n useEffect(() => {\n const autosave = () => {\n if (modified) {\n setSaving(true)\n\n let url: string\n let method: string\n let entitySlug: string\n\n if (collection && id) {\n entitySlug = collection.slug\n url = `${serverURL}${api}/${entitySlug}/${id}?draft=true&autosave=true&locale=${localeRef.current}`\n method = 'PATCH'\n }\n\n if (globalDoc) {\n entitySlug = globalDoc.slug\n url = `${serverURL}${api}/globals/${entitySlug}?draft=true&autosave=true&locale=${localeRef.current}`\n method = 'POST'\n }\n\n if (url) {\n setTimeout(async () => {\n if (modifiedRef.current) {\n const body = {\n ...reduceFieldsToValues(fieldRef.current, true),\n _status: 'draft',\n }\n const res = await fetch(url, {\n body: JSON.stringify(body),\n credentials: 'include',\n headers: {\n 'Accept-Language': i18n.language,\n 'Content-Type': 'application/json',\n },\n method,\n })\n\n if (res.status === 200) {\n const newDate = new Date()\n setLastSaved(newDate.getTime())\n reportUpdate({\n id,\n entitySlug,\n updatedAt: newDate.toISOString(),\n })\n void getVersions()\n }\n }\n\n setSaving(false)\n }, 1000)\n }\n }\n }\n\n void autosave()\n }, [\n i18n,\n debouncedFields,\n modified,\n serverURL,\n api,\n collection,\n globalDoc,\n reportUpdate,\n id,\n getVersions,\n ])\n\n useEffect(() => {\n if (versions?.docs?.[0]) {\n setLastSaved(new Date(versions.docs[0].updatedAt).getTime())\n } else if (publishedDocUpdatedAt) {\n setLastSaved(new Date(publishedDocUpdatedAt).getTime())\n }\n }, [publishedDocUpdatedAt, versions])\n\n return (\n <div className={baseClass}>\n {saving && t('general:saving')}\n {!saving && lastSaved && (\n <React.Fragment>\n {t('version:lastSavedAgo', {\n distance: formatTimeToNow({ date: lastSaved, i18n }),\n })}\n </React.Fragment>\n )}\n </div>\n )\n}\n"],"names":["useDocumentEvents","React","useEffect","useRef","useState","useAllFormFields","useFormModified","useDebounce","useConfig","useDocumentInfo","useLocale","useTranslation","formatTimeToNow","reduceFieldsToValues","baseClass","Autosave","id","collection","global","globalDoc","publishedDocUpdatedAt","routes","api","serverURL","docConfig","getVersions","versions","reportUpdate","versionsConfig","fields","modified","code","locale","i18n","t","interval","drafts","autosave","saving","setSaving","lastSaved","setLastSaved","debouncedFields","fieldRef","modifiedRef","localeRef","current","url","method","entitySlug","slug","setTimeout","body","_status","res","fetch","JSON","stringify","credentials","headers","language","status","newDate","Date","getTime","updatedAt","toISOString","docs","div","className","Fragment","distance","date"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
position: sticky;
|
|
6
6
|
top: 0;
|
|
7
7
|
width: 100%;
|
|
8
|
-
z-index:
|
|
8
|
+
z-index: 5;
|
|
9
9
|
display: flex;
|
|
10
10
|
align-items: center;
|
|
11
11
|
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
align-items: center;
|
|
28
28
|
gap: var(--base);
|
|
29
29
|
padding-bottom: 1px;
|
|
30
|
-
z-index:
|
|
30
|
+
z-index: 4;
|
|
31
31
|
height: var(--doc-controls-height);
|
|
32
32
|
}
|
|
33
33
|
|
|
@@ -1,14 +1,26 @@
|
|
|
1
1
|
import type { Data } from 'payload/types';
|
|
2
|
+
import type CropType from 'react-image-crop';
|
|
2
3
|
import React from 'react';
|
|
3
4
|
import 'react-image-crop/dist/ReactCrop.css';
|
|
4
5
|
import './index.scss';
|
|
6
|
+
type FocalPosition = {
|
|
7
|
+
x: number;
|
|
8
|
+
y: number;
|
|
9
|
+
};
|
|
5
10
|
export type EditUploadProps = {
|
|
6
11
|
doc?: Data;
|
|
7
12
|
fileName: string;
|
|
8
13
|
fileSrc: string;
|
|
9
14
|
imageCacheTag?: string;
|
|
15
|
+
initialCrop?: CropType;
|
|
16
|
+
initialFocalPoint?: FocalPosition;
|
|
17
|
+
onSave?: ({ crop, pointPosition }: {
|
|
18
|
+
crop: CropType;
|
|
19
|
+
pointPosition: FocalPosition;
|
|
20
|
+
}) => void;
|
|
10
21
|
showCrop?: boolean;
|
|
11
22
|
showFocalPoint?: boolean;
|
|
12
23
|
};
|
|
13
24
|
export declare const EditUpload: React.FC<EditUploadProps>;
|
|
25
|
+
export {};
|
|
14
26
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/elements/EditUpload/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/elements/EditUpload/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAA;AAG5C,OAAO,KAA2B,MAAM,OAAO,CAAA;AAE/C,OAAO,qCAAqC,CAAA;AAM5C,OAAO,cAAc,CAAA;AAerB,KAAK,aAAa,GAAG;IACnB,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;CACV,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,GAAG,CAAC,EAAE,IAAI,CAAA;IACV,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,WAAW,CAAC,EAAE,QAAQ,CAAA;IACtB,iBAAiB,CAAC,EAAE,aAAa,CAAA;IACjC,MAAM,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,aAAa,EAAE,aAAa,CAAA;KAAE,KAAK,IAAI,CAAA;IAC5F,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB,CAAA;AAeD,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAgPhD,CAAA"}
|
|
@@ -4,7 +4,6 @@ import React, { useRef, useState } from 'react';
|
|
|
4
4
|
import ReactCrop from 'react-image-crop';
|
|
5
5
|
import { editDrawerSlug } from '../../elements/Upload/index.js';
|
|
6
6
|
import { Plus } from '../../icons/Plus/index.js';
|
|
7
|
-
import { useFormQueryParams } from '../../providers/FormQueryParams/index.js';
|
|
8
7
|
import { useTranslation } from '../../providers/Translation/index.js';
|
|
9
8
|
import { Button } from '../Button/index.js';
|
|
10
9
|
const baseClass = 'edit-upload';
|
|
@@ -16,23 +15,29 @@ const Input = ({ name, onChange, value })=>/*#__PURE__*/ React.createElement("di
|
|
|
16
15
|
type: "number",
|
|
17
16
|
value: value
|
|
18
17
|
}));
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
const defaultCrop = {
|
|
19
|
+
height: 100,
|
|
20
|
+
unit: '%',
|
|
21
|
+
width: 100,
|
|
22
|
+
x: 0,
|
|
23
|
+
y: 0
|
|
24
|
+
};
|
|
25
|
+
const defaultPointPosition = {
|
|
26
|
+
x: 50,
|
|
27
|
+
y: 50
|
|
28
|
+
};
|
|
29
|
+
export const EditUpload = ({ fileName, fileSrc, imageCacheTag, initialCrop, initialFocalPoint, onSave, showCrop, showFocalPoint })=>{
|
|
30
|
+
const { useModal } = facelessUIImport;
|
|
21
31
|
const { closeModal } = useModal();
|
|
22
32
|
const { t } = useTranslation();
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
});
|
|
32
|
-
const [pointPosition, setPointPosition] = useState({
|
|
33
|
-
x: uploadEdits?.focalPoint?.x || 50,
|
|
34
|
-
y: uploadEdits?.focalPoint?.y || 50
|
|
35
|
-
});
|
|
33
|
+
const [crop, setCrop] = useState(()=>({
|
|
34
|
+
...defaultCrop,
|
|
35
|
+
...initialCrop
|
|
36
|
+
}));
|
|
37
|
+
const [pointPosition, setPointPosition] = useState(()=>({
|
|
38
|
+
...defaultPointPosition,
|
|
39
|
+
...initialFocalPoint
|
|
40
|
+
}));
|
|
36
41
|
const [checkBounds, setCheckBounds] = useState(false);
|
|
37
42
|
const [originalHeight, setOriginalHeight] = useState(0);
|
|
38
43
|
const [originalWidth, setOriginalWidth] = useState(0);
|
|
@@ -60,14 +65,9 @@ export const EditUpload = ({ fileName, fileSrc, imageCacheTag, showCrop, showFoc
|
|
|
60
65
|
}
|
|
61
66
|
};
|
|
62
67
|
const saveEdits = ()=>{
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
uploadEdits: crop || pointPosition ? {
|
|
67
|
-
crop: crop || null,
|
|
68
|
-
focalPoint: pointPosition ? pointPosition : null
|
|
69
|
-
} : null
|
|
70
|
-
}
|
|
68
|
+
if (typeof onSave === 'function') onSave({
|
|
69
|
+
crop,
|
|
70
|
+
pointPosition
|
|
71
71
|
});
|
|
72
72
|
closeModal(editDrawerSlug);
|
|
73
73
|
};
|
|
@@ -106,7 +106,7 @@ export const EditUpload = ({ fileName, fileSrc, imageCacheTag, showCrop, showFoc
|
|
|
106
106
|
"aria-label": t('general:applyChanges'),
|
|
107
107
|
buttonStyle: "primary",
|
|
108
108
|
className: `${baseClass}__save`,
|
|
109
|
-
onClick:
|
|
109
|
+
onClick: saveEdits
|
|
110
110
|
}, t('general:applyChanges')))), /*#__PURE__*/ React.createElement("div", {
|
|
111
111
|
className: `${baseClass}__toolWrap`
|
|
112
112
|
}, /*#__PURE__*/ React.createElement("div", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/elements/EditUpload/index.tsx"],"sourcesContent":["'use client'\nimport type { Data } from 'payload/types'\nimport type CropType from 'react-image-crop'\n\nimport * as facelessUIImport from '@faceless-ui/modal'\nimport React, { useRef, useState } from 'react'\nimport ReactCrop from 'react-image-crop'\nimport 'react-image-crop/dist/ReactCrop.css'\n\nimport { editDrawerSlug } from '../../elements/Upload/index.js'\nimport { Plus } from '../../icons/Plus/index.js'\nimport { useFormQueryParams } from '../../providers/FormQueryParams/index.js'\nimport { useTranslation } from '../../providers/Translation/index.js'\nimport { Button } from '../Button/index.js'\nimport './index.scss'\n\nconst baseClass = 'edit-upload'\n\nconst Input: React.FC<{ name: string; onChange: (value: string) => void; value: string }> = ({\n name,\n onChange,\n value,\n}) => (\n <div className={`${baseClass}__input`}>\n {name}\n <input name={name} onChange={(e) => onChange(e.target.value)} type=\"number\" value={value} />\n </div>\n)\n\nexport type EditUploadProps = {\n doc?: Data\n fileName: string\n fileSrc: string\n imageCacheTag?: string\n showCrop?: boolean\n showFocalPoint?: boolean\n}\n\nexport const EditUpload: React.FC<EditUploadProps> = ({\n fileName,\n fileSrc,\n imageCacheTag,\n showCrop,\n showFocalPoint,\n}) => {\n const { Modal, useModal } = facelessUIImport\n\n const { closeModal } = useModal()\n const { t } = useTranslation()\n const { dispatchFormQueryParams, formQueryParams } = useFormQueryParams()\n const { uploadEdits } = formQueryParams || {}\n const [crop, setCrop] = useState<CropType>({\n height: uploadEdits?.crop?.height || 100,\n unit: '%',\n width: uploadEdits?.crop?.width || 100,\n x: uploadEdits?.crop?.x || 0,\n y: uploadEdits?.crop?.y || 0,\n })\n\n const [pointPosition, setPointPosition] = useState<{ x: number; y: number }>({\n x: uploadEdits?.focalPoint?.x || 50,\n y: uploadEdits?.focalPoint?.y || 50,\n })\n const [checkBounds, setCheckBounds] = useState<boolean>(false)\n const [originalHeight, setOriginalHeight] = useState<number>(0)\n const [originalWidth, setOriginalWidth] = useState<number>(0)\n\n const focalWrapRef = useRef<HTMLDivElement | undefined>()\n const imageRef = useRef<HTMLImageElement | undefined>()\n const cropRef = useRef<HTMLDivElement | undefined>()\n\n const fineTuneCrop = ({ dimension, value }: { dimension: 'height' | 'width'; value: string }) => {\n const intValue = parseInt(value)\n if (dimension === 'width' && intValue >= originalWidth) return null\n if (dimension === 'height' && intValue >= originalHeight) return null\n\n const percentage = 100 * (intValue / (dimension === 'width' ? originalWidth : originalHeight))\n\n if (percentage === 100 || percentage === 0) return null\n\n setCrop({\n ...crop,\n [dimension]: percentage,\n })\n }\n\n const fineTuneFocalPoint = ({ coordinate, value }: { coordinate: 'x' | 'y'; value: string }) => {\n const intValue = parseInt(value)\n if (intValue >= 0 && intValue <= 100) {\n setPointPosition((prevPosition) => ({ ...prevPosition, [coordinate]: intValue }))\n }\n }\n\n const saveEdits = () => {\n dispatchFormQueryParams({\n type: 'SET',\n params: {\n uploadEdits:\n crop || pointPosition\n ? {\n crop: crop || null,\n focalPoint: pointPosition ? pointPosition : null,\n }\n : null,\n },\n })\n closeModal(editDrawerSlug)\n }\n\n const onDragEnd = React.useCallback(({ x, y }) => {\n setPointPosition({ x, y })\n setCheckBounds(false)\n }, [])\n\n const centerFocalPoint = () => {\n const containerRect = focalWrapRef.current.getBoundingClientRect()\n const boundsRect = showCrop\n ? cropRef.current.getBoundingClientRect()\n : imageRef.current.getBoundingClientRect()\n const xCenter =\n ((boundsRect.left - containerRect.left + boundsRect.width / 2) / containerRect.width) * 100\n const yCenter =\n ((boundsRect.top - containerRect.top + boundsRect.height / 2) / containerRect.height) * 100\n setPointPosition({ x: xCenter, y: yCenter })\n }\n\n const fileSrcToUse = imageCacheTag ? `${fileSrc}?${imageCacheTag}` : fileSrc\n\n return (\n <div className={baseClass}>\n <div className={`${baseClass}__header`}>\n <h2 title={`${t('general:editing')} ${fileName}`}>\n {t('general:editing')} {fileName}\n </h2>\n <div className={`${baseClass}__actions`}>\n <Button\n aria-label={t('general:cancel')}\n buttonStyle=\"secondary\"\n className={`${baseClass}__cancel`}\n onClick={() => closeModal(editDrawerSlug)}\n >\n {t('general:cancel')}\n </Button>\n <Button\n aria-label={t('general:applyChanges')}\n buttonStyle=\"primary\"\n className={`${baseClass}__save`}\n onClick={() => saveEdits()}\n >\n {t('general:applyChanges')}\n </Button>\n </div>\n </div>\n <div className={`${baseClass}__toolWrap`}>\n <div className={`${baseClass}__crop`}>\n <div\n className={`${baseClass}__focal-wrapper`}\n ref={focalWrapRef}\n style={{\n aspectRatio: `${originalWidth / originalHeight}`,\n }}\n >\n {showCrop ? (\n <ReactCrop\n className={`${baseClass}__reactCrop`}\n crop={crop}\n onChange={(_, c) => setCrop(c)}\n onComplete={() => setCheckBounds(true)}\n renderSelectionAddon={() => {\n return <div className={`${baseClass}__crop-window`} ref={cropRef} />\n }}\n >\n <img\n alt={t('upload:setCropArea')}\n onLoad={(e) => {\n setOriginalHeight(e.currentTarget.naturalHeight)\n setOriginalWidth(e.currentTarget.naturalWidth)\n }}\n ref={imageRef}\n src={fileSrcToUse}\n />\n </ReactCrop>\n ) : (\n <img\n alt={t('upload:setFocalPoint')}\n onLoad={(e) => {\n setOriginalHeight(e.currentTarget.naturalHeight)\n setOriginalWidth(e.currentTarget.naturalWidth)\n }}\n ref={imageRef}\n src={fileSrcToUse}\n />\n )}\n {showFocalPoint && (\n <DraggableElement\n boundsRef={showCrop ? cropRef : imageRef}\n checkBounds={showCrop ? checkBounds : false}\n className={`${baseClass}__focalPoint`}\n containerRef={focalWrapRef}\n initialPosition={pointPosition}\n onDragEnd={onDragEnd}\n setCheckBounds={showCrop ? setCheckBounds : false}\n >\n <Plus />\n </DraggableElement>\n )}\n </div>\n </div>\n {(showCrop || showFocalPoint) && (\n <div className={`${baseClass}__sidebar`}>\n {showCrop && (\n <div className={`${baseClass}__groupWrap`}>\n <div>\n <div className={`${baseClass}__titleWrap`}>\n <h3>{t('upload:crop')}</h3>\n <Button\n buttonStyle=\"none\"\n className={`${baseClass}__reset`}\n onClick={() =>\n setCrop({\n height: 100,\n unit: '%',\n width: 100,\n x: 0,\n y: 0,\n })\n }\n >\n {t('general:reset')}\n </Button>\n </div>\n </div>\n <span className={`${baseClass}__description`}>\n {t('upload:cropToolDescription')}\n </span>\n <div className={`${baseClass}__inputsWrap`}>\n <Input\n name={`${t('upload:width')} (px)`}\n onChange={(value) => fineTuneCrop({ dimension: 'width', value })}\n value={((crop.width / 100) * originalWidth).toFixed(0)}\n />\n <Input\n name={`${t('upload:height')} (px)`}\n onChange={(value) => fineTuneCrop({ dimension: 'height', value })}\n value={((crop.height / 100) * originalHeight).toFixed(0)}\n />\n </div>\n </div>\n )}\n\n {showFocalPoint && (\n <div className={`${baseClass}__groupWrap`}>\n <div>\n <div className={`${baseClass}__titleWrap`}>\n <h3>{t('upload:focalPoint')}</h3>\n <Button\n buttonStyle=\"none\"\n className={`${baseClass}__reset`}\n onClick={centerFocalPoint}\n >\n {t('general:reset')}\n </Button>\n </div>\n </div>\n <span className={`${baseClass}__description`}>\n {t('upload:focalPointDescription')}\n </span>\n <div className={`${baseClass}__inputsWrap`}>\n <Input\n name=\"X %\"\n onChange={(value) => fineTuneFocalPoint({ coordinate: 'x', value })}\n value={pointPosition.x.toFixed(0)}\n />\n <Input\n name=\"Y %\"\n onChange={(value) => fineTuneFocalPoint({ coordinate: 'y', value })}\n value={pointPosition.y.toFixed(0)}\n />\n </div>\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n )\n}\n\nconst DraggableElement = ({\n boundsRef,\n checkBounds,\n children,\n className,\n containerRef,\n initialPosition = { x: 50, y: 50 },\n onDragEnd,\n setCheckBounds,\n}) => {\n const [position, setPosition] = useState({ x: initialPosition.x, y: initialPosition.y })\n const [isDragging, setIsDragging] = useState(false)\n const dragRef = useRef<HTMLButtonElement | undefined>()\n\n const getCoordinates = React.useCallback(\n (mouseXArg?: number, mouseYArg?: number, recenter?: boolean) => {\n const containerRect = containerRef.current.getBoundingClientRect()\n const boundsRect = boundsRef.current.getBoundingClientRect()\n const mouseX = mouseXArg ?? boundsRect.left\n const mouseY = mouseYArg ?? boundsRect.top\n\n const xOutOfBounds = mouseX < boundsRect.left || mouseX > boundsRect.right\n const yOutOfBounds = mouseY < boundsRect.top || mouseY > boundsRect.bottom\n\n let x = ((mouseX - containerRect.left) / containerRect.width) * 100\n let y = ((mouseY - containerRect.top) / containerRect.height) * 100\n const xCenter =\n ((boundsRect.left - containerRect.left + boundsRect.width / 2) / containerRect.width) * 100\n const yCenter =\n ((boundsRect.top - containerRect.top + boundsRect.height / 2) / containerRect.height) * 100\n if (xOutOfBounds || yOutOfBounds) {\n setIsDragging(false)\n if (mouseX < boundsRect.left) {\n x = ((boundsRect.left - containerRect.left) / containerRect.width) * 100\n } else if (mouseX > boundsRect.right) {\n x =\n ((containerRect.width - (containerRect.right - boundsRect.right)) /\n containerRect.width) *\n 100\n }\n\n if (mouseY < boundsRect.top) {\n y = ((boundsRect.top - containerRect.top) / containerRect.height) * 100\n } else if (mouseY > boundsRect.bottom) {\n y =\n ((containerRect.height - (containerRect.bottom - boundsRect.bottom)) /\n containerRect.height) *\n 100\n }\n\n if (recenter) {\n x = xOutOfBounds ? xCenter : x\n y = yOutOfBounds ? yCenter : y\n }\n }\n\n return { x, y }\n },\n [boundsRef, containerRef],\n )\n\n const handleMouseDown = (event) => {\n event.preventDefault()\n setIsDragging(true)\n }\n\n const handleMouseMove = (event) => {\n if (!isDragging) return null\n const { x, y } = getCoordinates(event.clientX, event.clientY)\n\n setPosition({ x, y })\n }\n\n const onDrop = () => {\n setIsDragging(false)\n onDragEnd(position)\n }\n\n React.useEffect(() => {\n if (isDragging || !dragRef.current) return\n if (checkBounds) {\n const { height, left, top, width } = dragRef.current.getBoundingClientRect()\n const { x, y } = getCoordinates(left + width / 2, top + height / 2, true)\n onDragEnd({ x, y })\n setPosition({ x, y })\n setCheckBounds(false)\n return\n }\n }, [getCoordinates, isDragging, checkBounds, setCheckBounds, position.x, position.y, onDragEnd])\n\n React.useEffect(() => {\n setPosition({ x: initialPosition.x, y: initialPosition.y })\n }, [initialPosition.x, initialPosition.y])\n\n return (\n <div\n className={[\n `${baseClass}__draggable-container`,\n isDragging && `${baseClass}__draggable-container--dragging`,\n ]\n .filter(Boolean)\n .join(' ')}\n onMouseMove={handleMouseMove}\n >\n <button\n className={[`${baseClass}__draggable`, className].filter(Boolean).join(' ')}\n onMouseDown={handleMouseDown}\n onMouseUp={onDrop}\n ref={dragRef}\n style={{ left: `${position.x}%`, top: `${position.y}%` }}\n type=\"button\"\n >\n {children}\n </button>\n <div />\n </div>\n )\n}\n"],"names":["facelessUIImport","React","useRef","useState","ReactCrop","editDrawerSlug","Plus","useFormQueryParams","useTranslation","Button","baseClass","Input","name","onChange","value","div","className","input","e","target","type","EditUpload","fileName","fileSrc","imageCacheTag","showCrop","showFocalPoint","Modal","useModal","closeModal","t","dispatchFormQueryParams","formQueryParams","uploadEdits","crop","setCrop","height","unit","width","x","y","pointPosition","setPointPosition","focalPoint","checkBounds","setCheckBounds","originalHeight","setOriginalHeight","originalWidth","setOriginalWidth","focalWrapRef","imageRef","cropRef","fineTuneCrop","dimension","intValue","parseInt","percentage","fineTuneFocalPoint","coordinate","prevPosition","saveEdits","params","onDragEnd","useCallback","centerFocalPoint","containerRect","current","getBoundingClientRect","boundsRect","xCenter","left","yCenter","top","fileSrcToUse","h2","title","aria-label","buttonStyle","onClick","ref","style","aspectRatio","_","c","onComplete","renderSelectionAddon","img","alt","onLoad","currentTarget","naturalHeight","naturalWidth","src","DraggableElement","boundsRef","containerRef","initialPosition","h3","span","toFixed","children","position","setPosition","isDragging","setIsDragging","dragRef","getCoordinates","mouseXArg","mouseYArg","recenter","mouseX","mouseY","xOutOfBounds","right","yOutOfBounds","bottom","handleMouseDown","event","preventDefault","handleMouseMove","clientX","clientY","onDrop","useEffect","filter","Boolean","join","onMouseMove","button","onMouseDown","onMouseUp"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA;AAIA,YAAYA,sBAAsB,qBAAoB;AACtD,OAAOC,SAASC,MAAM,EAAEC,QAAQ,QAAQ,QAAO;AAC/C,OAAOC,eAAe,mBAAkB;AAGxC,SAASC,cAAc,QAAQ,iCAAgC;AAC/D,SAASC,IAAI,QAAQ,4BAA2B;AAChD,SAASC,kBAAkB,QAAQ,2CAA0C;AAC7E,SAASC,cAAc,QAAQ,uCAAsC;AACrE,SAASC,MAAM,QAAQ,qBAAoB;AAG3C,MAAMC,YAAY;AAElB,MAAMC,QAAsF,CAAC,EAC3FC,IAAI,EACJC,QAAQ,EACRC,KAAK,EACN,iBACC,oBAACC;QAAIC,WAAW,CAAC,EAAEN,UAAU,OAAO,CAAC;OAClCE,oBACD,oBAACK;QAAML,MAAMA;QAAMC,UAAU,CAACK,IAAML,SAASK,EAAEC,MAAM,CAACL,KAAK;QAAGM,MAAK;QAASN,OAAOA;;AAavF,OAAO,MAAMO,aAAwC,CAAC,EACpDC,QAAQ,EACRC,OAAO,EACPC,aAAa,EACbC,QAAQ,EACRC,cAAc,EACf;IACC,MAAM,EAAEC,KAAK,EAAEC,QAAQ,EAAE,GAAG5B;IAE5B,MAAM,EAAE6B,UAAU,EAAE,GAAGD;IACvB,MAAM,EAAEE,CAAC,EAAE,GAAGtB;IACd,MAAM,EAAEuB,uBAAuB,EAAEC,eAAe,EAAE,GAAGzB;IACrD,MAAM,EAAE0B,WAAW,EAAE,GAAGD,mBAAmB,CAAC;IAC5C,MAAM,CAACE,MAAMC,QAAQ,GAAGhC,SAAmB;QACzCiC,QAAQH,aAAaC,MAAME,UAAU;QACrCC,MAAM;QACNC,OAAOL,aAAaC,MAAMI,SAAS;QACnCC,GAAGN,aAAaC,MAAMK,KAAK;QAC3BC,GAAGP,aAAaC,MAAMM,KAAK;IAC7B;IAEA,MAAM,CAACC,eAAeC,iBAAiB,GAAGvC,SAAmC;QAC3EoC,GAAGN,aAAaU,YAAYJ,KAAK;QACjCC,GAAGP,aAAaU,YAAYH,KAAK;IACnC;IACA,MAAM,CAACI,aAAaC,eAAe,GAAG1C,SAAkB;IACxD,MAAM,CAAC2C,gBAAgBC,kBAAkB,GAAG5C,SAAiB;IAC7D,MAAM,CAAC6C,eAAeC,iBAAiB,GAAG9C,SAAiB;IAE3D,MAAM+C,eAAehD;IACrB,MAAMiD,WAAWjD;IACjB,MAAMkD,UAAUlD;IAEhB,MAAMmD,eAAe,CAAC,EAAEC,SAAS,EAAExC,KAAK,EAAoD;QAC1F,MAAMyC,WAAWC,SAAS1C;QAC1B,IAAIwC,cAAc,WAAWC,YAAYP,eAAe,OAAO;QAC/D,IAAIM,cAAc,YAAYC,YAAYT,gBAAgB,OAAO;QAEjE,MAAMW,aAAa,MAAOF,CAAAA,WAAYD,CAAAA,cAAc,UAAUN,gBAAgBF,cAAa,CAAC;QAE5F,IAAIW,eAAe,OAAOA,eAAe,GAAG,OAAO;QAEnDtB,QAAQ;YACN,GAAGD,IAAI;YACP,CAACoB,UAAU,EAAEG;QACf;IACF;IAEA,MAAMC,qBAAqB,CAAC,EAAEC,UAAU,EAAE7C,KAAK,EAA4C;QACzF,MAAMyC,WAAWC,SAAS1C;QAC1B,IAAIyC,YAAY,KAAKA,YAAY,KAAK;YACpCb,iBAAiB,CAACkB,eAAkB,CAAA;oBAAE,GAAGA,YAAY;oBAAE,CAACD,WAAW,EAAEJ;gBAAS,CAAA;QAChF;IACF;IAEA,MAAMM,YAAY;QAChB9B,wBAAwB;YACtBX,MAAM;YACN0C,QAAQ;gBACN7B,aACEC,QAAQO,gBACJ;oBACEP,MAAMA,QAAQ;oBACdS,YAAYF,gBAAgBA,gBAAgB;gBAC9C,IACA;YACR;QACF;QACAZ,WAAWxB;IACb;IAEA,MAAM0D,YAAY9D,MAAM+D,WAAW,CAAC,CAAC,EAAEzB,CAAC,EAAEC,CAAC,EAAE;QAC3CE,iBAAiB;YAAEH;YAAGC;QAAE;QACxBK,eAAe;IACjB,GAAG,EAAE;IAEL,MAAMoB,mBAAmB;QACvB,MAAMC,gBAAgBhB,aAAaiB,OAAO,CAACC,qBAAqB;QAChE,MAAMC,aAAa5C,WACf2B,QAAQe,OAAO,CAACC,qBAAqB,KACrCjB,SAASgB,OAAO,CAACC,qBAAqB;QAC1C,MAAME,UACJ,AAAED,CAAAA,WAAWE,IAAI,GAAGL,cAAcK,IAAI,GAAGF,WAAW/B,KAAK,GAAG,CAAA,IAAK4B,cAAc5B,KAAK,GAAI;QAC1F,MAAMkC,UACJ,AAAEH,CAAAA,WAAWI,GAAG,GAAGP,cAAcO,GAAG,GAAGJ,WAAWjC,MAAM,GAAG,CAAA,IAAK8B,cAAc9B,MAAM,GAAI;QAC1FM,iBAAiB;YAAEH,GAAG+B;YAAS9B,GAAGgC;QAAQ;IAC5C;IAEA,MAAME,eAAelD,gBAAgB,CAAC,EAAED,QAAQ,CAAC,EAAEC,cAAc,CAAC,GAAGD;IAErE,qBACE,oBAACR;QAAIC,WAAWN;qBACd,oBAACK;QAAIC,WAAW,CAAC,EAAEN,UAAU,QAAQ,CAAC;qBACpC,oBAACiE;QAAGC,OAAO,CAAC,EAAE9C,EAAE,mBAAmB,CAAC,EAAER,SAAS,CAAC;OAC7CQ,EAAE,oBAAmB,KAAER,yBAE1B,oBAACP;QAAIC,WAAW,CAAC,EAAEN,UAAU,SAAS,CAAC;qBACrC,oBAACD;QACCoE,cAAY/C,EAAE;QACdgD,aAAY;QACZ9D,WAAW,CAAC,EAAEN,UAAU,QAAQ,CAAC;QACjCqE,SAAS,IAAMlD,WAAWxB;OAEzByB,EAAE,kCAEL,oBAACrB;QACCoE,cAAY/C,EAAE;QACdgD,aAAY;QACZ9D,WAAW,CAAC,EAAEN,UAAU,MAAM,CAAC;QAC/BqE,SAAS,IAAMlB;OAEd/B,EAAE,0CAIT,oBAACf;QAAIC,WAAW,CAAC,EAAEN,UAAU,UAAU,CAAC;qBACtC,oBAACK;QAAIC,WAAW,CAAC,EAAEN,UAAU,MAAM,CAAC;qBAClC,oBAACK;QACCC,WAAW,CAAC,EAAEN,UAAU,eAAe,CAAC;QACxCsE,KAAK9B;QACL+B,OAAO;YACLC,aAAa,CAAC,EAAElC,gBAAgBF,eAAe,CAAC;QAClD;OAECrB,yBACC,oBAACrB;QACCY,WAAW,CAAC,EAAEN,UAAU,WAAW,CAAC;QACpCwB,MAAMA;QACNrB,UAAU,CAACsE,GAAGC,IAAMjD,QAAQiD;QAC5BC,YAAY,IAAMxC,eAAe;QACjCyC,sBAAsB;YACpB,qBAAO,oBAACvE;gBAAIC,WAAW,CAAC,EAAEN,UAAU,aAAa,CAAC;gBAAEsE,KAAK5B;;QAC3D;qBAEA,oBAACmC;QACCC,KAAK1D,EAAE;QACP2D,QAAQ,CAACvE;YACP6B,kBAAkB7B,EAAEwE,aAAa,CAACC,aAAa;YAC/C1C,iBAAiB/B,EAAEwE,aAAa,CAACE,YAAY;QAC/C;QACAZ,KAAK7B;QACL0C,KAAKnB;wBAIT,oBAACa;QACCC,KAAK1D,EAAE;QACP2D,QAAQ,CAACvE;YACP6B,kBAAkB7B,EAAEwE,aAAa,CAACC,aAAa;YAC/C1C,iBAAiB/B,EAAEwE,aAAa,CAACE,YAAY;QAC/C;QACAZ,KAAK7B;QACL0C,KAAKnB;QAGRhD,gCACC,oBAACoE;QACCC,WAAWtE,WAAW2B,UAAUD;QAChCP,aAAanB,WAAWmB,cAAc;QACtC5B,WAAW,CAAC,EAAEN,UAAU,YAAY,CAAC;QACrCsF,cAAc9C;QACd+C,iBAAiBxD;QACjBsB,WAAWA;QACXlB,gBAAgBpB,WAAWoB,iBAAiB;qBAE5C,oBAACvC,gBAKR,AAACmB,CAAAA,YAAYC,cAAa,mBACzB,oBAACX;QAAIC,WAAW,CAAC,EAAEN,UAAU,SAAS,CAAC;OACpCe,0BACC,oBAACV;QAAIC,WAAW,CAAC,EAAEN,UAAU,WAAW,CAAC;qBACvC,oBAACK,2BACC,oBAACA;QAAIC,WAAW,CAAC,EAAEN,UAAU,WAAW,CAAC;qBACvC,oBAACwF,YAAIpE,EAAE,+BACP,oBAACrB;QACCqE,aAAY;QACZ9D,WAAW,CAAC,EAAEN,UAAU,OAAO,CAAC;QAChCqE,SAAS,IACP5C,QAAQ;gBACNC,QAAQ;gBACRC,MAAM;gBACNC,OAAO;gBACPC,GAAG;gBACHC,GAAG;YACL;OAGDV,EAAE,mCAIT,oBAACqE;QAAKnF,WAAW,CAAC,EAAEN,UAAU,aAAa,CAAC;OACzCoB,EAAE,8CAEL,oBAACf;QAAIC,WAAW,CAAC,EAAEN,UAAU,YAAY,CAAC;qBACxC,oBAACC;QACCC,MAAM,CAAC,EAAEkB,EAAE,gBAAgB,KAAK,CAAC;QACjCjB,UAAU,CAACC,QAAUuC,aAAa;gBAAEC,WAAW;gBAASxC;YAAM;QAC9DA,OAAO,AAAC,CAAA,AAACoB,KAAKI,KAAK,GAAG,MAAOU,aAAY,EAAGoD,OAAO,CAAC;sBAEtD,oBAACzF;QACCC,MAAM,CAAC,EAAEkB,EAAE,iBAAiB,KAAK,CAAC;QAClCjB,UAAU,CAACC,QAAUuC,aAAa;gBAAEC,WAAW;gBAAUxC;YAAM;QAC/DA,OAAO,AAAC,CAAA,AAACoB,KAAKE,MAAM,GAAG,MAAOU,cAAa,EAAGsD,OAAO,CAAC;UAM7D1E,gCACC,oBAACX;QAAIC,WAAW,CAAC,EAAEN,UAAU,WAAW,CAAC;qBACvC,oBAACK,2BACC,oBAACA;QAAIC,WAAW,CAAC,EAAEN,UAAU,WAAW,CAAC;qBACvC,oBAACwF,YAAIpE,EAAE,qCACP,oBAACrB;QACCqE,aAAY;QACZ9D,WAAW,CAAC,EAAEN,UAAU,OAAO,CAAC;QAChCqE,SAASd;OAERnC,EAAE,mCAIT,oBAACqE;QAAKnF,WAAW,CAAC,EAAEN,UAAU,aAAa,CAAC;OACzCoB,EAAE,gDAEL,oBAACf;QAAIC,WAAW,CAAC,EAAEN,UAAU,YAAY,CAAC;qBACxC,oBAACC;QACCC,MAAK;QACLC,UAAU,CAACC,QAAU4C,mBAAmB;gBAAEC,YAAY;gBAAK7C;YAAM;QACjEA,OAAO2B,cAAcF,CAAC,CAAC6D,OAAO,CAAC;sBAEjC,oBAACzF;QACCC,MAAK;QACLC,UAAU,CAACC,QAAU4C,mBAAmB;gBAAEC,YAAY;gBAAK7C;YAAM;QACjEA,OAAO2B,cAAcD,CAAC,CAAC4D,OAAO,CAAC;;AAUnD,EAAC;AAED,MAAMN,mBAAmB,CAAC,EACxBC,SAAS,EACTnD,WAAW,EACXyD,QAAQ,EACRrF,SAAS,EACTgF,YAAY,EACZC,kBAAkB;IAAE1D,GAAG;IAAIC,GAAG;AAAG,CAAC,EAClCuB,SAAS,EACTlB,cAAc,EACf;IACC,MAAM,CAACyD,UAAUC,YAAY,GAAGpG,SAAS;QAAEoC,GAAG0D,gBAAgB1D,CAAC;QAAEC,GAAGyD,gBAAgBzD,CAAC;IAAC;IACtF,MAAM,CAACgE,YAAYC,cAAc,GAAGtG,SAAS;IAC7C,MAAMuG,UAAUxG;IAEhB,MAAMyG,iBAAiB1G,MAAM+D,WAAW,CACtC,CAAC4C,WAAoBC,WAAoBC;QACvC,MAAM5C,gBAAgB8B,aAAa7B,OAAO,CAACC,qBAAqB;QAChE,MAAMC,aAAa0B,UAAU5B,OAAO,CAACC,qBAAqB;QAC1D,MAAM2C,SAASH,aAAavC,WAAWE,IAAI;QAC3C,MAAMyC,SAASH,aAAaxC,WAAWI,GAAG;QAE1C,MAAMwC,eAAeF,SAAS1C,WAAWE,IAAI,IAAIwC,SAAS1C,WAAW6C,KAAK;QAC1E,MAAMC,eAAeH,SAAS3C,WAAWI,GAAG,IAAIuC,SAAS3C,WAAW+C,MAAM;QAE1E,IAAI7E,IAAI,AAAEwE,CAAAA,SAAS7C,cAAcK,IAAI,AAAD,IAAKL,cAAc5B,KAAK,GAAI;QAChE,IAAIE,IAAI,AAAEwE,CAAAA,SAAS9C,cAAcO,GAAG,AAAD,IAAKP,cAAc9B,MAAM,GAAI;QAChE,MAAMkC,UACJ,AAAED,CAAAA,WAAWE,IAAI,GAAGL,cAAcK,IAAI,GAAGF,WAAW/B,KAAK,GAAG,CAAA,IAAK4B,cAAc5B,KAAK,GAAI;QAC1F,MAAMkC,UACJ,AAAEH,CAAAA,WAAWI,GAAG,GAAGP,cAAcO,GAAG,GAAGJ,WAAWjC,MAAM,GAAG,CAAA,IAAK8B,cAAc9B,MAAM,GAAI;QAC1F,IAAI6E,gBAAgBE,cAAc;YAChCV,cAAc;YACd,IAAIM,SAAS1C,WAAWE,IAAI,EAAE;gBAC5BhC,IAAI,AAAE8B,CAAAA,WAAWE,IAAI,GAAGL,cAAcK,IAAI,AAAD,IAAKL,cAAc5B,KAAK,GAAI;YACvE,OAAO,IAAIyE,SAAS1C,WAAW6C,KAAK,EAAE;gBACpC3E,IACE,AAAE2B,CAAAA,cAAc5B,KAAK,GAAI4B,CAAAA,cAAcgD,KAAK,GAAG7C,WAAW6C,KAAK,AAAD,CAAC,IAC7DhD,cAAc5B,KAAK,GACrB;YACJ;YAEA,IAAI0E,SAAS3C,WAAWI,GAAG,EAAE;gBAC3BjC,IAAI,AAAE6B,CAAAA,WAAWI,GAAG,GAAGP,cAAcO,GAAG,AAAD,IAAKP,cAAc9B,MAAM,GAAI;YACtE,OAAO,IAAI4E,SAAS3C,WAAW+C,MAAM,EAAE;gBACrC5E,IACE,AAAE0B,CAAAA,cAAc9B,MAAM,GAAI8B,CAAAA,cAAckD,MAAM,GAAG/C,WAAW+C,MAAM,AAAD,CAAC,IAChElD,cAAc9B,MAAM,GACtB;YACJ;YAEA,IAAI0E,UAAU;gBACZvE,IAAI0E,eAAe3C,UAAU/B;gBAC7BC,IAAI2E,eAAe3C,UAAUhC;YAC/B;QACF;QAEA,OAAO;YAAED;YAAGC;QAAE;IAChB,GACA;QAACuD;QAAWC;KAAa;IAG3B,MAAMqB,kBAAkB,CAACC;QACvBA,MAAMC,cAAc;QACpBd,cAAc;IAChB;IAEA,MAAMe,kBAAkB,CAACF;QACvB,IAAI,CAACd,YAAY,OAAO;QACxB,MAAM,EAAEjE,CAAC,EAAEC,CAAC,EAAE,GAAGmE,eAAeW,MAAMG,OAAO,EAAEH,MAAMI,OAAO;QAE5DnB,YAAY;YAAEhE;YAAGC;QAAE;IACrB;IAEA,MAAMmF,SAAS;QACblB,cAAc;QACd1C,UAAUuC;IACZ;IAEArG,MAAM2H,SAAS,CAAC;QACd,IAAIpB,cAAc,CAACE,QAAQvC,OAAO,EAAE;QACpC,IAAIvB,aAAa;YACf,MAAM,EAAER,MAAM,EAAEmC,IAAI,EAAEE,GAAG,EAAEnC,KAAK,EAAE,GAAGoE,QAAQvC,OAAO,CAACC,qBAAqB;YAC1E,MAAM,EAAE7B,CAAC,EAAEC,CAAC,EAAE,GAAGmE,eAAepC,OAAOjC,QAAQ,GAAGmC,MAAMrC,SAAS,GAAG;YACpE2B,UAAU;gBAAExB;gBAAGC;YAAE;YACjB+D,YAAY;gBAAEhE;gBAAGC;YAAE;YACnBK,eAAe;YACf;QACF;IACF,GAAG;QAAC8D;QAAgBH;QAAY5D;QAAaC;QAAgByD,SAAS/D,CAAC;QAAE+D,SAAS9D,CAAC;QAAEuB;KAAU;IAE/F9D,MAAM2H,SAAS,CAAC;QACdrB,YAAY;YAAEhE,GAAG0D,gBAAgB1D,CAAC;YAAEC,GAAGyD,gBAAgBzD,CAAC;QAAC;IAC3D,GAAG;QAACyD,gBAAgB1D,CAAC;QAAE0D,gBAAgBzD,CAAC;KAAC;IAEzC,qBACE,oBAACzB;QACCC,WAAW;YACT,CAAC,EAAEN,UAAU,qBAAqB,CAAC;YACnC8F,cAAc,CAAC,EAAE9F,UAAU,+BAA+B,CAAC;SAC5D,CACEmH,MAAM,CAACC,SACPC,IAAI,CAAC;QACRC,aAAaR;qBAEb,oBAACS;QACCjH,WAAW;YAAC,CAAC,EAAEN,UAAU,WAAW,CAAC;YAAEM;SAAU,CAAC6G,MAAM,CAACC,SAASC,IAAI,CAAC;QACvEG,aAAab;QACbc,WAAWR;QACX3C,KAAK0B;QACLzB,OAAO;YAAEV,MAAM,CAAC,EAAE+B,SAAS/D,CAAC,CAAC,CAAC,CAAC;YAAEkC,KAAK,CAAC,EAAE6B,SAAS9D,CAAC,CAAC,CAAC,CAAC;QAAC;QACvDpB,MAAK;OAEJiF,yBAEH,oBAACtF;AAGP"}
|
|
1
|
+
{"version":3,"sources":["../../../src/elements/EditUpload/index.tsx"],"sourcesContent":["'use client'\nimport type { Data } from 'payload/types'\nimport type CropType from 'react-image-crop'\n\nimport * as facelessUIImport from '@faceless-ui/modal'\nimport React, { useRef, useState } from 'react'\nimport ReactCrop from 'react-image-crop'\nimport 'react-image-crop/dist/ReactCrop.css'\n\nimport { editDrawerSlug } from '../../elements/Upload/index.js'\nimport { Plus } from '../../icons/Plus/index.js'\nimport { useTranslation } from '../../providers/Translation/index.js'\nimport { Button } from '../Button/index.js'\nimport './index.scss'\n\nconst baseClass = 'edit-upload'\n\nconst Input: React.FC<{ name: string; onChange: (value: string) => void; value: string }> = ({\n name,\n onChange,\n value,\n}) => (\n <div className={`${baseClass}__input`}>\n {name}\n <input name={name} onChange={(e) => onChange(e.target.value)} type=\"number\" value={value} />\n </div>\n)\n\ntype FocalPosition = {\n x: number\n y: number\n}\n\nexport type EditUploadProps = {\n doc?: Data\n fileName: string\n fileSrc: string\n imageCacheTag?: string\n initialCrop?: CropType\n initialFocalPoint?: FocalPosition\n onSave?: ({ crop, pointPosition }: { crop: CropType; pointPosition: FocalPosition }) => void\n showCrop?: boolean\n showFocalPoint?: boolean\n}\n\nconst defaultCrop: CropType = {\n height: 100,\n unit: '%',\n width: 100,\n x: 0,\n y: 0,\n}\n\nconst defaultPointPosition: FocalPosition = {\n x: 50,\n y: 50,\n}\n\nexport const EditUpload: React.FC<EditUploadProps> = ({\n fileName,\n fileSrc,\n imageCacheTag,\n initialCrop,\n initialFocalPoint,\n onSave,\n showCrop,\n showFocalPoint,\n}) => {\n const { useModal } = facelessUIImport\n\n const { closeModal } = useModal()\n const { t } = useTranslation()\n\n const [crop, setCrop] = useState<CropType>(() => ({\n ...defaultCrop,\n ...initialCrop,\n }))\n\n const [pointPosition, setPointPosition] = useState<FocalPosition>(() => ({\n ...defaultPointPosition,\n ...initialFocalPoint,\n }))\n const [checkBounds, setCheckBounds] = useState<boolean>(false)\n const [originalHeight, setOriginalHeight] = useState<number>(0)\n const [originalWidth, setOriginalWidth] = useState<number>(0)\n\n const focalWrapRef = useRef<HTMLDivElement | undefined>()\n const imageRef = useRef<HTMLImageElement | undefined>()\n const cropRef = useRef<HTMLDivElement | undefined>()\n\n const fineTuneCrop = ({ dimension, value }: { dimension: 'height' | 'width'; value: string }) => {\n const intValue = parseInt(value)\n if (dimension === 'width' && intValue >= originalWidth) return null\n if (dimension === 'height' && intValue >= originalHeight) return null\n\n const percentage = 100 * (intValue / (dimension === 'width' ? originalWidth : originalHeight))\n\n if (percentage === 100 || percentage === 0) return null\n\n setCrop({\n ...crop,\n [dimension]: percentage,\n })\n }\n\n const fineTuneFocalPoint = ({ coordinate, value }: { coordinate: 'x' | 'y'; value: string }) => {\n const intValue = parseInt(value)\n if (intValue >= 0 && intValue <= 100) {\n setPointPosition((prevPosition) => ({ ...prevPosition, [coordinate]: intValue }))\n }\n }\n\n const saveEdits = () => {\n if (typeof onSave === 'function')\n onSave({\n crop,\n pointPosition,\n })\n closeModal(editDrawerSlug)\n }\n\n const onDragEnd = React.useCallback(({ x, y }) => {\n setPointPosition({ x, y })\n setCheckBounds(false)\n }, [])\n\n const centerFocalPoint = () => {\n const containerRect = focalWrapRef.current.getBoundingClientRect()\n const boundsRect = showCrop\n ? cropRef.current.getBoundingClientRect()\n : imageRef.current.getBoundingClientRect()\n const xCenter =\n ((boundsRect.left - containerRect.left + boundsRect.width / 2) / containerRect.width) * 100\n const yCenter =\n ((boundsRect.top - containerRect.top + boundsRect.height / 2) / containerRect.height) * 100\n setPointPosition({ x: xCenter, y: yCenter })\n }\n\n const fileSrcToUse = imageCacheTag ? `${fileSrc}?${imageCacheTag}` : fileSrc\n\n return (\n <div className={baseClass}>\n <div className={`${baseClass}__header`}>\n <h2 title={`${t('general:editing')} ${fileName}`}>\n {t('general:editing')} {fileName}\n </h2>\n <div className={`${baseClass}__actions`}>\n <Button\n aria-label={t('general:cancel')}\n buttonStyle=\"secondary\"\n className={`${baseClass}__cancel`}\n onClick={() => closeModal(editDrawerSlug)}\n >\n {t('general:cancel')}\n </Button>\n <Button\n aria-label={t('general:applyChanges')}\n buttonStyle=\"primary\"\n className={`${baseClass}__save`}\n onClick={saveEdits}\n >\n {t('general:applyChanges')}\n </Button>\n </div>\n </div>\n <div className={`${baseClass}__toolWrap`}>\n <div className={`${baseClass}__crop`}>\n <div\n className={`${baseClass}__focal-wrapper`}\n ref={focalWrapRef}\n style={{\n aspectRatio: `${originalWidth / originalHeight}`,\n }}\n >\n {showCrop ? (\n <ReactCrop\n className={`${baseClass}__reactCrop`}\n crop={crop}\n onChange={(_, c) => setCrop(c)}\n onComplete={() => setCheckBounds(true)}\n renderSelectionAddon={() => {\n return <div className={`${baseClass}__crop-window`} ref={cropRef} />\n }}\n >\n <img\n alt={t('upload:setCropArea')}\n onLoad={(e) => {\n setOriginalHeight(e.currentTarget.naturalHeight)\n setOriginalWidth(e.currentTarget.naturalWidth)\n }}\n ref={imageRef}\n src={fileSrcToUse}\n />\n </ReactCrop>\n ) : (\n <img\n alt={t('upload:setFocalPoint')}\n onLoad={(e) => {\n setOriginalHeight(e.currentTarget.naturalHeight)\n setOriginalWidth(e.currentTarget.naturalWidth)\n }}\n ref={imageRef}\n src={fileSrcToUse}\n />\n )}\n {showFocalPoint && (\n <DraggableElement\n boundsRef={showCrop ? cropRef : imageRef}\n checkBounds={showCrop ? checkBounds : false}\n className={`${baseClass}__focalPoint`}\n containerRef={focalWrapRef}\n initialPosition={pointPosition}\n onDragEnd={onDragEnd}\n setCheckBounds={showCrop ? setCheckBounds : false}\n >\n <Plus />\n </DraggableElement>\n )}\n </div>\n </div>\n {(showCrop || showFocalPoint) && (\n <div className={`${baseClass}__sidebar`}>\n {showCrop && (\n <div className={`${baseClass}__groupWrap`}>\n <div>\n <div className={`${baseClass}__titleWrap`}>\n <h3>{t('upload:crop')}</h3>\n <Button\n buttonStyle=\"none\"\n className={`${baseClass}__reset`}\n onClick={() =>\n setCrop({\n height: 100,\n unit: '%',\n width: 100,\n x: 0,\n y: 0,\n })\n }\n >\n {t('general:reset')}\n </Button>\n </div>\n </div>\n <span className={`${baseClass}__description`}>\n {t('upload:cropToolDescription')}\n </span>\n <div className={`${baseClass}__inputsWrap`}>\n <Input\n name={`${t('upload:width')} (px)`}\n onChange={(value) => fineTuneCrop({ dimension: 'width', value })}\n value={((crop.width / 100) * originalWidth).toFixed(0)}\n />\n <Input\n name={`${t('upload:height')} (px)`}\n onChange={(value) => fineTuneCrop({ dimension: 'height', value })}\n value={((crop.height / 100) * originalHeight).toFixed(0)}\n />\n </div>\n </div>\n )}\n\n {showFocalPoint && (\n <div className={`${baseClass}__groupWrap`}>\n <div>\n <div className={`${baseClass}__titleWrap`}>\n <h3>{t('upload:focalPoint')}</h3>\n <Button\n buttonStyle=\"none\"\n className={`${baseClass}__reset`}\n onClick={centerFocalPoint}\n >\n {t('general:reset')}\n </Button>\n </div>\n </div>\n <span className={`${baseClass}__description`}>\n {t('upload:focalPointDescription')}\n </span>\n <div className={`${baseClass}__inputsWrap`}>\n <Input\n name=\"X %\"\n onChange={(value) => fineTuneFocalPoint({ coordinate: 'x', value })}\n value={pointPosition.x.toFixed(0)}\n />\n <Input\n name=\"Y %\"\n onChange={(value) => fineTuneFocalPoint({ coordinate: 'y', value })}\n value={pointPosition.y.toFixed(0)}\n />\n </div>\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n )\n}\n\nconst DraggableElement = ({\n boundsRef,\n checkBounds,\n children,\n className,\n containerRef,\n initialPosition = { x: 50, y: 50 },\n onDragEnd,\n setCheckBounds,\n}) => {\n const [position, setPosition] = useState({ x: initialPosition.x, y: initialPosition.y })\n const [isDragging, setIsDragging] = useState(false)\n const dragRef = useRef<HTMLButtonElement | undefined>()\n\n const getCoordinates = React.useCallback(\n (mouseXArg?: number, mouseYArg?: number, recenter?: boolean) => {\n const containerRect = containerRef.current.getBoundingClientRect()\n const boundsRect = boundsRef.current.getBoundingClientRect()\n const mouseX = mouseXArg ?? boundsRect.left\n const mouseY = mouseYArg ?? boundsRect.top\n\n const xOutOfBounds = mouseX < boundsRect.left || mouseX > boundsRect.right\n const yOutOfBounds = mouseY < boundsRect.top || mouseY > boundsRect.bottom\n\n let x = ((mouseX - containerRect.left) / containerRect.width) * 100\n let y = ((mouseY - containerRect.top) / containerRect.height) * 100\n const xCenter =\n ((boundsRect.left - containerRect.left + boundsRect.width / 2) / containerRect.width) * 100\n const yCenter =\n ((boundsRect.top - containerRect.top + boundsRect.height / 2) / containerRect.height) * 100\n if (xOutOfBounds || yOutOfBounds) {\n setIsDragging(false)\n if (mouseX < boundsRect.left) {\n x = ((boundsRect.left - containerRect.left) / containerRect.width) * 100\n } else if (mouseX > boundsRect.right) {\n x =\n ((containerRect.width - (containerRect.right - boundsRect.right)) /\n containerRect.width) *\n 100\n }\n\n if (mouseY < boundsRect.top) {\n y = ((boundsRect.top - containerRect.top) / containerRect.height) * 100\n } else if (mouseY > boundsRect.bottom) {\n y =\n ((containerRect.height - (containerRect.bottom - boundsRect.bottom)) /\n containerRect.height) *\n 100\n }\n\n if (recenter) {\n x = xOutOfBounds ? xCenter : x\n y = yOutOfBounds ? yCenter : y\n }\n }\n\n return { x, y }\n },\n [boundsRef, containerRef],\n )\n\n const handleMouseDown = (event) => {\n event.preventDefault()\n setIsDragging(true)\n }\n\n const handleMouseMove = (event) => {\n if (!isDragging) return null\n const { x, y } = getCoordinates(event.clientX, event.clientY)\n\n setPosition({ x, y })\n }\n\n const onDrop = () => {\n setIsDragging(false)\n onDragEnd(position)\n }\n\n React.useEffect(() => {\n if (isDragging || !dragRef.current) return\n if (checkBounds) {\n const { height, left, top, width } = dragRef.current.getBoundingClientRect()\n const { x, y } = getCoordinates(left + width / 2, top + height / 2, true)\n onDragEnd({ x, y })\n setPosition({ x, y })\n setCheckBounds(false)\n return\n }\n }, [getCoordinates, isDragging, checkBounds, setCheckBounds, position.x, position.y, onDragEnd])\n\n React.useEffect(() => {\n setPosition({ x: initialPosition.x, y: initialPosition.y })\n }, [initialPosition.x, initialPosition.y])\n\n return (\n <div\n className={[\n `${baseClass}__draggable-container`,\n isDragging && `${baseClass}__draggable-container--dragging`,\n ]\n .filter(Boolean)\n .join(' ')}\n onMouseMove={handleMouseMove}\n >\n <button\n className={[`${baseClass}__draggable`, className].filter(Boolean).join(' ')}\n onMouseDown={handleMouseDown}\n onMouseUp={onDrop}\n ref={dragRef}\n style={{ left: `${position.x}%`, top: `${position.y}%` }}\n type=\"button\"\n >\n {children}\n </button>\n <div />\n </div>\n )\n}\n"],"names":["facelessUIImport","React","useRef","useState","ReactCrop","editDrawerSlug","Plus","useTranslation","Button","baseClass","Input","name","onChange","value","div","className","input","e","target","type","defaultCrop","height","unit","width","x","y","defaultPointPosition","EditUpload","fileName","fileSrc","imageCacheTag","initialCrop","initialFocalPoint","onSave","showCrop","showFocalPoint","useModal","closeModal","t","crop","setCrop","pointPosition","setPointPosition","checkBounds","setCheckBounds","originalHeight","setOriginalHeight","originalWidth","setOriginalWidth","focalWrapRef","imageRef","cropRef","fineTuneCrop","dimension","intValue","parseInt","percentage","fineTuneFocalPoint","coordinate","prevPosition","saveEdits","onDragEnd","useCallback","centerFocalPoint","containerRect","current","getBoundingClientRect","boundsRect","xCenter","left","yCenter","top","fileSrcToUse","h2","title","aria-label","buttonStyle","onClick","ref","style","aspectRatio","_","c","onComplete","renderSelectionAddon","img","alt","onLoad","currentTarget","naturalHeight","naturalWidth","src","DraggableElement","boundsRef","containerRef","initialPosition","h3","span","toFixed","children","position","setPosition","isDragging","setIsDragging","dragRef","getCoordinates","mouseXArg","mouseYArg","recenter","mouseX","mouseY","xOutOfBounds","right","yOutOfBounds","bottom","handleMouseDown","event","preventDefault","handleMouseMove","clientX","clientY","onDrop","useEffect","filter","Boolean","join","onMouseMove","button","onMouseDown","onMouseUp"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/elements/Upload/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/elements/Upload/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAA;AAKzE,OAAO,KAA2C,MAAM,OAAO,CAAA;AAe/D,OAAO,cAAc,CAAA;AAGrB,eAAO,MAAM,cAAc,gBAAgB,CAAA;AAC3C,eAAO,MAAM,eAAe,kBAAkB,CAAA;AAU9C,eAAO,MAAM,aAAa;;;uBAgBzB,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,cAAc,EAAE,MAAM,CAAA;IACtB,YAAY,CAAC,EAAE,SAAS,CAAA;IACxB,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,KAAK,IAAI,CAAA;IAChC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,yBAAyB,CAAC,QAAQ,CAAC,CAAA;CAClD,CAAA;AAED,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CA0MxC,CAAA"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { FieldError } from '@payloadcms/ui/forms/FieldError';
|
|
3
|
+
import { useFormQueryParams } from '@payloadcms/ui/providers/FormQueryParams';
|
|
3
4
|
import { isImage } from 'payload/utilities';
|
|
4
5
|
import React, { useCallback, useEffect, useState } from 'react';
|
|
5
6
|
import { fieldBaseClass } from '../../fields/shared/index.js';
|
|
6
|
-
import { useFormSubmitted } from '../../forms/Form/context.js';
|
|
7
|
+
import { useForm, useFormSubmitted } from '../../forms/Form/context.js';
|
|
7
8
|
import { useField } from '../../forms/useField/index.js';
|
|
8
9
|
import { useDocumentInfo } from '../../providers/DocumentInfo/index.js';
|
|
9
10
|
import { useTranslation } from '../../providers/Translation/index.js';
|
|
@@ -42,12 +43,18 @@ export const Upload = (props)=>{
|
|
|
42
43
|
const [replacingFile, setReplacingFile] = useState(false);
|
|
43
44
|
const [fileSrc, setFileSrc] = useState(null);
|
|
44
45
|
const { t } = useTranslation();
|
|
46
|
+
const { setModified } = useForm();
|
|
47
|
+
const { dispatchFormQueryParams, formQueryParams } = useFormQueryParams();
|
|
45
48
|
const [doc, setDoc] = useState(reduceFieldsToValues(initialState || {}, true));
|
|
46
49
|
const { docPermissions } = useDocumentInfo();
|
|
47
50
|
const { errorMessage, setValue, showError, value } = useField({
|
|
48
51
|
path: 'file',
|
|
49
52
|
validate
|
|
50
53
|
});
|
|
54
|
+
const [crop, setCrop] = useState({
|
|
55
|
+
x: 0,
|
|
56
|
+
y: 0
|
|
57
|
+
});
|
|
51
58
|
const handleFileNameChange = (e)=>{
|
|
52
59
|
const updatedFileName = e.target.value;
|
|
53
60
|
if (value) {
|
|
@@ -75,6 +82,29 @@ export const Upload = (props)=>{
|
|
|
75
82
|
}, [
|
|
76
83
|
setValue
|
|
77
84
|
]);
|
|
85
|
+
const onEditsSave = React.useCallback(({ crop, pointPosition })=>{
|
|
86
|
+
setCrop({
|
|
87
|
+
x: crop.x || 0,
|
|
88
|
+
y: crop.y || 0
|
|
89
|
+
});
|
|
90
|
+
const zoomScale = 100 / Math.min(crop.width, crop.height);
|
|
91
|
+
document.documentElement.style.setProperty('--file-details-thumbnail--zoom', `${zoomScale}`);
|
|
92
|
+
document.documentElement.style.setProperty('--file-details-thumbnail--top-offset', `${zoomScale * (50 - crop.height / 2 - crop.y)}%`);
|
|
93
|
+
document.documentElement.style.setProperty('--file-details-thumbnail--left-offset', `${zoomScale * (50 - crop.width / 2 - crop.x)}%`);
|
|
94
|
+
setModified(true);
|
|
95
|
+
dispatchFormQueryParams({
|
|
96
|
+
type: 'SET',
|
|
97
|
+
params: {
|
|
98
|
+
uploadEdits: crop || pointPosition ? {
|
|
99
|
+
crop: crop || null,
|
|
100
|
+
focalPoint: pointPosition ? pointPosition : null
|
|
101
|
+
} : null
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
}, [
|
|
105
|
+
dispatchFormQueryParams,
|
|
106
|
+
setModified
|
|
107
|
+
]);
|
|
78
108
|
useEffect(()=>{
|
|
79
109
|
setDoc(reduceFieldsToValues(initialState || {}, true));
|
|
80
110
|
setReplacingFile(false);
|
|
@@ -159,6 +189,12 @@ export const Upload = (props)=>{
|
|
|
159
189
|
fileName: value?.name || doc?.filename,
|
|
160
190
|
fileSrc: fileSrc || doc?.url,
|
|
161
191
|
imageCacheTag: lastSubmittedTime,
|
|
192
|
+
initialCrop: formQueryParams?.uploadEdits?.crop ?? {},
|
|
193
|
+
initialFocalPoint: {
|
|
194
|
+
x: formQueryParams?.uploadEdits?.focalPoint.x || 0,
|
|
195
|
+
y: formQueryParams?.uploadEdits?.focalPoint.y || 0
|
|
196
|
+
},
|
|
197
|
+
onSave: onEditsSave,
|
|
162
198
|
showCrop: showCrop,
|
|
163
199
|
showFocalPoint: showFocalPoint
|
|
164
200
|
})), doc && hasImageSizes && /*#__PURE__*/ React.createElement(Drawer, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/elements/Upload/index.tsx"],"sourcesContent":["'use client'\nimport type { FormState, SanitizedCollectionConfig } from 'payload/types'\n\nimport { FieldError } from '@payloadcms/ui/forms/FieldError'\nimport { isImage } from 'payload/utilities'\nimport React, { useCallback, useEffect, useState } from 'react'\n\nimport { fieldBaseClass } from '../../fields/shared/index.js'\nimport { useFormSubmitted } from '../../forms/Form/context.js'\nimport { useField } from '../../forms/useField/index.js'\nimport { useDocumentInfo } from '../../providers/DocumentInfo/index.js'\nimport { useTranslation } from '../../providers/Translation/index.js'\nimport { reduceFieldsToValues } from '../../utilities/reduceFieldsToValues.js'\nimport { Button } from '../Button/index.js'\nimport { Drawer, DrawerToggler } from '../Drawer/index.js'\nimport { Dropzone } from '../Dropzone/index.js'\nimport { EditUpload } from '../EditUpload/index.js'\nimport { FileDetails } from '../FileDetails/index.js'\nimport { PreviewSizes } from '../PreviewSizes/index.js'\nimport { Thumbnail } from '../Thumbnail/index.js'\nimport './index.scss'\n\nconst baseClass = 'file-field'\nexport const editDrawerSlug = 'edit-upload'\nexport const sizePreviewSlug = 'preview-sizes'\n\nconst validate = (value) => {\n if (!value && value !== undefined) {\n return 'A file is required.'\n }\n\n return true\n}\n\nexport const UploadActions = ({ canEdit, showSizePreviews }) => {\n const { t } = useTranslation()\n return (\n <div className={`${baseClass}__file-mutation`}>\n {showSizePreviews && (\n <DrawerToggler className={`${baseClass}__previewSizes`} slug={sizePreviewSlug}>\n {t('upload:previewSizes')}\n </DrawerToggler>\n )}\n {canEdit && (\n <DrawerToggler className={`${baseClass}__edit`} slug={editDrawerSlug}>\n {t('upload:editImage')}\n </DrawerToggler>\n )}\n </div>\n )\n}\n\nexport type UploadProps = {\n collectionSlug: string\n initialState?: FormState\n onChange?: (file?: File) => void\n updatedAt?: string\n uploadConfig: SanitizedCollectionConfig['upload']\n}\n\nexport const Upload: React.FC<UploadProps> = (props) => {\n const { collectionSlug, initialState, onChange, updatedAt, uploadConfig } = props\n\n const submitted = useFormSubmitted()\n const [replacingFile, setReplacingFile] = useState(false)\n const [fileSrc, setFileSrc] = useState<null | string>(null)\n const { t } = useTranslation()\n const [doc, setDoc] = useState(reduceFieldsToValues(initialState || {}, true))\n const { docPermissions } = useDocumentInfo()\n const { errorMessage, setValue, showError, value } = useField<File>({\n path: 'file',\n validate,\n })\n\n const handleFileNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const updatedFileName = e.target.value\n if (value) {\n const fileValue = value\n // Creating a new File object with updated properties\n const newFile = new File([fileValue], updatedFileName, { type: fileValue.type })\n setValue(newFile) // Updating the state with the new File object\n }\n }\n\n const handleFileSelection = React.useCallback(\n (files: FileList) => {\n const fileToUpload = files?.[0]\n setValue(fileToUpload)\n },\n [setValue],\n )\n\n const handleFileRemoval = useCallback(() => {\n setReplacingFile(true)\n setValue(null)\n setFileSrc('')\n }, [setValue])\n\n useEffect(() => {\n setDoc(reduceFieldsToValues(initialState || {}, true))\n setReplacingFile(false)\n }, [initialState])\n\n useEffect(() => {\n if (value instanceof File) {\n const fileReader = new FileReader()\n fileReader.onload = (e) => {\n const imgSrc = e.target?.result\n\n if (typeof imgSrc === 'string') {\n setFileSrc(imgSrc)\n }\n }\n fileReader.readAsDataURL(value)\n }\n\n if (typeof onChange === 'function') {\n onChange(value)\n }\n }, [value, onChange, updatedAt])\n\n const canRemoveUpload =\n docPermissions?.update?.permission &&\n 'delete' in docPermissions &&\n docPermissions?.delete?.permission\n\n const hasImageSizes = uploadConfig?.imageSizes?.length > 0\n const hasResizeOptions = Boolean(uploadConfig?.resizeOptions)\n\n const { crop: showCrop = true, focalPoint = true } = uploadConfig\n\n const showFocalPoint = focalPoint && (hasImageSizes || hasResizeOptions)\n\n const lastSubmittedTime = submitted ? new Date().toISOString() : null\n\n return (\n <div className={[fieldBaseClass, baseClass].filter(Boolean).join(' ')}>\n <FieldError message={errorMessage} showError={showError} />\n {doc.filename && !replacingFile && (\n <FileDetails\n canEdit={showCrop || showFocalPoint}\n collectionSlug={collectionSlug}\n doc={doc}\n handleRemove={canRemoveUpload ? handleFileRemoval : undefined}\n hasImageSizes={hasImageSizes}\n imageCacheTag={lastSubmittedTime}\n uploadConfig={uploadConfig}\n />\n )}\n {(!doc.filename || replacingFile) && (\n <div className={`${baseClass}__upload`}>\n {!value && (\n <Dropzone\n className={`${baseClass}__dropzone`}\n mimeTypes={uploadConfig?.mimeTypes}\n onChange={handleFileSelection}\n />\n )}\n\n {value && (\n <React.Fragment>\n <div className={`${baseClass}__thumbnail-wrap`}>\n <Thumbnail\n collectionSlug={collectionSlug}\n fileSrc={isImage(value.type) ? fileSrc : null}\n />\n </div>\n <div className={`${baseClass}__file-adjustments`}>\n <input\n className={`${baseClass}__filename`}\n onChange={handleFileNameChange}\n type=\"text\"\n value={value.name}\n />\n\n {isImage(value.type) && value.type !== 'image/svg+xml' && (\n <UploadActions\n canEdit={showCrop || showFocalPoint}\n showSizePreviews={hasImageSizes && doc.filename && !replacingFile}\n />\n )}\n </div>\n <Button\n buttonStyle=\"icon-label\"\n className={`${baseClass}__remove`}\n icon=\"x\"\n iconStyle=\"with-border\"\n onClick={handleFileRemoval}\n round\n tooltip={t('general:cancel')}\n />\n </React.Fragment>\n )}\n </div>\n )}\n {(value || doc.filename) && (\n <Drawer Header={null} slug={editDrawerSlug}>\n <EditUpload\n doc={doc || undefined}\n fileName={value?.name || doc?.filename}\n fileSrc={fileSrc || doc?.url}\n imageCacheTag={lastSubmittedTime}\n showCrop={showCrop}\n showFocalPoint={showFocalPoint}\n />\n </Drawer>\n )}\n {doc && hasImageSizes && (\n <Drawer\n className={`${baseClass}__previewDrawer`}\n hoverTitle\n slug={sizePreviewSlug}\n title={t('upload:sizesFor', { label: doc?.filename })}\n >\n <PreviewSizes doc={doc} uploadConfig={uploadConfig} />\n </Drawer>\n )}\n </div>\n )\n}\n"],"names":["FieldError","isImage","React","useCallback","useEffect","useState","fieldBaseClass","useFormSubmitted","useField","useDocumentInfo","useTranslation","reduceFieldsToValues","Button","Drawer","DrawerToggler","Dropzone","EditUpload","FileDetails","PreviewSizes","Thumbnail","baseClass","editDrawerSlug","sizePreviewSlug","validate","value","undefined","UploadActions","canEdit","showSizePreviews","t","div","className","slug","Upload","props","collectionSlug","initialState","onChange","updatedAt","uploadConfig","submitted","replacingFile","setReplacingFile","fileSrc","setFileSrc","doc","setDoc","docPermissions","errorMessage","setValue","showError","path","handleFileNameChange","e","updatedFileName","target","fileValue","newFile","File","type","handleFileSelection","files","fileToUpload","handleFileRemoval","fileReader","FileReader","onload","imgSrc","result","readAsDataURL","canRemoveUpload","update","permission","delete","hasImageSizes","imageSizes","length","hasResizeOptions","Boolean","resizeOptions","crop","showCrop","focalPoint","showFocalPoint","lastSubmittedTime","Date","toISOString","filter","join","message","filename","handleRemove","imageCacheTag","mimeTypes","Fragment","input","name","buttonStyle","icon","iconStyle","onClick","round","tooltip","Header","fileName","url","hoverTitle","title","label"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/elements/Upload/index.tsx"],"sourcesContent":["'use client'\nimport type { FormState, SanitizedCollectionConfig } from 'payload/types'\n\nimport { FieldError } from '@payloadcms/ui/forms/FieldError'\nimport { useFormQueryParams } from '@payloadcms/ui/providers/FormQueryParams'\nimport { isImage } from 'payload/utilities'\nimport React, { useCallback, useEffect, useState } from 'react'\n\nimport { fieldBaseClass } from '../../fields/shared/index.js'\nimport { useForm, useFormSubmitted } from '../../forms/Form/context.js'\nimport { useField } from '../../forms/useField/index.js'\nimport { useDocumentInfo } from '../../providers/DocumentInfo/index.js'\nimport { useTranslation } from '../../providers/Translation/index.js'\nimport { reduceFieldsToValues } from '../../utilities/reduceFieldsToValues.js'\nimport { Button } from '../Button/index.js'\nimport { Drawer, DrawerToggler } from '../Drawer/index.js'\nimport { Dropzone } from '../Dropzone/index.js'\nimport { EditUpload } from '../EditUpload/index.js'\nimport { FileDetails } from '../FileDetails/index.js'\nimport { PreviewSizes } from '../PreviewSizes/index.js'\nimport { Thumbnail } from '../Thumbnail/index.js'\nimport './index.scss'\n\nconst baseClass = 'file-field'\nexport const editDrawerSlug = 'edit-upload'\nexport const sizePreviewSlug = 'preview-sizes'\n\nconst validate = (value) => {\n if (!value && value !== undefined) {\n return 'A file is required.'\n }\n\n return true\n}\n\nexport const UploadActions = ({ canEdit, showSizePreviews }) => {\n const { t } = useTranslation()\n return (\n <div className={`${baseClass}__file-mutation`}>\n {showSizePreviews && (\n <DrawerToggler className={`${baseClass}__previewSizes`} slug={sizePreviewSlug}>\n {t('upload:previewSizes')}\n </DrawerToggler>\n )}\n {canEdit && (\n <DrawerToggler className={`${baseClass}__edit`} slug={editDrawerSlug}>\n {t('upload:editImage')}\n </DrawerToggler>\n )}\n </div>\n )\n}\n\nexport type UploadProps = {\n collectionSlug: string\n initialState?: FormState\n onChange?: (file?: File) => void\n updatedAt?: string\n uploadConfig: SanitizedCollectionConfig['upload']\n}\n\nexport const Upload: React.FC<UploadProps> = (props) => {\n const { collectionSlug, initialState, onChange, updatedAt, uploadConfig } = props\n\n const submitted = useFormSubmitted()\n const [replacingFile, setReplacingFile] = useState(false)\n const [fileSrc, setFileSrc] = useState<null | string>(null)\n const { t } = useTranslation()\n const { setModified } = useForm()\n const { dispatchFormQueryParams, formQueryParams } = useFormQueryParams()\n const [doc, setDoc] = useState(reduceFieldsToValues(initialState || {}, true))\n const { docPermissions } = useDocumentInfo()\n const { errorMessage, setValue, showError, value } = useField<File>({\n path: 'file',\n validate,\n })\n const [crop, setCrop] = useState({ x: 0, y: 0 })\n\n const handleFileNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const updatedFileName = e.target.value\n if (value) {\n const fileValue = value\n // Creating a new File object with updated properties\n const newFile = new File([fileValue], updatedFileName, { type: fileValue.type })\n setValue(newFile) // Updating the state with the new File object\n }\n }\n\n const handleFileSelection = React.useCallback(\n (files: FileList) => {\n const fileToUpload = files?.[0]\n setValue(fileToUpload)\n },\n [setValue],\n )\n\n const handleFileRemoval = useCallback(() => {\n setReplacingFile(true)\n setValue(null)\n setFileSrc('')\n }, [setValue])\n\n const onEditsSave = React.useCallback(\n ({ crop, pointPosition }) => {\n setCrop({\n x: crop.x || 0,\n y: crop.y || 0,\n })\n const zoomScale = 100 / Math.min(crop.width, crop.height)\n\n document.documentElement.style.setProperty('--file-details-thumbnail--zoom', `${zoomScale}`)\n document.documentElement.style.setProperty(\n '--file-details-thumbnail--top-offset',\n `${zoomScale * (50 - crop.height / 2 - crop.y)}%`,\n )\n document.documentElement.style.setProperty(\n '--file-details-thumbnail--left-offset',\n `${zoomScale * (50 - crop.width / 2 - crop.x)}%`,\n )\n setModified(true)\n dispatchFormQueryParams({\n type: 'SET',\n params: {\n uploadEdits:\n crop || pointPosition\n ? {\n crop: crop || null,\n focalPoint: pointPosition ? pointPosition : null,\n }\n : null,\n },\n })\n },\n [dispatchFormQueryParams, setModified],\n )\n\n useEffect(() => {\n setDoc(reduceFieldsToValues(initialState || {}, true))\n setReplacingFile(false)\n }, [initialState])\n\n useEffect(() => {\n if (value instanceof File) {\n const fileReader = new FileReader()\n fileReader.onload = (e) => {\n const imgSrc = e.target?.result\n\n if (typeof imgSrc === 'string') {\n setFileSrc(imgSrc)\n }\n }\n fileReader.readAsDataURL(value)\n }\n\n if (typeof onChange === 'function') {\n onChange(value)\n }\n }, [value, onChange, updatedAt])\n\n const canRemoveUpload =\n docPermissions?.update?.permission &&\n 'delete' in docPermissions &&\n docPermissions?.delete?.permission\n\n const hasImageSizes = uploadConfig?.imageSizes?.length > 0\n const hasResizeOptions = Boolean(uploadConfig?.resizeOptions)\n\n const { crop: showCrop = true, focalPoint = true } = uploadConfig\n\n const showFocalPoint = focalPoint && (hasImageSizes || hasResizeOptions)\n\n const lastSubmittedTime = submitted ? new Date().toISOString() : null\n\n return (\n <div className={[fieldBaseClass, baseClass].filter(Boolean).join(' ')}>\n <FieldError message={errorMessage} showError={showError} />\n {doc.filename && !replacingFile && (\n <FileDetails\n canEdit={showCrop || showFocalPoint}\n collectionSlug={collectionSlug}\n doc={doc}\n handleRemove={canRemoveUpload ? handleFileRemoval : undefined}\n hasImageSizes={hasImageSizes}\n imageCacheTag={lastSubmittedTime}\n uploadConfig={uploadConfig}\n />\n )}\n {(!doc.filename || replacingFile) && (\n <div className={`${baseClass}__upload`}>\n {!value && (\n <Dropzone\n className={`${baseClass}__dropzone`}\n mimeTypes={uploadConfig?.mimeTypes}\n onChange={handleFileSelection}\n />\n )}\n\n {value && (\n <React.Fragment>\n <div className={`${baseClass}__thumbnail-wrap`}>\n <Thumbnail\n collectionSlug={collectionSlug}\n fileSrc={isImage(value.type) ? fileSrc : null}\n />\n </div>\n <div className={`${baseClass}__file-adjustments`}>\n <input\n className={`${baseClass}__filename`}\n onChange={handleFileNameChange}\n type=\"text\"\n value={value.name}\n />\n\n {isImage(value.type) && value.type !== 'image/svg+xml' && (\n <UploadActions\n canEdit={showCrop || showFocalPoint}\n showSizePreviews={hasImageSizes && doc.filename && !replacingFile}\n />\n )}\n </div>\n <Button\n buttonStyle=\"icon-label\"\n className={`${baseClass}__remove`}\n icon=\"x\"\n iconStyle=\"with-border\"\n onClick={handleFileRemoval}\n round\n tooltip={t('general:cancel')}\n />\n </React.Fragment>\n )}\n </div>\n )}\n {(value || doc.filename) && (\n <Drawer Header={null} slug={editDrawerSlug}>\n <EditUpload\n doc={doc || undefined}\n fileName={value?.name || doc?.filename}\n fileSrc={fileSrc || doc?.url}\n imageCacheTag={lastSubmittedTime}\n initialCrop={formQueryParams?.uploadEdits?.crop ?? {}}\n initialFocalPoint={{\n x: formQueryParams?.uploadEdits?.focalPoint.x || 0,\n y: formQueryParams?.uploadEdits?.focalPoint.y || 0,\n }}\n onSave={onEditsSave}\n showCrop={showCrop}\n showFocalPoint={showFocalPoint}\n />\n </Drawer>\n )}\n {doc && hasImageSizes && (\n <Drawer\n className={`${baseClass}__previewDrawer`}\n hoverTitle\n slug={sizePreviewSlug}\n title={t('upload:sizesFor', { label: doc?.filename })}\n >\n <PreviewSizes doc={doc} uploadConfig={uploadConfig} />\n </Drawer>\n )}\n </div>\n )\n}\n"],"names":["FieldError","useFormQueryParams","isImage","React","useCallback","useEffect","useState","fieldBaseClass","useForm","useFormSubmitted","useField","useDocumentInfo","useTranslation","reduceFieldsToValues","Button","Drawer","DrawerToggler","Dropzone","EditUpload","FileDetails","PreviewSizes","Thumbnail","baseClass","editDrawerSlug","sizePreviewSlug","validate","value","undefined","UploadActions","canEdit","showSizePreviews","t","div","className","slug","Upload","props","collectionSlug","initialState","onChange","updatedAt","uploadConfig","submitted","replacingFile","setReplacingFile","fileSrc","setFileSrc","setModified","dispatchFormQueryParams","formQueryParams","doc","setDoc","docPermissions","errorMessage","setValue","showError","path","crop","setCrop","x","y","handleFileNameChange","e","updatedFileName","target","fileValue","newFile","File","type","handleFileSelection","files","fileToUpload","handleFileRemoval","onEditsSave","pointPosition","zoomScale","Math","min","width","height","document","documentElement","style","setProperty","params","uploadEdits","focalPoint","fileReader","FileReader","onload","imgSrc","result","readAsDataURL","canRemoveUpload","update","permission","delete","hasImageSizes","imageSizes","length","hasResizeOptions","Boolean","resizeOptions","showCrop","showFocalPoint","lastSubmittedTime","Date","toISOString","filter","join","message","filename","handleRemove","imageCacheTag","mimeTypes","Fragment","input","name","buttonStyle","icon","iconStyle","onClick","round","tooltip","Header","fileName","url","initialCrop","initialFocalPoint","onSave","hoverTitle","title","label"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|