@orion-studios/payload-studio 0.5.0-beta.47 → 0.5.0-beta.48

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/index.mjs CHANGED
@@ -4,15 +4,15 @@ import {
4
4
  import {
5
5
  admin_app_exports
6
6
  } from "./chunk-XVH5SCBD.mjs";
7
- import {
8
- blocks_exports
9
- } from "./chunk-4AOYZGIY.mjs";
10
7
  import {
11
8
  nextjs_exports
12
9
  } from "./chunk-SKZUOCR2.mjs";
13
10
  import {
14
11
  studio_exports
15
12
  } from "./chunk-N67KVM2S.mjs";
13
+ import {
14
+ blocks_exports
15
+ } from "./chunk-4AOYZGIY.mjs";
16
16
  import {
17
17
  studio_pages_exports
18
18
  } from "./chunk-OHAGPJBM.mjs";
@@ -307,6 +307,45 @@ h4 {
307
307
  margin-top: 1rem;
308
308
  }
309
309
 
310
+ .testimonials-stage {
311
+ position: relative;
312
+ margin-top: 1rem;
313
+ }
314
+
315
+ .testimonials-stage .split.testimonials-grid {
316
+ margin-top: 0;
317
+ }
318
+
319
+ .testimonial-nav {
320
+ position: absolute;
321
+ top: 50%;
322
+ transform: translateY(-50%);
323
+ width: 42px;
324
+ height: 42px;
325
+ border-radius: 999px;
326
+ border: 1px solid rgba(19, 33, 28, 0.14);
327
+ background: rgba(255, 255, 255, 0.92);
328
+ box-shadow: 0 18px 34px rgba(15, 125, 82, 0.12);
329
+ display: grid;
330
+ place-items: center;
331
+ cursor: pointer;
332
+ user-select: none;
333
+ }
334
+
335
+ .testimonial-nav span {
336
+ color: var(--orion-studio-accent);
337
+ font-size: 1.55rem;
338
+ line-height: 1;
339
+ }
340
+
341
+ .testimonial-nav--prev {
342
+ left: 0.35rem;
343
+ }
344
+
345
+ .testimonial-nav--next {
346
+ right: 0.35rem;
347
+ }
348
+
310
349
  .quote {
311
350
  font-size: 0.98rem;
312
351
  color: var(--orion-studio-ink);
@@ -2013,35 +2013,7 @@ function BuilderPageEditor({ initialDoc, pageID }) {
2013
2013
  setActiveSidebarPanel("addSections");
2014
2014
  }, [layout.length]);
2015
2015
  (0, import_react.useEffect)(() => {
2016
- const timers = [];
2017
- layout.forEach((block, index) => {
2018
- if (normalizeText(block.blockType, "") !== "testimonials") {
2019
- return;
2020
- }
2021
- const key = typeof block.id === "string" && block.id ? String(block.id) : `testimonials-${index}`;
2022
- const items = Array.isArray(block.items) ? block.items : [];
2023
- const visibleCountRaw = Math.floor(parsePixelNumber(block.visibleCount, 3));
2024
- const visibleCount = Math.max(1, Math.min(6, visibleCountRaw));
2025
- const autoRotate = typeof block.autoRotate === "boolean" ? Boolean(block.autoRotate) : true;
2026
- const intervalSeconds = Math.max(
2027
- 2,
2028
- Math.floor(parsePixelNumber(block.rotateIntervalSeconds, 7))
2029
- );
2030
- if (!autoRotate || items.length <= visibleCount) {
2031
- return;
2032
- }
2033
- const timer = window.setInterval(() => {
2034
- setTestimonialsOffsets((current) => {
2035
- const offset = typeof current[key] === "number" ? current[key] : 0;
2036
- const next = (offset + visibleCount) % items.length;
2037
- return offset === next ? current : { ...current, [key]: next };
2038
- });
2039
- }, intervalSeconds * 1e3);
2040
- timers.push(timer);
2041
- });
2042
- return () => {
2043
- timers.forEach((timer) => window.clearInterval(timer));
2044
- };
2016
+ return;
2045
2017
  }, [layout]);
2046
2018
  (0, import_react.useEffect)(() => {
2047
2019
  if (historyBypassRef.current) {
@@ -2878,13 +2850,14 @@ function BuilderPageEditor({ initialDoc, pageID }) {
2878
2850
  const items = Array.isArray(block.items) ? block.items : [];
2879
2851
  const visibleCountRaw = Math.floor(parsePixelNumber(block.visibleCount, 3));
2880
2852
  const visibleCount = Math.max(1, Math.min(6, visibleCountRaw));
2881
- const autoRotate = typeof block.autoRotate === "boolean" ? Boolean(block.autoRotate) : true;
2882
2853
  const key = typeof block.id === "string" && block.id ? String(block.id) : `testimonials-${index}`;
2883
2854
  const offset = typeof testimonialsOffsets[key] === "number" ? testimonialsOffsets[key] : 0;
2884
- const windowedItems = !autoRotate || items.length <= visibleCount ? items.map((item, itemIndex) => ({ item, itemIndex })) : Array.from({ length: visibleCount }, (_, slotIndex) => {
2855
+ const canNavigate = items.length > visibleCount;
2856
+ const windowSize = Math.min(visibleCount, items.length);
2857
+ const windowedItems = canNavigate ? Array.from({ length: windowSize }, (_, slotIndex) => {
2885
2858
  const itemIndex = (offset + slotIndex) % items.length;
2886
2859
  return { item: items[itemIndex], itemIndex };
2887
- });
2860
+ }) : items.map((item, itemIndex) => ({ item, itemIndex }));
2888
2861
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2889
2862
  BlockFrame,
2890
2863
  {
@@ -2908,60 +2881,100 @@ function BuilderPageEditor({ initialDoc, pageID }) {
2908
2881
  value: normalizeText(block.title)
2909
2882
  }
2910
2883
  ) }) }),
2911
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "split testimonials-grid", children: windowedItems.map(({ item, itemIndex }) => {
2912
- const isItemSelected = selectedIndex === index && selectedItemIndex === itemIndex;
2913
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2914
- "article",
2884
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: `testimonials-stage ${canNavigate ? "is-navigable" : ""}`, children: [
2885
+ canNavigate ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2886
+ "button",
2915
2887
  {
2916
- className: "panel",
2917
- onMouseDownCapture: () => {
2918
- setSelectedIndex(index);
2919
- openSelectedItem(itemIndex);
2888
+ "aria-label": "Previous testimonials",
2889
+ className: "testimonial-nav testimonial-nav--prev",
2890
+ onClick: (event) => {
2891
+ event.preventDefault();
2892
+ event.stopPropagation();
2893
+ setTestimonialsOffsets((current) => {
2894
+ const currentOffset = typeof current[key] === "number" ? current[key] : 0;
2895
+ const shift = windowSize;
2896
+ const next = ((currentOffset - shift) % items.length + items.length) % items.length;
2897
+ return currentOffset === next ? current : { ...current, [key]: next };
2898
+ });
2920
2899
  },
2921
- style: isItemSelected ? { outline: "2px solid rgba(15, 125, 82, 0.55)", outlineOffset: 3 } : void 0,
2922
- children: [
2923
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "quote", children: [
2924
- '"',
2925
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2926
- InlineText,
2927
- {
2928
- as: "span",
2929
- multiline: true,
2930
- onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "quote", value),
2931
- placeholder: "Customer quote",
2932
- value: normalizeText(item?.quote)
2933
- }
2934
- ),
2935
- '"'
2936
- ] }),
2937
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "quote-author", children: [
2938
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "quote-avatar", children: normalizeText(item?.name, "C").split(" ").slice(0, 2).map((part) => part[0]).join("").toUpperCase() }),
2939
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
2900
+ type: "button",
2901
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { "aria-hidden": "true", children: "\u2039" })
2902
+ }
2903
+ ) : null,
2904
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "split testimonials-grid", children: windowedItems.map(({ item, itemIndex }) => {
2905
+ const isItemSelected = selectedIndex === index && selectedItemIndex === itemIndex;
2906
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2907
+ "article",
2908
+ {
2909
+ className: "panel",
2910
+ onMouseDownCapture: () => {
2911
+ setSelectedIndex(index);
2912
+ openSelectedItem(itemIndex);
2913
+ },
2914
+ style: isItemSelected ? { outline: "2px solid rgba(15, 125, 82, 0.55)", outlineOffset: 3 } : void 0,
2915
+ children: [
2916
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "quote", children: [
2917
+ '"',
2940
2918
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2941
2919
  InlineText,
2942
2920
  {
2943
2921
  as: "span",
2944
- onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "name", value),
2945
- placeholder: "Customer name",
2946
- value: normalizeText(item?.name)
2922
+ multiline: true,
2923
+ onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "quote", value),
2924
+ placeholder: "Customer quote",
2925
+ value: normalizeText(item?.quote)
2947
2926
  }
2948
2927
  ),
2949
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "var(--ink-500)", fontSize: "0.88rem" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2950
- InlineText,
2951
- {
2952
- as: "span",
2953
- onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "location", value),
2954
- placeholder: "Location",
2955
- value: normalizeText(item?.location)
2956
- }
2957
- ) })
2928
+ '"'
2929
+ ] }),
2930
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "quote-author", children: [
2931
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "quote-avatar", children: normalizeText(item?.name, "C").split(" ").slice(0, 2).map((part) => part[0]).join("").toUpperCase() }),
2932
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
2933
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2934
+ InlineText,
2935
+ {
2936
+ as: "span",
2937
+ onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "name", value),
2938
+ placeholder: "Customer name",
2939
+ value: normalizeText(item?.name)
2940
+ }
2941
+ ),
2942
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "var(--ink-500)", fontSize: "0.88rem" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2943
+ InlineText,
2944
+ {
2945
+ as: "span",
2946
+ onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "location", value),
2947
+ placeholder: "Location",
2948
+ value: normalizeText(item?.location)
2949
+ }
2950
+ ) })
2951
+ ] })
2958
2952
  ] })
