@orion-studios/payload-studio 0.5.0-beta.41 → 0.5.0-beta.43

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.
@@ -476,6 +476,17 @@ var FeatureGridBlock = {
476
476
  type: "text",
477
477
  required: true
478
478
  },
479
+ {
480
+ name: "itemsPerRow",
481
+ type: "number",
482
+ defaultValue: 3,
483
+ min: 1,
484
+ max: 6,
485
+ admin: {
486
+ description: "How many items to show per row on desktop.",
487
+ step: 1
488
+ }
489
+ },
479
490
  {
480
491
  name: "items",
481
492
  type: "array",
@@ -17,7 +17,7 @@ import {
17
17
  defaultPageLayoutBlocks,
18
18
  sectionPresets,
19
19
  templateStarterPresets
20
- } from "../chunk-XQYJXB46.mjs";
20
+ } from "../chunk-ICGXZCFJ.mjs";
21
21
  import "../chunk-SIL2J5MF.mjs";
22
22
  import "../chunk-6BWS3CLP.mjs";
23
23
  export {
@@ -57,6 +57,7 @@ var defaultNodeData = {
57
57
  },
58
58
  featureGrid: {
59
59
  ...withSectionStyleDefaults({}),
60
+ itemsPerRow: 3,
60
61
  items: [
61
62
  { description: "Explain this point.", iconType: "badge", icon: "01", imageCornerStyle: "rounded", imageFit: "cover", imagePosition: "center", title: "Feature One" },
62
63
  { description: "Explain this point.", iconType: "badge", icon: "02", imageCornerStyle: "rounded", imageFit: "cover", imagePosition: "center", title: "Feature Two" },
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-N67KVM2S.mjs";
4
4
  import {
5
5
  studioDocumentToLayout
6
- } from "./chunk-LB72FZZ3.mjs";
6
+ } from "./chunk-7TTLMA6K.mjs";
7
7
  import {
8
8
  __export
9
9
  } from "./chunk-6BWS3CLP.mjs";
@@ -312,6 +312,17 @@ var FeatureGridBlock = {
312
312
  type: "text",
313
313
  required: true
314
314
  },
315
+ {
316
+ name: "itemsPerRow",
317
+ type: "number",
318
+ defaultValue: 3,
319
+ min: 1,
320
+ max: 6,
321
+ admin: {
322
+ description: "How many items to show per row on desktop.",
323
+ step: 1
324
+ }
325
+ },
315
326
  {
316
327
  name: "items",
317
328
  type: "array",
package/dist/index.js CHANGED
@@ -1017,6 +1017,17 @@ var FeatureGridBlock = {
1017
1017
  type: "text",
1018
1018
  required: true
1019
1019
  },
1020
+ {
1021
+ name: "itemsPerRow",
1022
+ type: "number",
1023
+ defaultValue: 3,
1024
+ min: 1,
1025
+ max: 6,
1026
+ admin: {
1027
+ description: "How many items to show per row on desktop.",
1028
+ step: 1
1029
+ }
1030
+ },
1020
1031
  {
1021
1032
  name: "items",
1022
1033
  type: "array",
@@ -2355,6 +2366,7 @@ var defaultNodeData = {
2355
2366
  },
2356
2367
  featureGrid: {
2357
2368
  ...withSectionStyleDefaults({}),
2369
+ itemsPerRow: 3,
2358
2370
  items: [
2359
2371
  { description: "Explain this point.", iconType: "badge", icon: "01", imageCornerStyle: "rounded", imageFit: "cover", imagePosition: "center", title: "Feature One" },
2360
2372
  { description: "Explain this point.", iconType: "badge", icon: "02", imageCornerStyle: "rounded", imageFit: "cover", imagePosition: "center", title: "Feature Two" },
package/dist/index.mjs CHANGED
@@ -6,16 +6,16 @@ import {
6
6
  } from "./chunk-7IGLXLUB.mjs";
7
7
  import {
8
8
  blocks_exports
9
- } from "./chunk-XQYJXB46.mjs";
9
+ } from "./chunk-ICGXZCFJ.mjs";
10
10
  import {
11
11
  nextjs_exports
12
- } from "./chunk-GNYOAC5N.mjs";
12
+ } from "./chunk-C6VEHNJW.mjs";
13
13
  import {
14
14
  studio_exports
15
15
  } from "./chunk-N67KVM2S.mjs";
16
16
  import {
17
17
  studio_pages_exports
18
- } from "./chunk-LB72FZZ3.mjs";
18
+ } from "./chunk-7TTLMA6K.mjs";
19
19
  import "./chunk-SIL2J5MF.mjs";
20
20
  import "./chunk-6BWS3CLP.mjs";
21
21
  export {
@@ -146,6 +146,7 @@ var defaultNodeData = {
146
146
  },
147
147
  featureGrid: {
148
148
  ...withSectionStyleDefaults({}),
149
+ itemsPerRow: 3,
149
150
  items: [
150
151
  { description: "Explain this point.", iconType: "badge", icon: "01", imageCornerStyle: "rounded", imageFit: "cover", imagePosition: "center", title: "Feature One" },
151
152
  { description: "Explain this point.", iconType: "badge", icon: "02", imageCornerStyle: "rounded", imageFit: "cover", imagePosition: "center", title: "Feature Two" },
@@ -4,9 +4,9 @@ import {
4
4
  createPayloadClient,
5
5
  createSiteQueries,
6
6
  resolveMedia
7
- } from "../chunk-GNYOAC5N.mjs";
7
+ } from "../chunk-C6VEHNJW.mjs";
8
8
  import "../chunk-N67KVM2S.mjs";
9
- import "../chunk-LB72FZZ3.mjs";
9
+ import "../chunk-7TTLMA6K.mjs";
10
10
  import "../chunk-SIL2J5MF.mjs";
11
11
  import "../chunk-6BWS3CLP.mjs";
12
12
  export {
@@ -228,7 +228,8 @@ h4 {
228
228
  .feature-grid {
229
229
  display: grid;
230
230
  gap: 0.9rem;
231
- grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
231
+ /* Mobile-first: stack. Projects can override in their own globals.css. */
232
+ grid-template-columns: 1fr;
232
233
  margin-top: 1rem;
233
234
  }
234
235
 
@@ -280,7 +281,8 @@ h4 {
280
281
  .card-grid.services {
281
282
  display: grid;
282
283
  gap: 0.9rem;
283
- grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
284
+ /* Mobile-first: stack. */
285
+ grid-template-columns: 1fr;
284
286
  margin-top: 1rem;
285
287
  }
286
288
 
@@ -300,7 +302,8 @@ h4 {
300
302
  .split.testimonials-grid {
301
303
  display: grid;
302
304
  gap: 0.9rem;
303
- grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
305
+ /* Mobile-first: stack. */
306
+ grid-template-columns: 1fr;
304
307
  margin-top: 1rem;
305
308
  }
306
309
 
@@ -391,7 +394,8 @@ h4 {
391
394
  .orion-stats-grid {
392
395
  display: grid;
393
396
  gap: 0.9rem;
394
- grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
397
+ /* Mobile-first: stack. */
398
+ grid-template-columns: 1fr;
395
399
  margin-top: 1rem;
396
400
  }
397
401
 
@@ -426,7 +430,8 @@ h4 {
426
430
  .orion-logo-wall {
427
431
  display: grid;
428
432
  gap: 0.8rem;
429
- grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
433
+ /* Mobile-first: stack. */
434
+ grid-template-columns: 1fr;
430
435
  margin-top: 1rem;
431
436
  }
432
437
 
@@ -456,10 +461,37 @@ h4 {
456
461
  .orion-before-after-grid {
457
462
  display: grid;
458
463
  gap: 1rem;
459
- grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
464
+ /* Mobile-first: stack. */
465
+ grid-template-columns: 1fr;
460
466
  margin-top: 1rem;
461
467
  }
462
468
 
469
+ @media (min-width: 720px) {
470
+ .feature-grid {
471
+ grid-template-columns: var(--feature-grid-template-columns, repeat(auto-fit, minmax(200px, 1fr)));
472
+ }
473
+
474
+ .card-grid.services {
475
+ grid-template-columns: var(--services-grid-template-columns, repeat(auto-fit, minmax(240px, 1fr)));
476
+ }
477
+
478
+ .split.testimonials-grid {
479
+ grid-template-columns: var(--testimonials-grid-columns, repeat(auto-fit, minmax(260px, 1fr)));
480
+ }
481
+
482
+ .orion-stats-grid {
483
+ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
484
+ }
485
+
486
+ .orion-logo-wall {
487
+ grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
488
+ }
489
+
490
+ .orion-before-after-grid {
491
+ grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
492
+ }
493
+ }
494
+
463
495
  .orion-before-after-card {
464
496
  background: #fff;
465
497
  border: 1px solid rgba(13, 74, 55, 0.12);
@@ -95,6 +95,7 @@ var defaultNodeData = {
95
95
  },
96
96
  featureGrid: {
97
97
  ...withSectionStyleDefaults({}),
98
+ itemsPerRow: 3,
98
99
  items: [
99
100
  { description: "Explain this point.", iconType: "badge", icon: "01", imageCornerStyle: "rounded", imageFit: "cover", imagePosition: "center", title: "Feature One" },
100
101
  { description: "Explain this point.", iconType: "badge", icon: "02", imageCornerStyle: "rounded", imageFit: "cover", imagePosition: "center", title: "Feature Two" },
@@ -2327,6 +2328,8 @@ function BuilderPageEditor({ initialDoc, pageID }) {
2327
2328
  if (type === "featureGrid") {
2328
2329
  const variant = normalizeText(block.variant, "cards");
2329
2330
  const backgroundColor = normalizeText(block.backgroundColor);
2331
+ const itemsPerRowRaw = Math.floor(parsePixelNumber(block.itemsPerRow, 3));
2332
+ const itemsPerRow = Math.max(1, Math.min(6, itemsPerRowRaw));
2330
2333
  const items = Array.isArray(block.items) ? block.items : [];
2331
2334
  if (variant === "highlight") {
2332
2335
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -2353,77 +2356,89 @@ function BuilderPageEditor({ initialDoc, pageID }) {
2353
2356
  value: normalizeText(block.title)
2354
2357
  }
2355
2358
  ) }) }),
2356
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "feature-grid", children: items.map((item, itemIndex) => {
2357
- const itemRecord = item;
2358
- const itemMedia = resolveMedia(itemRecord?.media);
2359
- const itemImageHeight = parsePixelNumber(itemRecord?.imageHeight, 120);
2360
- const iconType = normalizeText(itemRecord?.iconType, "badge");
2361
- const iconBadge = normalizeText(itemRecord?.icon);
2362
- const iconLucide = normalizeText(itemRecord?.iconLucide);
2363
- const itemPositionX = parseOptionalPercentNumber(itemRecord?.imagePositionX);
2364
- const itemPositionY = parseOptionalPercentNumber(itemRecord?.imagePositionY);
2365
- const itemImageStyle = getImagePresentationStyle({
2366
- cornerStyle: normalizeImageCornerStyle(itemRecord?.imageCornerStyle),
2367
- fit: normalizeImageFit(itemRecord?.imageFit),
2368
- position: normalizeImagePosition(itemRecord?.imagePosition),
2369
- positionX: itemPositionX,
2370
- positionY: itemPositionY
2371
- });
2372
- const isItemSelected = selectedIndex === index && selectedItemIndex === itemIndex;
2373
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2374
- "article",
2375
- {
2376
- className: "feature-item",
2377
- onMouseDownCapture: () => {
2378
- setSelectedIndex(index);
2379
- openSelectedItem(itemIndex);
2380
- },
2381
- style: isItemSelected ? { outline: "2px solid rgba(255, 255, 255, 0.72)", outlineOffset: 2 } : void 0,
2382
- children: [
2383
- itemMedia?.url ? (
2384
- // eslint-disable-next-line @next/next/no-img-element
2385
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2386
- "img",
2387
- {
2388
- alt: itemMedia.alt || normalizeText(itemRecord?.title, "Feature image"),
2389
- className: "feature-item-media",
2390
- src: itemMedia.url,
2391
- style: { ...itemImageStyle, height: itemImageHeight }
2392
- }
2393
- )
2394
- ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "feature-icon", children: iconType === "lucide" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: iconLucide || "Icon" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2395
- InlineText,
2396
- {
2397
- as: "span",
2398
- onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "icon", value),
2399
- placeholder: "01",
2400
- value: iconBadge
2401
- }
2402
- ) }),
2403
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2404
- InlineText,
2405
- {
2406
- as: "h3",
2407
- onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "title", value),
2408
- placeholder: "Feature title",
2409
- value: normalizeText(itemRecord?.title)
2410
- }
2411
- ),
2412
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2413
- InlineText,
2414
- {
2415
- as: "p",
2416
- multiline: true,
2417
- onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "description", value),
2418
- placeholder: "Feature description",
2419
- value: normalizeText(itemRecord?.description)
2420
- }
2421
- )
2422
- ]
2359
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2360
+ "div",
2361
+ {
2362
+ className: "feature-grid",
2363
+ style: {
2364
+ ["--feature-grid-template-columns"]: `repeat(${Math.max(
2365
+ 1,
2366
+ Math.min(itemsPerRow, items.length || itemsPerRow)
2367
+ )}, minmax(0, 1fr))`
2423
2368
  },
2424
- `item-${itemIndex}`
2425
- );
2426
- }) })
2369
+ children: items.map((item, itemIndex) => {
2370
+ const itemRecord = item;
2371
+ const itemMedia = resolveMedia(itemRecord?.media);
2372
+ const itemImageHeight = parsePixelNumber(itemRecord?.imageHeight, 120);
2373
+ const iconType = normalizeText(itemRecord?.iconType, "badge");
2374
+ const iconBadge = normalizeText(itemRecord?.icon);
2375
+ const iconLucide = normalizeText(itemRecord?.iconLucide);
2376
+ const itemPositionX = parseOptionalPercentNumber(itemRecord?.imagePositionX);
2377
+ const itemPositionY = parseOptionalPercentNumber(itemRecord?.imagePositionY);
2378
+ const itemImageStyle = getImagePresentationStyle({
2379
+ cornerStyle: normalizeImageCornerStyle(itemRecord?.imageCornerStyle),
2380
+ fit: normalizeImageFit(itemRecord?.imageFit),
2381
+ position: normalizeImagePosition(itemRecord?.imagePosition),
2382
+ positionX: itemPositionX,
2383
+ positionY: itemPositionY
2384
+ });
2385
+ const isItemSelected = selectedIndex === index && selectedItemIndex === itemIndex;
2386
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2387
+ "article",
2388
+ {
2389
+ className: "feature-item",
2390
+ onMouseDownCapture: () => {
2391
+ setSelectedIndex(index);
2392
+ openSelectedItem(itemIndex);
2393
+ },
2394
+ style: isItemSelected ? { outline: "2px solid rgba(255, 255, 255, 0.72)", outlineOffset: 2 } : void 0,
2395
+ children: [
2396
+ itemMedia?.url ? (
2397
+ // eslint-disable-next-line @next/next/no-img-element
2398
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2399
+ "img",
2400
+ {
2401
+ alt: itemMedia.alt || normalizeText(itemRecord?.title, "Feature image"),
2402
+ className: "feature-item-media",
2403
+ src: itemMedia.url,
2404
+ style: { ...itemImageStyle, height: itemImageHeight }
2405
+ }
2406
+ )
2407
+ ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "feature-icon", children: iconType === "lucide" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: iconLucide || "Icon" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2408
+ InlineText,
2409
+ {
2410
+ as: "span",
2411
+ onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "icon", value),
2412
+ placeholder: "01",
2413
+ value: iconBadge
2414
+ }
2415
+ ) }),
2416
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2417
+ InlineText,
2418
+ {
2419
+ as: "h3",
2420
+ onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "title", value),
2421
+ placeholder: "Feature title",
2422
+ value: normalizeText(itemRecord?.title)
2423
+ }
2424
+ ),
2425
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2426
+ InlineText,
2427
+ {
2428
+ as: "p",
2429
+ multiline: true,
2430
+ onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "description", value),
2431
+ placeholder: "Feature description",
2432
+ value: normalizeText(itemRecord?.description)
2433
+ }
2434
+ )
2435
+ ]
2436
+ },
2437
+ `item-${itemIndex}`
2438
+ );
2439
+ })
2440
+ }
2441
+ )
2427
2442
  ] }) })
