@fluid-app/portal-widgets 0.1.19 → 0.1.20

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.
Files changed (65) hide show
  1. package/dist/ListWidget-C0RDtImi.cjs +2 -0
  2. package/dist/{ListWidget-RHQ2fQXa.cjs → ListWidget-DPVLRWoB.cjs} +37 -49
  3. package/dist/ListWidget-DPVLRWoB.cjs.map +1 -0
  4. package/dist/{ListWidget-C-jcsCb4.mjs → ListWidget-DdvuIQXy.mjs} +37 -39
  5. package/dist/ListWidget-DdvuIQXy.mjs.map +1 -0
  6. package/dist/{MySiteWidget-A_cYFgxJ.cjs → MySiteWidget-1xqN0Bcg.cjs} +1 -1
  7. package/dist/{MySiteWidget-A_cYFgxJ.cjs.map → MySiteWidget-1xqN0Bcg.cjs.map} +1 -1
  8. package/dist/{MySiteWidget-DariqlfU.mjs → MySiteWidget-CX_jY14-.mjs} +1 -1
  9. package/dist/{MySiteWidget-DariqlfU.mjs.map → MySiteWidget-CX_jY14-.mjs.map} +1 -1
  10. package/dist/NestedWidget-DjZYPLc7.cjs +2 -0
  11. package/dist/{NestedWidget-BaRb7Z5r.mjs → NestedWidget-DoevHJKG.mjs} +27 -3
  12. package/dist/NestedWidget-DoevHJKG.mjs.map +1 -0
  13. package/dist/{NestedWidget-Dbo3dXEi.cjs → NestedWidget-DszMmpt7.cjs} +28 -14
  14. package/dist/NestedWidget-DszMmpt7.cjs.map +1 -0
  15. package/dist/{QuickShareWidget-DXq5lcDn.mjs → QuickShareWidget-CdvP1eRx.mjs} +1 -1
  16. package/dist/{QuickShareWidget-DXq5lcDn.mjs.map → QuickShareWidget-CdvP1eRx.mjs.map} +1 -1
  17. package/dist/{QuickShareWidget-DWvgEy74.cjs → QuickShareWidget-Dg2OcMYg.cjs} +1 -1
  18. package/dist/{QuickShareWidget-DWvgEy74.cjs.map → QuickShareWidget-Dg2OcMYg.cjs.map} +1 -1
  19. package/dist/{RecentActivityWidget-BvncOdax.mjs → RecentActivityWidget-Cj-vLOGu.mjs} +1 -1
  20. package/dist/{RecentActivityWidget-BvncOdax.mjs.map → RecentActivityWidget-Cj-vLOGu.mjs.map} +1 -1
  21. package/dist/{RecentActivityWidget-wODng8dt.cjs → RecentActivityWidget-RGChzfaD.cjs} +1 -1
  22. package/dist/{RecentActivityWidget-wODng8dt.cjs.map → RecentActivityWidget-RGChzfaD.cjs.map} +1 -1
  23. package/dist/{SpacerWidget-BFboILmz.cjs → SpacerWidget-BdVf_Yqm.cjs} +1 -1
  24. package/dist/{SpacerWidget-BFboILmz.cjs.map → SpacerWidget-BdVf_Yqm.cjs.map} +1 -1
  25. package/dist/{SpacerWidget-Cc0IuKda.mjs → SpacerWidget-DxR5K3hp.mjs} +1 -1
  26. package/dist/{SpacerWidget-Cc0IuKda.mjs.map → SpacerWidget-DxR5K3hp.mjs.map} +1 -1
  27. package/dist/{TableWidget-iS_DwHOX.cjs → TableWidget-BQNVZUkg.cjs} +15 -13
  28. package/dist/TableWidget-BQNVZUkg.cjs.map +1 -0
  29. package/dist/TableWidget-amUotAZN.cjs +2 -0
  30. package/dist/{TableWidget-DqAN_2sf.mjs → TableWidget-bpvdvJHI.mjs} +14 -2
  31. package/dist/TableWidget-bpvdvJHI.mjs.map +1 -0
  32. package/dist/{ToDoWidget-D8YIsl7y.mjs → ToDoWidget-4EZIWq_Z.mjs} +1 -1
  33. package/dist/{ToDoWidget-D8YIsl7y.mjs.map → ToDoWidget-4EZIWq_Z.mjs.map} +1 -1
  34. package/dist/{ToDoWidget-Dvs0GDkx.cjs → ToDoWidget-D5BFKUrZ.cjs} +1 -1
  35. package/dist/{ToDoWidget-Dvs0GDkx.cjs.map → ToDoWidget-D5BFKUrZ.cjs.map} +1 -1
  36. package/dist/{VideoWidget-D_1kluGw.mjs → VideoWidget-CYSOjVec.mjs} +1 -1
  37. package/dist/{VideoWidget-D_1kluGw.mjs.map → VideoWidget-CYSOjVec.mjs.map} +1 -1
  38. package/dist/{VideoWidget-D3Fw1jZE.cjs → VideoWidget-CqRHfFnI.cjs} +1 -1
  39. package/dist/{VideoWidget-D3Fw1jZE.cjs.map → VideoWidget-CqRHfFnI.cjs.map} +1 -1
  40. package/dist/WidgetInteractionContext-DjlpWpTR.cjs +31 -0
  41. package/dist/WidgetInteractionContext-DjlpWpTR.cjs.map +1 -0
  42. package/dist/WidgetInteractionContext-awLrJeAK.mjs +18 -0
  43. package/dist/WidgetInteractionContext-awLrJeAK.mjs.map +1 -0
  44. package/dist/contexts/index.cjs +3 -0
  45. package/dist/contexts/index.d.cts +19 -1
  46. package/dist/contexts/index.d.cts.map +1 -1
  47. package/dist/contexts/index.d.mts +19 -1
  48. package/dist/contexts/index.d.mts.map +1 -1
  49. package/dist/contexts/index.mjs +2 -1
  50. package/dist/core/index.d.mts +1 -1
  51. package/dist/widgets/index.cjs +18 -18
  52. package/dist/widgets/index.cjs.map +1 -1
  53. package/dist/widgets/index.d.cts +1 -2
  54. package/dist/widgets/index.d.cts.map +1 -1
  55. package/dist/widgets/index.d.mts +2 -3
  56. package/dist/widgets/index.d.mts.map +1 -1
  57. package/dist/widgets/index.mjs +18 -18
  58. package/package.json +3 -3
  59. package/dist/ListWidget-C-jcsCb4.mjs.map +0 -1
  60. package/dist/ListWidget-RHQ2fQXa.cjs.map +0 -1
  61. package/dist/NestedWidget-BaRb7Z5r.mjs.map +0 -1
  62. package/dist/NestedWidget-Dbo3dXEi.cjs.map +0 -1
  63. package/dist/TableWidget-DqAN_2sf.mjs.map +0 -1
  64. package/dist/TableWidget-iS_DwHOX.cjs.map +0 -1
  65. /package/dist/{fields-4FC6JUNH.d.mts → fields-BGGlw1MW.d.mts} +0 -0
@@ -0,0 +1,2 @@
1
+ const require_ListWidget = require("./ListWidget-DPVLRWoB.cjs");
2
+ exports.listWidgetPropertySchema = require_ListWidget.listWidgetPropertySchema;
@@ -1,6 +1,7 @@
1
1
  const require_chunk = require("./chunk-CZWwpsFl.cjs");
2
2
  const require_scroll_arrows = require("./scroll-arrows-BZIlsE_x.cjs");
3
3
  const require_MediaRenderer = require("./MediaRenderer-CcJvyOJ1.cjs");
4
+ const require_WidgetInteractionContext = require("./WidgetInteractionContext-DjlpWpTR.cjs");
4
5
  let react_jsx_runtime = require("react/jsx-runtime");
5
6
  let react = require("react");
6
7
  let dompurify = require("dompurify");
@@ -135,23 +136,6 @@ function DiscountBadge({ discount }) {
135
136
  children: getStringValue(discount)
136
137
  });
137
138
  }
138
- function FavoriteButton({ className }) {
139
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
140
- className: className || "bg-background/80 hover:bg-background absolute top-2 left-2 z-10 rounded-full p-2 backdrop-blur-sm transition-colors",
141
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
142
- className: "text-muted-foreground h-5 w-5",
143
- fill: "none",
144
- stroke: "currentColor",
145
- viewBox: "0 0 24 24",
146
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
147
- strokeLinecap: "round",
148
- strokeLinejoin: "round",
149
- strokeWidth: 2,
150
- d: "M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"
151
- })
152
- })
153
- });
154
- }
155
139
  //#endregion
156
140
  //#region src/widgets/list-widget/UnorderedList.tsx
157
141
  const getImageUrl$1 = (item) => {
@@ -174,17 +158,29 @@ const getResponsiveGridClass = (columns) => {
174
158
  6: "grid-cols-2 @lg:grid-cols-6"
175
159
  }[columns] || "grid-cols-2 @lg:grid-cols-3";
176
160
  };