2959
- ] })
2960
- ]
2961
- },
2962
- `testimonial-${itemIndex}`
2963
- );
2964
- }) })
2953
+ ]
2954
+ },
2955
+ `testimonial-${itemIndex}`
2956
+ );
2957
+ }) }),
2958
+ canNavigate ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2959
+ "button",
2960
+ {
2961
+ "aria-label": "Next testimonials",
2962
+ className: "testimonial-nav testimonial-nav--next",
2963
+ onClick: (event) => {
2964
+ event.preventDefault();
2965
+ event.stopPropagation();
2966
+ setTestimonialsOffsets((current) => {
2967
+ const currentOffset = typeof current[key] === "number" ? current[key] : 0;
2968
+ const shift = windowSize;
2969
+ const next = (currentOffset + shift) % items.length;
2970
+ return currentOffset === next ? current : { ...current, [key]: next };
2971
+ });
2972
+ },
2973
+ type: "button",
2974
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { "aria-hidden": "true", children: "\u203A" })
2975
+ }
2976
+ ) : null
2977
+ ] })
2965
2978
  ] })
2966
2979
  )
2967
2980
  },
@@ -1985,35 +1985,7 @@ function BuilderPageEditor({ initialDoc, pageID }) {
1985
1985
  setActiveSidebarPanel("addSections");
1986
1986
  }, [layout.length]);