2428
2443
  )
2429
2444
  },
@@ -2453,77 +2468,89 @@ function BuilderPageEditor({ initialDoc, pageID }) {
2453
2468
  value: normalizeText(block.title)
2454
2469
  }
2455
2470
  ) }) }),
2456
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "card-grid services", children: items.map((item, itemIndex) => {
2457
- const itemRecord = item;
2458
- const itemMedia = resolveMedia(itemRecord?.media);
2459
- const itemImageHeight = parsePixelNumber(itemRecord?.imageHeight, 120);
2460
- const iconType = normalizeText(itemRecord?.iconType, "badge");
2461
- const iconBadge = normalizeText(itemRecord?.icon);
2462
- const iconLucide = normalizeText(itemRecord?.iconLucide);
2463
- const itemPositionX = parseOptionalPercentNumber(itemRecord?.imagePositionX);
2464
- const itemPositionY = parseOptionalPercentNumber(itemRecord?.imagePositionY);
2465
- const itemImageStyle = getImagePresentationStyle({
2466
- cornerStyle: normalizeImageCornerStyle(itemRecord?.imageCornerStyle),
2467
- fit: normalizeImageFit(itemRecord?.imageFit),
2468
- position: normalizeImagePosition(itemRecord?.imagePosition),
2469
- positionX: itemPositionX,
2470
- positionY: itemPositionY
2471
- });
2472
- const isItemSelected = selectedIndex === index && selectedItemIndex === itemIndex;
2473
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2474
- "article",
2475
- {
2476
- className: "service-card",
2477
- onMouseDownCapture: () => {
2478
- setSelectedIndex(index);
2479
- openSelectedItem(itemIndex);
2480
- },
2481
- style: isItemSelected ? { outline: "2px solid rgba(15, 125, 82, 0.55)", outlineOffset: 3 } : void 0,
2482
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "service-body", children: [
2483
- itemMedia?.url ? (
2484
- // eslint-disable-next-line @next/next/no-img-element
2485
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2486
- "img",
2487
- {
2488
- alt: itemMedia.alt || normalizeText(itemRecord?.title, "Feature image"),
2489
- className: "feature-item-media feature-item-media-card",
2490
- src: itemMedia.url,
2491
- style: { ...itemImageStyle, height: itemImageHeight }
2492
- }
2493
- )
2494
- ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "service-tag", children: iconType === "lucide" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: iconLucide || "Icon" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2495
- InlineText,
2496
- {
2497
- as: "span",
2498
- onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "icon", value),
2499
- placeholder: "01",
2500
- value: iconBadge
2501
- }
2502
- ) }),
2503
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2504
- InlineText,
2505
- {
2506
- as: "h3",
2507
- onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "title", value),
2508
- placeholder: "Feature title",
2509
- value: normalizeText(itemRecord?.title)
2510
- }
2511
- ),
2512
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2513
- InlineText,
2514
- {
2515
- as: "p",
2516
- multiline: true,
2517
- onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "description", value),
2518
- placeholder: "Feature description",
2519
- value: normalizeText(itemRecord?.description)
2520
- }
2521
- )
2522
- ] })
2471
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2472
+ "div",
2473
+ {
2474
+ className: "card-grid services",
2475
+ style: {
2476
+ ["--services-grid-template-columns"]: `repeat(${Math.max(
2477
+ 1,
2478
+ Math.min(itemsPerRow, items.length || itemsPerRow)
2479
+ )}, minmax(0, 1fr))`
2523
2480
  },
2524
- `item-${itemIndex}`
2525
- );
2526
- }) })
2481
+ children: items.map((item, itemIndex) => {
2482
+ const itemRecord = item;
2483
+ const itemMedia = resolveMedia(itemRecord?.media);
2484
+ const itemImageHeight = parsePixelNumber(itemRecord?.imageHeight, 120);
2485
+ const iconType = normalizeText(itemRecord?.iconType, "badge");
2486
+ const iconBadge = normalizeText(itemRecord?.icon);
2487
+ const iconLucide = normalizeText(itemRecord?.iconLucide);
2488
+ const itemPositionX = parseOptionalPercentNumber(itemRecord?.imagePositionX);
2489
+ const itemPositionY = parseOptionalPercentNumber(itemRecord?.imagePositionY);
2490
+ const itemImageStyle = getImagePresentationStyle({
2491
+ cornerStyle: normalizeImageCornerStyle(itemRecord?.imageCornerStyle),
2492
+ fit: normalizeImageFit(itemRecord?.imageFit),
2493
+ position: normalizeImagePosition(itemRecord?.imagePosition),
2494
+ positionX: itemPositionX,
2495
+ positionY: itemPositionY
2496
+ });
2497
+ const isItemSelected = selectedIndex === index && selectedItemIndex === itemIndex;
2498
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2499
+ "article",
2500
+ {
2501
+ className: "service-card",
2502
+ onMouseDownCapture: () => {
2503
+ setSelectedIndex(index);
2504
+ openSelectedItem(itemIndex);
2505
+ },
2506
+ style: isItemSelected ? { outline: "2px solid rgba(15, 125, 82, 0.55)", outlineOffset: 3 } : void 0,
2507
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "service-body", children: [
2508
+ itemMedia?.url ? (
2509
+ // eslint-disable-next-line @next/next/no-img-element
2510
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2511
+ "img",
2512
+ {
2513
+ alt: itemMedia.alt || normalizeText(itemRecord?.title, "Feature image"),
2514
+ className: "feature-item-media feature-item-media-card",
2515
+ src: itemMedia.url,
2516
+ style: { ...itemImageStyle, height: itemImageHeight }
2517
+ }
2518
+ )
2519
+ ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "service-tag", children: iconType === "lucide" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: iconLucide || "Icon" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2520
+ InlineText,
2521
+ {
2522
+ as: "span",
2523
+ onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "icon", value),
2524
+ placeholder: "01",
2525
+ value: iconBadge
2526
+ }
2527
+ ) }),
2528
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2529
+ InlineText,
2530
+ {
2531
+ as: "h3",
2532
+ onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "title", value),
2533
+ placeholder: "Feature title",
2534
+ value: normalizeText(itemRecord?.title)
2535
+ }
2536
+ ),
2537
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2538
+ InlineText,
2539
+ {
2540
+ as: "p",
2541
+ multiline: true,
2542
+ onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "description", value),
2543
+ placeholder: "Feature description",
2544
+ value: normalizeText(itemRecord?.description)
2545
+ }
2546
+ )
2547
+ ] })
2548
+ },
2549
+ `item-${itemIndex}`
2550
+ );
2551
+ })
2552
+ }
2553
+ )
2527
2554
  ] })