177
- function UnorderedList({ items, columns, gap, borderRadius, imageAspectRatio, showBadge, showFavorite, padding, itemTitleColor, itemTitleSize, descriptionColor, descriptionSize, priceColor, priceSize, originalPriceColor, metaTextColor, metaTextSize, showMetaText }) {
161
+ function UnorderedList({ items, columns, gap, borderRadius, imageAspectRatio, showBadge, padding, itemTitleColor, itemTitleSize, descriptionColor, descriptionSize, priceColor, priceSize, originalPriceColor, metaTextColor, metaTextSize, showMetaText }) {
162
+ const gridClass = getResponsiveGridClass(columns);
163
+ const { onItemClick } = require_WidgetInteractionContext.useWidgetInteraction();
178
164
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
179
- className: `grid ${getResponsiveGridClass(columns)} gap-${_fluid_app_portal_core_registries.gapValues[gap]}`,
165
+ className: `grid ${gridClass} gap-${_fluid_app_portal_core_registries.gapValues[gap]}`,
180
166
  children: items.map((item) => {
181
167
  const imageUrl = getImageUrl$1(item);
182
168
  const aspectRatioClass = getAspectRatioClass$1(imageAspectRatio);
183
169
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
184
- className: `relative rounded-${borderRadius} bg-background overflow-hidden shadow-sm transition-shadow hover:shadow-md`,
170
+ className: `relative rounded-${borderRadius} bg-background overflow-hidden shadow-sm transition-shadow hover:shadow-md ${onItemClick ? "cursor-pointer" : ""}`,
171
+ ...onItemClick ? {
172
+ role: "button",
173
+ tabIndex: 0,
174
+ onClick: () => onItemClick(item),
175
+ onKeyDown: (e) => {
176
+ if (e.key === "Enter" || e.key === " ") {
177
+ e.preventDefault();
178
+ onItemClick(item);
179
+ }
180
+ }
181
+ } : {},
185
182
  children: [
186
183
  showBadge && item.discount && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DiscountBadge, { discount: item.discount }),
187
- showFavorite && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FavoriteButton, {}),
188
184
  imageUrl && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
189
185
  className: `w-full ${aspectRatioClass} overflow-hidden`,
190
186
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
@@ -233,7 +229,7 @@ const largeNumberSizes = {
233
229
  xl: "16rem",
234
230
  "2xl": "20rem"
235
231
  };
236
- function OrderedList({ items, scrollAxis, gap, borderRadius, imageAspectRatio, showBadge, showFavorite, padding, itemTitleColor, itemTitleSize, descriptionColor, descriptionSize, priceColor, priceSize, originalPriceColor, metaTextColor, metaTextSize, numberColor, numberSize, showMetaText }) {
232
+ function OrderedList({ items, scrollAxis, gap, borderRadius, imageAspectRatio, showBadge, padding, itemTitleColor, itemTitleSize, descriptionColor, descriptionSize, priceColor, priceSize, originalPriceColor, metaTextColor, metaTextSize, numberColor, numberSize, showMetaText }) {
237
233
  const scrollContainerRef = (0, react.useRef)(null);
238
234
  const scrollByAmount = (direction) => {
239
235
  const container = scrollContainerRef.current;
@@ -244,6 +240,18 @@ function OrderedList({ items, scrollAxis, gap, borderRadius, imageAspectRatio, s
244
240
  behavior: "smooth"
245
241
  });
246
242
  };
243
+ const { onItemClick } = require_WidgetInteractionContext.useWidgetInteraction();
244
+ const interactionProps = (item) => onItemClick ? {
245
+ role: "button",
246
+ tabIndex: 0,
247
+ onClick: () => onItemClick(item),
248
+ onKeyDown: (e) => {
249
+ if (e.key === "Enter" || e.key === " ") {
250
+ e.preventDefault();
251
+ onItemClick(item);
252
+ }
253
+ }
254
+ } : {};
247
255
  const contentProps = {
248
256
  padding,
249
257
  itemTitleColor,
@@ -266,7 +274,8 @@ function OrderedList({ items, scrollAxis, gap, borderRadius, imageAspectRatio, s
266
274
  const imageUrl = getImageUrl(item);
267
275
  const aspectRatioClass = getAspectRatioClass(imageAspectRatio);
268
276
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
269
- className: "relative w-[300px] flex-shrink-0",
277
+ className: `relative w-[300px] flex-shrink-0 ${onItemClick ? "cursor-pointer" : ""}`,
278
+ ...interactionProps(item),
270
279
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
271
280
  className: `absolute top-0 left-0 text-${numberColor} z-0 leading-none font-bold opacity-20`,
272
281
  style: { fontSize: largeNumberSizes[numberSize] },
@@ -275,7 +284,6 @@ function OrderedList({ items, scrollAxis, gap, borderRadius, imageAspectRatio, s
275
284
  className: `relative z-10 ml-20 rounded-${borderRadius} bg-background overflow-hidden shadow-sm transition-shadow hover:shadow-md`,
276
285
  children: [
277
286
  showBadge && item.discount && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DiscountBadge, { discount: item.discount }),
278
- showFavorite && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FavoriteButton, {}),
279
287
  imageUrl && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
280
288
  className: `w-full ${aspectRatioClass} overflow-hidden`,
281
289
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
@@ -305,7 +313,8 @@ function OrderedList({ items, scrollAxis, gap, borderRadius, imageAspectRatio, s
305
313
  children: items.map((item, index) => {
306
314
  const imageUrl = getImageUrl(item);
307
315
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
308
- className: `relative flex gap-${_fluid_app_portal_core_registries.gapValues[gap]} rounded-${borderRadius} bg-background overflow-hidden shadow-sm transition-shadow hover:shadow-md ${`p-${padding}`}`,
316
+ className: `relative flex gap-${_fluid_app_portal_core_registries.gapValues[gap]} rounded-${borderRadius} bg-background overflow-hidden shadow-sm transition-shadow hover:shadow-md ${`p-${padding}`} ${onItemClick ? "cursor-pointer" : ""}`,
317
+ ...interactionProps(item),
309
318
  children: [
310
319
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
311
320
  className: `flex-shrink-0 text-${numberColor} text-${numberSize === "md" ? "base" : numberSize} flex w-16 items-center justify-center font-bold`,
@@ -329,8 +338,7 @@ function OrderedList({ items, scrollAxis, gap, borderRadius, imageAspectRatio, s
329
338
  showBadge && item.discount && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
330
339
  className: "bg-destructive text-destructive-foreground absolute top-2 right-2 rounded-md px-2 py-1 text-xs font-bold",
331
340
  children: getStringValue(item.discount)
332
- }),
333
- showFavorite && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FavoriteButton, { className: "bg-background/80 hover:bg-background absolute top-2 right-12 rounded-full p-2 backdrop-blur-sm transition-colors" })
341
+ })
334
342
  ]
335
343
  }, item.id);
336
344
  })
@@ -339,10 +347,6 @@ function OrderedList({ items, scrollAxis, gap, borderRadius, imageAspectRatio, s
339
347
  }
340
348
  //#endregion
341
349
  //#region src/widgets/ListWidget.tsx
342
- var ListWidget_exports = /* @__PURE__ */ require_chunk.__exportAll({
343
- ListWidget: () => ListWidget,
344
- listWidgetPropertySchema: () => listWidgetPropertySchema
345
- });
346
350
  const DEFAULT_ITEMS = [];
347
351
  function getFeaturedAssetUrl(value) {
348
352
  if (!value) return void 0;
@@ -366,7 +370,7 @@ function getFeaturedAssetUrl(value) {
366
370
  function ListWidget({ listType = "unordered", scrollAxis = "horizontal", titleEnabled = true, title, items = DEFAULT_ITEMS, titleColor = "foreground", titleSize = "lg", itemTitleColor = "foreground", itemTitleSize = "sm", descriptionColor = "foreground", descriptionSize = "sm", priceColor = "foreground", priceSize = "md", originalPriceColor = "muted", metaTextColor = "muted", metaTextSize = "xs", numberColor = "primary", numberSize = "2xl", borderRadius = "md", padding = 4, gap = "md", columns = 3, imageAspectRatio = "square", background = {
367
371
  type: "solid",
368
372
  color: "background"
369
- }, showBadge = true, showFavorite = true, showMetaText = true, maxItems = 12, showFeaturedSection = false, featuredAsset, featuredTitle, featuredSubtitle, featuredButtonText, featuredButtonUrl, featuredSubtitleColor = "background", featuredSubtitleSize = "md", className, ...props }) {
373
+ }, showBadge = true, showMetaText = true, maxItems = 12, showFeaturedSection = false, featuredAsset, featuredTitle, featuredSubtitle, featuredButtonText, featuredButtonUrl, featuredSubtitleColor = "background", featuredSubtitleSize = "md", className, ...props }) {
370
374
  const displayItems = maxItems ? items.slice(0, maxItems) : items;
371
375
  const hasItems = displayItems.length > 0;
372
376
  const itemStyleProps = {
@@ -382,7 +386,6 @@ function ListWidget({ listType = "unordered", scrollAxis = "horizontal", titleEn
382
386
  metaTextSize,
383
387
  showMetaText,
384
388
  showBadge,
385
- showFavorite,
386
389
  borderRadius,
387
390
  imageAspectRatio,
388
391
  gap
@@ -588,15 +591,6 @@ const listWidgetPropertySchema = {
588
591
  tab: "styling",
589
592
  group: "List Configuration"
590
593
  },
591
- {
592
- key: "showFavorite",
593
- label: "Show Favorite Icon",
594
- type: "boolean",
595
- description: "Display favorite/heart icon on images",
596
- defaultValue: true,
597
- tab: "styling",
598
- group: "List Configuration"
599
- },
600
594
  {
601
595
  key: "showMetaText",
602
596
  label: "Show QV/CV Text",
@@ -903,12 +897,6 @@ Object.defineProperty(exports, "ListWidget", {
903
897
  return ListWidget;
904
898
  }
905
899
  });
906
- Object.defineProperty(exports, "ListWidget_exports", {
907
- enumerable: true,
908
- get: function() {
909
- return ListWidget_exports;
910
- }
911
- });
912
900
  Object.defineProperty(exports, "listWidgetPropertySchema", {
913
901
  enumerable: true,
914
902
  get: function() {
@@ -916,4 +904,4 @@ Object.defineProperty(exports, "listWidgetPropertySchema", {
916
904
  }
917
905
  });
918
906
 
919
- //# sourceMappingURL=ListWidget-RHQ2fQXa.cjs.map
907
+ //# sourceMappingURL=ListWidget-DPVLRWoB.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ListWidget-DPVLRWoB.cjs","names":["MediaRenderer","DOMPurify","getImageUrl","getAspectRatioClass","useWidgetInteraction","gapValues","useWidgetInteraction","gapValues","ScrollArrows"],"sources":["../src/widgets/list-widget/FeaturedSection.tsx","../src/widgets/list-widget/ListItemCard.tsx","../src/widgets/list-widget/UnorderedList.tsx","../src/widgets/list-widget/OrderedList.tsx","../src/widgets/ListWidget.tsx"],"sourcesContent":["import type React from \"react\";\nimport type {\n BorderRadiusOptions,\n FontSizeOptions,\n ColorOptions,\n} from \"@fluid-app/portal-core/types\";\nimport { MediaRenderer } from \"../../components/MediaRenderer\";\n\ninterface FeaturedSectionProps {\n borderRadius: BorderRadiusOptions;\n titleSize: FontSizeOptions;\n featuredTitle?: string | undefined;\n featuredSubtitle?: string | undefined;\n featuredButtonText?: string | undefined;\n featuredButtonUrl?: string | undefined;\n featuredSubtitleColor: ColorOptions;\n featuredSubtitleSize: FontSizeOptions;\n asset: { url: string; isVideo: boolean };\n}\n\nexport function FeaturedSection({\n borderRadius,\n titleSize,\n featuredTitle,\n featuredSubtitle,\n featuredButtonText,\n featuredButtonUrl,\n featuredSubtitleColor,\n featuredSubtitleSize,\n asset,\n}: FeaturedSectionProps): React.JSX.Element {\n return (\n <div\n className={`relative h-full min-h-[300px] w-full overflow-hidden rounded-${borderRadius}`}\n >\n <div className=\"absolute inset-0 h-full w-full\">\n <MediaRenderer\n src={asset.url}\n mediaType={asset.isVideo ? \"video\" : \"image\"}\n alt={featuredTitle || \"Featured\"}\n objectFit=\"cover\"\n autoplay={asset.isVideo}\n loop={asset.isVideo}\n muted={asset.isVideo}\n controls={false}\n />\n </div>\n\n <div className=\"absolute inset-0 bg-black/40\" />\n\n <div className=\"absolute inset-0 flex flex-col items-start justify-end p-8\">\n {featuredTitle && (\n <h3\n className={`mb-2 font-bold text-white text-${titleSize === \"md\" ? \"base\" : titleSize}`}\n >\n {featuredTitle}\n </h3>\n )}\n {featuredSubtitle && (\n <p\n className={`mb-4 text-${featuredSubtitleColor} text-${featuredSubtitleSize === \"md\" ? \"base\" : featuredSubtitleSize}`}\n >\n {featuredSubtitle}\n </p>\n )}\n {featuredButtonText && (\n <a\n href={featuredButtonUrl || \"#\"}\n className={`text-foreground bg-white px-6 py-2 font-medium transition-opacity hover:opacity-90 rounded-${borderRadius}`}\n >\n {featuredButtonText}\n </a>\n )}\n </div>\n </div>\n );\n}\n","import type React from \"react\";\nimport DOMPurify from \"dompurify\";\nimport type {\n ColorOptions,\n FontSizeOptions,\n PaddingOptions,\n} from \"@fluid-app/portal-core/types\";\n\ntype ListItem = {\n id: string;\n image?: string;\n imageUrl?: string;\n videoUrl?: string;\n title?: string;\n description?: string;\n price?: string;\n display_price?: string;\n originalPrice?: string;\n discount?: string;\n qv?: string;\n cv?: string;\n [key: string]: unknown;\n};\n\nfunction getStringValue(value: unknown): string {\n if (!value) return \"\";\n if (typeof value === \"string\") return value;\n if (typeof value === \"number\") return String(value);\n if (typeof value === \"object\" && value !== null) {\n if (\"body\" in value) {\n const body = (value as { body: unknown }).body;\n if (typeof body === \"string\") return body;\n }\n if (\"text\" in value) {\n const text = (value as { text: unknown }).text;\n if (typeof text === \"string\") return text;\n }\n if (\"value\" in value) {\n const val = (value as { value: unknown }).value;\n if (typeof val === \"string\") return val;\n if (typeof val === \"number\") return String(val);\n }\n }\n return \"\";\n}\n\n/**\n * Strips parenthetical text like \"(USD)\" from price strings.\n * Matches the shop page's stripParentheticalText pattern.\n */\nfunction stripParentheticalText(text: string): string {\n return text.replace(/\\s*\\([^)]*\\)/g, \"\").trim();\n}\n\n/**\n * Formats a price for display. Follows the shop page pattern:\n * prices arrive pre-formatted from the API via display_price\n * (e.g. \"$19.99\", \"€15.00 (EUR)\") so we just extract the string\n * and strip parenthetical suffixes.\n */\nfunction formatPrice(value: unknown): string {\n const str = getStringValue(value);\n if (!str) return \"\";\n return stripParentheticalText(str);\n}\n\nexport interface ListItemCardContentProps {\n item: ListItem;\n padding: PaddingOptions;\n itemTitleColor: ColorOptions;\n itemTitleSize: FontSizeOptions;\n descriptionColor: ColorOptions;\n descriptionSize: FontSizeOptions;\n priceColor: ColorOptions;\n priceSize: FontSizeOptions;\n originalPriceColor: ColorOptions;\n metaTextColor: ColorOptions;\n metaTextSize: FontSizeOptions;\n showMetaText: boolean;\n}\n\nexport function ListItemCardContent({\n item,\n padding,\n itemTitleColor,\n itemTitleSize,\n descriptionColor,\n descriptionSize,\n priceColor,\n priceSize,\n originalPriceColor,\n metaTextColor,\n metaTextSize,\n showMetaText,\n}: ListItemCardContentProps): React.JSX.Element {\n return (\n <div className={`p-${padding}`}>\n {item.title && (\n <h3\n className={`text-${itemTitleColor} text-${itemTitleSize === \"md\" ? \"base\" : itemTitleSize} mb-1 font-semibold`}\n >\n {getStringValue(item.title)}\n </h3>\n )}\n {item.description && (\n <div\n className={`text-${descriptionColor} text-${descriptionSize === \"md\" ? \"base\" : descriptionSize} mb-2 line-clamp-2 overflow-hidden`}\n dangerouslySetInnerHTML={{\n __html: DOMPurify.sanitize(item.description ?? \"\", {\n ALLOWED_TAGS: [\n \"br\",\n \"strong\",\n \"em\",\n \"b\",\n \"i\",\n \"ul\",\n \"ol\",\n \"li\",\n \"p\",\n ],\n ALLOWED_ATTR: [],\n }),\n }}\n />\n )}\n <div className=\"flex items-center gap-2\">\n {(item.display_price || item.price) && (\n <span\n className={`text-${priceColor} text-${priceSize === \"md\" ? \"base\" : priceSize} font-bold`}\n >\n {formatPrice(item.display_price || item.price)}\n </span>\n )}\n {item.originalPrice && (\n <span\n className={`text-${originalPriceColor} text-${descriptionSize === \"md\" ? \"base\" : descriptionSize} line-through`}\n >\n {formatPrice(item.originalPrice)}\n </span>\n )}\n </div>\n {showMetaText && (item.qv || item.cv) && (\n <div\n className={`mt-2 flex gap-3 text-${metaTextColor} text-${metaTextSize === \"md\" ? \"base\" : metaTextSize}`}\n >\n {item.qv && <span>QV: {getStringValue(item.qv)}</span>}\n {item.cv && <span>CV: {getStringValue(item.cv)}</span>}\n </div>\n )}\n </div>\n );\n}\n\nexport function DiscountBadge({\n discount,\n}: {\n discount: string;\n}): React.JSX.Element {\n return (\n <div className=\"bg-destructive text-destructive-foreground absolute top-2 right-2 z-10 rounded-md px-2 py-1 text-xs font-bold\">\n {getStringValue(discount)}\n </div>\n );\n}\n\nexport { getStringValue };\nexport type { ListItem };\n","import type React from \"react\";\nimport type {\n ColorOptions,\n FontSizeOptions,\n BorderRadiusOptions,\n PaddingOptions,\n GapOptions,\n} from \"@fluid-app/portal-core/types\";\nimport { gapValues } from \"../../core/fields\";\nimport { useWidgetInteraction } from \"../../contexts/WidgetInteractionContext\";\nimport {\n ListItemCardContent,\n DiscountBadge,\n type ListItem,\n} from \"./ListItemCard\";\n\ntype ImageAspectRatio = \"square\" | \"landscape\" | \"portrait\";\n\nconst getImageUrl = (item: ListItem): string | undefined => {\n return item.imageUrl || item.image;\n};\n\nconst getAspectRatioClass = (ratio: ImageAspectRatio): string => {\n const ratios = {\n square: \"aspect-square\",\n landscape: \"aspect-video\",\n portrait: \"aspect-[3/4]\",\n };\n return ratios[ratio];\n};\n\nconst getResponsiveGridClass = (columns: number): string => {\n const responsiveClasses: Record<number, string> = {\n 1: \"grid-cols-2 @lg:grid-cols-1\",\n 2: \"grid-cols-2 @lg:grid-cols-2\",\n 3: \"grid-cols-2 @lg:grid-cols-3\",\n 4: \"grid-cols-2 @lg:grid-cols-4\",\n 5: \"grid-cols-2 @lg:grid-cols-5\",\n 6: \"grid-cols-2 @lg:grid-cols-6\",\n };\n return responsiveClasses[columns] || \"grid-cols-2 @lg:grid-cols-3\";\n};\n\nexport interface UnorderedListProps {\n items: ListItem[];\n columns: number;\n gap: GapOptions;\n borderRadius: BorderRadiusOptions;\n imageAspectRatio: ImageAspectRatio;\n showBadge: boolean;\n padding: PaddingOptions;\n itemTitleColor: ColorOptions;\n itemTitleSize: FontSizeOptions;\n descriptionColor: ColorOptions;\n descriptionSize: FontSizeOptions;\n priceColor: ColorOptions;\n priceSize: FontSizeOptions;\n originalPriceColor: ColorOptions;\n metaTextColor: ColorOptions;\n metaTextSize: FontSizeOptions;\n showMetaText: boolean;\n}\n\nexport function UnorderedList({\n items,\n columns,\n gap,\n borderRadius,\n imageAspectRatio,\n showBadge,\n padding,\n itemTitleColor,\n itemTitleSize,\n descriptionColor,\n descriptionSize,\n priceColor,\n priceSize,\n originalPriceColor,\n metaTextColor,\n metaTextSize,\n showMetaText,\n}: UnorderedListProps): React.JSX.Element {\n const gridClass = getResponsiveGridClass(columns);\n const { onItemClick } = useWidgetInteraction();\n\n return (\n <div className={`grid ${gridClass} gap-${gapValues[gap]}`}>\n {items.map((item) => {\n const imageUrl = getImageUrl(item);\n const aspectRatioClass = getAspectRatioClass(imageAspectRatio);\n\n return (\n <div\n key={item.id}\n className={`relative rounded-${borderRadius} bg-background overflow-hidden shadow-sm transition-shadow hover:shadow-md ${onItemClick ? \"cursor-pointer\" : \"\"}`}\n {...(onItemClick\n ? {\n role: \"button\",\n tabIndex: 0,\n onClick: () => onItemClick(item),\n onKeyDown: (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onItemClick(item);\n }\n },\n }\n : {})}\n >\n {showBadge && item.discount && (\n <DiscountBadge discount={item.discount} />\n )}\n {imageUrl && (\n <div className={`w-full ${aspectRatioClass} overflow-hidden`}>\n <img\n src={imageUrl}\n alt={item.title || \"Product\"}\n className=\"h-full w-full object-cover\"\n />\n </div>\n )}\n <ListItemCardContent\n item={item}\n padding={padding}\n itemTitleColor={itemTitleColor}\n itemTitleSize={itemTitleSize}\n descriptionColor={descriptionColor}\n descriptionSize={descriptionSize}\n priceColor={priceColor}\n priceSize={priceSize}\n originalPriceColor={originalPriceColor}\n metaTextColor={metaTextColor}\n metaTextSize={metaTextSize}\n showMetaText={showMetaText}\n />\n </div>\n );\n })}\n </div>\n );\n}\n","import { useRef } from \"react\";\nimport type React from \"react\";\nimport type {\n ColorOptions,\n FontSizeOptions,\n BorderRadiusOptions,\n PaddingOptions,\n GapOptions,\n} from \"@fluid-app/portal-core/types\";\nimport { gapValues } from \"../../core/fields\";\nimport { useWidgetInteraction } from \"../../contexts/WidgetInteractionContext\";\nimport { ScrollArrows } from \"../../ui/scroll-arrows\";\nimport {\n ListItemCardContent,\n DiscountBadge,\n getStringValue,\n type ListItem,\n} from \"./ListItemCard\";\n\ntype ImageAspectRatio = \"square\" | \"landscape\" | \"portrait\";\ntype ScrollAxis = \"horizontal\" | \"vertical\";\n\nconst SCROLL_ITEM_WIDTH = 300;\n\nconst getImageUrl = (item: ListItem): string | undefined => {\n return item.imageUrl || item.image;\n};\n\nconst getAspectRatioClass = (ratio: ImageAspectRatio): string => {\n const ratios = {\n square: \"aspect-square\",\n landscape: \"aspect-video\",\n portrait: \"aspect-[3/4]\",\n };\n return ratios[ratio];\n};\n\nexport interface OrderedListProps {\n items: ListItem[];\n scrollAxis: ScrollAxis;\n gap: GapOptions;\n borderRadius: BorderRadiusOptions;\n imageAspectRatio: ImageAspectRatio;\n showBadge: boolean;\n padding: PaddingOptions;\n itemTitleColor: ColorOptions;\n itemTitleSize: FontSizeOptions;\n descriptionColor: ColorOptions;\n descriptionSize: FontSizeOptions;\n priceColor: ColorOptions;\n priceSize: FontSizeOptions;\n originalPriceColor: ColorOptions;\n metaTextColor: ColorOptions;\n metaTextSize: FontSizeOptions;\n numberColor: ColorOptions;\n numberSize: FontSizeOptions;\n showMetaText: boolean;\n}\n\nconst largeNumberSizes: Record<FontSizeOptions, string> = {\n xs: \"8rem\",\n sm: \"10rem\",\n md: \"12rem\",\n lg: \"14rem\",\n xl: \"16rem\",\n \"2xl\": \"20rem\",\n};\n\nexport function OrderedList({\n items,\n scrollAxis,\n gap,\n borderRadius,\n imageAspectRatio,\n showBadge,\n padding,\n itemTitleColor,\n itemTitleSize,\n descriptionColor,\n descriptionSize,\n priceColor,\n priceSize,\n originalPriceColor,\n metaTextColor,\n metaTextSize,\n numberColor,\n numberSize,\n showMetaText,\n}: OrderedListProps): React.JSX.Element | null {\n const scrollContainerRef = useRef<HTMLDivElement>(null);\n\n const scrollByAmount = (direction: \"prev\" | \"next\") => {\n const container = scrollContainerRef.current;\n if (!container) return;\n\n const computedGap = parseFloat(getComputedStyle(container).gap) || 0;\n const scrollAmount = SCROLL_ITEM_WIDTH + computedGap;\n\n container.scrollTo({\n left:\n container.scrollLeft +\n (direction === \"next\" ? scrollAmount : -scrollAmount),\n behavior: \"smooth\",\n });\n };\n\n const { onItemClick } = useWidgetInteraction();\n\n const interactionProps = (item: ListItem) =>\n onItemClick\n ? ({\n role: \"button\" as const,\n tabIndex: 0,\n onClick: () => onItemClick(item),\n onKeyDown: (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onItemClick(item);\n }\n },\n } as const)\n : {};\n\n const contentProps = {\n padding,\n itemTitleColor,\n itemTitleSize,\n descriptionColor,\n descriptionSize,\n priceColor,\n priceSize,\n originalPriceColor,\n metaTextColor,\n metaTextSize,\n showMetaText,\n };\n\n if (scrollAxis === \"horizontal\") {\n return (\n <div className=\"relative\">\n <div\n ref={scrollContainerRef}\n className={`flex gap-${gapValues[gap]} scrollbar-hide overflow-x-auto overflow-y-hidden scroll-smooth`}\n >\n {items.map((item, index) => {\n const imageUrl = getImageUrl(item);\n const aspectRatioClass = getAspectRatioClass(imageAspectRatio);\n\n return (\n <div\n key={item.id}\n className={`relative w-[300px] flex-shrink-0 ${onItemClick ? \"cursor-pointer\" : \"\"}`}\n {...interactionProps(item)}\n >\n <div\n className={`absolute top-0 left-0 text-${numberColor} z-0 leading-none font-bold opacity-20`}\n style={{ fontSize: largeNumberSizes[numberSize] }}\n >\n {index + 1}\n </div>\n\n <div\n className={`relative z-10 ml-20 rounded-${borderRadius} bg-background overflow-hidden shadow-sm transition-shadow hover:shadow-md`}\n >\n {showBadge && item.discount && (\n <DiscountBadge discount={item.discount} />\n )}\n {imageUrl && (\n <div\n className={`w-full ${aspectRatioClass} overflow-hidden`}\n >\n <img\n src={imageUrl}\n alt={item.title || \"Product\"}\n className=\"h-full w-full object-cover\"\n />\n </div>\n )}\n <ListItemCardContent item={item} {...contentProps} />\n </div>\n </div>\n );\n })}\n </div>\n\n <div className=\"absolute inset-x-0 top-1/2 z-20 flex w-full -translate-y-1/2 items-center justify-between px-8\">\n <ScrollArrows\n onPrevious={() => scrollByAmount(\"prev\")}\n onNext={() => scrollByAmount(\"next\")}\n />\n </div>\n </div>\n );\n }\n\n if (scrollAxis === \"vertical\") {\n return (\n <div className={`flex flex-col gap-${gapValues[gap]}`}>\n {items.map((item, index) => {\n const imageUrl = getImageUrl(item);\n\n return (\n <div\n key={item.id}\n className={`relative flex gap-${gapValues[gap]} rounded-${borderRadius} bg-background overflow-hidden shadow-sm transition-shadow hover:shadow-md ${`p-${padding}`} ${onItemClick ? \"cursor-pointer\" : \"\"}`}\n {...interactionProps(item)}\n >\n <div\n className={`flex-shrink-0 text-${numberColor} text-${numberSize === \"md\" ? \"base\" : numberSize} flex w-16 items-center justify-center font-bold`}\n >\n {index + 1}\n </div>\n {imageUrl && (\n <div className=\"h-24 w-24 flex-shrink-0 overflow-hidden rounded-md\">\n <img\n src={imageUrl}\n alt={item.title || \"Product\"}\n className=\"h-full w-full object-cover\"\n />\n </div>\n )}\n <div className=\"flex-1\">\n <ListItemCardContent item={item} {...contentProps} />\n </div>\n {showBadge && item.discount && (\n <div className=\"bg-destructive text-destructive-foreground absolute top-2 right-2 rounded-md px-2 py-1 text-xs font-bold\">\n {getStringValue(item.discount)}\n </div>\n )}\n </div>\n );\n })}\n </div>\n );\n }\n\n return null;\n}\n","import type { ComponentProps } from \"react\";\nimport type React from \"react\";\nimport type {\n ColorOptions,\n FontSizeOptions,\n BorderRadiusOptions,\n PaddingOptions,\n GapOptions,\n BackgroundValue,\n} from \"@fluid-app/portal-core/types\";\nimport type { WidgetPropertySchema } from \"@fluid-app/portal-core/registries\";\nimport {\n getBorderRadiusField,\n getColorField,\n getFontSizeField,\n getPaddingField,\n getGapField,\n} from \"../core/fields\";\nimport { FeaturedSection } from \"./list-widget/FeaturedSection\";\nimport { UnorderedList } from \"./list-widget/UnorderedList\";\nimport { OrderedList } from \"./list-widget/OrderedList\";\n\nconst DEFAULT_ITEMS: ListItem[] = [];\n\ntype ListItem = {\n id: string;\n image?: string;\n imageUrl?: string;\n videoUrl?: string;\n title?: string;\n description?: string;\n price?: string;\n originalPrice?: string;\n discount?: string;\n qv?: string;\n cv?: string;\n [key: string]: unknown;\n};\n\ntype ImageAspectRatio = \"square\" | \"landscape\" | \"portrait\";\ntype ListType = \"ordered\" | \"unordered\";\ntype ScrollAxis = \"horizontal\" | \"vertical\";\n\ntype ListWidgetProps = ComponentProps<\"div\"> & {\n // List configuration\n listType?: ListType;\n scrollAxis?: ScrollAxis;\n titleEnabled?: boolean;\n title?: string;\n items?: ListItem[];\n\n // Text styling\n titleColor?: ColorOptions;\n titleSize?: FontSizeOptions;\n itemTitleColor?: ColorOptions;\n itemTitleSize?: FontSizeOptions;\n descriptionColor?: ColorOptions;\n descriptionSize?: FontSizeOptions;\n priceColor?: ColorOptions;\n priceSize?: FontSizeOptions;\n originalPriceColor?: ColorOptions;\n metaTextColor?: ColorOptions;\n metaTextSize?: FontSizeOptions;\n\n // Ordered list styling\n numberColor?: ColorOptions;\n numberSize?: FontSizeOptions;\n\n // Layout\n borderRadius?: BorderRadiusOptions;\n padding?: PaddingOptions;\n gap?: GapOptions;\n columns?: number;\n imageAspectRatio?: ImageAspectRatio;\n background?: BackgroundValue;\n\n // Behavior\n showBadge?: boolean;\n showMetaText?: boolean;\n maxItems?: number;\n\n // Featured section\n showFeaturedSection?: boolean;\n featuredAsset?: string | { [key: string]: unknown };\n featuredTitle?: string;\n featuredSubtitle?: string;\n featuredButtonText?: string;\n featuredButtonUrl?: string;\n featuredSubtitleColor?: ColorOptions;\n featuredSubtitleSize?: FontSizeOptions;\n};\n\nfunction getFeaturedAssetUrl(\n value: string | { [key: string]: unknown } | undefined,\n): { url: string; isVideo: boolean } | undefined {\n if (!value) return undefined;\n\n // Handle string URLs\n if (typeof value === \"string\") {\n const isVideo = /\\.(mp4|webm|ogg|mov)$/i.test(value);\n return { url: value, isVideo };\n }\n\n // Handle ShareableItem objects\n if (typeof value === \"object\") {\n // Check for video URL first\n const videoUrl =\n (value.videoUrl as string) ||\n (value.video_url as string) ||\n (value.url as string);\n if (videoUrl && /\\.(mp4|webm|ogg|mov)$/i.test(videoUrl)) {\n return { url: videoUrl, isVideo: true };\n }\n\n // Fall back to image URL\n const imageUrl =\n (value.imageUrl as string) ||\n (value.image_url as string) ||\n (value.url as string);\n if (imageUrl) {\n return { url: imageUrl, isVideo: false };\n }\n }\n\n return undefined;\n}\n\nexport function ListWidget({\n listType = \"unordered\",\n scrollAxis = \"horizontal\",\n titleEnabled = true,\n title,\n items = DEFAULT_ITEMS,\n titleColor = \"foreground\",\n titleSize = \"lg\",\n itemTitleColor = \"foreground\",\n itemTitleSize = \"sm\",\n descriptionColor = \"foreground\",\n descriptionSize = \"sm\",\n priceColor = \"foreground\",\n priceSize = \"md\",\n originalPriceColor = \"muted\",\n metaTextColor = \"muted\",\n metaTextSize = \"xs\",\n numberColor = \"primary\",\n numberSize = \"2xl\",\n borderRadius = \"md\",\n padding = 4,\n gap = \"md\",\n columns = 3,\n imageAspectRatio = \"square\",\n background = { type: \"solid\", color: \"background\" },\n showBadge = true,\n showMetaText = true,\n maxItems = 12,\n showFeaturedSection = false,\n featuredAsset,\n featuredTitle,\n featuredSubtitle,\n featuredButtonText,\n featuredButtonUrl,\n featuredSubtitleColor = \"background\",\n featuredSubtitleSize = \"md\",\n className,\n ...props\n}: ListWidgetProps): React.JSX.Element {\n const displayItems = maxItems ? items.slice(0, maxItems) : items;\n const hasItems = displayItems.length > 0;\n\n const itemStyleProps = {\n padding,\n itemTitleColor,\n itemTitleSize,\n descriptionColor,\n descriptionSize,\n priceColor,\n priceSize,\n originalPriceColor,\n metaTextColor,\n metaTextSize,\n showMetaText,\n showBadge,\n borderRadius,\n imageAspectRatio,\n gap,\n };\n\n const hasFeaturedAsset = getFeaturedAssetUrl(featuredAsset);\n const shouldShowFeaturedSection = showFeaturedSection && hasFeaturedAsset;\n\n // Background styling\n const backgroundColor = background.color || \"background\";\n const backgroundImage =\n (background.resource?.image_url || background.resource?.imageUrl) &&\n background.type === \"image\"\n ? `url(${background.resource.image_url || background.resource.imageUrl})`\n : \"none\";\n\n return (\n <div\n className={`@container bg-${backgroundColor} ${className}`}\n style={{ backgroundImage }}\n {...props}\n >\n {titleEnabled && title && (\n <h2\n className={`text-${titleColor} text-${titleSize === \"md\" ? \"base\" : titleSize} mb-6 font-bold`}\n >\n {title}\n </h2>\n )}\n {!hasItems ? (\n <div className=\"border-border bg-muted flex items-center justify-center rounded-md border-2 border-dashed py-12 text-center\">\n <p className=\"text-muted\">No items to display</p>\n </div>\n ) : shouldShowFeaturedSection ? (\n <div className=\"flex flex-col gap-4 @lg:flex-row @lg:gap-6\">\n <div className=\"w-full @lg:w-[45%]\">\n <FeaturedSection\n borderRadius={borderRadius}\n titleSize={titleSize}\n featuredTitle={featuredTitle}\n featuredSubtitle={featuredSubtitle}\n featuredButtonText={featuredButtonText}\n featuredButtonUrl={featuredButtonUrl}\n featuredSubtitleColor={featuredSubtitleColor}\n featuredSubtitleSize={featuredSubtitleSize}\n asset={hasFeaturedAsset!}\n />\n </div>\n <div className=\"w-full @lg:w-[55%]\">\n {listType === \"unordered\" ? (\n <UnorderedList\n items={displayItems}\n columns={columns}\n {...itemStyleProps}\n />\n ) : (\n <OrderedList\n items={displayItems}\n scrollAxis={scrollAxis}\n numberColor={numberColor}\n numberSize={numberSize}\n {...itemStyleProps}\n />\n )}\n </div>\n </div>\n ) : listType === \"unordered\" ? (\n <UnorderedList\n items={displayItems}\n columns={columns}\n {...itemStyleProps}\n />\n ) : (\n <OrderedList\n items={displayItems}\n scrollAxis={scrollAxis}\n numberColor={numberColor}\n numberSize={numberSize}\n {...itemStyleProps}\n />\n )}\n </div>\n );\n}\n\nexport const listWidgetPropertySchema: WidgetPropertySchema = {\n widgetType: \"ListWidget\",\n displayName: \"List\",\n tabsConfig: [\n { id: \"styling\", label: \"Styling\" },\n { id: \"data\", label: \"Data\" },\n ],\n dataSourceTargetProps: [\"items\"],\n fields: [\n // Styling tab - Title group\n {\n key: \"titleEnabled\",\n label: \"Widget Title\",\n type: \"boolean\",\n description: \"Enable the title displayed above the list\",\n defaultValue: true,\n tab: \"styling\",\n group: \"Title\",\n },\n {\n key: \"title\",\n label: \"Title\",\n type: \"text\",\n description: \"Header text for the list\",\n defaultValue: \"List\",\n tab: \"styling\",\n group: \"Title\",\n requiresKeyToBeTrue: \"titleEnabled\",\n },\n getFontSizeField({\n key: \"titleSize\",\n label: \"Title Font Size\",\n description: \"Size of the list title\",\n defaultValue: \"xl\",\n tab: \"styling\",\n group: \"Title\",\n requiresKeyToBeTrue: \"titleEnabled\",\n }),\n getColorField({\n key: \"titleColor\",\n label: \"Title Color\",\n description: \"Color for the list title\",\n defaultValue: \"foreground\",\n tab: \"styling\",\n group: \"Title\",\n requiresKeyToBeTrue: \"titleEnabled\",\n }),\n\n // Styling tab - Design group\n getPaddingField({\n key: \"padding\",\n label: \"Padding\",\n description: \"Padding inside the container\",\n defaultValue: 4,\n tab: \"styling\",\n group: \"Design\",\n }),\n getBorderRadiusField({\n key: \"borderRadius\",\n label: \"Border Radius\",\n description: \"Rounded corners for the container and images\",\n defaultValue: \"md\",\n tab: \"styling\",\n group: \"Design\",\n }),\n getGapField({\n key: \"gap\",\n label: \"Gap\",\n description: \"Spacing between items\",\n defaultValue: \"md\",\n tab: \"styling\",\n group: \"Design\",\n }),\n {\n type: \"background\",\n defaultValue: \"background\",\n key: \"background\",\n label: \"Background\",\n description: \"Background color or image for the widget\",\n tab: \"styling\",\n group: \"Design\",\n },\n\n // Styling tab - List Configuration group\n {\n key: \"listType\",\n label: \"List Type\",\n type: \"select\",\n description: \"Type of list layout\",\n defaultValue: \"unordered\",\n options: [\n { label: \"Unordered (Grid)\", value: \"unordered\" },\n { label: \"Ordered (Numbered)\", value: \"ordered\" },\n ],\n tab: \"styling\",\n group: \"List Configuration\",\n },\n {\n key: \"maxItems\",\n label: \"Max Items\",\n type: \"number\",\n description: \"Maximum number of items to display\",\n min: 1,\n max: 100,\n step: 1,\n defaultValue: 12,\n tab: \"styling\",\n group: \"List Configuration\",\n },\n {\n key: \"imageAspectRatio\",\n label: \"Image Aspect Ratio\",\n type: \"buttonGroup\",\n description: \"Aspect ratio for item images\",\n defaultValue: \"square\",\n options: [\n { label: \"Square\", value: \"square\" },\n { label: \"Landscape\", value: \"landscape\" },\n { label: \"Portrait\", value: \"portrait\" },\n ],\n tab: \"styling\",\n group: \"List Configuration\",\n },\n {\n key: \"showBadge\",\n label: \"Show Discount Badge\",\n type: \"boolean\",\n description: \"Display discount badge on images\",\n defaultValue: true,\n tab: \"styling\",\n group: \"List Configuration\",\n },\n {\n key: \"showMetaText\",\n label: \"Show QV/CV Text\",\n type: \"boolean\",\n description: \"Display QV and CV values\",\n defaultValue: true,\n tab: \"styling\",\n group: \"List Configuration\",\n },\n\n // Styling tab - Unordered List Configuration\n {\n key: \"columns\",\n label: \"Grid Columns\",\n type: \"number\",\n description: \"Number of columns in the grid (unordered list only)\",\n min: 1,\n max: 6,\n step: 1,\n defaultValue: 3,\n tab: \"styling\",\n group: \"Unordered List Configuration\",\n requiresKeyValue: { key: \"listType\", value: \"unordered\" },\n },\n\n // Styling tab - Ordered List Configuration\n {\n key: \"scrollAxis\",\n label: \"Scroll Direction\",\n type: \"select\",\n description: \"Direction for ordered list scrolling\",\n defaultValue: \"horizontal\",\n options: [\n { label: \"Horizontal\", value: \"horizontal\" },\n { label: \"Vertical\", value: \"vertical\" },\n ],\n tab: \"styling\",\n group: \"Ordered List Configuration\",\n requiresKeyValue: { key: \"listType\", value: \"ordered\" },\n },\n getColorField({\n key: \"numberColor\",\n label: \"Number Color\",\n description: \"Color for ordered list numbers\",\n defaultValue: \"primary\",\n tab: \"styling\",\n group: \"Ordered List Configuration\",\n requiresKeyValue: { key: \"listType\", value: \"ordered\" },\n }),\n getFontSizeField({\n key: \"numberSize\",\n label: \"Number Font Size\",\n description: \"Size of ordered list numbers\",\n defaultValue: \"2xl\",\n tab: \"styling\",\n group: \"Ordered List Configuration\",\n requiresKeyValue: { key: \"listType\", value: \"ordered\" },\n }),\n\n // Styling tab - Item Styling group\n getColorField({\n key: \"itemTitleColor\",\n label: \"Item Title Color\",\n description: \"Color for item titles\",\n defaultValue: \"foreground\",\n tab: \"styling\",\n group: \"Item Styling\",\n }),\n getFontSizeField({\n key: \"itemTitleSize\",\n label: \"Item Title Font Size\",\n description: \"Size of item titles\",\n defaultValue: \"sm\",\n tab: \"styling\",\n group: \"Item Styling\",\n }),\n {\n key: \"separator2\",\n type: \"separator\",\n label: \"Separator\",\n tab: \"styling\",\n group: \"Item Styling\",\n },\n getColorField({\n key: \"descriptionColor\",\n label: \"Description Color\",\n description: \"Color for descriptions\",\n defaultValue: \"foreground\",\n tab: \"styling\",\n group: \"Item Styling\",\n }),\n getFontSizeField({\n key: \"descriptionSize\",\n label: \"Description Font Size\",\n description: \"Size of descriptions\",\n defaultValue: \"sm\",\n tab: \"styling\",\n group: \"Item Styling\",\n }),\n {\n key: \"separator3\",\n type: \"separator\",\n label: \"Separator\",\n tab: \"styling\",\n group: \"Item Styling\",\n },\n getColorField({\n key: \"priceColor\",\n label: \"Price Color\",\n description: \"Color for prices\",\n defaultValue: \"foreground\",\n tab: \"styling\",\n group: \"Item Styling\",\n }),\n getFontSizeField({\n key: \"priceSize\",\n label: \"Price Font Size\",\n description: \"Size of prices\",\n defaultValue: \"md\",\n tab: \"styling\",\n group: \"Item Styling\",\n }),\n getColorField({\n key: \"originalPriceColor\",\n label: \"Original Price Color\",\n description: \"Color for crossed-out original prices\",\n defaultValue: \"foreground\",\n tab: \"styling\",\n group: \"Item Styling\",\n }),\n {\n key: \"separator4\",\n type: \"separator\",\n label: \"Separator\",\n tab: \"styling\",\n group: \"Item Styling\",\n },\n getColorField({\n key: \"metaTextColor\",\n label: \"Meta Text Color\",\n description: \"Color for QV/CV text\",\n defaultValue: \"foreground\",\n tab: \"styling\",\n group: \"Item Styling\",\n }),\n getFontSizeField({\n key: \"metaTextSize\",\n label: \"Meta Text Font Size\",\n description: \"Size of QV/CV text\",\n defaultValue: \"xs\",\n tab: \"styling\",\n group: \"Item Styling\",\n }),\n\n // Styling tab - Featured Section group\n {\n key: \"showFeaturedSection\",\n label: \"Show Featured Section\",\n type: \"boolean\",\n description: \"Display a featured content section\",\n defaultValue: false,\n tab: \"styling\",\n group: \"Featured Section\",\n },\n {\n key: \"featuredAsset\",\n label: \"Featured Asset\",\n type: \"resource\",\n description:\n \"Select a single image or video resource for the featured section\",\n tab: \"styling\",\n group: \"Featured Section\",\n allowedTypes: [\"Medium\"],\n requiresKeyToBeTrue: \"showFeaturedSection\",\n },\n {\n key: \"featuredTitle\",\n label: \"Featured Title\",\n type: \"text\",\n description: \"Title for featured section\",\n tab: \"styling\",\n group: \"Featured Section\",\n requiresKeyToBeTrue: \"showFeaturedSection\",\n },\n {\n key: \"featuredSubtitle\",\n label: \"Featured Subtitle\",\n type: \"text\",\n description: \"Subtitle for featured section\",\n tab: \"styling\",\n group: \"Featured Section\",\n requiresKeyToBeTrue: \"showFeaturedSection\",\n },\n {\n key: \"featuredButtonText\",\n label: \"Featured Button Text\",\n type: \"text\",\n description: \"Text for featured section button\",\n tab: \"styling\",\n group: \"Featured Section\",\n requiresKeyToBeTrue: \"showFeaturedSection\",\n },\n {\n key: \"featuredButtonUrl\",\n label: \"Featured Button URL\",\n type: \"text\",\n description: \"URL for featured section button\",\n tab: \"styling\",\n group: \"Featured Section\",\n requiresKeyToBeTrue: \"showFeaturedSection\",\n },\n getColorField({\n key: \"featuredSubtitleColor\",\n label: \"Featured Subtitle Color\",\n description: \"Color for featured subtitle\",\n defaultValue: \"background\",\n tab: \"styling\",\n group: \"Featured Section\",\n requiresKeyToBeTrue: \"showFeaturedSection\",\n }),\n getFontSizeField({\n key: \"featuredSubtitleSize\",\n label: \"Featured Subtitle Font Size\",\n description: \"Size of featured subtitle\",\n defaultValue: \"md\",\n tab: \"styling\",\n group: \"Featured Section\",\n requiresKeyToBeTrue: \"showFeaturedSection\",\n }),\n\n // Data tab - Data Configuration\n {\n key: \"dataSource\",\n label: \"Data Source\",\n type: \"dataSource\",\n description: \"\",\n tab: \"data\",\n group: \"Data Configuration\",\n },\n ],\n itemConfigSchema: {\n description: \"Configure settings for this list item\",\n fields: [\n {\n key: \"title\",\n label: \"Custom Title\",\n type: \"text\",\n description: \"Override the item's title\",\n },\n {\n key: \"description\",\n label: \"Custom Description\",\n type: \"textarea\",\n description: \"Override the item's description\",\n rows: 3,\n },\n {\n key: \"price\",\n label: \"Price\",\n type: \"text\",\n description: \"Current price\",\n },\n {\n key: \"originalPrice\",\n label: \"Original Price\",\n type: \"text\",\n description: \"Original price (will be crossed out)\",\n },\n {\n key: \"discount\",\n label: \"Discount Badge\",\n type: \"text\",\n description: \"Discount text (e.g., '40% Off')\",\n },\n {\n key: \"qv\",\n label: \"QV Value\",\n type: \"text\",\n description: \"Qualifying Volume value\",\n },\n {\n key: \"cv\",\n label: \"CV Value\",\n type: \"text\",\n description: \"Commission Volume value\",\n },\n {\n key: \"image\",\n label: \"Image URL\",\n type: \"text\",\n description: \"Custom image URL for this item\",\n },\n ],\n },\n} as const satisfies WidgetPropertySchema;\n"],"mappings":"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ACL,OAAO;GACR,CAAC;0DACe;GACf,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACF;GACE,KAAK;GACL,MAAM;GACN,OAAO;GACP,KAAK;GACL,OAAO;GACR;uDACa;GACZ,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;0DACe;GACf,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;uDACY;GACZ,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACF;GACE,KAAK;GACL,MAAM;GACN,OAAO;GACP,KAAK;GACL,OAAO;GACR;uDACa;GACZ,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;0DACe;GACf,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EAGF;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aACE;GACF,KAAK;GACL,OAAO;GACP,cAAc,CAAC,SAAS;GACxB,qBAAqB;GACtB;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,KAAK;GACL,OAAO;GACP,qBAAqB;GACtB;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,KAAK;GACL,OAAO;GACP,qBAAqB;GACtB;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,KAAK;GACL,OAAO;GACP,qBAAqB;GACtB;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,KAAK;GACL,OAAO;GACP,qBAAqB;GACtB;uDACa;GACZ,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACP,qBAAqB;GACtB,CAAC;0DACe;GACf,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACP,qBAAqB;GACtB,CAAC;EAGF;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,KAAK;GACL,OAAO;GACR;EACF;CACD,kBAAkB;EAChB,aAAa;EACb,QAAQ;GACN;IACE,KAAK;IACL,OAAO;IACP,MAAM;IACN,aAAa;IACd;GACD;IACE,KAAK;IACL,OAAO;IACP,MAAM;IACN,aAAa;IACb,MAAM;IACP;GACD;IACE,KAAK;IACL,OAAO;IACP,MAAM;IACN,aAAa;IACd;GACD;IACE,KAAK;IACL,OAAO;IACP,MAAM;IACN,aAAa;IACd;GACD;IACE,KAAK;IACL,OAAO;IACP,MAAM;IACN,aAAa;IACd;GACD;IACE,KAAK;IACL,OAAO;IACP,MAAM;IACN,aAAa;IACd;GACD;IACE,KAAK;IACL,OAAO;IACP,MAAM;IACN,aAAa;IACd;GACD;IACE,KAAK;IACL,OAAO;IACP,MAAM;IACN,aAAa;IACd;GACF;EACF;CACF"}
@@ -2,6 +2,7 @@ import { t as __exportAll } from "./rolldown-runtime-wcPFST8Q.mjs";
2
2
  import { a as getFontSizeField, c as getPaddingField, i as getColorField, n as getBorderRadiusField, o as getGapField, t as gapValues } from "./fields-wPOk-SmZ.mjs";
3
3
  import { t as ScrollArrows } from "./scroll-arrows-BevCYRNT.mjs";
4
4
  import { t as MediaRenderer } from "./MediaRenderer-Uq90PZcY.mjs";
5
+ import { n as useWidgetInteraction } from "./WidgetInteractionContext-awLrJeAK.mjs";
5
6
  import { jsx, jsxs } from "react/jsx-runtime";
6
7
  import { useRef } from "react";
7
8
  import DOMPurify from "dompurify";
@@ -134,23 +135,6 @@ function DiscountBadge({ discount }) {
134
135
  children: getStringValue(discount)
135
136
  });
136
137
  }
137
- function FavoriteButton({ className }) {
138
- return /* @__PURE__ */ jsx("button", {
139
- className: className || "bg-background/80 hover:bg-background absolute top-2 left-2 z-10 rounded-full p-2 backdrop-blur-sm transition-colors",
140
- children: /* @__PURE__ */ jsx("svg", {
141
- className: "text-muted-foreground h-5 w-5",
142
- fill: "none",
143
- stroke: "currentColor",
144
- viewBox: "0 0 24 24",
145
- children: /* @__PURE__ */ jsx("path", {
146
- strokeLinecap: "round",
147
- strokeLinejoin: "round",
148
- strokeWidth: 2,
149
- d: "M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"
150
- })
151
- })
152
- });
153
- }
154
138
  //#endregion
155
139
  //#region src/widgets/list-widget/UnorderedList.tsx
156
140
  const getImageUrl$1 = (item) => {
@@ -173,17 +157,29 @@ const getResponsiveGridClass = (columns) => {
173
157
  6: "grid-cols-2 @lg:grid-cols-6"
174
158
  }[columns] || "grid-cols-2 @lg:grid-cols-3";
175
159
  };
176
- function UnorderedList({ items, columns, gap, borderRadius, imageAspectRatio, showBadge, showFavorite, padding, itemTitleColor, itemTitleSize, descriptionColor, descriptionSize, priceColor, priceSize, originalPriceColor, metaTextColor, metaTextSize, showMetaText }) {
160
+ function UnorderedList({ items, columns, gap, borderRadius, imageAspectRatio, showBadge, padding, itemTitleColor, itemTitleSize, descriptionColor, descriptionSize, priceColor, priceSize, originalPriceColor, metaTextColor, metaTextSize, showMetaText }) {
161
+ const gridClass = getResponsiveGridClass(columns);
162
+ const { onItemClick } = useWidgetInteraction();
177
163
  return /* @__PURE__ */ jsx("div", {
178
- className: `grid ${getResponsiveGridClass(columns)} gap-${gapValues[gap]}`,
164
+ className: `grid ${gridClass} gap-${gapValues[gap]}`,
179
165
  children: items.map((item) => {
180
166
  const imageUrl = getImageUrl$1(item);
181
167
  const aspectRatioClass = getAspectRatioClass$1(imageAspectRatio);
182
168
  return /* @__PURE__ */ jsxs("div", {
183
- className: `relative rounded-${borderRadius} bg-background overflow-hidden shadow-sm transition-shadow hover:shadow-md`,
169
+ className: `relative rounded-${borderRadius} bg-background overflow-hidden shadow-sm transition-shadow hover:shadow-md ${onItemClick ? "cursor-pointer" : ""}`,
170
+ ...onItemClick ? {
171
+ role: "button",
172
+ tabIndex: 0,
173
+ onClick: () => onItemClick(item),
174
+ onKeyDown: (e) => {
175
+ if (e.key === "Enter" || e.key === " ") {
176
+ e.preventDefault();
177
+ onItemClick(item);
178
+ }
179
+ }
180
+ } : {},
184
181
  children: [
185
182
  showBadge && item.discount && /* @__PURE__ */ jsx(DiscountBadge, { discount: item.discount }),
186
- showFavorite && /* @__PURE__ */ jsx(FavoriteButton, {}),
187
183
  imageUrl && /* @__PURE__ */ jsx("div", {
188
184
  className: `w-full ${aspectRatioClass} overflow-hidden`,
189
185
  children: /* @__PURE__ */ jsx("img", {
@@ -232,7 +228,7 @@ const largeNumberSizes = {
232
228
  xl: "16rem",
233
229
  "2xl": "20rem"
234
230
  };
235
- function OrderedList({ items, scrollAxis, gap, borderRadius, imageAspectRatio, showBadge, showFavorite, padding, itemTitleColor, itemTitleSize, descriptionColor, descriptionSize, priceColor, priceSize, originalPriceColor, metaTextColor, metaTextSize, numberColor, numberSize, showMetaText }) {
231
+ function OrderedList({ items, scrollAxis, gap, borderRadius, imageAspectRatio, showBadge, padding, itemTitleColor, itemTitleSize, descriptionColor, descriptionSize, priceColor, priceSize, originalPriceColor, metaTextColor, metaTextSize, numberColor, numberSize, showMetaText }) {
236
232
  const scrollContainerRef = useRef(null);
237
233
  const scrollByAmount = (direction) => {
238
234
  const container = scrollContainerRef.current;
@@ -243,6 +239,18 @@ function OrderedList({ items, scrollAxis, gap, borderRadius, imageAspectRatio, s
243
239
  behavior: "smooth"
244
240
  });
245
241
  };
242
+ const { onItemClick } = useWidgetInteraction();
243
+ const interactionProps = (item) => onItemClick ? {
244
+ role: "button",
245
+ tabIndex: 0,
246
+ onClick: () => onItemClick(item),
247
+ onKeyDown: (e) => {
248
+ if (e.key === "Enter" || e.key === " ") {
249
+ e.preventDefault();
250
+ onItemClick(item);
251
+ }
252
+ }
253
+ } : {};
246
254
  const contentProps = {
247
255
  padding,
248
256
  itemTitleColor,
@@ -265,7 +273,8 @@ function OrderedList({ items, scrollAxis, gap, borderRadius, imageAspectRatio, s
265
273
  const imageUrl = getImageUrl(item);
266
274
  const aspectRatioClass = getAspectRatioClass(imageAspectRatio);
267
275
  return /* @__PURE__ */ jsxs("div", {
268
- className: "relative w-[300px] flex-shrink-0",
276
+ className: `relative w-[300px] flex-shrink-0 ${onItemClick ? "cursor-pointer" : ""}`,
277
+ ...interactionProps(item),
269
278
  children: [/* @__PURE__ */ jsx("div", {
270
279
  className: `absolute top-0 left-0 text-${numberColor} z-0 leading-none font-bold opacity-20`,
271
280
  style: { fontSize: largeNumberSizes[numberSize] },
@@ -274,7 +283,6 @@ function OrderedList({ items, scrollAxis, gap, borderRadius, imageAspectRatio, s
274
283
  className: `relative z-10 ml-20 rounded-${borderRadius} bg-background overflow-hidden shadow-sm transition-shadow hover:shadow-md`,
275
284
  children: [
276
285
  showBadge && item.discount && /* @__PURE__ */ jsx(DiscountBadge, { discount: item.discount }),
277
- showFavorite && /* @__PURE__ */ jsx(FavoriteButton, {}),
278
286
  imageUrl && /* @__PURE__ */ jsx("div", {
279
287
  className: `w-full ${aspectRatioClass} overflow-hidden`,
280
288
  children: /* @__PURE__ */ jsx("img", {
@@ -304,7 +312,8 @@ function OrderedList({ items, scrollAxis, gap, borderRadius, imageAspectRatio, s
304
312
  children: items.map((item, index) => {
305
313
  const imageUrl = getImageUrl(item);
306
314
  return /* @__PURE__ */ jsxs("div", {
307
- className: `relative flex gap-${gapValues[gap]} rounded-${borderRadius} bg-background overflow-hidden shadow-sm transition-shadow hover:shadow-md ${`p-${padding}`}`,
315
+ className: `relative flex gap-${gapValues[gap]} rounded-${borderRadius} bg-background overflow-hidden shadow-sm transition-shadow hover:shadow-md ${`p-${padding}`} ${onItemClick ? "cursor-pointer" : ""}`,
316
+ ...interactionProps(item),
308
317
  children: [
309
318
  /* @__PURE__ */ jsx("div", {
310
319
  className: `flex-shrink-0 text-${numberColor} text-${numberSize === "md" ? "base" : numberSize} flex w-16 items-center justify-center font-bold`,
@@ -328,8 +337,7 @@ function OrderedList({ items, scrollAxis, gap, borderRadius, imageAspectRatio, s
328
337
  showBadge && item.discount && /* @__PURE__ */ jsx("div", {
329
338
  className: "bg-destructive text-destructive-foreground absolute top-2 right-2 rounded-md px-2 py-1 text-xs font-bold",
330
339
  children: getStringValue(item.discount)
331
- }),
332
- showFavorite && /* @__PURE__ */ jsx(FavoriteButton, { className: "bg-background/80 hover:bg-background absolute top-2 right-12 rounded-full p-2 backdrop-blur-sm transition-colors" })
340
+ })
333
341
  ]
334
342
  }, item.id);
335
343
  })
@@ -365,7 +373,7 @@ function getFeaturedAssetUrl(value) {
365
373
  function ListWidget({ listType = "unordered", scrollAxis = "horizontal", titleEnabled = true, title, items = DEFAULT_ITEMS, titleColor = "foreground", titleSize = "lg", itemTitleColor = "foreground", itemTitleSize = "sm", descriptionColor = "foreground", descriptionSize = "sm", priceColor = "foreground", priceSize = "md", originalPriceColor = "muted", metaTextColor = "muted", metaTextSize = "xs", numberColor = "primary", numberSize = "2xl", borderRadius = "md", padding = 4, gap = "md", columns = 3, imageAspectRatio = "square", background = {
366
374
  type: "solid",
367
375
  color: "background"
368
- }, showBadge = true, showFavorite = true, showMetaText = true, maxItems = 12, showFeaturedSection = false, featuredAsset, featuredTitle, featuredSubtitle, featuredButtonText, featuredButtonUrl, featuredSubtitleColor = "background", featuredSubtitleSize = "md", className, ...props }) {
376
+ }, showBadge = true, showMetaText = true, maxItems = 12, showFeaturedSection = false, featuredAsset, featuredTitle, featuredSubtitle, featuredButtonText, featuredButtonUrl, featuredSubtitleColor = "background", featuredSubtitleSize = "md", className, ...props }) {
369
377
  const displayItems = maxItems ? items.slice(0, maxItems) : items;
370
378
  const hasItems = displayItems.length > 0;
371
379
  const itemStyleProps = {
@@ -381,7 +389,6 @@ function ListWidget({ listType = "unordered", scrollAxis = "horizontal", titleEn
381
389
  metaTextSize,
382
390
  showMetaText,
383
391
  showBadge,
384
- showFavorite,
385
392
  borderRadius,
386
393
  imageAspectRatio,
387
394
  gap
@@ -587,15 +594,6 @@ const listWidgetPropertySchema = {
587
594
  tab: "styling",
588
595
  group: "List Configuration"
589
596
  },
590
- {
591
- key: "showFavorite",
592
- label: "Show Favorite Icon",
593
- type: "boolean",
594
- description: "Display favorite/heart icon on images",
595
- defaultValue: true,
596
- tab: "styling",
597
- group: "List Configuration"
598
- },
599
597
  {
600
598
  key: "showMetaText",
601
599
  label: "Show QV/CV Text",
@@ -898,4 +896,4 @@ const listWidgetPropertySchema = {
898
896
  //#endregion
899
897
  export { ListWidget_exports as n, listWidgetPropertySchema as r, ListWidget as t };
900
898
 
901
- //# sourceMappingURL=ListWidget-C-jcsCb4.mjs.map
899
+ //# sourceMappingURL=ListWidget-DdvuIQXy.mjs.map