1987
1987
  useEffect(() => {
1988
- const timers = [];
1989
- layout.forEach((block, index) => {
1990
- if (normalizeText(block.blockType, "") !== "testimonials") {
1991
- return;
1992
- }
1993
- const key = typeof block.id === "string" && block.id ? String(block.id) : `testimonials-${index}`;
1994
- const items = Array.isArray(block.items) ? block.items : [];
1995
- const visibleCountRaw = Math.floor(parsePixelNumber(block.visibleCount, 3));
1996
- const visibleCount = Math.max(1, Math.min(6, visibleCountRaw));
1997
- const autoRotate = typeof block.autoRotate === "boolean" ? Boolean(block.autoRotate) : true;
1998
- const intervalSeconds = Math.max(
1999
- 2,
2000
- Math.floor(parsePixelNumber(block.rotateIntervalSeconds, 7))
2001
- );
2002
- if (!autoRotate || items.length <= visibleCount) {
2003
- return;
2004
- }
2005
- const timer = window.setInterval(() => {
2006
- setTestimonialsOffsets((current) => {
2007
- const offset = typeof current[key] === "number" ? current[key] : 0;
2008
- const next = (offset + visibleCount) % items.length;
2009
- return offset === next ? current : { ...current, [key]: next };
2010
- });
2011
- }, intervalSeconds * 1e3);
2012
- timers.push(timer);
2013
- });
2014
- return () => {
2015
- timers.forEach((timer) => window.clearInterval(timer));
2016
- };
1988
+ return;
2017
1989
  }, [layout]);