2528
2555
  )
2529
2556
  },
@@ -4301,6 +4328,25 @@ function BuilderPageEditor({ initialDoc, pageID }) {
4301
4328
  }
4302
4329
  )
4303
4330
  ] }),
4331
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
4332
+ "Items Per Row (Desktop)",
4333
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
4334
+ "select",
4335
+ {
4336
+ onChange: (event) => updateSelectedField("itemsPerRow", Number(event.target.value)),
4337
+ style: sidebarInputStyle,
4338
+ value: Math.max(1, Math.min(6, Math.floor(parsePixelNumber(selectedBlock.itemsPerRow, 3)))),
4339
+ children: [
4340
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: 1, children: "1" }),
4341
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: 2, children: "2" }),
4342
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: 3, children: "3" }),
4343
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: 4, children: "4" }),
4344
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: 5, children: "5" }),
4345
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: 6, children: "6" })
4346
+ ]
4347
+ }
4348
+ )
4349
+ ] }),
4304
4350
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
4305
4351
  "Highlight Background Color",
4306
4352
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -67,6 +67,7 @@ var defaultNodeData = {
67
67
  },
68
68
  featureGrid: {
69
69
  ...withSectionStyleDefaults({}),
70
+ itemsPerRow: 3,
70
71
  items: [
71
72
  { description: "Explain this point.", iconType: "badge", icon: "01", imageCornerStyle: "rounded", imageFit: "cover", imagePosition: "center", title: "Feature One" },
72
73
  { description: "Explain this point.", iconType: "badge", icon: "02", imageCornerStyle: "rounded", imageFit: "cover", imagePosition: "center", title: "Feature Two" },
@@ -2299,6 +2300,8 @@ function BuilderPageEditor({ initialDoc, pageID }) {
2299
2300
  if (type === "featureGrid") {
2300
2301
  const variant = normalizeText(block.variant, "cards");
2301
2302
  const backgroundColor = normalizeText(block.backgroundColor);
2303
+ const itemsPerRowRaw = Math.floor(parsePixelNumber(block.itemsPerRow, 3));
2304
+ const itemsPerRow = Math.max(1, Math.min(6, itemsPerRowRaw));
2302
2305
  const items = Array.isArray(block.items) ? block.items : [];
2303
2306
  if (variant === "highlight") {
2304
2307
  return /* @__PURE__ */ jsx(
@@ -2325,77 +2328,89 @@ function BuilderPageEditor({ initialDoc, pageID }) {
2325
2328
  value: normalizeText(block.title)
2326
2329
  }
2327
2330
  ) }) }),
2328
- /* @__PURE__ */ jsx("div", { className: "feature-grid", children: items.map((item, itemIndex) => {
2329
- const itemRecord = item;
2330
- const itemMedia = resolveMedia(itemRecord?.media);
2331
- const itemImageHeight = parsePixelNumber(itemRecord?.imageHeight, 120);
2332
- const iconType = normalizeText(itemRecord?.iconType, "badge");
2333
- const iconBadge = normalizeText(itemRecord?.icon);
2334
- const iconLucide = normalizeText(itemRecord?.iconLucide);
2335
- const itemPositionX = parseOptionalPercentNumber(itemRecord?.imagePositionX);
2336
- const itemPositionY = parseOptionalPercentNumber(itemRecord?.imagePositionY);
2337
- const itemImageStyle = getImagePresentationStyle({
2338
- cornerStyle: normalizeImageCornerStyle(itemRecord?.imageCornerStyle),
2339
- fit: normalizeImageFit(itemRecord?.imageFit),
2340
- position: normalizeImagePosition(itemRecord?.imagePosition),
2341
- positionX: itemPositionX,
2342
- positionY: itemPositionY
2343
- });
2344
- const isItemSelected = selectedIndex === index && selectedItemIndex === itemIndex;
2345
- return /* @__PURE__ */ jsxs(
2346
- "article",
2347
- {
2348
- className: "feature-item",
2349
- onMouseDownCapture: () => {
2350
- setSelectedIndex(index);
2351
- openSelectedItem(itemIndex);
2352
- },
2353
- style: isItemSelected ? { outline: "2px solid rgba(255, 255, 255, 0.72)", outlineOffset: 2 } : void 0,
2354
- children: [
2355
- itemMedia?.url ? (
2356
- // eslint-disable-next-line @next/next/no-img-element
2357
- /* @__PURE__ */ jsx(
2358
- "img",
2359
- {
2360
- alt: itemMedia.alt || normalizeText(itemRecord?.title, "Feature image"),
2361
- className: "feature-item-media",
2362
- src: itemMedia.url,
2363
- style: { ...itemImageStyle, height: itemImageHeight }
2364
- }
2365
- )
2366
- ) : /* @__PURE__ */ jsx("div", { className: "feature-icon", children: iconType === "lucide" ? /* @__PURE__ */ jsx("span", { children: iconLucide || "Icon" }) : /* @__PURE__ */ jsx(
2367
- InlineText,
2368
- {
2369
- as: "span",
2370
- onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "icon", value),
2371
- placeholder: "01",
2372
- value: iconBadge
2373
- }
2374
- ) }),
2375
- /* @__PURE__ */ jsx(
2376
- InlineText,
2377
- {
2378
- as: "h3",
2379
- onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "title", value),
2380
- placeholder: "Feature title",
2381
- value: normalizeText(itemRecord?.title)
2382
- }
2383
- ),
2384
- /* @__PURE__ */ jsx(
2385
- InlineText,
2386
- {
2387
- as: "p",
2388
- multiline: true,
2389
- onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "description", value),
2390
- placeholder: "Feature description",
2391
- value: normalizeText(itemRecord?.description)
2392
- }
2393
- )
2394
- ]
2331
+ /* @__PURE__ */ jsx(
2332
+ "div",
2333
+ {
2334
+ className: "feature-grid",
2335
+ style: {
2336
+ ["--feature-grid-template-columns"]: `repeat(${Math.max(
2337
+ 1,
2338
+ Math.min(itemsPerRow, items.length || itemsPerRow)
2339
+ )}, minmax(0, 1fr))`
2395
2340
  },
2396
- `item-${itemIndex}`
2397
- );
2398
- }) })
2341
+ children: items.map((item, itemIndex) => {
2342
+ const itemRecord = item;
2343
+ const itemMedia = resolveMedia(itemRecord?.media);
2344
+ const itemImageHeight = parsePixelNumber(itemRecord?.imageHeight, 120);
2345
+ const iconType = normalizeText(itemRecord?.iconType, "badge");
2346
+ const iconBadge = normalizeText(itemRecord?.icon);
2347
+ const iconLucide = normalizeText(itemRecord?.iconLucide);
2348
+ const itemPositionX = parseOptionalPercentNumber(itemRecord?.imagePositionX);
2349
+ const itemPositionY = parseOptionalPercentNumber(itemRecord?.imagePositionY);
2350
+ const itemImageStyle = getImagePresentationStyle({
2351
+ cornerStyle: normalizeImageCornerStyle(itemRecord?.imageCornerStyle),
2352
+ fit: normalizeImageFit(itemRecord?.imageFit),
2353
+ position: normalizeImagePosition(itemRecord?.imagePosition),
2354
+ positionX: itemPositionX,
2355
+ positionY: itemPositionY
2356
+ });
2357
+ const isItemSelected = selectedIndex === index && selectedItemIndex === itemIndex;
2358
+ return /* @__PURE__ */ jsxs(
2359
+ "article",
2360
+ {
2361
+ className: "feature-item",
2362
+ onMouseDownCapture: () => {
2363
+ setSelectedIndex(index);
2364
+ openSelectedItem(itemIndex);
2365
+ },
2366
+ style: isItemSelected ? { outline: "2px solid rgba(255, 255, 255, 0.72)", outlineOffset: 2 } : void 0,
2367
+ children: [
2368
+ itemMedia?.url ? (
2369
+ // eslint-disable-next-line @next/next/no-img-element
2370
+ /* @__PURE__ */ jsx(
2371
+ "img",
2372
+ {
2373
+ alt: itemMedia.alt || normalizeText(itemRecord?.title, "Feature image"),
2374
+ className: "feature-item-media",
2375
+ src: itemMedia.url,
2376
+ style: { ...itemImageStyle, height: itemImageHeight }
2377
+ }
2378
+ )
2379
+ ) : /* @__PURE__ */ jsx("div", { className: "feature-icon", children: iconType === "lucide" ? /* @__PURE__ */ jsx("span", { children: iconLucide || "Icon" }) : /* @__PURE__ */ jsx(
2380
+ InlineText,
2381
+ {
2382
+ as: "span",
2383
+ onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "icon", value),
2384
+ placeholder: "01",
2385
+ value: iconBadge
2386
+ }
2387
+ ) }),
2388
+ /* @__PURE__ */ jsx(
2389
+ InlineText,
2390
+ {
2391
+ as: "h3",
2392
+ onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "title", value),
2393
+ placeholder: "Feature title",
2394
+ value: normalizeText(itemRecord?.title)
2395
+ }
2396
+ ),
2397
+ /* @__PURE__ */ jsx(
2398
+ InlineText,
2399
+ {
2400
+ as: "p",
2401
+ multiline: true,
2402
+ onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "description", value),
2403
+ placeholder: "Feature description",
2404
+ value: normalizeText(itemRecord?.description)
2405
+ }
2406
+ )
2407
+ ]
2408
+ },
2409
+ `item-${itemIndex}`
2410
+ );
2411
+ })
2412
+ }
2413
+ )
2399
2414
  ] }) })
