datocms-plugin-media-layouts 0.1.0 → 0.1.1
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/README.md
CHANGED
|
@@ -9,10 +9,12 @@ A DatoCMS plugin that extends JSON fields to allow editors to select assets with
|
|
|
9
9
|
- **Self-contained data**: Stores URL, filename, and all metadata directly in JSON—no additional API calls needed
|
|
10
10
|
- **Three operational modes**: Single asset, multiple assets (gallery), or predefined layout slots
|
|
11
11
|
- **Aspect ratio control**: 9 presets plus custom ratios for precise cropping
|
|
12
|
-
- **Width presets**: Original (max) plus 320px mobile to 4K resolution
|
|
12
|
+
- **Width presets**: Original (max) plus 320px mobile to 4K resolution, with named custom presets and custom widths
|
|
13
13
|
- **Focal point support**: Preserves focal point data from DatoCMS media library
|
|
14
14
|
- **Metadata editing**: Edit alt text, title, and focal point directly from the field
|
|
15
|
-
- **
|
|
15
|
+
- **Per-asset options**: Optional CSS class and lazy loading toggle per image
|
|
16
|
+
- **Layout builder**: Grid or masonry layouts with drag-and-drop placement, slot spans, and auto-sizing from aspect ratio
|
|
17
|
+
- **Layout metadata**: Optional layout aspect ratio + width for overall composition sizing
|
|
16
18
|
- **Automatic height calculation**: Heights computed from width and aspect ratio for easy imgix integration
|
|
17
19
|
|
|
18
20
|
## Installation
|
|
@@ -34,6 +36,7 @@ Configure default values that apply to all fields using this plugin:
|
|
|
34
36
|
|---------|-------------|---------|
|
|
35
37
|
| Default Aspect Ratio | Applied to new assets when no field override exists | 16:9 |
|
|
36
38
|
| Default Width | Applied to new assets when no field override exists | 1920px |
|
|
39
|
+
| Width Presets | Named width options shown in all width selectors | (none) |
|
|
37
40
|
|
|
38
41
|
### Field Configuration
|
|
39
42
|
|
|
@@ -49,13 +52,26 @@ Select multiple images, each with independent layout settings. Stores an array o
|
|
|
49
52
|
|
|
50
53
|
#### Layout Mode (Predefined Slots)
|
|
51
54
|
|
|
52
|
-
Define a
|
|
55
|
+
Define a layout with named slots that editors fill with assets. Choose a style:
|
|
56
|
+
|
|
57
|
+
- **Grid**: Explicit rows/columns (1–4 columns, 1–6 rows), slots placed in cells
|
|
58
|
+
- **Masonry**: Column-based layout with variable heights and ordered slots
|
|
59
|
+
|
|
60
|
+
Each slot has:
|
|
53
61
|
- **Label**: Descriptive name (e.g., "Hero Image", "Sidebar Thumbnail")
|
|
54
|
-
- **Aspect Ratio**: Fixed ratio for this slot
|
|
55
|
-
- **Width**: Fixed output width for this slot (including
|
|
62
|
+
- **Aspect Ratio**: Fixed ratio for this slot (including Custom)
|
|
63
|
+
- **Width**: Fixed output width for this slot (including Custom)
|
|
56
64
|
- **Required**: Whether the slot must be filled
|
|
57
65
|
|
|
58
|
-
|
|
66
|
+
Layout builder enhancements:
|
|
67
|
+
- **Drag-and-drop placement**: Move or swap slots directly in the preview
|
|
68
|
+
- **Slot spans** (grid): Slots can span multiple rows/columns
|
|
69
|
+
- **Auto size from aspect ratio** (grid): Let spans be calculated based on the slot ratio
|
|
70
|
+
- **Column span** (masonry): Control the width of a masonry tile
|
|
71
|
+
|
|
72
|
+
Optional layout metadata:
|
|
73
|
+
- **Layout aspect ratio**: Auto, preset, or custom ratio for the overall composition
|
|
74
|
+
- **Layout width**: Auto, preset, or custom width for the overall composition (used to compute layout dimensions)
|
|
59
75
|
|
|
60
76
|
### Field Overrides
|
|
61
77
|
|
|
@@ -63,6 +79,12 @@ For single/multiple modes, you can optionally override global defaults:
|
|
|
63
79
|
- Toggle "Override default aspect ratio" to set a field-specific ratio
|
|
64
80
|
- Toggle "Override default width" to set a field-specific width
|
|
65
81
|
|
|
82
|
+
### Per-Asset Options
|
|
83
|
+
|
|
84
|
+
You can optionally enable extra per-image fields:
|
|
85
|
+
- **CSS class**: Text input to pass a custom class name
|
|
86
|
+
- **Lazy loading**: Boolean toggle for lazy loading preference
|
|
87
|
+
|
|
66
88
|
## Aspect Ratio Options
|
|
67
89
|
|
|
68
90
|
| Value | Label | Use Case |
|
|
@@ -92,6 +114,17 @@ For single/multiple modes, you can optionally override global defaults:
|
|
|
92
114
|
| 2560px | 2K | High-resolution displays |
|
|
93
115
|
| 3840px | 4K | Ultra HD displays |
|
|
94
116
|
|
|
117
|
+
Custom widths are supported: select "Custom..." and enter any pixel value
|
|
118
|
+
between 1 and 10000. Heights are still calculated automatically.
|
|
119
|
+
|
|
120
|
+
You can also add named custom presets in the plugin configuration (label + width),
|
|
121
|
+
which appear alongside the built-in options to guide editors with context-specific
|
|
122
|
+
sizes.
|
|
123
|
+
|
|
124
|
+
Custom presets are available in all width selectors (global defaults, field overrides,
|
|
125
|
+
asset/slot width pickers, and layout width). Layout width excludes the "Original"
|
|
126
|
+
option and supports Auto + Custom values.
|
|
127
|
+
|
|
95
128
|
## Data Model
|
|
96
129
|
|
|
97
130
|
The plugin stores all asset data directly in the JSON field, including the URL. No additional API calls are needed to render images.
|
|
@@ -107,6 +140,8 @@ The plugin stores all asset data directly in the JSON field, including the URL.
|
|
|
107
140
|
"size": 245000,
|
|
108
141
|
"alt": "A beautiful sunset",
|
|
109
142
|
"title": "Sunset at the beach",
|
|
143
|
+
"cssClass": "hero-image",
|
|
144
|
+
"lazyLoading": true,
|
|
110
145
|
"focalPoint": { "x": 0.5, "y": 0.3 },
|
|
111
146
|
"aspectRatio": "16:9",
|
|
112
147
|
"width": 1920,
|
|
@@ -128,6 +163,8 @@ The plugin stores all asset data directly in the JSON field, including the URL.
|
|
|
128
163
|
"size": 180000,
|
|
129
164
|
"alt": "First image",
|
|
130
165
|
"title": null,
|
|
166
|
+
"cssClass": "",
|
|
167
|
+
"lazyLoading": false,
|
|
131
168
|
"focalPoint": null,
|
|
132
169
|
"aspectRatio": "1:1",
|
|
133
170
|
"width": 640,
|
|
@@ -143,6 +180,8 @@ The plugin stores all asset data directly in the JSON field, including the URL.
|
|
|
143
180
|
"size": 320000,
|
|
144
181
|
"alt": "Second image",
|
|
145
182
|
"title": null,
|
|
183
|
+
"cssClass": "gallery-item",
|
|
184
|
+
"lazyLoading": true,
|
|
146
185
|
"focalPoint": { "x": 0.3, "y": 0.5 },
|
|
147
186
|
"aspectRatio": "4:3",
|
|
148
187
|
"width": 1024,
|
|
@@ -156,40 +195,79 @@ The plugin stores all asset data directly in the JSON field, including the URL.
|
|
|
156
195
|
### Layout Mode
|
|
157
196
|
|
|
158
197
|
```json
|
|
159
|
-
|
|
160
|
-
{
|
|
161
|
-
"
|
|
162
|
-
"
|
|
163
|
-
"
|
|
164
|
-
"
|
|
165
|
-
"
|
|
166
|
-
"
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
198
|
+
{
|
|
199
|
+
"layout": {
|
|
200
|
+
"columns": 2,
|
|
201
|
+
"rows": 2,
|
|
202
|
+
"layoutStyle": "grid",
|
|
203
|
+
"layoutAspectRatio": "16:9",
|
|
204
|
+
"layoutWidth": 1920,
|
|
205
|
+
"slots": [
|
|
206
|
+
{
|
|
207
|
+
"id": "hero",
|
|
208
|
+
"label": "Hero",
|
|
209
|
+
"aspectRatio": "21:9",
|
|
210
|
+
"width": 1920,
|
|
211
|
+
"row": 0,
|
|
212
|
+
"col": 0,
|
|
213
|
+
"rowSpan": 1,
|
|
214
|
+
"colSpan": 2,
|
|
215
|
+
"autoSpan": false,
|
|
216
|
+
"required": true
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
"id": "sidebar",
|
|
220
|
+
"label": "Sidebar",
|
|
221
|
+
"aspectRatio": "1:1",
|
|
222
|
+
"width": 320,
|
|
223
|
+
"row": 1,
|
|
224
|
+
"col": 1,
|
|
225
|
+
"rowSpan": 1,
|
|
226
|
+
"colSpan": 1,
|
|
227
|
+
"autoSpan": false,
|
|
228
|
+
"required": false
|
|
229
|
+
}
|
|
230
|
+
]
|
|
175
231
|
},
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
232
|
+
"assignments": [
|
|
233
|
+
{
|
|
234
|
+
"slotId": "hero",
|
|
235
|
+
"uploadId": "abc123",
|
|
236
|
+
"url": "https://www.datocms-assets.com/12345/hero.jpg",
|
|
237
|
+
"filename": "hero.jpg",
|
|
238
|
+
"format": "jpg",
|
|
239
|
+
"size": 450000,
|
|
240
|
+
"alt": "Hero banner",
|
|
241
|
+
"title": null,
|
|
242
|
+
"cssClass": "hero-image",
|
|
243
|
+
"lazyLoading": true,
|
|
244
|
+
"focalPoint": { "x": 0.5, "y": 0.5 },
|
|
245
|
+
"aspectRatio": "21:9",
|
|
246
|
+
"width": 1920,
|
|
247
|
+
"height": 823,
|
|
248
|
+
"originalWidth": 4000,
|
|
249
|
+
"originalHeight": 2000
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
"slotId": "sidebar",
|
|
253
|
+
"uploadId": "def456",
|
|
254
|
+
"url": "https://www.datocms-assets.com/12345/sidebar.jpg",
|
|
255
|
+
"filename": "sidebar.jpg",
|
|
256
|
+
"format": "jpg",
|
|
257
|
+
"size": 85000,
|
|
258
|
+
"alt": "Sidebar image",
|
|
259
|
+
"title": null,
|
|
260
|
+
"cssClass": "",
|
|
261
|
+
"lazyLoading": false,
|
|
262
|
+
"focalPoint": null,
|
|
263
|
+
"aspectRatio": "1:1",
|
|
264
|
+
"width": 320,
|
|
265
|
+
"height": 320,
|
|
266
|
+
"originalWidth": 800,
|
|
267
|
+
"originalHeight": 800
|
|
268
|
+
}
|
|
269
|
+
]
|
|
270
|
+
}
|
|
193
271
|
```
|
|
194
272
|
|
|
195
273
|
### TypeScript Types
|
|
@@ -203,6 +281,8 @@ type MediaLayoutItem = {
|
|
|
203
281
|
size: number;
|
|
204
282
|
alt: string | null;
|
|
205
283
|
title: string | null;
|
|
284
|
+
cssClass?: string;
|
|
285
|
+
lazyLoading?: boolean;
|
|
206
286
|
focalPoint: { x: number; y: number } | null;
|
|
207
287
|
aspectRatio: string;
|
|
208
288
|
customAspectRatio?: string; // When aspectRatio is "custom"
|
|
@@ -212,6 +292,30 @@ type MediaLayoutItem = {
|
|
|
212
292
|
originalHeight: number | null;
|
|
213
293
|
};
|
|
214
294
|
|
|
295
|
+
type LayoutSlot = {
|
|
296
|
+
id: string;
|
|
297
|
+
label: string;
|
|
298
|
+
aspectRatio: string;
|
|
299
|
+
customAspectRatio?: string; // When aspectRatio is "custom"
|
|
300
|
+
width: number | 'original';
|
|
301
|
+
row: number;
|
|
302
|
+
col: number;
|
|
303
|
+
rowSpan?: number;
|
|
304
|
+
colSpan?: number;
|
|
305
|
+
autoSpan?: boolean;
|
|
306
|
+
required: boolean;
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
type LayoutConfig = {
|
|
310
|
+
slots: LayoutSlot[];
|
|
311
|
+
columns: number;
|
|
312
|
+
rows: number;
|
|
313
|
+
layoutStyle?: 'grid' | 'masonry';
|
|
314
|
+
layoutAspectRatio?: string;
|
|
315
|
+
layoutCustomAspectRatio?: string;
|
|
316
|
+
layoutWidth?: number;
|
|
317
|
+
};
|
|
318
|
+
|
|
215
319
|
// Single mode value
|
|
216
320
|
type SingleFieldValue = MediaLayoutItem | null;
|
|
217
321
|
|
|
@@ -220,7 +324,10 @@ type MultipleFieldValue = MediaLayoutItem[];
|
|
|
220
324
|
|
|
221
325
|
// Layout mode value
|
|
222
326
|
type SlotAssignment = MediaLayoutItem & { slotId: string };
|
|
223
|
-
type LayoutFieldValue =
|
|
327
|
+
type LayoutFieldValue = {
|
|
328
|
+
layout: LayoutConfig;
|
|
329
|
+
assignments: SlotAssignment[];
|
|
330
|
+
};
|
|
224
331
|
```
|
|
225
332
|
|
|
226
333
|
## Usage with imgix
|