2018
1990
  useEffect(() => {
2019
1991
  if (historyBypassRef.current) {
@@ -2850,13 +2822,14 @@ function BuilderPageEditor({ initialDoc, pageID }) {
2850
2822
  const items = Array.isArray(block.items) ? block.items : [];
2851
2823
  const visibleCountRaw = Math.floor(parsePixelNumber(block.visibleCount, 3));
2852
2824
  const visibleCount = Math.max(1, Math.min(6, visibleCountRaw));
2853
- const autoRotate = typeof block.autoRotate === "boolean" ? Boolean(block.autoRotate) : true;
2854
2825
  const key = typeof block.id === "string" && block.id ? String(block.id) : `testimonials-${index}`;
2855
2826
  const offset = typeof testimonialsOffsets[key] === "number" ? testimonialsOffsets[key] : 0;
2856
- const windowedItems = !autoRotate || items.length <= visibleCount ? items.map((item, itemIndex) => ({ item, itemIndex })) : Array.from({ length: visibleCount }, (_, slotIndex) => {
2827
+ const canNavigate = items.length > visibleCount;
2828
+ const windowSize = Math.min(visibleCount, items.length);
2829
+ const windowedItems = canNavigate ? Array.from({ length: windowSize }, (_, slotIndex) => {
2857
2830
  const itemIndex = (offset + slotIndex) % items.length;
2858
2831
  return { item: items[itemIndex], itemIndex };
2859
- });
2832
+ }) : items.map((item, itemIndex) => ({ item, itemIndex }));
2860
2833
  return /* @__PURE__ */ jsx(
2861
2834
  BlockFrame,
2862
2835
  {
@@ -2880,60 +2853,100 @@ function BuilderPageEditor({ initialDoc, pageID }) {
2880
2853
  value: normalizeText(block.title)
2881
2854
  }
2882
2855
  ) }) }),
2883
- /* @__PURE__ */ jsx("div", { className: "split testimonials-grid", children: windowedItems.map(({ item, itemIndex }) => {
2884
- const isItemSelected = selectedIndex === index && selectedItemIndex === itemIndex;
2885
- return /* @__PURE__ */ jsxs(
2886
- "article",
2856
+ /* @__PURE__ */ jsxs("div", { className: `testimonials-stage ${canNavigate ? "is-navigable" : ""}`, children: [
2857
+ canNavigate ? /* @__PURE__ */ jsx(
2858
+ "button",
2887
2859
  {
2888
- className: "panel",
2889
- onMouseDownCapture: () => {
2890
- setSelectedIndex(index);
2891
- openSelectedItem(itemIndex);
2860
+ "aria-label": "Previous testimonials",
2861
+ className: "testimonial-nav testimonial-nav--prev",
2862
+ onClick: (event) => {
2863
+ event.preventDefault();
2864
+ event.stopPropagation();
2865
+ setTestimonialsOffsets((current) => {
2866
+ const currentOffset = typeof current[key] === "number" ? current[key] : 0;
2867
+ const shift = windowSize;
2868
+ const next = ((currentOffset - shift) % items.length + items.length) % items.length;
2869
+ return currentOffset === next ? current : { ...current, [key]: next };
2870
+ });
2892
2871
  },
2893
- style: isItemSelected ? { outline: "2px solid rgba(15, 125, 82, 0.55)", outlineOffset: 3 } : void 0,
2894
- children: [
2895
- /* @__PURE__ */ jsxs("p", { className: "quote", children: [
2896
- '"',
2897
- /* @__PURE__ */ jsx(
2898
- InlineText,
2899
- {
2900
- as: "span",
2901
- multiline: true,
2902
- onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "quote", value),
2903
- placeholder: "Customer quote",
2904
- value: normalizeText(item?.quote)
2905
- }
2906
- ),
2907
- '"'
2908
- ] }),
2909
- /* @__PURE__ */ jsxs("div", { className: "quote-author", children: [
2910
- /* @__PURE__ */ jsx("div", { className: "quote-avatar", children: normalizeText(item?.name, "C").split(" ").slice(0, 2).map((part) => part[0]).join("").toUpperCase() }),
2911
- /* @__PURE__ */ jsxs("div", { children: [
2872
+ type: "button",
2873
+ children: /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\u2039" })
2874
+ }
2875
+ ) : null,
2876
+ /* @__PURE__ */ jsx("div", { className: "split testimonials-grid", children: windowedItems.map(({ item, itemIndex }) => {
2877
+ const isItemSelected = selectedIndex === index && selectedItemIndex === itemIndex;
2878
+ return /* @__PURE__ */ jsxs(
2879
+ "article",
2880
+ {
2881
+ className: "panel",
2882
+ onMouseDownCapture: () => {
2883
+ setSelectedIndex(index);
2884
+ openSelectedItem(itemIndex);
2885
+ },
2886
+ style: isItemSelected ? { outline: "2px solid rgba(15, 125, 82, 0.55)", outlineOffset: 3 } : void 0,
2887
+ children: [
2888
+ /* @__PURE__ */ jsxs("p", { className: "quote", children: [
2889
+ '"',
2912
2890
  /* @__PURE__ */ jsx(
2913
2891
  InlineText,
2914
2892
  {
2915
2893
  as: "span",
2916
- onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "name", value),
2917
- placeholder: "Customer name",
2918
- value: normalizeText(item?.name)
2894
+ multiline: true,
2895
+ onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "quote", value),
2896
+ placeholder: "Customer quote",
2897
+ value: normalizeText(item?.quote)
2919
2898
  }
2920
2899
  ),
2921
- /* @__PURE__ */ jsx("div", { style: { color: "var(--ink-500)", fontSize: "0.88rem" }, children: /* @__PURE__ */ jsx(
2922
- InlineText,
2923
- {
2924
- as: "span",
2925
- onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "location", value),
2926
- placeholder: "Location",
2927
- value: normalizeText(item?.location)
2928
- }
2929
- ) })
2900
+ '"'
2901
+ ] }),
2902
+ /* @__PURE__ */ jsxs("div", { className: "quote-author", children: [
2903
+ /* @__PURE__ */ jsx("div", { className: "quote-avatar", children: normalizeText(item?.name, "C").split(" ").slice(0, 2).map((part) => part[0]).join("").toUpperCase() }),
2904
+ /* @__PURE__ */ jsxs("div", { children: [
2905
+ /* @__PURE__ */ jsx(
2906
+ InlineText,
2907
+ {
2908
+ as: "span",
2909
+ onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "name", value),
2910
+ placeholder: "Customer name",
2911
+ value: normalizeText(item?.name)
2912
+ }
2913
+ ),
2914
+ /* @__PURE__ */ jsx("div", { style: { color: "var(--ink-500)", fontSize: "0.88rem" }, children: /* @__PURE__ */ jsx(
2915
+ InlineText,
2916
+ {
2917
+ as: "span",
2918
+ onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "location", value),
2919
+ placeholder: "Location",
2920
+ value: normalizeText(item?.location)
2921
+ }
2922
+ ) })
2923
+ ] })
2930
2924
  ] })
2931
- ] })
2932
- ]
2933
- },
2934
- `testimonial-${itemIndex}`
2935
- );
2936
- }) })
2925
+ ]
2926
+ },
2927
+ `testimonial-${itemIndex}`
2928
+ );
2929
+ }) }),
2930
+ canNavigate ? /* @__PURE__ */ jsx(
2931
+ "button",
2932
+ {
2933
+ "aria-label": "Next testimonials",
2934
+ className: "testimonial-nav testimonial-nav--next",
2935
+ onClick: (event) => {
2936
+ event.preventDefault();
2937
+ event.stopPropagation();
2938
+ setTestimonialsOffsets((current) => {
2939
+ const currentOffset = typeof current[key] === "number" ? current[key] : 0;
2940
+ const shift = windowSize;
2941
+ const next = (currentOffset + shift) % items.length;
2942
+ return currentOffset === next ? current : { ...current, [key]: next };
2943
+ });
2944
+ },
2945
+ type: "button",
2946
+ children: /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\u203A" })
2947
+ }
2948
+ ) : null
2949
+ ] })
2937
2950
  ] })
2938
2951
  )
2939
2952
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orion-studios/payload-studio",
3
- "version": "0.5.0-beta.47",
3
+ "version": "0.5.0-beta.48",
4
4
  "description": "Unified Payload CMS toolkit for Orion Studios",
5
5
  "types": "./dist/index.d.ts",
6
6
  "main": "./dist/index.js",