2400
2415
  )
2401
2416
  },
@@ -2425,77 +2440,89 @@ function BuilderPageEditor({ initialDoc, pageID }) {
2425
2440
  value: normalizeText(block.title)
2426
2441
  }
2427
2442
  ) }) }),
2428
- /* @__PURE__ */ jsx("div", { className: "card-grid services", children: items.map((item, itemIndex) => {
2429
- const itemRecord = item;
2430
- const itemMedia = resolveMedia(itemRecord?.media);
2431
- const itemImageHeight = parsePixelNumber(itemRecord?.imageHeight, 120);
2432
- const iconType = normalizeText(itemRecord?.iconType, "badge");
2433
- const iconBadge = normalizeText(itemRecord?.icon);
2434
- const iconLucide = normalizeText(itemRecord?.iconLucide);
2435
- const itemPositionX = parseOptionalPercentNumber(itemRecord?.imagePositionX);
2436
- const itemPositionY = parseOptionalPercentNumber(itemRecord?.imagePositionY);
2437
- const itemImageStyle = getImagePresentationStyle({
2438
- cornerStyle: normalizeImageCornerStyle(itemRecord?.imageCornerStyle),
2439
- fit: normalizeImageFit(itemRecord?.imageFit),
2440
- position: normalizeImagePosition(itemRecord?.imagePosition),
2441
- positionX: itemPositionX,
2442
- positionY: itemPositionY
2443
- });
2444
- const isItemSelected = selectedIndex === index && selectedItemIndex === itemIndex;
2445
- return /* @__PURE__ */ jsx(
2446
- "article",
2447
- {
2448
- className: "service-card",
2449
- onMouseDownCapture: () => {
2450
- setSelectedIndex(index);
2451
- openSelectedItem(itemIndex);
2452
- },
2453
- style: isItemSelected ? { outline: "2px solid rgba(15, 125, 82, 0.55)", outlineOffset: 3 } : void 0,
2454
- children: /* @__PURE__ */ jsxs("div", { className: "service-body", children: [
2455
- itemMedia?.url ? (
2456
- // eslint-disable-next-line @next/next/no-img-element
2457
- /* @__PURE__ */ jsx(
2458
- "img",
2459
- {
2460
- alt: itemMedia.alt || normalizeText(itemRecord?.title, "Feature image"),
2461
- className: "feature-item-media feature-item-media-card",
2462
- src: itemMedia.url,
2463
- style: { ...itemImageStyle, height: itemImageHeight }
2464
- }
2465
- )
2466
- ) : /* @__PURE__ */ jsx("div", { className: "service-tag", children: iconType === "lucide" ? /* @__PURE__ */ jsx("span", { children: iconLucide || "Icon" }) : /* @__PURE__ */ jsx(
2467
- InlineText,
2468
- {
2469
- as: "span",
2470
- onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "icon", value),
2471
- placeholder: "01",
2472
- value: iconBadge
2473
- }
2474
- ) }),
2475
- /* @__PURE__ */ jsx(
2476
- InlineText,
2477
- {
2478
- as: "h3",
2479
- onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "title", value),
2480
- placeholder: "Feature title",
2481
- value: normalizeText(itemRecord?.title)
2482
- }
2483
- ),
2484
- /* @__PURE__ */ jsx(
2485
- InlineText,
2486
- {
2487
- as: "p",
2488
- multiline: true,
2489
- onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "description", value),
2490
- placeholder: "Feature description",
2491
- value: normalizeText(itemRecord?.description)
2492
- }
2493
- )
2494
- ] })
2443
+ /* @__PURE__ */ jsx(
2444
+ "div",
2445
+ {
2446
+ className: "card-grid services",
2447
+ style: {
2448
+ ["--services-grid-template-columns"]: `repeat(${Math.max(
2449
+ 1,
2450
+ Math.min(itemsPerRow, items.length || itemsPerRow)
2451
+ )}, minmax(0, 1fr))`
2495
2452
  },
2496
- `item-${itemIndex}`
2497
- );
2498
- }) })
2453
+ children: items.map((item, itemIndex) => {
2454
+ const itemRecord = item;
2455
+ const itemMedia = resolveMedia(itemRecord?.media);
2456
+ const itemImageHeight = parsePixelNumber(itemRecord?.imageHeight, 120);
2457
+ const iconType = normalizeText(itemRecord?.iconType, "badge");
2458
+ const iconBadge = normalizeText(itemRecord?.icon);
2459
+ const iconLucide = normalizeText(itemRecord?.iconLucide);
2460
+ const itemPositionX = parseOptionalPercentNumber(itemRecord?.imagePositionX);
2461
+ const itemPositionY = parseOptionalPercentNumber(itemRecord?.imagePositionY);
2462
+ const itemImageStyle = getImagePresentationStyle({
2463
+ cornerStyle: normalizeImageCornerStyle(itemRecord?.imageCornerStyle),
2464
+ fit: normalizeImageFit(itemRecord?.imageFit),
2465
+ position: normalizeImagePosition(itemRecord?.imagePosition),
2466
+ positionX: itemPositionX,
2467
+ positionY: itemPositionY
2468
+ });
2469
+ const isItemSelected = selectedIndex === index && selectedItemIndex === itemIndex;
2470
+ return /* @__PURE__ */ jsx(
2471
+ "article",
2472
+ {
2473
+ className: "service-card",
2474
+ onMouseDownCapture: () => {
2475
+ setSelectedIndex(index);
2476
+ openSelectedItem(itemIndex);
2477
+ },
2478
+ style: isItemSelected ? { outline: "2px solid rgba(15, 125, 82, 0.55)", outlineOffset: 3 } : void 0,
2479
+ children: /* @__PURE__ */ jsxs("div", { className: "service-body", children: [
2480
+ itemMedia?.url ? (
2481
+ // eslint-disable-next-line @next/next/no-img-element
2482
+ /* @__PURE__ */ jsx(
2483
+ "img",
2484
+ {
2485
+ alt: itemMedia.alt || normalizeText(itemRecord?.title, "Feature image"),
2486
+ className: "feature-item-media feature-item-media-card",
2487
+ src: itemMedia.url,
2488
+ style: { ...itemImageStyle, height: itemImageHeight }
2489
+ }
2490
+ )
2491
+ ) : /* @__PURE__ */ jsx("div", { className: "service-tag", children: iconType === "lucide" ? /* @__PURE__ */ jsx("span", { children: iconLucide || "Icon" }) : /* @__PURE__ */ jsx(
2492
+ InlineText,
2493
+ {
2494
+ as: "span",
2495
+ onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "icon", value),
2496
+ placeholder: "01",
2497
+ value: iconBadge
2498
+ }
2499
+ ) }),
2500
+ /* @__PURE__ */ jsx(
2501
+ InlineText,
2502
+ {
2503
+ as: "h3",
2504
+ onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "title", value),
2505
+ placeholder: "Feature title",
2506
+ value: normalizeText(itemRecord?.title)
2507
+ }
2508
+ ),
2509
+ /* @__PURE__ */ jsx(
2510
+ InlineText,
2511
+ {
2512
+ as: "p",
2513
+ multiline: true,
2514
+ onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "description", value),
2515
+ placeholder: "Feature description",
2516
+ value: normalizeText(itemRecord?.description)
2517
+ }
2518
+ )
2519
+ ] })
2520
+ },
2521
+ `item-${itemIndex}`
2522
+ );
2523
+ })
2524
+ }
2525
+ )
2499
2526
  ] })
