payload-plugin-aspect-preview 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +21 -0
- package/README.md +94 -0
- package/dist/components/AspectRatioPreviewGrid.d.ts +11 -0
- package/dist/components/AspectRatioPreviewGrid.js +230 -0
- package/dist/components/AspectRatioPreviewGrid.js.map +1 -0
- package/dist/components/CustomUpload.d.ts +4 -0
- package/dist/components/CustomUpload.js +167 -0
- package/dist/components/CustomUpload.js.map +1 -0
- package/dist/components/FocalPointEditor.d.ts +4 -0
- package/dist/components/FocalPointEditor.js +629 -0
- package/dist/components/FocalPointEditor.js.map +1 -0
- package/dist/defaults.d.ts +2 -0
- package/dist/defaults.js +58 -0
- package/dist/defaults.js.map +1 -0
- package/dist/exports/client.d.ts +3 -0
- package/dist/exports/client.js +5 -0
- package/dist/exports/client.js.map +1 -0
- package/dist/exports/types.d.ts +1 -0
- package/dist/exports/types.js +3 -0
- package/dist/exports/types.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin.d.ts +3 -0
- package/dist/plugin.js +52 -0
- package/dist/plugin.js.map +1 -0
- package/dist/styles.scss +482 -0
- package/dist/types.d.ts +39 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +82 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/FocalPointEditor.tsx"],"sourcesContent":["'use client'\n\nimport { useConfig, useDocumentInfo, useForm, useUploadEdits } from '@payloadcms/ui'\nimport React, { useCallback, useEffect, useRef, useState } from 'react'\nimport 'react-image-crop/dist/ReactCrop.css'\nimport ReactCrop, { type Crop } from 'react-image-crop'\n\nimport { DEFAULT_ASPECT_RATIOS } from '../defaults'\nimport type { AspectRatioConfig, CropConfig } from '../types'\n\nimport { AspectRatioPreviewGrid } from './AspectRatioPreviewGrid'\n\nexport const FocalPointEditor: React.FC = () => {\n const { data } = useDocumentInfo()\n const { setModified } = useForm()\n const { uploadEdits, updateUploadEdits } = useUploadEdits()\n const { getEntityConfig } = useConfig()\n\n // Read the ratios the plugin stashed in the collection's `custom` config.\n // Falls back to the shipped defaults so the editor renders even if a\n // consumer wired the field without options.\n const collectionSlug = typeof data?.collection === 'string' ? data.collection : undefined\n const entityConfig = collectionSlug ? getEntityConfig({ collectionSlug }) : undefined\n const aspectRatios =\n (((entityConfig as unknown as { custom?: { aspectPreview?: { aspectRatios?: AspectRatioConfig[] } } })?.custom\n ?.aspectPreview?.aspectRatios) as AspectRatioConfig[] | undefined) ?? DEFAULT_ASPECT_RATIOS\n\n const hasUserEditedRef = useRef(false)\n\n // Bust the browser cache when the document is re-saved so the regenerated\n // cropped image (same URL, new bytes) shows up in the preview grid.\n const rawUrl = data?.url as string | undefined\n const updatedAtTag = data?.updatedAt ? String(data.updatedAt) : undefined\n const imageUrl = React.useMemo(() => {\n if (!rawUrl) return undefined\n if (!updatedAtTag) return rawUrl\n const sep = rawUrl.includes('?') ? '&' : '?'\n return `${rawUrl}${sep}v=${encodeURIComponent(updatedAtTag)}`\n }, [rawUrl, updatedAtTag])\n\n const [mode, setMode] = useState<'crop' | 'focal'>('focal')\n // Crop is undefined when none has been drawn yet. When the user enters crop\n // mode without an existing crop, ReactCrop should wait for them to draw one\n // — we don't pre-fill 100% any more.\n const [crop, setCrop] = useState<Crop | undefined>(\n uploadEdits?.crop\n ? {\n unit: uploadEdits.crop.unit as 'px' | '%',\n x: uploadEdits.crop.x,\n y: uploadEdits.crop.y,\n width: uploadEdits.crop.width,\n height: uploadEdits.crop.height,\n }\n : undefined,\n )\n const [focalPoint, setFocalPoint] = useState({\n x: uploadEdits?.focalPoint?.x || data?.focalX || 50,\n y: uploadEdits?.focalPoint?.y || data?.focalY || 50,\n })\n const containerRef = useRef<HTMLDivElement>(null)\n const [isDragging, setIsDragging] = useState(false)\n // Natural pixel dimensions of the underlying image. Needed because Payload's\n // cropImage requires `widthInPixels` / `heightInPixels` in addition to the\n // percent crop — without them sharp.extract receives NaN and the save fails.\n const [naturalSize, setNaturalSize] = useState<{ width: number; height: number }>(() => ({\n width: typeof data?.width === 'number' ? data.width : 0,\n height: typeof data?.height === 'number' ? data.height : 0,\n }))\n\n // Prefer the Payload document's authoritative width/height — that's what\n // sharp reads on the server. Fall back to the browser-decoded natural size.\n const docWidth = typeof data?.width === 'number' ? data.width : 0\n const docHeight = typeof data?.height === 'number' ? data.height : 0\n\n useEffect(() => {\n if (docWidth > 0 && docHeight > 0) {\n queueMicrotask(() => setNaturalSize({ width: docWidth, height: docHeight }))\n return\n }\n if (!imageUrl) return\n const img = new Image()\n img.onload = () => {\n setNaturalSize({ width: img.naturalWidth, height: img.naturalHeight })\n }\n img.src = imageUrl\n }, [imageUrl, docWidth, docHeight])\n\n const [prevUpdatedAtTag, setPrevUpdatedAtTag] = useState(updatedAtTag)\n\n // Re-sync local state from the saved document each time `updatedAt` changes.\n useEffect(() => {\n if (updatedAtTag && updatedAtTag !== prevUpdatedAtTag) {\n const nextFocal = {\n x: typeof data?.focalX === 'number' ? data.focalX : 50,\n y: typeof data?.focalY === 'number' ? data.focalY : 50,\n }\n queueMicrotask(() => {\n setPrevUpdatedAtTag(updatedAtTag)\n hasUserEditedRef.current = false\n setFocalPoint(nextFocal)\n setCrop(undefined)\n })\n if (uploadEdits?.crop || uploadEdits?.focalPoint) {\n updateUploadEdits({\n crop: undefined,\n focalPoint: nextFocal,\n heightInPixels: undefined,\n widthInPixels: undefined,\n })\n }\n }\n }, [\n updatedAtTag,\n prevUpdatedAtTag,\n data?.focalX,\n data?.focalY,\n uploadEdits?.crop,\n uploadEdits?.focalPoint,\n updateUploadEdits\n ])\n\n const hasRealCrop =\n !!crop &&\n crop.width > 0 &&\n crop.height > 0 &&\n (crop.width !== 100 || crop.height !== 100 || crop.x !== 0 || crop.y !== 0)\n\n // Auto-save to uploadEdits whenever state changes\n useEffect(() => {\n if (!hasUserEditedRef.current) return\n\n const timeout = setTimeout(() => {\n setModified(true)\n\n if (hasRealCrop && crop && naturalSize.width > 0 && naturalSize.height > 0) {\n // Payload's cropImage computes `left = floor(x% * imgW / 100)` and\n // `top = floor(y% * imgH / 100)`, then calls sharp.extract with our\n // widthInPixels / heightInPixels. Sharp rejects the call if\n // left + width > imgW (likewise for height) — even by 1px.\n // We must compute width/height with floor and clamp so they always\n // fit inside the image from that floored offset.\n const leftPx = Math.floor((crop.x / 100) * naturalSize.width)\n const topPx = Math.floor((crop.y / 100) * naturalSize.height)\n const widthInPixels = Math.max(\n 1,\n Math.min(Math.floor((crop.width / 100) * naturalSize.width), naturalSize.width - leftPx),\n )\n const heightInPixels = Math.max(\n 1,\n Math.min(\n Math.floor((crop.height / 100) * naturalSize.height),\n naturalSize.height - topPx,\n ),\n )\n updateUploadEdits({\n crop: {\n unit: '%',\n x: crop.x,\n y: crop.y,\n width: crop.width,\n height: crop.height,\n },\n focalPoint,\n heightInPixels,\n widthInPixels,\n })\n } else {\n updateUploadEdits({\n crop: undefined,\n focalPoint,\n heightInPixels: undefined,\n widthInPixels: undefined,\n })\n }\n }, 100)\n return () => clearTimeout(timeout)\n }, [crop, hasRealCrop, focalPoint, naturalSize, setModified, updateUploadEdits])\n\n const clampFocalToCrop = useCallback(\n (x: number, y: number) => {\n if (crop && crop.unit === '%' && hasRealCrop) {\n x = Math.max(crop.x, Math.min(crop.x + crop.width, x))\n y = Math.max(crop.y, Math.min(crop.y + crop.height, y))\n }\n return { x, y }\n },\n [crop, hasRealCrop],\n )\n\n // Focal point drag handlers\n const updateFocalFromEvent = useCallback(\n (e: React.MouseEvent | React.TouchEvent | MouseEvent | TouchEvent) => {\n const container = containerRef.current\n if (!container) return\n const rect = container.getBoundingClientRect()\n const clientX = 'touches' in e ? e.touches[0].clientX : e.clientX\n const clientY = 'touches' in e ? e.touches[0].clientY : e.clientY\n let x = ((clientX - rect.left) / rect.width) * 100\n let y = ((clientY - rect.top) / rect.height) * 100\n\n x = Math.max(0, Math.min(100, x))\n y = Math.max(0, Math.min(100, y))\n\n const clamped = clampFocalToCrop(x, y)\n hasUserEditedRef.current = true\n setFocalPoint(clamped)\n },\n [clampFocalToCrop],\n )\n\n const handleMouseDown = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault()\n setIsDragging(true)\n updateFocalFromEvent(e)\n },\n [updateFocalFromEvent],\n )\n\n const handleTouchStart = useCallback(\n (e: React.TouchEvent) => {\n setIsDragging(true)\n updateFocalFromEvent(e)\n },\n [updateFocalFromEvent],\n )\n\n useEffect(() => {\n if (!isDragging) return\n const handleMove = (e: MouseEvent | TouchEvent) => {\n e.preventDefault()\n updateFocalFromEvent(e)\n }\n const handleUp = () => setIsDragging(false)\n window.addEventListener('mousemove', handleMove)\n window.addEventListener('mouseup', handleUp)\n window.addEventListener('touchmove', handleMove, { passive: false })\n window.addEventListener('touchend', handleUp)\n return () => {\n window.removeEventListener('mousemove', handleMove)\n window.removeEventListener('mouseup', handleUp)\n window.removeEventListener('touchmove', handleMove)\n window.removeEventListener('touchend', handleUp)\n }\n }, [isDragging, updateFocalFromEvent])\n\n // react-image-crop gives two values: `crop` (in the current unit, often px\n // relative to the *displayed* image) and `percentCrop` (always 0-100%).\n // Store percentCrop so preview math is display-size-independent.\n const handleCropChange = useCallback((_crop: Crop, _percentCrop: Crop) => {\n hasUserEditedRef.current = true\n setCrop(_percentCrop)\n }, [])\n\n const handleReset = useCallback(() => {\n hasUserEditedRef.current = true\n setFocalPoint({ x: 50, y: 50 })\n setCrop(undefined)\n }, [])\n\n const handleCropFieldChange = useCallback(\n (field: 'x' | 'y' | 'width' | 'height', value: number) => {\n hasUserEditedRef.current = true\n setCrop((prev) => {\n // Bootstrap a crop on first edit\n const base: Crop = prev ?? { unit: '%', x: 0, y: 0, width: 100, height: 100 }\n const next: Crop = { ...base, [field]: value }\n // Clamp to image bounds (percent units)\n if (next.unit === '%') {\n next.x = Math.max(0, Math.min(100, next.x))\n next.y = Math.max(0, Math.min(100, next.y))\n next.width = Math.max(0, Math.min(100 - next.x, next.width))\n next.height = Math.max(0, Math.min(100 - next.y, next.height))\n }\n return next\n })\n },\n [],\n )\n\n if (!imageUrl) {\n return (\n <div className=\"focal-editor\">\n <div className=\"focal-editor__empty\">\n Upload an image to edit focal point and preview aspect ratios.\n </div>\n </div>\n )\n }\n\n const cropConfig: CropConfig | undefined =\n hasRealCrop && crop\n ? {\n unit: crop.unit as 'px' | '%',\n x: crop.x,\n y: crop.y,\n width: crop.width,\n height: crop.height,\n }\n : undefined\n\n const cropUnitLabel = crop?.unit === 'px' ? 'px' : '%'\n\n return (\n <div className=\"focal-editor\">\n <div className=\"focal-editor__layout\">\n {/* Left — sticky editor */}\n <div className=\"focal-editor__left\">\n {/* Toolbar: two rows of inputs on the left, button column on the right */}\n <div className=\"focal-editor__toolbar\">\n <div className=\"focal-editor__toolbar-inputs\">\n {/* Row 1 — focal point */}\n <div className=\"focal-editor__toolbar-col\">\n <span className=\"focal-editor__row-label\">Focal</span>\n <div className=\"focal-editor__subgroup\">\n <span className=\"focal-editor__subgroup-label\">Position</span>\n <div className=\"focal-editor__subgroup-inputs\">\n <div className=\"focal-editor__input-group\">\n <label htmlFor=\"focal-x\">X</label>\n <input\n id=\"focal-x\"\n type=\"number\"\n min={0}\n max={100}\n value={Math.round(focalPoint.x)}\n onChange={(e) => {\n hasUserEditedRef.current = true\n setFocalPoint((prev) => {\n const x = Math.max(0, Math.min(100, Number(e.target.value)))\n return clampFocalToCrop(x, prev.y)\n })\n }}\n />\n <span>%</span>\n </div>\n <div className=\"focal-editor__input-group\">\n <label htmlFor=\"focal-y\">Y</label>\n <input\n id=\"focal-y\"\n type=\"number\"\n min={0}\n max={100}\n value={Math.round(focalPoint.y)}\n onChange={(e) => {\n hasUserEditedRef.current = true\n setFocalPoint((prev) => {\n const y = Math.max(0, Math.min(100, Number(e.target.value)))\n return clampFocalToCrop(prev.x, y)\n })\n }}\n />\n <span>%</span>\n </div>\n </div>\n </div>\n </div>\n\n {/* Row 2 — crop */}\n <div className=\"focal-editor__toolbar-col\">\n <span className=\"focal-editor__row-label\">Crop</span>\n <div className=\"focal-editor__toolbar-row\">\n <div className=\"focal-editor__subgroup\">\n <span className=\"focal-editor__subgroup-label\">Position</span>\n <div className=\"focal-editor__subgroup-inputs\">\n <div className=\"focal-editor__input-group\">\n <label htmlFor=\"crop-x\">X</label>\n <input\n id=\"crop-x\"\n type=\"number\"\n min={0}\n max={100}\n value={crop ? Math.round(crop.x) : 0}\n onChange={(e) => handleCropFieldChange('x', Number(e.target.value))}\n disabled={!hasRealCrop}\n />\n <span>{cropUnitLabel}</span>\n </div>\n <div className=\"focal-editor__input-group\">\n <label htmlFor=\"crop-y\">Y</label>\n <input\n id=\"crop-y\"\n type=\"number\"\n min={0}\n max={100}\n value={crop ? Math.round(crop.y) : 0}\n onChange={(e) => handleCropFieldChange('y', Number(e.target.value))}\n disabled={!hasRealCrop}\n />\n <span>{cropUnitLabel}</span>\n </div>\n </div>\n </div>\n <div className=\"focal-editor__subgroup\">\n <span className=\"focal-editor__subgroup-label\">Size</span>\n <div className=\"focal-editor__subgroup-inputs\">\n <div className=\"focal-editor__input-group\">\n <label htmlFor=\"crop-w\">W</label>\n <input\n id=\"crop-w\"\n type=\"number\"\n min={0}\n max={100}\n value={crop ? Math.round(crop.width) : 0}\n onChange={(e) => handleCropFieldChange('width', Number(e.target.value))}\n disabled={!hasRealCrop}\n />\n <span>{cropUnitLabel}</span>\n </div>\n <div className=\"focal-editor__input-group\">\n <label htmlFor=\"crop-h\">H</label>\n <input\n id=\"crop-h\"\n type=\"number\"\n min={0}\n max={100}\n value={crop ? Math.round(crop.height) : 0}\n onChange={(e) => handleCropFieldChange('height', Number(e.target.value))}\n disabled={!hasRealCrop}\n />\n <span>{cropUnitLabel}</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <div className=\"focal-editor__toolbar-actions\">\n <button className=\"focal-editor__btn\" onClick={handleReset} type=\"button\">\n Reset\n </button>\n <div className=\"focal-editor__mode-toggle\">\n <button\n className={`focal-editor__mode-btn ${mode === 'focal' ? 'focal-editor__mode-btn--active' : ''}`}\n onClick={() => setMode('focal')}\n type=\"button\"\n >\n Focal Point\n </button>\n <button\n className={`focal-editor__mode-btn ${mode === 'crop' ? 'focal-editor__mode-btn--active' : ''}`}\n onClick={() => setMode('crop')}\n type=\"button\"\n >\n Crop\n </button>\n </div>\n </div>\n </div>\n\n {/* Full-width image within left column */}\n <div className=\"focal-editor__image-wrapper\">\n <ReactCrop\n crop={mode === 'crop' ? crop : undefined}\n onChange={handleCropChange}\n disabled={mode === 'focal'}\n className={`focal-editor__react-crop ${mode === 'focal' ? 'is-focal-mode' : 'is-crop-mode'}`}\n >\n <div\n style={{\n position: 'relative',\n display: 'inline-block',\n lineHeight: 0,\n width: '100%',\n }}\n >\n {\n /**\n *\n * As it's a CMS, we don't want to use next/image here,\n * it also wouldn't bring any value as it's not a production\n * website, but an admin panel. So we can use a simple\n * img tag here.\n *\n **/\n }\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img\n src={imageUrl}\n alt=\"Edit\"\n draggable={false}\n style={{ display: 'block', width: '100%', height: 'auto', objectFit: 'contain' }}\n onLoad={(e) => {\n const img = e.currentTarget\n const displayedW = img.clientWidth\n const displayedH = img.clientHeight\n // If a legacy px crop was loaded from uploadEdits, convert\n // it to percentages now that we know the displayed size.\n if (crop?.unit === 'px' && displayedW > 0 && displayedH > 0) {\n setCrop({\n unit: '%',\n x: (crop.x / displayedW) * 100,\n y: (crop.y / displayedH) * 100,\n width: (crop.width / displayedW) * 100,\n height: (crop.height / displayedH) * 100,\n })\n }\n }}\n />\n {/* Crop reference overlay — visible in focal mode so the user\n knows which region the focal point is relative to. */}\n {mode === 'focal' && crop && crop.unit === '%' && hasRealCrop && (\n <div\n className=\"focal-editor__crop-overlay\"\n style={{\n left: `${crop.x}%`,\n top: `${crop.y}%`,\n width: `${crop.width}%`,\n height: `${crop.height}%`,\n }}\n />\n )}\n <div\n ref={containerRef}\n className={`focal-editor__focal-overlay ${mode === 'focal' ? 'is-active' : ''}`}\n onMouseDown={handleMouseDown}\n onTouchStart={handleTouchStart}\n >\n {mode === 'focal' && (\n <div\n className=\"focal-editor__crosshair\"\n style={{\n left: `${focalPoint.x}%`,\n top: `${focalPoint.y}%`,\n }}\n >\n <div className=\"focal-editor__crosshair-h\" />\n <div className=\"focal-editor__crosshair-v\" />\n </div>\n )}\n </div>\n </div>\n </ReactCrop>\n </div>\n </div>\n\n {/* Right — CSS grid of aspect ratio previews */}\n <div className=\"focal-editor__right\">\n <AspectRatioPreviewGrid\n url={imageUrl}\n focalX={focalPoint.x}\n focalY={focalPoint.y}\n aspectRatios={aspectRatios}\n crop={cropConfig}\n />\n </div>\n </div>\n </div>\n )\n}\n\nexport default FocalPointEditor\n"],"names":["useConfig","useDocumentInfo","useForm","useUploadEdits","React","useCallback","useEffect","useRef","useState","ReactCrop","DEFAULT_ASPECT_RATIOS","AspectRatioPreviewGrid","FocalPointEditor","data","setModified","uploadEdits","updateUploadEdits","getEntityConfig","collectionSlug","collection","undefined","entityConfig","aspectRatios","custom","aspectPreview","hasUserEditedRef","rawUrl","url","updatedAtTag","updatedAt","String","imageUrl","useMemo","sep","includes","encodeURIComponent","mode","setMode","crop","setCrop","unit","x","y","width","height","focalPoint","setFocalPoint","focalX","focalY","containerRef","isDragging","setIsDragging","naturalSize","setNaturalSize","docWidth","docHeight","queueMicrotask","img","Image","onload","naturalWidth","naturalHeight","src","prevUpdatedAtTag","setPrevUpdatedAtTag","nextFocal","current","heightInPixels","widthInPixels","hasRealCrop","timeout","setTimeout","leftPx","Math","floor","topPx","max","min","clearTimeout","clampFocalToCrop","updateFocalFromEvent","e","container","rect","getBoundingClientRect","clientX","touches","clientY","left","top","clamped","handleMouseDown","preventDefault","handleTouchStart","handleMove","handleUp","window","addEventListener","passive","removeEventListener","handleCropChange","_crop","_percentCrop","handleReset","handleCropFieldChange","field","value","prev","base","next","div","className","cropConfig","cropUnitLabel","span","label","htmlFor","input","id","type","round","onChange","Number","target","disabled","button","onClick","style","position","display","lineHeight","alt","draggable","objectFit","onLoad","currentTarget","displayedW","clientWidth","displayedH","clientHeight","ref","onMouseDown","onTouchStart"],"mappings":"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"}
|
package/dist/defaults.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export const DEFAULT_ASPECT_RATIOS = [
|
|
2
|
+
{
|
|
3
|
+
name: 'Square',
|
|
4
|
+
ratio: '1:1',
|
|
5
|
+
width: 1,
|
|
6
|
+
height: 1,
|
|
7
|
+
source: 'crop',
|
|
8
|
+
usage: 'Avatars, thumbnails',
|
|
9
|
+
category: 'general'
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
name: 'Standard',
|
|
13
|
+
ratio: '4:3',
|
|
14
|
+
width: 4,
|
|
15
|
+
height: 3,
|
|
16
|
+
source: 'css',
|
|
17
|
+
usage: 'Standard cards',
|
|
18
|
+
category: 'general'
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: 'Classic',
|
|
22
|
+
ratio: '3:2',
|
|
23
|
+
width: 3,
|
|
24
|
+
height: 2,
|
|
25
|
+
source: 'css',
|
|
26
|
+
usage: 'Photography',
|
|
27
|
+
category: 'general'
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: 'Widescreen',
|
|
31
|
+
ratio: '16:9',
|
|
32
|
+
width: 16,
|
|
33
|
+
height: 9,
|
|
34
|
+
source: 'css',
|
|
35
|
+
usage: 'Hero / media blocks',
|
|
36
|
+
category: 'general'
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: 'Portrait',
|
|
40
|
+
ratio: '9:16',
|
|
41
|
+
width: 9,
|
|
42
|
+
height: 16,
|
|
43
|
+
source: 'css',
|
|
44
|
+
usage: 'Mobile / stories',
|
|
45
|
+
category: 'general'
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: 'Social Share',
|
|
49
|
+
ratio: '1.91:1',
|
|
50
|
+
width: 1200,
|
|
51
|
+
height: 630,
|
|
52
|
+
source: 'crop',
|
|
53
|
+
usage: 'Open Graph / social',
|
|
54
|
+
category: 'social'
|
|
55
|
+
}
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
//# sourceMappingURL=defaults.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/defaults.ts"],"sourcesContent":["import type { AspectRatioConfig } from './types.js'\n\nexport const DEFAULT_ASPECT_RATIOS: AspectRatioConfig[] = [\n { name: 'Square', ratio: '1:1', width: 1, height: 1, source: 'crop', usage: 'Avatars, thumbnails', category: 'general' },\n { name: 'Standard', ratio: '4:3', width: 4, height: 3, source: 'css', usage: 'Standard cards', category: 'general' },\n { name: 'Classic', ratio: '3:2', width: 3, height: 2, source: 'css', usage: 'Photography', category: 'general' },\n { name: 'Widescreen', ratio: '16:9', width: 16, height: 9, source: 'css', usage: 'Hero / media blocks', category: 'general' },\n { name: 'Portrait', ratio: '9:16', width: 9, height: 16, source: 'css', usage: 'Mobile / stories', category: 'general' },\n { name: 'Social Share', ratio: '1.91:1', width: 1200, height: 630, source: 'crop', usage: 'Open Graph / social', category: 'social' },\n]\n"],"names":["DEFAULT_ASPECT_RATIOS","name","ratio","width","height","source","usage","category"],"mappings":"AAEA,OAAO,MAAMA,wBAA6C;IACxD;QAAEC,MAAM;QAAUC,OAAO;QAAOC,OAAO;QAAGC,QAAQ;QAAGC,QAAQ;QAAQC,OAAO;QAAuBC,UAAU;IAAU;IACvH;QAAEN,MAAM;QAAYC,OAAO;QAAOC,OAAO;QAAGC,QAAQ;QAAGC,QAAQ;QAAOC,OAAO;QAAkBC,UAAU;IAAU;IACnH;QAAEN,MAAM;QAAWC,OAAO;QAAOC,OAAO;QAAGC,QAAQ;QAAGC,QAAQ;QAAOC,OAAO;QAAeC,UAAU;IAAU;IAC/G;QAAEN,MAAM;QAAcC,OAAO;QAAQC,OAAO;QAAIC,QAAQ;QAAGC,QAAQ;QAAOC,OAAO;QAAuBC,UAAU;IAAU;IAC5H;QAAEN,MAAM;QAAYC,OAAO;QAAQC,OAAO;QAAGC,QAAQ;QAAIC,QAAQ;QAAOC,OAAO;QAAoBC,UAAU;IAAU;IACvH;QAAEN,MAAM;QAAgBC,OAAO;QAAUC,OAAO;QAAMC,QAAQ;QAAKC,QAAQ;QAAQC,OAAO;QAAuBC,UAAU;IAAS;CACrI,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/exports/client.ts"],"sourcesContent":["export { FocalPointEditor } from '../components/FocalPointEditor.js'\nexport { AspectRatioPreviewGrid } from '../components/AspectRatioPreviewGrid.js'\nexport { CustomUpload } from '../components/CustomUpload.js'\n"],"names":["FocalPointEditor","AspectRatioPreviewGrid","CustomUpload"],"mappings":"AAAA,SAASA,gBAAgB,QAAQ,oCAAmC;AACpE,SAASC,sBAAsB,QAAQ,0CAAyC;AAChF,SAASC,YAAY,QAAQ,gCAA+B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { AspectPreviewPluginOptions, AspectRatioConfig, CropConfig, FocalPointState, UploadEditsState, } from '../types.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/exports/types.ts"],"sourcesContent":["export type {\n AspectPreviewPluginOptions,\n AspectRatioConfig,\n CropConfig,\n FocalPointState,\n UploadEditsState,\n} from '../types.js'\n"],"names":[],"mappings":"AAAA,WAMoB"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { aspectPreviewPlugin } from './plugin.js'\nexport { DEFAULT_ASPECT_RATIOS } from './defaults.js'\nexport type {\n AspectPreviewPluginOptions,\n AspectRatioConfig,\n CropConfig,\n FocalPointState,\n UploadEditsState,\n} from './types.js'\n"],"names":["aspectPreviewPlugin","DEFAULT_ASPECT_RATIOS"],"mappings":"AAAA,SAASA,mBAAmB,QAAQ,cAAa;AACjD,SAASC,qBAAqB,QAAQ,gBAAe"}
|
package/dist/plugin.d.ts
ADDED
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { DEFAULT_ASPECT_RATIOS } from './defaults.js';
|
|
2
|
+
const FIELD_COMPONENT = 'payload-plugin-aspect-preview/client#FocalPointEditor';
|
|
3
|
+
const UPLOAD_COMPONENT = 'payload-plugin-aspect-preview/client#CustomUpload';
|
|
4
|
+
export const aspectPreviewPlugin = (options)=>(config)=>{
|
|
5
|
+
const aspectRatios = options.aspectRatios ?? DEFAULT_ASPECT_RATIOS;
|
|
6
|
+
const enabled = new Set(options.collections);
|
|
7
|
+
return {
|
|
8
|
+
...config,
|
|
9
|
+
collections: config.collections?.map((collection)=>{
|
|
10
|
+
if (!enabled.has(collection.slug)) return collection;
|
|
11
|
+
const next = {
|
|
12
|
+
...collection,
|
|
13
|
+
fields: [
|
|
14
|
+
...collection.fields || [],
|
|
15
|
+
{
|
|
16
|
+
name: 'aspectPreview',
|
|
17
|
+
type: 'ui',
|
|
18
|
+
admin: {
|
|
19
|
+
components: {
|
|
20
|
+
Field: FIELD_COMPONENT
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
custom: {
|
|
26
|
+
...collection.custom,
|
|
27
|
+
aspectPreview: {
|
|
28
|
+
aspectRatios
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
// The Upload override is what removes Payload's default crop/adjust
|
|
33
|
+
// drawer so the inline editor is the only surface. Skip it when
|
|
34
|
+
// disabled, but keep the field + custom above for schema consistency.
|
|
35
|
+
if (!options.disabled) {
|
|
36
|
+
next.admin = {
|
|
37
|
+
...collection.admin,
|
|
38
|
+
components: {
|
|
39
|
+
...collection.admin?.components,
|
|
40
|
+
edit: {
|
|
41
|
+
...collection.admin?.components?.edit,
|
|
42
|
+
Upload: UPLOAD_COMPONENT
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
return next;
|
|
48
|
+
})
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/plugin.ts"],"sourcesContent":["import type { CollectionConfig, Config, Plugin } from 'payload'\n\nimport { DEFAULT_ASPECT_RATIOS } from './defaults.js'\nimport type { AspectPreviewPluginOptions } from './types.js'\n\nconst FIELD_COMPONENT = 'payload-plugin-aspect-preview/client#FocalPointEditor'\nconst UPLOAD_COMPONENT = 'payload-plugin-aspect-preview/client#CustomUpload'\n\nexport const aspectPreviewPlugin =\n (options: AspectPreviewPluginOptions): Plugin =>\n (config: Config): Config => {\n const aspectRatios = options.aspectRatios ?? DEFAULT_ASPECT_RATIOS\n const enabled = new Set(options.collections)\n\n return {\n ...config,\n collections: config.collections?.map((collection) => {\n if (!enabled.has(collection.slug)) return collection\n\n const next: CollectionConfig = {\n ...collection,\n fields: [\n ...(collection.fields || []),\n {\n name: 'aspectPreview',\n type: 'ui',\n admin: {\n components: {\n Field: FIELD_COMPONENT,\n },\n },\n },\n ],\n custom: {\n ...collection.custom,\n aspectPreview: { aspectRatios },\n },\n }\n\n // The Upload override is what removes Payload's default crop/adjust\n // drawer so the inline editor is the only surface. Skip it when\n // disabled, but keep the field + custom above for schema consistency.\n if (!options.disabled) {\n next.admin = {\n ...collection.admin,\n components: {\n ...collection.admin?.components,\n edit: {\n ...collection.admin?.components?.edit,\n Upload: UPLOAD_COMPONENT,\n },\n },\n }\n }\n\n return next\n }),\n }\n }\n"],"names":["DEFAULT_ASPECT_RATIOS","FIELD_COMPONENT","UPLOAD_COMPONENT","aspectPreviewPlugin","options","config","aspectRatios","enabled","Set","collections","map","collection","has","slug","next","fields","name","type","admin","components","Field","custom","aspectPreview","disabled","edit","Upload"],"mappings":"AAEA,SAASA,qBAAqB,QAAQ,gBAAe;AAGrD,MAAMC,kBAAkB;AACxB,MAAMC,mBAAmB;AAEzB,OAAO,MAAMC,sBACX,CAACC,UACD,CAACC;QACC,MAAMC,eAAeF,QAAQE,YAAY,IAAIN;QAC7C,MAAMO,UAAU,IAAIC,IAAIJ,QAAQK,WAAW;QAE3C,OAAO;YACL,GAAGJ,MAAM;YACTI,aAAaJ,OAAOI,WAAW,EAAEC,IAAI,CAACC;gBACpC,IAAI,CAACJ,QAAQK,GAAG,CAACD,WAAWE,IAAI,GAAG,OAAOF;gBAE1C,MAAMG,OAAyB;oBAC7B,GAAGH,UAAU;oBACbI,QAAQ;2BACFJ,WAAWI,MAAM,IAAI,EAAE;wBAC3B;4BACEC,MAAM;4BACNC,MAAM;4BACNC,OAAO;gCACLC,YAAY;oCACVC,OAAOnB;gCACT;4BACF;wBACF;qBACD;oBACDoB,QAAQ;wBACN,GAAGV,WAAWU,MAAM;wBACpBC,eAAe;4BAAEhB;wBAAa;oBAChC;gBACF;gBAEA,oEAAoE;gBACpE,gEAAgE;gBAChE,sEAAsE;gBACtE,IAAI,CAACF,QAAQmB,QAAQ,EAAE;oBACrBT,KAAKI,KAAK,GAAG;wBACX,GAAGP,WAAWO,KAAK;wBACnBC,YAAY;4BACV,GAAGR,WAAWO,KAAK,EAAEC,UAAU;4BAC/BK,MAAM;gCACJ,GAAGb,WAAWO,KAAK,EAAEC,YAAYK,IAAI;gCACrCC,QAAQvB;4BACV;wBACF;oBACF;gBACF;gBAEA,OAAOY;YACT;QACF;IACF,EAAC"}
|