2500
2527
  )
2501
2528
  },
@@ -4273,6 +4300,25 @@ function BuilderPageEditor({ initialDoc, pageID }) {
4273
4300
  }
4274
4301
  )
4275
4302
  ] }),
4303
+ /* @__PURE__ */ jsxs("label", { style: sidebarLabelStyle, children: [
4304
+ "Items Per Row (Desktop)",
4305
+ /* @__PURE__ */ jsxs(
4306
+ "select",
4307
+ {
4308
+ onChange: (event) => updateSelectedField("itemsPerRow", Number(event.target.value)),
4309
+ style: sidebarInputStyle,
4310
+ value: Math.max(1, Math.min(6, Math.floor(parsePixelNumber(selectedBlock.itemsPerRow, 3)))),
4311
+ children: [
4312
+ /* @__PURE__ */ jsx("option", { value: 1, children: "1" }),
4313
+ /* @__PURE__ */ jsx("option", { value: 2, children: "2" }),
4314
+ /* @__PURE__ */ jsx("option", { value: 3, children: "3" }),
4315
+ /* @__PURE__ */ jsx("option", { value: 4, children: "4" }),
4316
+ /* @__PURE__ */ jsx("option", { value: 5, children: "5" }),
4317
+ /* @__PURE__ */ jsx("option", { value: 6, children: "6" })
4318
+ ]
4319
+ }
4320
+ )
4321
+ ] }),
4276
4322
  /* @__PURE__ */ jsxs("label", { style: sidebarLabelStyle, children: [
4277
4323
  "Highlight Background Color",
4278
4324
  /* @__PURE__ */ jsx(
@@ -92,6 +92,7 @@ var defaultNodeData = {
92
92
  },
93
93
  featureGrid: {
94
94
  ...withSectionStyleDefaults({}),
95
+ itemsPerRow: 3,
95
96
  items: [
96
97
  { description: "Explain this point.", iconType: "badge", icon: "01", imageCornerStyle: "rounded", imageFit: "cover", imagePosition: "center", title: "Feature One" },
97
98
  { description: "Explain this point.", iconType: "badge", icon: "02", imageCornerStyle: "rounded", imageFit: "cover", imagePosition: "center", title: "Feature Two" },
@@ -6,7 +6,7 @@ import {
6
6
  pagePaletteGroups,
7
7
  pageStudioModuleManifest,
8
8
  studioDocumentToLayout
9
- } from "../chunk-LB72FZZ3.mjs";
9
+ } from "../chunk-7TTLMA6K.mjs";
10
10
  import "../chunk-SIL2J5MF.mjs";
11
11
  import "../chunk-6BWS3CLP.mjs";
12
12
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orion-studios/payload-studio",
3
- "version": "0.5.0-beta.41",
3
+ "version": "0.5.0-beta.43",
4
4
  "description": "Unified Payload CMS toolkit for Orion Studios",
5
5
  "types": "./dist/index.d.ts",
6
6
  "main": "./dist/index.js",