@fluid-app/portal-sdk 0.1.259 → 0.1.261
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/{AlertWidget-CcIBGBik.mjs → AlertWidget-Bua0I46v.mjs} +2 -2
- package/dist/{AlertWidget-CcIBGBik.mjs.map → AlertWidget-Bua0I46v.mjs.map} +1 -1
- package/dist/{AlertWidget-BZ67Uqfh.cjs → AlertWidget-ByokSA3K.cjs} +2 -2
- package/dist/{AlertWidget-BZ67Uqfh.cjs.map → AlertWidget-ByokSA3K.cjs.map} +1 -1
- package/dist/{BulletListWidget-iGJI33Ed.cjs → BulletListWidget-BwrMNPZ-.cjs} +2 -2
- package/dist/{BulletListWidget-iGJI33Ed.cjs.map → BulletListWidget-BwrMNPZ-.cjs.map} +1 -1
- package/dist/{BulletListWidget-mRwUgtzN.mjs → BulletListWidget-DvT2x5wg.mjs} +2 -2
- package/dist/{BulletListWidget-mRwUgtzN.mjs.map → BulletListWidget-DvT2x5wg.mjs.map} +1 -1
- package/dist/{CalendarWidget-ByY49yYX.mjs → CalendarWidget-BB1C5K_j.mjs} +2 -2
- package/dist/{CalendarWidget-ByY49yYX.mjs.map → CalendarWidget-BB1C5K_j.mjs.map} +1 -1
- package/dist/{CalendarWidget-CSipLdwg.cjs → CalendarWidget-MVJmxwFQ.cjs} +2 -2
- package/dist/{CalendarWidget-CSipLdwg.cjs.map → CalendarWidget-MVJmxwFQ.cjs.map} +1 -1
- package/dist/{CardWidget-CXsjl-Is.cjs → CardWidget-5hGl1bt9.cjs} +2 -2
- package/dist/{CardWidget-DK4VQau1.mjs → CardWidget-CEERBKUN.mjs} +2 -2
- package/dist/{CardWidget-DK4VQau1.mjs.map → CardWidget-CEERBKUN.mjs.map} +1 -1
- package/dist/{CardWidget-DovkTkKg.cjs → CardWidget-Cf4-dF-v.cjs} +2 -2
- package/dist/{CardWidget-DovkTkKg.cjs.map → CardWidget-Cf4-dF-v.cjs.map} +1 -1
- package/dist/{CarouselWidget-Cu1b3ERq.cjs → CarouselWidget-BJSO17JY.cjs} +2 -2
- package/dist/{CarouselWidget-Cu1b3ERq.cjs.map → CarouselWidget-BJSO17JY.cjs.map} +1 -1
- package/dist/{CarouselWidget-C0X-nFyW.mjs → CarouselWidget-Dhjf60LS.mjs} +2 -2
- package/dist/{CarouselWidget-C0X-nFyW.mjs.map → CarouselWidget-Dhjf60LS.mjs.map} +1 -1
- package/dist/{CatchUpWidget-C17xpj3Z.cjs → CatchUpWidget-CFF-Fgdo.cjs} +2 -2
- package/dist/{CatchUpWidget-C17xpj3Z.cjs.map → CatchUpWidget-CFF-Fgdo.cjs.map} +1 -1
- package/dist/{CatchUpWidget-Bj30ZbUk.mjs → CatchUpWidget-CM-iCMhK.mjs} +2 -2
- package/dist/{CatchUpWidget-Bj30ZbUk.mjs.map → CatchUpWidget-CM-iCMhK.mjs.map} +1 -1
- package/dist/{ChartWidget-Brxz8j4Q.cjs → ChartWidget-6nZLzlQM.cjs} +2 -2
- package/dist/{ChartWidget-Brxz8j4Q.cjs.map → ChartWidget-6nZLzlQM.cjs.map} +1 -1
- package/dist/{ChartWidget-CIscUHUD.mjs → ChartWidget-CJXZ9qf7.mjs} +2 -2
- package/dist/{ChartWidget-CIscUHUD.mjs.map → ChartWidget-CJXZ9qf7.mjs.map} +1 -1
- package/dist/{ChartWidget-CNhmJePK.cjs → ChartWidget-WXGJeXdl.cjs} +2 -2
- package/dist/{ContainerWidget-YMePQ1FG.mjs → ContainerWidget-2Rep2gGz.mjs} +3 -3
- package/dist/{ContainerWidget-YMePQ1FG.mjs.map → ContainerWidget-2Rep2gGz.mjs.map} +1 -1
- package/dist/{ContainerWidget-D5rr47AN.cjs → ContainerWidget-CpIynF1n.cjs} +3 -3
- package/dist/{ContainerWidget-wtuUrr1c.cjs → ContainerWidget-DX9qO1T-.cjs} +3 -3
- package/dist/{ContainerWidget-wtuUrr1c.cjs.map → ContainerWidget-DX9qO1T-.cjs.map} +1 -1
- package/dist/{EmbedWidget-DE1yhLR1.mjs → EmbedWidget-Czn_RJbm.mjs} +2 -2
- package/dist/{EmbedWidget-DE1yhLR1.mjs.map → EmbedWidget-Czn_RJbm.mjs.map} +1 -1
- package/dist/{EmbedWidget-BO0TonyK.cjs → EmbedWidget-DFlg5AI7.cjs} +2 -2
- package/dist/{EmbedWidget-BO0TonyK.cjs.map → EmbedWidget-DFlg5AI7.cjs.map} +1 -1
- package/dist/{FluidProvider-CDNk3Ssn.mjs → FluidProvider-C0YKxODs.mjs} +49 -49
- package/dist/{FluidProvider-CDNk3Ssn.mjs.map → FluidProvider-C0YKxODs.mjs.map} +1 -1
- package/dist/{FluidProvider-P_MBgI-c.cjs → FluidProvider-CoSgK0jL.cjs} +49 -49
- package/dist/{FluidProvider-P_MBgI-c.cjs.map → FluidProvider-CoSgK0jL.cjs.map} +1 -1
- package/dist/{ImageWidget-DmaAQZBK.mjs → ImageWidget--WJppfij.mjs} +2 -2
- package/dist/{ImageWidget-DmaAQZBK.mjs.map → ImageWidget--WJppfij.mjs.map} +1 -1
- package/dist/{ImageWidget-CbQVxMe3.cjs → ImageWidget-CU2cet5p.cjs} +2 -2
- package/dist/{ImageWidget-CbQVxMe3.cjs.map → ImageWidget-CU2cet5p.cjs.map} +1 -1
- package/dist/{LayoutWidget-BK8AxE60.cjs → LayoutWidget-8DwDBW24.cjs} +2 -2
- package/dist/{LayoutWidget-BK8AxE60.cjs.map → LayoutWidget-8DwDBW24.cjs.map} +1 -1
- package/dist/{LayoutWidget-K2iF13-C.cjs → LayoutWidget-CUjv-pB1.cjs} +2 -2
- package/dist/{LayoutWidget-8KxCmJcd.mjs → LayoutWidget-iKNNIRPq.mjs} +2 -2
- package/dist/{LayoutWidget-8KxCmJcd.mjs.map → LayoutWidget-iKNNIRPq.mjs.map} +1 -1
- package/dist/{LinkWidget-Dvb6WlaR.mjs → LinkWidget-BoVmB_zf.mjs} +2 -2
- package/dist/{LinkWidget-Dvb6WlaR.mjs.map → LinkWidget-BoVmB_zf.mjs.map} +1 -1
- package/dist/{LinkWidget-DnAGzdnF.cjs → LinkWidget-BzgMcUuV.cjs} +2 -2
- package/dist/{LinkWidget-88wWH7-i.cjs → LinkWidget-DpylGthu.cjs} +2 -2
- package/dist/{LinkWidget-88wWH7-i.cjs.map → LinkWidget-DpylGthu.cjs.map} +1 -1
- package/dist/{ListWidget-xetptWnX.cjs → ListWidget-CQgei8SF.cjs} +2 -2
- package/dist/{ListWidget-xetptWnX.cjs.map → ListWidget-CQgei8SF.cjs.map} +1 -1
- package/dist/{ListWidget-Bsi4jdcz.mjs → ListWidget-CuwsaMQ9.mjs} +2 -2
- package/dist/{ListWidget-Bsi4jdcz.mjs.map → ListWidget-CuwsaMQ9.mjs.map} +1 -1
- package/dist/{ListWidget-BzuYuJkf.cjs → ListWidget-TXPwy2v6.cjs} +2 -2
- package/dist/MessagingScreen-CKIs5m0_.cjs +48 -0
- package/dist/{MessagingScreen-SQXX6kkC.mjs → MessagingScreen-Ck6c7BK3.mjs} +2 -2
- package/dist/{MessagingScreen-SQXX6kkC.mjs.map → MessagingScreen-Ck6c7BK3.mjs.map} +1 -1
- package/dist/MessagingScreen-DgS_ZEzO.mjs +46 -0
- package/dist/{MessagingScreen-CsZsCnnX.cjs → MessagingScreen-ga_zEAeB.cjs} +2 -2
- package/dist/{MessagingScreen-CsZsCnnX.cjs.map → MessagingScreen-ga_zEAeB.cjs.map} +1 -1
- package/dist/{MySiteWidget-DXY59o3T.cjs → MySiteWidget-BziY8ylH.cjs} +2 -2
- package/dist/{MySiteWidget-DXY59o3T.cjs.map → MySiteWidget-BziY8ylH.cjs.map} +1 -1
- package/dist/{MySiteWidget-8XrZA0Un.mjs → MySiteWidget-CsJzjc7o.mjs} +2 -2
- package/dist/{MySiteWidget-8XrZA0Un.mjs.map → MySiteWidget-CsJzjc7o.mjs.map} +1 -1
- package/dist/{NestedWidget-CSA2gUPx.cjs → NestedWidget-B1Rwz6nb.cjs} +2 -2
- package/dist/{NestedWidget-B8lW9Fzv.mjs → NestedWidget-DrZ62oaO.mjs} +2 -2
- package/dist/{NestedWidget-B8lW9Fzv.mjs.map → NestedWidget-DrZ62oaO.mjs.map} +1 -1
- package/dist/{NestedWidget-C2D4eWqb.cjs → NestedWidget-vrohV65N.cjs} +2 -2
- package/dist/{NestedWidget-C2D4eWqb.cjs.map → NestedWidget-vrohV65N.cjs.map} +1 -1
- package/dist/{PointsWidget-ComTSNQZ.cjs → PointsWidget-DI3N8-6W.cjs} +2 -2
- package/dist/{PointsWidget-ComTSNQZ.cjs.map → PointsWidget-DI3N8-6W.cjs.map} +1 -1
- package/dist/{PointsWidget-CRvG5LOV.mjs → PointsWidget-ubAn0b-m.mjs} +2 -2
- package/dist/{PointsWidget-CRvG5LOV.mjs.map → PointsWidget-ubAn0b-m.mjs.map} +1 -1
- package/dist/ProfileScreen-90-Jf8IH.mjs +46 -0
- package/dist/ProfileScreen-B7sbMdbH.cjs +48 -0
- package/dist/{ProfileScreen-C6Z8g6-L.cjs → ProfileScreen-DYO-1rw4.cjs} +2 -2
- package/dist/{ProfileScreen-C6Z8g6-L.cjs.map → ProfileScreen-DYO-1rw4.cjs.map} +1 -1
- package/dist/{ProfileScreen-C45yTIj-.mjs → ProfileScreen-FG1DZum3.mjs} +2 -2
- package/dist/{ProfileScreen-C45yTIj-.mjs.map → ProfileScreen-FG1DZum3.mjs.map} +1 -1
- package/dist/{QuickLinksWidget-Bcl4CxfW.cjs → QuickLinksWidget-Cpq1V-uX.cjs} +2 -2
- package/dist/{QuickLinksWidget-Bcl4CxfW.cjs.map → QuickLinksWidget-Cpq1V-uX.cjs.map} +1 -1
- package/dist/{QuickLinksWidget-roBJQ1Ge.mjs → QuickLinksWidget-J5axodVF.mjs} +2 -2
- package/dist/{QuickLinksWidget-roBJQ1Ge.mjs.map → QuickLinksWidget-J5axodVF.mjs.map} +1 -1
- package/dist/{QuickShareWidget-D_Ghjgwz.cjs → QuickShareWidget-CYPOXs8X.cjs} +2 -2
- package/dist/{QuickShareWidget-D_Ghjgwz.cjs.map → QuickShareWidget-CYPOXs8X.cjs.map} +1 -1
- package/dist/{QuickShareWidget-D-NVbmfw.mjs → QuickShareWidget-CyYW9nS6.mjs} +2 -2
- package/dist/{QuickShareWidget-D-NVbmfw.mjs.map → QuickShareWidget-CyYW9nS6.mjs.map} +1 -1
- package/dist/{RecentActivityWidget-Bz54YXQN.mjs → RecentActivityWidget-CndO-Ac0.mjs} +2 -2
- package/dist/{RecentActivityWidget-Bz54YXQN.mjs.map → RecentActivityWidget-CndO-Ac0.mjs.map} +1 -1
- package/dist/{RecentActivityWidget-sv_3ewZa.cjs → RecentActivityWidget-Cp3fYBM2.cjs} +2 -2
- package/dist/{RecentActivityWidget-sv_3ewZa.cjs.map → RecentActivityWidget-Cp3fYBM2.cjs.map} +1 -1
- package/dist/{SeparatorWidget-CY6uMLHP.cjs → SeparatorWidget-DW_9_L9_.cjs} +2 -2
- package/dist/{SeparatorWidget-CY6uMLHP.cjs.map → SeparatorWidget-DW_9_L9_.cjs.map} +1 -1
- package/dist/{SeparatorWidget-DR75Yj_C.mjs → SeparatorWidget-eI7b2n6u.mjs} +2 -2
- package/dist/{SeparatorWidget-DR75Yj_C.mjs.map → SeparatorWidget-eI7b2n6u.mjs.map} +1 -1
- package/dist/{ShopScreen-C3PYT1v_.cjs → ShopScreen-BDhf2CmC.cjs} +2 -2
- package/dist/{ShopScreen-C3PYT1v_.cjs.map → ShopScreen-BDhf2CmC.cjs.map} +1 -1
- package/dist/ShopScreen-BgTi5eCl.cjs +49 -0
- package/dist/ShopScreen-BhYkCXLT.mjs +47 -0
- package/dist/{ShopScreen-BFKwuM2U.mjs → ShopScreen-D0p5rQD8.mjs} +2 -2
- package/dist/{ShopScreen-BFKwuM2U.mjs.map → ShopScreen-D0p5rQD8.mjs.map} +1 -1
- package/dist/{TableWidget-yky-XAA1.cjs → TableWidget-BORWeyOR.cjs} +2 -2
- package/dist/{TableWidget-CiI5pArP.cjs → TableWidget-CT6T3IgY.cjs} +2 -2
- package/dist/{TableWidget-CiI5pArP.cjs.map → TableWidget-CT6T3IgY.cjs.map} +1 -1
- package/dist/{TableWidget-C87Czlh6.mjs → TableWidget-D8HBHejy.mjs} +2 -2
- package/dist/{TableWidget-C87Czlh6.mjs.map → TableWidget-D8HBHejy.mjs.map} +1 -1
- package/dist/{TextWidget-C7oY0X3r.cjs → TextWidget-CMOofhaH.cjs} +2 -2
- package/dist/{TextWidget-C7oY0X3r.cjs.map → TextWidget-CMOofhaH.cjs.map} +1 -1
- package/dist/{TextWidget-CfLUQr6V.mjs → TextWidget-DSGevTKM.mjs} +2 -2
- package/dist/{TextWidget-CfLUQr6V.mjs.map → TextWidget-DSGevTKM.mjs.map} +1 -1
- package/dist/{ToDoWidget-BY-6VIxD.mjs → ToDoWidget-5IiWutYI.mjs} +2 -2
- package/dist/{ToDoWidget-BY-6VIxD.mjs.map → ToDoWidget-5IiWutYI.mjs.map} +1 -1
- package/dist/{ToDoWidget-CpO7jdw0.cjs → ToDoWidget-B97blWRO.cjs} +2 -2
- package/dist/{ToDoWidget-CpO7jdw0.cjs.map → ToDoWidget-B97blWRO.cjs.map} +1 -1
- package/dist/{ToDoWidget-CjY1i0lz.cjs → ToDoWidget-kn1dtlKi.cjs} +2 -2
- package/dist/{VideoWidget-DSPDdiYr.mjs → VideoWidget-BiaPF0-w.mjs} +2 -2
- package/dist/{VideoWidget-DSPDdiYr.mjs.map → VideoWidget-BiaPF0-w.mjs.map} +1 -1
- package/dist/{VideoWidget-BpEF3gRZ.cjs → VideoWidget-zdT_mVo9.cjs} +2 -2
- package/dist/{VideoWidget-BpEF3gRZ.cjs.map → VideoWidget-zdT_mVo9.cjs.map} +1 -1
- package/dist/index.cjs +42 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +42 -42
- package/dist/index.mjs.map +1 -1
- package/dist/{registries-kvRRUHcO.mjs → registries-6F90ZS1m.mjs} +10 -1
- package/dist/registries-6F90ZS1m.mjs.map +1 -0
- package/dist/{registries-DBb6VjAX.cjs → registries-CVsthTnW.cjs} +10 -1
- package/dist/registries-CVsthTnW.cjs.map +1 -0
- package/package.json +18 -18
- package/dist/MessagingScreen-J59IMCoQ.mjs +0 -46
- package/dist/MessagingScreen-Sur4umLF.cjs +0 -48
- package/dist/ProfileScreen-B1J74rK1.cjs +0 -48
- package/dist/ProfileScreen-BdmW4weg.mjs +0 -46
- package/dist/ShopScreen-C_8yLQjA.mjs +0 -47
- package/dist/ShopScreen-Cg_DoIMi.cjs +0 -49
- package/dist/registries-DBb6VjAX.cjs.map +0 -1
- package/dist/registries-kvRRUHcO.mjs.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { I as __exportAll } from "./portal_tenant_content-DPLnrtOG.mjs";
|
|
2
|
-
import { i as getBorderColorField, n as borderWidthClasses, o as getBorderRadiusField, p as getHeightField, s as getBorderWidthField, t as borderColorClasses } from "./registries-
|
|
2
|
+
import { i as getBorderColorField, n as borderWidthClasses, o as getBorderRadiusField, p as getHeightField, s as getBorderWidthField, t as borderColorClasses } from "./registries-6F90ZS1m.mjs";
|
|
3
3
|
import { t as MediaRenderer } from "./MediaRenderer-13Jlf38P.mjs";
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
5
5
|
//#region ../widgets/src/widgets/ImageWidget.tsx
|
|
@@ -158,4 +158,4 @@ const imageWidgetPropertySchema = {
|
|
|
158
158
|
//#endregion
|
|
159
159
|
export { ImageWidget_exports as n, imageWidgetPropertySchema as r, ImageWidget as t };
|
|
160
160
|
|
|
161
|
-
//# sourceMappingURL=ImageWidget
|
|
161
|
+
//# sourceMappingURL=ImageWidget--WJppfij.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImageWidget
|
|
1
|
+
{"version":3,"file":"ImageWidget--WJppfij.mjs","names":[],"sources":["../../widgets/src/widgets/ImageWidget.tsx"],"sourcesContent":["import type { ComponentProps } from \"react\";\nimport type React from \"react\";\nimport {\n getBorderRadiusField,\n getHeightField,\n type WidgetPropertySchema,\n} from \"@fluid-app/portal-core/registries\";\nimport type {\n BorderRadiusOptions,\n BorderWidthOptions,\n ColorOptions,\n ShareableItem,\n} from \"@fluid-app/portal-core/types\";\nimport {\n getBorderWidthField,\n getBorderColorField,\n borderWidthClasses,\n borderColorClasses,\n} from \"../core/fields\";\nimport { MediaRenderer } from \"../components/MediaRenderer\";\n\ntype ImageWidgetProps = ComponentProps<\"div\"> & {\n src?: string;\n alt?: string;\n borderRadius?: BorderRadiusOptions;\n borderWidth?: BorderWidthOptions;\n borderColor?: ColorOptions;\n verticalSizing?: \"auto\" | \"fixed\";\n fixedHeight?: string;\n displayFit?: \"cover\" | \"contain\";\n focusPoint?: string;\n linkUrl?: string;\n resource?: ShareableItem;\n useCustomUrl?: boolean;\n editMode?: boolean;\n};\n\nexport function ImageWidget({\n src = \"\",\n alt = \"\",\n borderRadius = \"md\",\n borderWidth = \"none\",\n borderColor = \"muted\",\n verticalSizing = \"auto\",\n fixedHeight = \"200px\",\n displayFit = \"cover\",\n focusPoint,\n linkUrl,\n resource,\n useCustomUrl,\n editMode = false,\n}: ImageWidgetProps): React.JSX.Element {\n const effectiveSrc = useCustomUrl ? src : (resource?.imageUrl ?? src);\n const effectiveAlt = resource?.title ?? alt;\n\n const isFixed = verticalSizing === \"fixed\";\n\n const content = (\n <div\n className={`w-full rounded-${borderRadius} ${borderWidthClasses[borderWidth]} ${borderWidth !== \"none\" ? borderColorClasses[borderColor] : \"\"} overflow-hidden`}\n style={isFixed ? { height: fixedHeight } : undefined}\n >\n <MediaRenderer\n mediaType=\"image\"\n src={effectiveSrc}\n alt={effectiveAlt}\n objectFit={isFixed ? displayFit : \"contain\"}\n focusPoint={isFixed ? focusPoint : undefined}\n />\n </div>\n );\n\n if (linkUrl && !editMode) {\n return (\n <a href={linkUrl} target=\"_blank\" rel=\"noopener noreferrer\">\n {content}\n </a>\n );\n }\n\n return content;\n}\n\nexport const imageWidgetPropertySchema: WidgetPropertySchema = {\n widgetType: \"ImageWidget\",\n displayName: \"Image\",\n fields: [\n // Content\n {\n key: \"resource\",\n label: \"Select Image\",\n type: \"resource\",\n description: \"Browse and select an image\",\n allowedTypes: [\"Medium\"],\n group: \"Content\",\n },\n {\n key: \"useCustomUrl\",\n label: \"Use Custom URL\",\n type: \"boolean\",\n description: \"Enter a custom image URL instead of selecting media\",\n defaultValue: false,\n group: \"Content\",\n },\n {\n key: \"src\",\n label: \"Image URL\",\n type: \"text\",\n description: \"The source URL of the image\",\n defaultValue:\n \"https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=800&auto=format&fit=crop\",\n group: \"Content\",\n requiresKeyToBeTrue: \"useCustomUrl\",\n },\n {\n key: \"alt\",\n label: \"Alt Text\",\n type: \"text\",\n description: \"Alternative text for the image (for accessibility)\",\n defaultValue: \"Placeholder image\",\n group: \"Content\",\n },\n\n // Design\n getBorderRadiusField({\n key: \"borderRadius\",\n label: \"Border Radius\",\n description: \"Border radius for the container\",\n defaultValue: \"md\",\n group: \"Design\",\n }),\n getBorderWidthField({\n key: \"borderWidth\",\n label: \"Border Width\",\n description: \"Border width for the widget\",\n defaultValue: \"none\",\n group: \"Design\",\n }),\n getBorderColorField({\n key: \"borderColor\",\n label: \"Border Color\",\n description: \"Border color for the widget\",\n defaultValue: \"muted\",\n group: \"Design\",\n }),\n {\n key: \"verticalSizing\",\n label: \"Vertical Sizing\",\n type: \"buttonGroup\",\n description: \"How the image height is determined\",\n options: [\n { label: \"Auto\", value: \"auto\" },\n { label: \"Fixed\", value: \"fixed\" },\n ],\n defaultValue: \"auto\",\n group: \"Design\",\n },\n getHeightField({\n key: \"fixedHeight\",\n label: \"Height\",\n description: \"Fixed height of the image container\",\n defaultValue: \"200px\",\n group: \"Design\",\n requiresKeyValue: { key: \"verticalSizing\", value: \"fixed\" },\n }),\n {\n key: \"displayFit\",\n label: \"Display Fit\",\n type: \"buttonGroup\",\n description: \"How the image fills its container\",\n options: [\n { label: \"Cover\", value: \"cover\" },\n { label: \"Contain\", value: \"contain\" },\n ],\n defaultValue: \"cover\",\n group: \"Design\",\n requiresKeyValue: { key: \"verticalSizing\", value: \"fixed\" },\n },\n {\n key: \"focusPoint\",\n label: \"Focus Point\",\n type: \"contentPosition\",\n description: \"The focal point of the image within its container\",\n defaultValue: \"center\",\n group: \"Design\",\n requiresKeyValue: { key: \"verticalSizing\", value: \"fixed\" },\n },\n\n // Link\n {\n key: \"linkUrl\",\n label: \"Link URL\",\n type: \"text\",\n description: \"Optional URL to wrap the image in a link\",\n defaultValue: \"\",\n group: \"Link\",\n },\n ],\n};\n"],"mappings":";;;;;;;;;AAqCA,SAAgB,YAAY,EAC1B,MAAM,IACN,MAAM,IACN,eAAe,MACf,cAAc,QACd,cAAc,SACd,iBAAiB,QACjB,cAAc,SACd,aAAa,SACb,YACA,SACA,UACA,cACA,WAAW,SAC2B;CACtC,MAAM,eAAe,eAAe,MAAO,UAAU,YAAY;CACjE,MAAM,eAAe,UAAU,SAAS;CAExC,MAAM,UAAU,mBAAmB;CAEnC,MAAM,UACJ,oBAAC,OAAD;EACE,WAAW,kBAAkB,aAAa,GAAG,mBAAmB,aAAa,GAAG,gBAAgB,SAAS,mBAAmB,eAAe,GAAG;EAC9I,OAAO,UAAU,EAAE,QAAQ,aAAa,GAAG,KAAA;YAE3C,oBAAC,eAAD;GACE,WAAU;GACV,KAAK;GACL,KAAK;GACL,WAAW,UAAU,aAAa;GAClC,YAAY,UAAU,aAAa,KAAA;GACnC,CAAA;EACE,CAAA;AAGR,KAAI,WAAW,CAAC,SACd,QACE,oBAAC,KAAD;EAAG,MAAM;EAAS,QAAO;EAAS,KAAI;YACnC;EACC,CAAA;AAIR,QAAO;;AAGT,MAAa,4BAAkD;CAC7D,YAAY;CACZ,aAAa;CACb,QAAQ;EAEN;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc,CAAC,SAAS;GACxB,OAAO;GACR;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,OAAO;GACR;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cACE;GACF,OAAO;GACP,qBAAqB;GACtB;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,OAAO;GACR;EAGD,qBAAqB;GACnB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,OAAO;GACR,CAAC;EACF,oBAAoB;GAClB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,OAAO;GACR,CAAC;EACF,oBAAoB;GAClB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,OAAO;GACR,CAAC;EACF;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,SAAS,CACP;IAAE,OAAO;IAAQ,OAAO;IAAQ,EAChC;IAAE,OAAO;IAAS,OAAO;IAAS,CACnC;GACD,cAAc;GACd,OAAO;GACR;EACD,eAAe;GACb,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,OAAO;GACP,kBAAkB;IAAE,KAAK;IAAkB,OAAO;IAAS;GAC5D,CAAC;EACF;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,SAAS,CACP;IAAE,OAAO;IAAS,OAAO;IAAS,EAClC;IAAE,OAAO;IAAW,OAAO;IAAW,CACvC;GACD,cAAc;GACd,OAAO;GACP,kBAAkB;IAAE,KAAK;IAAkB,OAAO;IAAS;GAC5D;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,OAAO;GACP,kBAAkB;IAAE,KAAK;IAAkB,OAAO;IAAS;GAC5D;EAGD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,OAAO;GACR;EACF;CACF"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_chunk = require("./chunk-9hOWP6kD.cjs");
|
|
2
|
-
const require_registries = require("./registries-
|
|
2
|
+
const require_registries = require("./registries-CVsthTnW.cjs");
|
|
3
3
|
const require_MediaRenderer = require("./MediaRenderer-CvN8Ku0i.cjs");
|
|
4
4
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
5
5
|
//#region ../widgets/src/widgets/ImageWidget.tsx
|
|
@@ -175,4 +175,4 @@ Object.defineProperty(exports, "imageWidgetPropertySchema", {
|
|
|
175
175
|
}
|
|
176
176
|
});
|
|
177
177
|
|
|
178
|
-
//# sourceMappingURL=ImageWidget-
|
|
178
|
+
//# sourceMappingURL=ImageWidget-CU2cet5p.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImageWidget-
|
|
1
|
+
{"version":3,"file":"ImageWidget-CU2cet5p.cjs","names":["borderWidthClasses","borderColorClasses","MediaRenderer","getBorderRadiusField","getBorderWidthField","getBorderColorField","getHeightField"],"sources":["../../widgets/src/widgets/ImageWidget.tsx"],"sourcesContent":["import type { ComponentProps } from \"react\";\nimport type React from \"react\";\nimport {\n getBorderRadiusField,\n getHeightField,\n type WidgetPropertySchema,\n} from \"@fluid-app/portal-core/registries\";\nimport type {\n BorderRadiusOptions,\n BorderWidthOptions,\n ColorOptions,\n ShareableItem,\n} from \"@fluid-app/portal-core/types\";\nimport {\n getBorderWidthField,\n getBorderColorField,\n borderWidthClasses,\n borderColorClasses,\n} from \"../core/fields\";\nimport { MediaRenderer } from \"../components/MediaRenderer\";\n\ntype ImageWidgetProps = ComponentProps<\"div\"> & {\n src?: string;\n alt?: string;\n borderRadius?: BorderRadiusOptions;\n borderWidth?: BorderWidthOptions;\n borderColor?: ColorOptions;\n verticalSizing?: \"auto\" | \"fixed\";\n fixedHeight?: string;\n displayFit?: \"cover\" | \"contain\";\n focusPoint?: string;\n linkUrl?: string;\n resource?: ShareableItem;\n useCustomUrl?: boolean;\n editMode?: boolean;\n};\n\nexport function ImageWidget({\n src = \"\",\n alt = \"\",\n borderRadius = \"md\",\n borderWidth = \"none\",\n borderColor = \"muted\",\n verticalSizing = \"auto\",\n fixedHeight = \"200px\",\n displayFit = \"cover\",\n focusPoint,\n linkUrl,\n resource,\n useCustomUrl,\n editMode = false,\n}: ImageWidgetProps): React.JSX.Element {\n const effectiveSrc = useCustomUrl ? src : (resource?.imageUrl ?? src);\n const effectiveAlt = resource?.title ?? alt;\n\n const isFixed = verticalSizing === \"fixed\";\n\n const content = (\n <div\n className={`w-full rounded-${borderRadius} ${borderWidthClasses[borderWidth]} ${borderWidth !== \"none\" ? borderColorClasses[borderColor] : \"\"} overflow-hidden`}\n style={isFixed ? { height: fixedHeight } : undefined}\n >\n <MediaRenderer\n mediaType=\"image\"\n src={effectiveSrc}\n alt={effectiveAlt}\n objectFit={isFixed ? displayFit : \"contain\"}\n focusPoint={isFixed ? focusPoint : undefined}\n />\n </div>\n );\n\n if (linkUrl && !editMode) {\n return (\n <a href={linkUrl} target=\"_blank\" rel=\"noopener noreferrer\">\n {content}\n </a>\n );\n }\n\n return content;\n}\n\nexport const imageWidgetPropertySchema: WidgetPropertySchema = {\n widgetType: \"ImageWidget\",\n displayName: \"Image\",\n fields: [\n // Content\n {\n key: \"resource\",\n label: \"Select Image\",\n type: \"resource\",\n description: \"Browse and select an image\",\n allowedTypes: [\"Medium\"],\n group: \"Content\",\n },\n {\n key: \"useCustomUrl\",\n label: \"Use Custom URL\",\n type: \"boolean\",\n description: \"Enter a custom image URL instead of selecting media\",\n defaultValue: false,\n group: \"Content\",\n },\n {\n key: \"src\",\n label: \"Image URL\",\n type: \"text\",\n description: \"The source URL of the image\",\n defaultValue:\n \"https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=800&auto=format&fit=crop\",\n group: \"Content\",\n requiresKeyToBeTrue: \"useCustomUrl\",\n },\n {\n key: \"alt\",\n label: \"Alt Text\",\n type: \"text\",\n description: \"Alternative text for the image (for accessibility)\",\n defaultValue: \"Placeholder image\",\n group: \"Content\",\n },\n\n // Design\n getBorderRadiusField({\n key: \"borderRadius\",\n label: \"Border Radius\",\n description: \"Border radius for the container\",\n defaultValue: \"md\",\n group: \"Design\",\n }),\n getBorderWidthField({\n key: \"borderWidth\",\n label: \"Border Width\",\n description: \"Border width for the widget\",\n defaultValue: \"none\",\n group: \"Design\",\n }),\n getBorderColorField({\n key: \"borderColor\",\n label: \"Border Color\",\n description: \"Border color for the widget\",\n defaultValue: \"muted\",\n group: \"Design\",\n }),\n {\n key: \"verticalSizing\",\n label: \"Vertical Sizing\",\n type: \"buttonGroup\",\n description: \"How the image height is determined\",\n options: [\n { label: \"Auto\", value: \"auto\" },\n { label: \"Fixed\", value: \"fixed\" },\n ],\n defaultValue: \"auto\",\n group: \"Design\",\n },\n getHeightField({\n key: \"fixedHeight\",\n label: \"Height\",\n description: \"Fixed height of the image container\",\n defaultValue: \"200px\",\n group: \"Design\",\n requiresKeyValue: { key: \"verticalSizing\", value: \"fixed\" },\n }),\n {\n key: \"displayFit\",\n label: \"Display Fit\",\n type: \"buttonGroup\",\n description: \"How the image fills its container\",\n options: [\n { label: \"Cover\", value: \"cover\" },\n { label: \"Contain\", value: \"contain\" },\n ],\n defaultValue: \"cover\",\n group: \"Design\",\n requiresKeyValue: { key: \"verticalSizing\", value: \"fixed\" },\n },\n {\n key: \"focusPoint\",\n label: \"Focus Point\",\n type: \"contentPosition\",\n description: \"The focal point of the image within its container\",\n defaultValue: \"center\",\n group: \"Design\",\n requiresKeyValue: { key: \"verticalSizing\", value: \"fixed\" },\n },\n\n // Link\n {\n key: \"linkUrl\",\n label: \"Link URL\",\n type: \"text\",\n description: \"Optional URL to wrap the image in a link\",\n defaultValue: \"\",\n group: \"Link\",\n },\n ],\n};\n"],"mappings":";;;;;;;;;AAqCA,SAAgB,YAAY,EAC1B,MAAM,IACN,MAAM,IACN,eAAe,MACf,cAAc,QACd,cAAc,SACd,iBAAiB,QACjB,cAAc,SACd,aAAa,SACb,YACA,SACA,UACA,cACA,WAAW,SAC2B;CACtC,MAAM,eAAe,eAAe,MAAO,UAAU,YAAY;CACjE,MAAM,eAAe,UAAU,SAAS;CAExC,MAAM,UAAU,mBAAmB;CAEnC,MAAM,UACJ,iBAAA,GAAA,kBAAA,KAAC,OAAD;EACE,WAAW,kBAAkB,aAAa,GAAGA,mBAAAA,mBAAmB,aAAa,GAAG,gBAAgB,SAASC,mBAAAA,mBAAmB,eAAe,GAAG;EAC9I,OAAO,UAAU,EAAE,QAAQ,aAAa,GAAG,KAAA;YAE3C,iBAAA,GAAA,kBAAA,KAACC,sBAAAA,eAAD;GACE,WAAU;GACV,KAAK;GACL,KAAK;GACL,WAAW,UAAU,aAAa;GAClC,YAAY,UAAU,aAAa,KAAA;GACnC,CAAA;EACE,CAAA;AAGR,KAAI,WAAW,CAAC,SACd,QACE,iBAAA,GAAA,kBAAA,KAAC,KAAD;EAAG,MAAM;EAAS,QAAO;EAAS,KAAI;YACnC;EACC,CAAA;AAIR,QAAO;;AAGT,MAAa,4BAAkD;CAC7D,YAAY;CACZ,aAAa;CACb,QAAQ;EAEN;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc,CAAC,SAAS;GACxB,OAAO;GACR;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,OAAO;GACR;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cACE;GACF,OAAO;GACP,qBAAqB;GACtB;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,OAAO;GACR;EAGDC,mBAAAA,qBAAqB;GACnB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,OAAO;GACR,CAAC;EACFC,mBAAAA,oBAAoB;GAClB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,OAAO;GACR,CAAC;EACFC,mBAAAA,oBAAoB;GAClB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,OAAO;GACR,CAAC;EACF;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,SAAS,CACP;IAAE,OAAO;IAAQ,OAAO;IAAQ,EAChC;IAAE,OAAO;IAAS,OAAO;IAAS,CACnC;GACD,cAAc;GACd,OAAO;GACR;EACDC,mBAAAA,eAAe;GACb,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,OAAO;GACP,kBAAkB;IAAE,KAAK;IAAkB,OAAO;IAAS;GAC5D,CAAC;EACF;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,SAAS,CACP;IAAE,OAAO;IAAS,OAAO;IAAS,EAClC;IAAE,OAAO;IAAW,OAAO;IAAW,CACvC;GACD,cAAc;GACd,OAAO;GACP,kBAAkB;IAAE,KAAK;IAAkB,OAAO;IAAS;GAC5D;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,OAAO;GACP,kBAAkB;IAAE,KAAK;IAAkB,OAAO;IAAS;GAC5D;EAGD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,OAAO;GACR;EACF;CACF"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require("./chunk-9hOWP6kD.cjs");
|
|
2
2
|
const require_ScreenRenderer = require("./ScreenRenderer-j7Nz1HQx.cjs");
|
|
3
|
-
const require_registries = require("./registries-
|
|
3
|
+
const require_registries = require("./registries-CVsthTnW.cjs");
|
|
4
4
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
5
5
|
/** @deprecated Use SECTION_LAYOUT_CONFIG instead */
|
|
6
6
|
const sectionLayoutConfig = {
|
|
@@ -200,4 +200,4 @@ Object.defineProperty(exports, "sectionLayoutConfig", {
|
|
|
200
200
|
}
|
|
201
201
|
});
|
|
202
202
|
|
|
203
|
-
//# sourceMappingURL=LayoutWidget-
|
|
203
|
+
//# sourceMappingURL=LayoutWidget-8DwDBW24.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LayoutWidget-BK8AxE60.cjs","names":["useRegistry","ScreenRenderer","useScreenRenderer","DefaultScreenRenderer","gapValues","borderWidthClasses","borderColorClasses","getGapField","getPaddingField","getBorderRadiusField","getBorderWidthField","getBorderColorField"],"sources":["../../core/src/types/field-types.ts","../../core/src/widget-utils/widget-utils.ts","../../widgets/src/widgets/LayoutWidget.tsx"],"sourcesContent":["import type { ShareableItem } from \"./shareable-item\";\n\n// ============================================================================\n// Color Options - Derive type from constant for single source of truth\n// ============================================================================\n\n/**\n * Color options constant - single source of truth for color values.\n * Use COLOR_OPTIONS.primary instead of \"primary\" for type-safe comparisons.\n */\nexport const COLOR_OPTIONS = {\n background: \"background\",\n foreground: \"foreground\",\n primary: \"primary\",\n secondary: \"secondary\",\n accent: \"accent\",\n muted: \"muted\",\n border: \"border\",\n destructive: \"destructive\",\n transparent: \"transparent\",\n} as const;\n\n/**\n * Union type of all color options, derived from COLOR_OPTIONS constant.\n * @see deriving-typeof-for-object-keys pattern\n */\nexport type ColorOptions = (typeof COLOR_OPTIONS)[keyof typeof COLOR_OPTIONS];\n\n// ============================================================================\n// Size Options - Derive types from constants for single source of truth\n// ============================================================================\n\nexport const FONT_SIZE_OPTIONS = {\n \"2xl\": \"2xl\",\n xl: \"xl\",\n lg: \"lg\",\n md: \"md\",\n sm: \"sm\",\n xs: \"xs\",\n} as const;\n\nexport type FontSizeOptions =\n (typeof FONT_SIZE_OPTIONS)[keyof typeof FONT_SIZE_OPTIONS];\n\nexport const FONT_WEIGHT_OPTIONS = {\n normal: \"normal\",\n medium: \"medium\",\n semibold: \"semibold\",\n bold: \"bold\",\n} as const;\n\nexport type FontWeightOptions =\n (typeof FONT_WEIGHT_OPTIONS)[keyof typeof FONT_WEIGHT_OPTIONS];\n\nexport const BORDER_RADIUS_OPTIONS = {\n none: \"none\",\n sm: \"sm\",\n md: \"md\",\n lg: \"lg\",\n xl: \"xl\",\n full: \"full\",\n} as const;\n\nexport type BorderRadiusOptions =\n (typeof BORDER_RADIUS_OPTIONS)[keyof typeof BORDER_RADIUS_OPTIONS];\n\nexport const BORDER_WIDTH_OPTIONS = {\n none: \"none\",\n thin: \"thin\",\n medium: \"medium\",\n thick: \"thick\",\n} as const;\n\nexport type BorderWidthOptions =\n (typeof BORDER_WIDTH_OPTIONS)[keyof typeof BORDER_WIDTH_OPTIONS];\n\n/** Padding values - numeric, so we use a tuple for derivation */\nexport const PADDING_VALUES = [0, 2, 4, 6, 8, 10] as const;\nexport type PaddingOptions = (typeof PADDING_VALUES)[number];\n\nexport const BUTTON_SIZE_OPTIONS = {\n sm: \"sm\",\n default: \"default\",\n lg: \"lg\",\n xl: \"xl\",\n} as const;\n\nexport type ButtonSizeOptions =\n (typeof BUTTON_SIZE_OPTIONS)[keyof typeof BUTTON_SIZE_OPTIONS];\n\nexport const GAP_OPTIONS = {\n none: \"none\",\n xs: \"xs\",\n sm: \"sm\",\n md: \"md\",\n lg: \"lg\",\n xl: \"xl\",\n} as const;\n\nexport type GapOptions = (typeof GAP_OPTIONS)[keyof typeof GAP_OPTIONS];\n\n// ============================================================================\n// Alignment Options - Derive from constants\n// ============================================================================\n\nexport const VERTICAL_ALIGN_OPTIONS = {\n top: \"top\",\n center: \"center\",\n bottom: \"bottom\",\n} as const;\n\nexport type VerticalAlign =\n (typeof VERTICAL_ALIGN_OPTIONS)[keyof typeof VERTICAL_ALIGN_OPTIONS];\n\nexport const HORIZONTAL_ALIGN_OPTIONS = {\n left: \"left\",\n center: \"center\",\n right: \"right\",\n} as const;\n\nexport type HorizontalAlign =\n (typeof HORIZONTAL_ALIGN_OPTIONS)[keyof typeof HORIZONTAL_ALIGN_OPTIONS];\n\nexport type AlignOptions = {\n vertical?: VerticalAlign;\n horizontal?: HorizontalAlign;\n};\n\n// ============================================================================\n// Background Options - Derive from constant\n// ============================================================================\n\nexport const BACKGROUND_TYPES = {\n solid: \"solid\",\n image: \"image\",\n} as const;\n\nexport type BackgroundType =\n (typeof BACKGROUND_TYPES)[keyof typeof BACKGROUND_TYPES];\nexport interface BackgroundValue {\n type: BackgroundType;\n color?: ColorOptions;\n resource?: ShareableItem;\n}\n\n// ============================================================================\n// Section Layout - Derive type from config keys (single source of truth)\n// ============================================================================\n\n/**\n * Section layout configuration - single source of truth for layout types.\n * SectionLayoutType is derived from these keys to prevent drift.\n */\nexport const SECTION_LAYOUT_CONFIG: {\n readonly \"single-column\": {\n readonly columns: 1;\n readonly widths: readonly [\"1fr\"];\n readonly gridClasses: \"\";\n };\n readonly \"2c-equal\": {\n readonly columns: 2;\n readonly widths: readonly [\"1fr\", \"1fr\"];\n readonly gridClasses: \"@md:grid-cols-2\";\n };\n readonly \"2c-left-wider\": {\n readonly columns: 2;\n readonly widths: readonly [\"2fr\", \"1fr\"];\n readonly gridClasses: \"@md:grid-cols-[2fr_1fr]\";\n };\n readonly \"2c-right-wider\": {\n readonly columns: 2;\n readonly widths: readonly [\"1fr\", \"2fr\"];\n readonly gridClasses: \"@md:grid-cols-[1fr_2fr]\";\n };\n readonly \"2c-left-narrow\": {\n readonly columns: 2;\n readonly widths: readonly [\"1fr\", \"3fr\"];\n readonly gridClasses: \"@md:grid-cols-[1fr_3fr]\";\n };\n readonly \"2c-right-narrow\": {\n readonly columns: 2;\n readonly widths: readonly [\"3fr\", \"1fr\"];\n readonly gridClasses: \"@md:grid-cols-[3fr_1fr]\";\n };\n readonly \"3c-equal\": {\n readonly columns: 3;\n readonly widths: readonly [\"1fr\", \"1fr\", \"1fr\"];\n readonly gridClasses: \"@md:grid-cols-3\";\n };\n readonly \"3c-middle-wider\": {\n readonly columns: 3;\n readonly widths: readonly [\"1fr\", \"2fr\", \"1fr\"];\n readonly gridClasses: \"@md:grid-cols-[1fr_2fr_1fr]\";\n };\n} = {\n \"single-column\": { columns: 1, widths: [\"1fr\"], gridClasses: \"\" },\n \"2c-equal\": {\n columns: 2,\n widths: [\"1fr\", \"1fr\"],\n gridClasses: \"@md:grid-cols-2\",\n },\n \"2c-left-wider\": {\n columns: 2,\n widths: [\"2fr\", \"1fr\"],\n gridClasses: \"@md:grid-cols-[2fr_1fr]\",\n },\n \"2c-right-wider\": {\n columns: 2,\n widths: [\"1fr\", \"2fr\"],\n gridClasses: \"@md:grid-cols-[1fr_2fr]\",\n },\n \"2c-left-narrow\": {\n columns: 2,\n widths: [\"1fr\", \"3fr\"],\n gridClasses: \"@md:grid-cols-[1fr_3fr]\",\n },\n \"2c-right-narrow\": {\n columns: 2,\n widths: [\"3fr\", \"1fr\"],\n gridClasses: \"@md:grid-cols-[3fr_1fr]\",\n },\n \"3c-equal\": {\n columns: 3,\n widths: [\"1fr\", \"1fr\", \"1fr\"],\n gridClasses: \"@md:grid-cols-3\",\n },\n \"3c-middle-wider\": {\n columns: 3,\n widths: [\"1fr\", \"2fr\", \"1fr\"],\n gridClasses: \"@md:grid-cols-[1fr_2fr_1fr]\",\n },\n} as const satisfies Record<\n string,\n {\n readonly columns: number;\n readonly widths: readonly string[];\n readonly gridClasses: string;\n }\n>;\n\n/**\n * Union type of all section layout types, derived from SECTION_LAYOUT_CONFIG keys.\n * @see deriving-typeof-for-object-keys pattern\n */\nexport type SectionLayoutType = keyof typeof SECTION_LAYOUT_CONFIG;\n\n/** @deprecated Use SECTION_LAYOUT_CONFIG instead */\nexport const sectionLayoutConfig: typeof SECTION_LAYOUT_CONFIG =\n SECTION_LAYOUT_CONFIG;\n","import type { WidgetSchema, WidgetPath } from \"../types\";\nimport { WIDGET_TYPE_NAMES, isWidgetType } from \"../types\";\n\n/**\n * Generates a unique ID for a widget\n */\nexport function generateWidgetId(type?: string): string {\n const uuid = crypto.randomUUID();\n return type ? `${type}-${uuid}` : uuid;\n}\n\n/**\n * Converts a widget path to a unique string identifier\n */\nexport function pathToId(path: WidgetPath): string {\n return path.join(\"-\");\n}\n\n/**\n * Converts a path string back to a WidgetPath array\n */\nexport function idToPath(id: string): WidgetPath {\n return id.split(\"-\").map((segment) => parseInt(segment, 10));\n}\n\n/**\n * Ensures all widgets in an array have valid IDs\n * Note: Handles null values for sparse arrays (e.g., grid layouts with empty cells)\n */\nexport function ensureWidgetIds(\n widgets: readonly (WidgetSchema | null)[],\n): (WidgetSchema | null)[] {\n return widgets?.map((widget, index) => {\n if (!widget) return null;\n return {\n ...widget,\n id: widget.id || `widget-${index}-${crypto.randomUUID()}`,\n };\n });\n}\n\n/**\n * Deep clones a widget and regenerates all IDs (including nested children)\n */\nexport function deepCloneWidget(widget: WidgetSchema): WidgetSchema {\n // Handle LayoutWidget children recursively\n // Use type guard for discriminated union narrowing (narrowing-discriminated-unions rule)\n if (\n isWidgetType(widget, WIDGET_TYPE_NAMES.Layout) &&\n Array.isArray(widget.props.children)\n ) {\n // Build cloned widget with recursively cloned children\n return {\n type: widget.type,\n props: {\n ...widget.props,\n children: (\n widget.props.children as readonly (WidgetSchema | null)[]\n ).map((child) => (child ? deepCloneWidget(child) : null)),\n },\n id: generateWidgetId(widget.type),\n };\n }\n\n // Clone non-container widget\n return {\n type: widget.type,\n props: { ...widget.props },\n id: generateWidgetId(widget.type),\n };\n}\n\n/**\n * Deep clones an array of widgets and regenerates all IDs\n */\nexport function deepCloneWidgets(\n widgets: readonly WidgetSchema[],\n): WidgetSchema[] {\n return widgets.map((widget) => deepCloneWidget(widget));\n}\n\n/**\n * Gets a widget at a specific path in the widget tree\n */\nexport function getWidgetByPath(\n screen: readonly (WidgetSchema | null)[],\n path: WidgetPath,\n): WidgetSchema | null {\n if (path.length === 0 || path[0] === undefined) return null;\n\n let current: WidgetSchema | null = screen[path[0]] ?? null;\n\n for (let i = 1; i < path.length; i++) {\n // Use type guard for discriminated union narrowing (narrowing-discriminated-unions rule)\n if (!isWidgetType(current, WIDGET_TYPE_NAMES.Layout)) return null;\n\n const children = (current.props.children ??\n []) as readonly (WidgetSchema | null)[];\n const index = path[i];\n if (index === undefined) return null;\n current = children[index] ?? null;\n }\n\n return current;\n}\n\n/**\n * Groups children by column index.\n * Accepts nullable children (sparse arrays from grid layouts) and filters them out.\n */\nexport function groupChildrenByColumn(\n children: readonly (WidgetSchema | null)[],\n columnCount: number,\n): WidgetSchema[][] {\n // Use explicit type annotation to avoid never[] inference (narrowing-empty-array-type rule)\n const columns: WidgetSchema[][] = Array.from(\n { length: columnCount },\n (): WidgetSchema[] => [],\n );\n\n // Filter out nulls first, then process (truthiness narrowing rule)\n // This avoids the narrowing-callback-scope issue since we work with non-null array\n const nonNullChildren = children.filter(\n (child): child is WidgetSchema => child !== null,\n );\n\n for (const child of nonNullChildren) {\n // Default to column 0 if no columnIndex specified\n const colIndex = Math.min(child.columnIndex ?? 0, columnCount - 1);\n const column = columns[colIndex];\n if (column) {\n column.push(child);\n }\n }\n\n return columns;\n}\n","import { ScreenRenderer as DefaultScreenRenderer } from \"../core/ScreenRenderer\";\nimport { useRegistry } from \"../contexts/RegistryContext\";\nimport { useScreenRenderer } from \"../contexts/ScreenRendererContext\";\nimport type {\n TypedWidgetSchema,\n WidgetSchema,\n BorderRadiusOptions,\n BorderWidthOptions,\n ColorOptions,\n PaddingOptions,\n GapOptions,\n SectionLayoutType,\n BackgroundValue,\n} from \"@fluid-app/portal-core/types\";\nimport { sectionLayoutConfig } from \"@fluid-app/portal-core/types\";\nimport type { ComponentType } from \"react\";\nimport type React from \"react\";\nimport type { WidgetPropertySchema } from \"@fluid-app/portal-core/registries\";\nimport {\n getBorderRadiusField,\n getBorderWidthField,\n getBorderColorField,\n getGapField,\n getPaddingField,\n gapValues,\n borderWidthClasses,\n borderColorClasses,\n} from \"../core/fields\";\nimport { groupChildrenByColumn } from \"@fluid-app/portal-core/widget-utils\";\n\nconst DEFAULT_BACKGROUND: BackgroundValue = {\n type: \"solid\",\n color: \"background\",\n};\nconst DEFAULT_CHILDREN: (WidgetSchema | null)[] = [];\n\ntype LayoutProps<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n T extends Record<string, ComponentType<any>> = Record<\n string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ComponentType<any>\n >,\n> = {\n // Section layout type (masonry-style column configuration)\n sectionLayout?: SectionLayoutType;\n\n // Legacy props (deprecated, kept for backward compatibility)\n type?: \"flex\" | \"grid\";\n columns?: number;\n rows?: number;\n direction?: string;\n justify?: string;\n align?: string;\n wrap?: boolean;\n\n // Spacing\n gap?: number; // deprecated, use gapSize instead\n gapSize?: GapOptions;\n\n // Design\n background?: BackgroundValue;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n borderWidth?: BorderWidthOptions;\n borderColor?: ColorOptions;\n\n // Content - widgets with columnIndex property for masonry layout\n children: (TypedWidgetSchema<T> | null)[] | (WidgetSchema | null)[];\n\n // Widget registry (passed down from parent renderer)\n registry?: T;\n\n // Styling\n className?: string;\n minHeight?: number;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const LayoutWidget = <T extends Record<string, ComponentType<any>>>({\n sectionLayout = \"single-column\",\n gap = 4,\n gapSize,\n background = DEFAULT_BACKGROUND,\n padding = 0,\n borderRadius = \"md\",\n borderWidth = \"none\",\n borderColor = \"muted\",\n children = DEFAULT_CHILDREN,\n registry,\n className = \"\",\n minHeight,\n}: LayoutProps<T>): React.JSX.Element => {\n // Get registry from context if not provided as prop\n const contextRegistry = useRegistry();\n const effectiveRegistry = registry || contextRegistry;\n\n // Use ScreenRenderer from context (e.g. portal-builder's), fall back to local\n const ContextScreenRenderer = useScreenRenderer();\n const ScreenRenderer = ContextScreenRenderer ?? DefaultScreenRenderer;\n\n // Extract background values\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 // Get layout configuration\n const layoutConfig = sectionLayoutConfig[sectionLayout];\n const columnCount = layoutConfig.columns;\n\n // Calculate gap size\n const gapSizeValue = gapSize ? gapValues[gapSize] : gap;\n\n // Build CSS classes for masonry layout with responsive columns\n const layoutClasses = [\n \"grid\",\n \"grid-cols-1\", // Mobile: single column\n layoutConfig.gridClasses, // Desktop (@md+): configured columns\n `bg-${backgroundColor} p-${padding} rounded-${borderRadius} ${borderWidthClasses[borderWidth]} ${borderWidth !== \"none\" ? borderColorClasses[borderColor] : \"\"}`,\n `gap-${gapSizeValue}`,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n // Container style\n const containerStyle: React.CSSProperties = {\n ...(minHeight ? { minHeight: `${minHeight}px` } : {}),\n alignItems: \"start\", // Masonry-style: columns don't stretch to match height\n backgroundImage,\n };\n\n // If no registry is available, we can't render the children\n if (!effectiveRegistry) {\n console.warn(\"Layout widget: No registry provided, cannot render children\");\n return <div className={layoutClasses} style={containerStyle} />;\n }\n\n // Group children by column\n const columnGroups = groupChildrenByColumn(\n children as WidgetSchema[],\n columnCount,\n );\n\n // Regular render mode - render each column as a flex column\n return (\n <div className=\"@container\">\n <div className={layoutClasses} style={containerStyle}>\n {columnGroups.map((columnChildren, colIndex) => (\n <ScreenRenderer\n key={colIndex}\n screen={columnChildren}\n registry={effectiveRegistry}\n className={`flex flex-col gap-${gapSizeValue}`}\n />\n ))}\n </div>\n </div>\n );\n};\n\nexport const layoutWidgetPropertySchema: WidgetPropertySchema = {\n widgetType: \"LayoutWidget\",\n displayName: \"Layout\",\n fields: [\n // Layout Configuration - Visual selector matching Figma design\n {\n key: \"sectionLayout\",\n label: \"Layout Type\",\n type: \"sectionLayoutSelect\",\n description: \"Column layout configuration\",\n defaultValue: \"single-column\",\n group: \"Layout\",\n },\n\n // Design\n getGapField({\n key: \"gapSize\",\n label: \"Gap\",\n description: \"Gap between columns and widgets\",\n defaultValue: \"md\",\n group: \"Design\",\n }),\n {\n type: \"background\",\n key: \"background\",\n label: \"Background\",\n description: \"Background for the layout container\",\n defaultValue: \"background\",\n group: \"Design\",\n },\n getPaddingField({\n key: \"padding\",\n label: \"Padding\",\n description: \"Padding for the layout container\",\n defaultValue: 4,\n group: \"Design\",\n }),\n getBorderRadiusField({\n key: \"borderRadius\",\n label: \"Border Radius\",\n description: \"Border radius for the layout container\",\n defaultValue: \"md\",\n group: \"Design\",\n }),\n getBorderWidthField({\n key: \"borderWidth\",\n label: \"Border Width\",\n description: \"Border width for the widget\",\n defaultValue: \"none\",\n group: \"Design\",\n }),\n getBorderColorField({\n key: \"borderColor\",\n label: \"Border Color\",\n description: \"Border color for the widget\",\n defaultValue: \"muted\",\n group: \"Design\",\n }),\n ],\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"LayoutWidget-8DwDBW24.cjs","names":["useRegistry","ScreenRenderer","useScreenRenderer","DefaultScreenRenderer","gapValues","borderWidthClasses","borderColorClasses","getGapField","getPaddingField","getBorderRadiusField","getBorderWidthField","getBorderColorField"],"sources":["../../core/src/types/field-types.ts","../../core/src/widget-utils/widget-utils.ts","../../widgets/src/widgets/LayoutWidget.tsx"],"sourcesContent":["import type { ShareableItem } from \"./shareable-item\";\n\n// ============================================================================\n// Color Options - Derive type from constant for single source of truth\n// ============================================================================\n\n/**\n * Color options constant - single source of truth for color values.\n * Use COLOR_OPTIONS.primary instead of \"primary\" for type-safe comparisons.\n */\nexport const COLOR_OPTIONS = {\n background: \"background\",\n foreground: \"foreground\",\n primary: \"primary\",\n secondary: \"secondary\",\n accent: \"accent\",\n muted: \"muted\",\n border: \"border\",\n destructive: \"destructive\",\n transparent: \"transparent\",\n} as const;\n\n/**\n * Union type of all color options, derived from COLOR_OPTIONS constant.\n * @see deriving-typeof-for-object-keys pattern\n */\nexport type ColorOptions = (typeof COLOR_OPTIONS)[keyof typeof COLOR_OPTIONS];\n\n// ============================================================================\n// Size Options - Derive types from constants for single source of truth\n// ============================================================================\n\nexport const FONT_SIZE_OPTIONS = {\n \"2xl\": \"2xl\",\n xl: \"xl\",\n lg: \"lg\",\n md: \"md\",\n sm: \"sm\",\n xs: \"xs\",\n} as const;\n\nexport type FontSizeOptions =\n (typeof FONT_SIZE_OPTIONS)[keyof typeof FONT_SIZE_OPTIONS];\n\nexport const FONT_WEIGHT_OPTIONS = {\n normal: \"normal\",\n medium: \"medium\",\n semibold: \"semibold\",\n bold: \"bold\",\n} as const;\n\nexport type FontWeightOptions =\n (typeof FONT_WEIGHT_OPTIONS)[keyof typeof FONT_WEIGHT_OPTIONS];\n\nexport const BORDER_RADIUS_OPTIONS = {\n none: \"none\",\n sm: \"sm\",\n md: \"md\",\n lg: \"lg\",\n xl: \"xl\",\n full: \"full\",\n} as const;\n\nexport type BorderRadiusOptions =\n (typeof BORDER_RADIUS_OPTIONS)[keyof typeof BORDER_RADIUS_OPTIONS];\n\nexport const BORDER_WIDTH_OPTIONS = {\n none: \"none\",\n thin: \"thin\",\n medium: \"medium\",\n thick: \"thick\",\n} as const;\n\nexport type BorderWidthOptions =\n (typeof BORDER_WIDTH_OPTIONS)[keyof typeof BORDER_WIDTH_OPTIONS];\n\n/** Padding values - numeric, so we use a tuple for derivation */\nexport const PADDING_VALUES = [0, 2, 4, 6, 8, 10] as const;\nexport type PaddingOptions = (typeof PADDING_VALUES)[number];\n\nexport const BUTTON_SIZE_OPTIONS = {\n sm: \"sm\",\n default: \"default\",\n lg: \"lg\",\n xl: \"xl\",\n} as const;\n\nexport type ButtonSizeOptions =\n (typeof BUTTON_SIZE_OPTIONS)[keyof typeof BUTTON_SIZE_OPTIONS];\n\nexport const GAP_OPTIONS = {\n none: \"none\",\n xs: \"xs\",\n sm: \"sm\",\n md: \"md\",\n lg: \"lg\",\n xl: \"xl\",\n} as const;\n\nexport type GapOptions = (typeof GAP_OPTIONS)[keyof typeof GAP_OPTIONS];\n\n// ============================================================================\n// Alignment Options - Derive from constants\n// ============================================================================\n\nexport const VERTICAL_ALIGN_OPTIONS = {\n top: \"top\",\n center: \"center\",\n bottom: \"bottom\",\n} as const;\n\nexport type VerticalAlign =\n (typeof VERTICAL_ALIGN_OPTIONS)[keyof typeof VERTICAL_ALIGN_OPTIONS];\n\nexport const HORIZONTAL_ALIGN_OPTIONS = {\n left: \"left\",\n center: \"center\",\n right: \"right\",\n} as const;\n\nexport type HorizontalAlign =\n (typeof HORIZONTAL_ALIGN_OPTIONS)[keyof typeof HORIZONTAL_ALIGN_OPTIONS];\n\nexport type AlignOptions = {\n vertical?: VerticalAlign;\n horizontal?: HorizontalAlign;\n};\n\n// ============================================================================\n// Background Options - Derive from constant\n// ============================================================================\n\nexport const BACKGROUND_TYPES = {\n solid: \"solid\",\n image: \"image\",\n} as const;\n\nexport type BackgroundType =\n (typeof BACKGROUND_TYPES)[keyof typeof BACKGROUND_TYPES];\nexport interface BackgroundValue {\n type: BackgroundType;\n color?: ColorOptions;\n resource?: ShareableItem;\n}\n\n// ============================================================================\n// Section Layout - Derive type from config keys (single source of truth)\n// ============================================================================\n\n/**\n * Section layout configuration - single source of truth for layout types.\n * SectionLayoutType is derived from these keys to prevent drift.\n */\nexport const SECTION_LAYOUT_CONFIG: {\n readonly \"single-column\": {\n readonly columns: 1;\n readonly widths: readonly [\"1fr\"];\n readonly gridClasses: \"\";\n };\n readonly \"2c-equal\": {\n readonly columns: 2;\n readonly widths: readonly [\"1fr\", \"1fr\"];\n readonly gridClasses: \"@md:grid-cols-2\";\n };\n readonly \"2c-left-wider\": {\n readonly columns: 2;\n readonly widths: readonly [\"2fr\", \"1fr\"];\n readonly gridClasses: \"@md:grid-cols-[2fr_1fr]\";\n };\n readonly \"2c-right-wider\": {\n readonly columns: 2;\n readonly widths: readonly [\"1fr\", \"2fr\"];\n readonly gridClasses: \"@md:grid-cols-[1fr_2fr]\";\n };\n readonly \"2c-left-narrow\": {\n readonly columns: 2;\n readonly widths: readonly [\"1fr\", \"3fr\"];\n readonly gridClasses: \"@md:grid-cols-[1fr_3fr]\";\n };\n readonly \"2c-right-narrow\": {\n readonly columns: 2;\n readonly widths: readonly [\"3fr\", \"1fr\"];\n readonly gridClasses: \"@md:grid-cols-[3fr_1fr]\";\n };\n readonly \"3c-equal\": {\n readonly columns: 3;\n readonly widths: readonly [\"1fr\", \"1fr\", \"1fr\"];\n readonly gridClasses: \"@md:grid-cols-3\";\n };\n readonly \"3c-middle-wider\": {\n readonly columns: 3;\n readonly widths: readonly [\"1fr\", \"2fr\", \"1fr\"];\n readonly gridClasses: \"@md:grid-cols-[1fr_2fr_1fr]\";\n };\n} = {\n \"single-column\": { columns: 1, widths: [\"1fr\"], gridClasses: \"\" },\n \"2c-equal\": {\n columns: 2,\n widths: [\"1fr\", \"1fr\"],\n gridClasses: \"@md:grid-cols-2\",\n },\n \"2c-left-wider\": {\n columns: 2,\n widths: [\"2fr\", \"1fr\"],\n gridClasses: \"@md:grid-cols-[2fr_1fr]\",\n },\n \"2c-right-wider\": {\n columns: 2,\n widths: [\"1fr\", \"2fr\"],\n gridClasses: \"@md:grid-cols-[1fr_2fr]\",\n },\n \"2c-left-narrow\": {\n columns: 2,\n widths: [\"1fr\", \"3fr\"],\n gridClasses: \"@md:grid-cols-[1fr_3fr]\",\n },\n \"2c-right-narrow\": {\n columns: 2,\n widths: [\"3fr\", \"1fr\"],\n gridClasses: \"@md:grid-cols-[3fr_1fr]\",\n },\n \"3c-equal\": {\n columns: 3,\n widths: [\"1fr\", \"1fr\", \"1fr\"],\n gridClasses: \"@md:grid-cols-3\",\n },\n \"3c-middle-wider\": {\n columns: 3,\n widths: [\"1fr\", \"2fr\", \"1fr\"],\n gridClasses: \"@md:grid-cols-[1fr_2fr_1fr]\",\n },\n} as const satisfies Record<\n string,\n {\n readonly columns: number;\n readonly widths: readonly string[];\n readonly gridClasses: string;\n }\n>;\n\n/**\n * Union type of all section layout types, derived from SECTION_LAYOUT_CONFIG keys.\n * @see deriving-typeof-for-object-keys pattern\n */\nexport type SectionLayoutType = keyof typeof SECTION_LAYOUT_CONFIG;\n\n/** @deprecated Use SECTION_LAYOUT_CONFIG instead */\nexport const sectionLayoutConfig: typeof SECTION_LAYOUT_CONFIG =\n SECTION_LAYOUT_CONFIG;\n","import type { WidgetSchema, WidgetPath } from \"../types\";\nimport { WIDGET_TYPE_NAMES, isWidgetType } from \"../types\";\n\n/**\n * Generates a unique ID for a widget\n */\nexport function generateWidgetId(type?: string): string {\n const uuid = crypto.randomUUID();\n return type ? `${type}-${uuid}` : uuid;\n}\n\n/**\n * Converts a widget path to a unique string identifier\n */\nexport function pathToId(path: WidgetPath): string {\n return path.join(\"-\");\n}\n\n/**\n * Converts a path string back to a WidgetPath array\n */\nexport function idToPath(id: string): WidgetPath {\n return id.split(\"-\").map((segment) => parseInt(segment, 10));\n}\n\n/**\n * Ensures all widgets in an array have valid IDs\n * Note: Handles null values for sparse arrays (e.g., grid layouts with empty cells)\n */\nexport function ensureWidgetIds(\n widgets: readonly (WidgetSchema | null)[],\n): (WidgetSchema | null)[] {\n return widgets?.map((widget, index) => {\n if (!widget) return null;\n return {\n ...widget,\n id: widget.id || `widget-${index}-${crypto.randomUUID()}`,\n };\n });\n}\n\n/**\n * Deep clones a widget and regenerates all IDs (including nested children)\n */\nexport function deepCloneWidget(widget: WidgetSchema): WidgetSchema {\n // Handle LayoutWidget children recursively\n // Use type guard for discriminated union narrowing (narrowing-discriminated-unions rule)\n if (\n isWidgetType(widget, WIDGET_TYPE_NAMES.Layout) &&\n Array.isArray(widget.props.children)\n ) {\n // Build cloned widget with recursively cloned children\n return {\n type: widget.type,\n props: {\n ...widget.props,\n children: (\n widget.props.children as readonly (WidgetSchema | null)[]\n ).map((child) => (child ? deepCloneWidget(child) : null)),\n },\n id: generateWidgetId(widget.type),\n };\n }\n\n // Clone non-container widget\n return {\n type: widget.type,\n props: { ...widget.props },\n id: generateWidgetId(widget.type),\n };\n}\n\n/**\n * Deep clones an array of widgets and regenerates all IDs\n */\nexport function deepCloneWidgets(\n widgets: readonly WidgetSchema[],\n): WidgetSchema[] {\n return widgets.map((widget) => deepCloneWidget(widget));\n}\n\n/**\n * Gets a widget at a specific path in the widget tree\n */\nexport function getWidgetByPath(\n screen: readonly (WidgetSchema | null)[],\n path: WidgetPath,\n): WidgetSchema | null {\n if (path.length === 0 || path[0] === undefined) return null;\n\n let current: WidgetSchema | null = screen[path[0]] ?? null;\n\n for (let i = 1; i < path.length; i++) {\n // Use type guard for discriminated union narrowing (narrowing-discriminated-unions rule)\n if (!isWidgetType(current, WIDGET_TYPE_NAMES.Layout)) return null;\n\n const children = (current.props.children ??\n []) as readonly (WidgetSchema | null)[];\n const index = path[i];\n if (index === undefined) return null;\n current = children[index] ?? null;\n }\n\n return current;\n}\n\n/**\n * Groups children by column index.\n * Accepts nullable children (sparse arrays from grid layouts) and filters them out.\n */\nexport function groupChildrenByColumn(\n children: readonly (WidgetSchema | null)[],\n columnCount: number,\n): WidgetSchema[][] {\n // Use explicit type annotation to avoid never[] inference (narrowing-empty-array-type rule)\n const columns: WidgetSchema[][] = Array.from(\n { length: columnCount },\n (): WidgetSchema[] => [],\n );\n\n // Filter out nulls first, then process (truthiness narrowing rule)\n // This avoids the narrowing-callback-scope issue since we work with non-null array\n const nonNullChildren = children.filter(\n (child): child is WidgetSchema => child !== null,\n );\n\n for (const child of nonNullChildren) {\n // Default to column 0 if no columnIndex specified\n const colIndex = Math.min(child.columnIndex ?? 0, columnCount - 1);\n const column = columns[colIndex];\n if (column) {\n column.push(child);\n }\n }\n\n return columns;\n}\n","import { ScreenRenderer as DefaultScreenRenderer } from \"../core/ScreenRenderer\";\nimport { useRegistry } from \"../contexts/RegistryContext\";\nimport { useScreenRenderer } from \"../contexts/ScreenRendererContext\";\nimport type {\n TypedWidgetSchema,\n WidgetSchema,\n BorderRadiusOptions,\n BorderWidthOptions,\n ColorOptions,\n PaddingOptions,\n GapOptions,\n SectionLayoutType,\n BackgroundValue,\n} from \"@fluid-app/portal-core/types\";\nimport { sectionLayoutConfig } from \"@fluid-app/portal-core/types\";\nimport type { ComponentType } from \"react\";\nimport type React from \"react\";\nimport type { WidgetPropertySchema } from \"@fluid-app/portal-core/registries\";\nimport {\n getBorderRadiusField,\n getBorderWidthField,\n getBorderColorField,\n getGapField,\n getPaddingField,\n gapValues,\n borderWidthClasses,\n borderColorClasses,\n} from \"../core/fields\";\nimport { groupChildrenByColumn } from \"@fluid-app/portal-core/widget-utils\";\n\nconst DEFAULT_BACKGROUND: BackgroundValue = {\n type: \"solid\",\n color: \"background\",\n};\nconst DEFAULT_CHILDREN: (WidgetSchema | null)[] = [];\n\ntype LayoutProps<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n T extends Record<string, ComponentType<any>> = Record<\n string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ComponentType<any>\n >,\n> = {\n // Section layout type (masonry-style column configuration)\n sectionLayout?: SectionLayoutType;\n\n // Legacy props (deprecated, kept for backward compatibility)\n type?: \"flex\" | \"grid\";\n columns?: number;\n rows?: number;\n direction?: string;\n justify?: string;\n align?: string;\n wrap?: boolean;\n\n // Spacing\n gap?: number; // deprecated, use gapSize instead\n gapSize?: GapOptions;\n\n // Design\n background?: BackgroundValue;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n borderWidth?: BorderWidthOptions;\n borderColor?: ColorOptions;\n\n // Content - widgets with columnIndex property for masonry layout\n children: (TypedWidgetSchema<T> | null)[] | (WidgetSchema | null)[];\n\n // Widget registry (passed down from parent renderer)\n registry?: T;\n\n // Styling\n className?: string;\n minHeight?: number;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const LayoutWidget = <T extends Record<string, ComponentType<any>>>({\n sectionLayout = \"single-column\",\n gap = 4,\n gapSize,\n background = DEFAULT_BACKGROUND,\n padding = 0,\n borderRadius = \"md\",\n borderWidth = \"none\",\n borderColor = \"muted\",\n children = DEFAULT_CHILDREN,\n registry,\n className = \"\",\n minHeight,\n}: LayoutProps<T>): React.JSX.Element => {\n // Get registry from context if not provided as prop\n const contextRegistry = useRegistry();\n const effectiveRegistry = registry || contextRegistry;\n\n // Use ScreenRenderer from context (e.g. portal-builder's), fall back to local\n const ContextScreenRenderer = useScreenRenderer();\n const ScreenRenderer = ContextScreenRenderer ?? DefaultScreenRenderer;\n\n // Extract background values\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 // Get layout configuration\n const layoutConfig = sectionLayoutConfig[sectionLayout];\n const columnCount = layoutConfig.columns;\n\n // Calculate gap size\n const gapSizeValue = gapSize ? gapValues[gapSize] : gap;\n\n // Build CSS classes for masonry layout with responsive columns\n const layoutClasses = [\n \"grid\",\n \"grid-cols-1\", // Mobile: single column\n layoutConfig.gridClasses, // Desktop (@md+): configured columns\n `bg-${backgroundColor} p-${padding} rounded-${borderRadius} ${borderWidthClasses[borderWidth]} ${borderWidth !== \"none\" ? borderColorClasses[borderColor] : \"\"}`,\n `gap-${gapSizeValue}`,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n // Container style\n const containerStyle: React.CSSProperties = {\n ...(minHeight ? { minHeight: `${minHeight}px` } : {}),\n alignItems: \"start\", // Masonry-style: columns don't stretch to match height\n backgroundImage,\n };\n\n // If no registry is available, we can't render the children\n if (!effectiveRegistry) {\n console.warn(\"Layout widget: No registry provided, cannot render children\");\n return <div className={layoutClasses} style={containerStyle} />;\n }\n\n // Group children by column\n const columnGroups = groupChildrenByColumn(\n children as WidgetSchema[],\n columnCount,\n );\n\n // Regular render mode - render each column as a flex column\n return (\n <div className=\"@container\">\n <div className={layoutClasses} style={containerStyle}>\n {columnGroups.map((columnChildren, colIndex) => (\n <ScreenRenderer\n key={colIndex}\n screen={columnChildren}\n registry={effectiveRegistry}\n className={`flex flex-col gap-${gapSizeValue}`}\n />\n ))}\n </div>\n </div>\n );\n};\n\nexport const layoutWidgetPropertySchema: WidgetPropertySchema = {\n widgetType: \"LayoutWidget\",\n displayName: \"Layout\",\n fields: [\n // Layout Configuration - Visual selector matching Figma design\n {\n key: \"sectionLayout\",\n label: \"Layout Type\",\n type: \"sectionLayoutSelect\",\n description: \"Column layout configuration\",\n defaultValue: \"single-column\",\n group: \"Layout\",\n },\n\n // Design\n getGapField({\n key: \"gapSize\",\n label: \"Gap\",\n description: \"Gap between columns and widgets\",\n defaultValue: \"md\",\n group: \"Design\",\n }),\n {\n type: \"background\",\n key: \"background\",\n label: \"Background\",\n description: \"Background for the layout container\",\n defaultValue: \"background\",\n group: \"Design\",\n },\n getPaddingField({\n key: \"padding\",\n label: \"Padding\",\n description: \"Padding for the layout container\",\n defaultValue: 4,\n group: \"Design\",\n }),\n getBorderRadiusField({\n key: \"borderRadius\",\n label: \"Border Radius\",\n description: \"Border radius for the layout container\",\n defaultValue: \"md\",\n group: \"Design\",\n }),\n getBorderWidthField({\n key: \"borderWidth\",\n label: \"Border Width\",\n description: \"Border width for the widget\",\n defaultValue: \"none\",\n group: \"Design\",\n }),\n getBorderColorField({\n key: \"borderColor\",\n label: \"Border Color\",\n description: \"Border color for the widget\",\n defaultValue: \"muted\",\n group: \"Design\",\n }),\n ],\n};\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require("./chunk-9hOWP6kD.cjs");
|
|
2
2
|
require("./ScreenRenderer-j7Nz1HQx.cjs");
|
|
3
3
|
require("./registry-context-OIsrZ2Ij.cjs");
|
|
4
|
-
const require_LayoutWidget = require("./LayoutWidget-
|
|
5
|
-
require("./registries-
|
|
4
|
+
const require_LayoutWidget = require("./LayoutWidget-8DwDBW24.cjs");
|
|
5
|
+
require("./registries-CVsthTnW.cjs");
|
|
6
6
|
require("./fields-COJ84ouS.cjs");
|
|
7
7
|
exports.layoutWidgetPropertySchema = require_LayoutWidget.layoutWidgetPropertySchema;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { I as __exportAll } from "./portal_tenant_content-DPLnrtOG.mjs";
|
|
2
2
|
import { c as useScreenRenderer, t as ScreenRenderer, u as useRegistry } from "./ScreenRenderer-YOmW7J80.mjs";
|
|
3
|
-
import { f as getGapField, i as getBorderColorField, m as getPaddingField, n as borderWidthClasses, o as getBorderRadiusField, r as gapValues, s as getBorderWidthField, t as borderColorClasses } from "./registries-
|
|
3
|
+
import { f as getGapField, i as getBorderColorField, m as getPaddingField, n as borderWidthClasses, o as getBorderRadiusField, r as gapValues, s as getBorderWidthField, t as borderColorClasses } from "./registries-6F90ZS1m.mjs";
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
5
5
|
/** @deprecated Use SECTION_LAYOUT_CONFIG instead */
|
|
6
6
|
const sectionLayoutConfig = {
|
|
@@ -181,4 +181,4 @@ const layoutWidgetPropertySchema = {
|
|
|
181
181
|
//#endregion
|
|
182
182
|
export { sectionLayoutConfig as a, groupChildrenByColumn as i, LayoutWidget_exports as n, layoutWidgetPropertySchema as r, LayoutWidget as t };
|
|
183
183
|
|
|
184
|
-
//# sourceMappingURL=LayoutWidget-
|
|
184
|
+
//# sourceMappingURL=LayoutWidget-iKNNIRPq.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LayoutWidget-8KxCmJcd.mjs","names":["ScreenRenderer","DefaultScreenRenderer"],"sources":["../../core/src/types/field-types.ts","../../core/src/widget-utils/widget-utils.ts","../../widgets/src/widgets/LayoutWidget.tsx"],"sourcesContent":["import type { ShareableItem } from \"./shareable-item\";\n\n// ============================================================================\n// Color Options - Derive type from constant for single source of truth\n// ============================================================================\n\n/**\n * Color options constant - single source of truth for color values.\n * Use COLOR_OPTIONS.primary instead of \"primary\" for type-safe comparisons.\n */\nexport const COLOR_OPTIONS = {\n background: \"background\",\n foreground: \"foreground\",\n primary: \"primary\",\n secondary: \"secondary\",\n accent: \"accent\",\n muted: \"muted\",\n border: \"border\",\n destructive: \"destructive\",\n transparent: \"transparent\",\n} as const;\n\n/**\n * Union type of all color options, derived from COLOR_OPTIONS constant.\n * @see deriving-typeof-for-object-keys pattern\n */\nexport type ColorOptions = (typeof COLOR_OPTIONS)[keyof typeof COLOR_OPTIONS];\n\n// ============================================================================\n// Size Options - Derive types from constants for single source of truth\n// ============================================================================\n\nexport const FONT_SIZE_OPTIONS = {\n \"2xl\": \"2xl\",\n xl: \"xl\",\n lg: \"lg\",\n md: \"md\",\n sm: \"sm\",\n xs: \"xs\",\n} as const;\n\nexport type FontSizeOptions =\n (typeof FONT_SIZE_OPTIONS)[keyof typeof FONT_SIZE_OPTIONS];\n\nexport const FONT_WEIGHT_OPTIONS = {\n normal: \"normal\",\n medium: \"medium\",\n semibold: \"semibold\",\n bold: \"bold\",\n} as const;\n\nexport type FontWeightOptions =\n (typeof FONT_WEIGHT_OPTIONS)[keyof typeof FONT_WEIGHT_OPTIONS];\n\nexport const BORDER_RADIUS_OPTIONS = {\n none: \"none\",\n sm: \"sm\",\n md: \"md\",\n lg: \"lg\",\n xl: \"xl\",\n full: \"full\",\n} as const;\n\nexport type BorderRadiusOptions =\n (typeof BORDER_RADIUS_OPTIONS)[keyof typeof BORDER_RADIUS_OPTIONS];\n\nexport const BORDER_WIDTH_OPTIONS = {\n none: \"none\",\n thin: \"thin\",\n medium: \"medium\",\n thick: \"thick\",\n} as const;\n\nexport type BorderWidthOptions =\n (typeof BORDER_WIDTH_OPTIONS)[keyof typeof BORDER_WIDTH_OPTIONS];\n\n/** Padding values - numeric, so we use a tuple for derivation */\nexport const PADDING_VALUES = [0, 2, 4, 6, 8, 10] as const;\nexport type PaddingOptions = (typeof PADDING_VALUES)[number];\n\nexport const BUTTON_SIZE_OPTIONS = {\n sm: \"sm\",\n default: \"default\",\n lg: \"lg\",\n xl: \"xl\",\n} as const;\n\nexport type ButtonSizeOptions =\n (typeof BUTTON_SIZE_OPTIONS)[keyof typeof BUTTON_SIZE_OPTIONS];\n\nexport const GAP_OPTIONS = {\n none: \"none\",\n xs: \"xs\",\n sm: \"sm\",\n md: \"md\",\n lg: \"lg\",\n xl: \"xl\",\n} as const;\n\nexport type GapOptions = (typeof GAP_OPTIONS)[keyof typeof GAP_OPTIONS];\n\n// ============================================================================\n// Alignment Options - Derive from constants\n// ============================================================================\n\nexport const VERTICAL_ALIGN_OPTIONS = {\n top: \"top\",\n center: \"center\",\n bottom: \"bottom\",\n} as const;\n\nexport type VerticalAlign =\n (typeof VERTICAL_ALIGN_OPTIONS)[keyof typeof VERTICAL_ALIGN_OPTIONS];\n\nexport const HORIZONTAL_ALIGN_OPTIONS = {\n left: \"left\",\n center: \"center\",\n right: \"right\",\n} as const;\n\nexport type HorizontalAlign =\n (typeof HORIZONTAL_ALIGN_OPTIONS)[keyof typeof HORIZONTAL_ALIGN_OPTIONS];\n\nexport type AlignOptions = {\n vertical?: VerticalAlign;\n horizontal?: HorizontalAlign;\n};\n\n// ============================================================================\n// Background Options - Derive from constant\n// ============================================================================\n\nexport const BACKGROUND_TYPES = {\n solid: \"solid\",\n image: \"image\",\n} as const;\n\nexport type BackgroundType =\n (typeof BACKGROUND_TYPES)[keyof typeof BACKGROUND_TYPES];\nexport interface BackgroundValue {\n type: BackgroundType;\n color?: ColorOptions;\n resource?: ShareableItem;\n}\n\n// ============================================================================\n// Section Layout - Derive type from config keys (single source of truth)\n// ============================================================================\n\n/**\n * Section layout configuration - single source of truth for layout types.\n * SectionLayoutType is derived from these keys to prevent drift.\n */\nexport const SECTION_LAYOUT_CONFIG: {\n readonly \"single-column\": {\n readonly columns: 1;\n readonly widths: readonly [\"1fr\"];\n readonly gridClasses: \"\";\n };\n readonly \"2c-equal\": {\n readonly columns: 2;\n readonly widths: readonly [\"1fr\", \"1fr\"];\n readonly gridClasses: \"@md:grid-cols-2\";\n };\n readonly \"2c-left-wider\": {\n readonly columns: 2;\n readonly widths: readonly [\"2fr\", \"1fr\"];\n readonly gridClasses: \"@md:grid-cols-[2fr_1fr]\";\n };\n readonly \"2c-right-wider\": {\n readonly columns: 2;\n readonly widths: readonly [\"1fr\", \"2fr\"];\n readonly gridClasses: \"@md:grid-cols-[1fr_2fr]\";\n };\n readonly \"2c-left-narrow\": {\n readonly columns: 2;\n readonly widths: readonly [\"1fr\", \"3fr\"];\n readonly gridClasses: \"@md:grid-cols-[1fr_3fr]\";\n };\n readonly \"2c-right-narrow\": {\n readonly columns: 2;\n readonly widths: readonly [\"3fr\", \"1fr\"];\n readonly gridClasses: \"@md:grid-cols-[3fr_1fr]\";\n };\n readonly \"3c-equal\": {\n readonly columns: 3;\n readonly widths: readonly [\"1fr\", \"1fr\", \"1fr\"];\n readonly gridClasses: \"@md:grid-cols-3\";\n };\n readonly \"3c-middle-wider\": {\n readonly columns: 3;\n readonly widths: readonly [\"1fr\", \"2fr\", \"1fr\"];\n readonly gridClasses: \"@md:grid-cols-[1fr_2fr_1fr]\";\n };\n} = {\n \"single-column\": { columns: 1, widths: [\"1fr\"], gridClasses: \"\" },\n \"2c-equal\": {\n columns: 2,\n widths: [\"1fr\", \"1fr\"],\n gridClasses: \"@md:grid-cols-2\",\n },\n \"2c-left-wider\": {\n columns: 2,\n widths: [\"2fr\", \"1fr\"],\n gridClasses: \"@md:grid-cols-[2fr_1fr]\",\n },\n \"2c-right-wider\": {\n columns: 2,\n widths: [\"1fr\", \"2fr\"],\n gridClasses: \"@md:grid-cols-[1fr_2fr]\",\n },\n \"2c-left-narrow\": {\n columns: 2,\n widths: [\"1fr\", \"3fr\"],\n gridClasses: \"@md:grid-cols-[1fr_3fr]\",\n },\n \"2c-right-narrow\": {\n columns: 2,\n widths: [\"3fr\", \"1fr\"],\n gridClasses: \"@md:grid-cols-[3fr_1fr]\",\n },\n \"3c-equal\": {\n columns: 3,\n widths: [\"1fr\", \"1fr\", \"1fr\"],\n gridClasses: \"@md:grid-cols-3\",\n },\n \"3c-middle-wider\": {\n columns: 3,\n widths: [\"1fr\", \"2fr\", \"1fr\"],\n gridClasses: \"@md:grid-cols-[1fr_2fr_1fr]\",\n },\n} as const satisfies Record<\n string,\n {\n readonly columns: number;\n readonly widths: readonly string[];\n readonly gridClasses: string;\n }\n>;\n\n/**\n * Union type of all section layout types, derived from SECTION_LAYOUT_CONFIG keys.\n * @see deriving-typeof-for-object-keys pattern\n */\nexport type SectionLayoutType = keyof typeof SECTION_LAYOUT_CONFIG;\n\n/** @deprecated Use SECTION_LAYOUT_CONFIG instead */\nexport const sectionLayoutConfig: typeof SECTION_LAYOUT_CONFIG =\n SECTION_LAYOUT_CONFIG;\n","import type { WidgetSchema, WidgetPath } from \"../types\";\nimport { WIDGET_TYPE_NAMES, isWidgetType } from \"../types\";\n\n/**\n * Generates a unique ID for a widget\n */\nexport function generateWidgetId(type?: string): string {\n const uuid = crypto.randomUUID();\n return type ? `${type}-${uuid}` : uuid;\n}\n\n/**\n * Converts a widget path to a unique string identifier\n */\nexport function pathToId(path: WidgetPath): string {\n return path.join(\"-\");\n}\n\n/**\n * Converts a path string back to a WidgetPath array\n */\nexport function idToPath(id: string): WidgetPath {\n return id.split(\"-\").map((segment) => parseInt(segment, 10));\n}\n\n/**\n * Ensures all widgets in an array have valid IDs\n * Note: Handles null values for sparse arrays (e.g., grid layouts with empty cells)\n */\nexport function ensureWidgetIds(\n widgets: readonly (WidgetSchema | null)[],\n): (WidgetSchema | null)[] {\n return widgets?.map((widget, index) => {\n if (!widget) return null;\n return {\n ...widget,\n id: widget.id || `widget-${index}-${crypto.randomUUID()}`,\n };\n });\n}\n\n/**\n * Deep clones a widget and regenerates all IDs (including nested children)\n */\nexport function deepCloneWidget(widget: WidgetSchema): WidgetSchema {\n // Handle LayoutWidget children recursively\n // Use type guard for discriminated union narrowing (narrowing-discriminated-unions rule)\n if (\n isWidgetType(widget, WIDGET_TYPE_NAMES.Layout) &&\n Array.isArray(widget.props.children)\n ) {\n // Build cloned widget with recursively cloned children\n return {\n type: widget.type,\n props: {\n ...widget.props,\n children: (\n widget.props.children as readonly (WidgetSchema | null)[]\n ).map((child) => (child ? deepCloneWidget(child) : null)),\n },\n id: generateWidgetId(widget.type),\n };\n }\n\n // Clone non-container widget\n return {\n type: widget.type,\n props: { ...widget.props },\n id: generateWidgetId(widget.type),\n };\n}\n\n/**\n * Deep clones an array of widgets and regenerates all IDs\n */\nexport function deepCloneWidgets(\n widgets: readonly WidgetSchema[],\n): WidgetSchema[] {\n return widgets.map((widget) => deepCloneWidget(widget));\n}\n\n/**\n * Gets a widget at a specific path in the widget tree\n */\nexport function getWidgetByPath(\n screen: readonly (WidgetSchema | null)[],\n path: WidgetPath,\n): WidgetSchema | null {\n if (path.length === 0 || path[0] === undefined) return null;\n\n let current: WidgetSchema | null = screen[path[0]] ?? null;\n\n for (let i = 1; i < path.length; i++) {\n // Use type guard for discriminated union narrowing (narrowing-discriminated-unions rule)\n if (!isWidgetType(current, WIDGET_TYPE_NAMES.Layout)) return null;\n\n const children = (current.props.children ??\n []) as readonly (WidgetSchema | null)[];\n const index = path[i];\n if (index === undefined) return null;\n current = children[index] ?? null;\n }\n\n return current;\n}\n\n/**\n * Groups children by column index.\n * Accepts nullable children (sparse arrays from grid layouts) and filters them out.\n */\nexport function groupChildrenByColumn(\n children: readonly (WidgetSchema | null)[],\n columnCount: number,\n): WidgetSchema[][] {\n // Use explicit type annotation to avoid never[] inference (narrowing-empty-array-type rule)\n const columns: WidgetSchema[][] = Array.from(\n { length: columnCount },\n (): WidgetSchema[] => [],\n );\n\n // Filter out nulls first, then process (truthiness narrowing rule)\n // This avoids the narrowing-callback-scope issue since we work with non-null array\n const nonNullChildren = children.filter(\n (child): child is WidgetSchema => child !== null,\n );\n\n for (const child of nonNullChildren) {\n // Default to column 0 if no columnIndex specified\n const colIndex = Math.min(child.columnIndex ?? 0, columnCount - 1);\n const column = columns[colIndex];\n if (column) {\n column.push(child);\n }\n }\n\n return columns;\n}\n","import { ScreenRenderer as DefaultScreenRenderer } from \"../core/ScreenRenderer\";\nimport { useRegistry } from \"../contexts/RegistryContext\";\nimport { useScreenRenderer } from \"../contexts/ScreenRendererContext\";\nimport type {\n TypedWidgetSchema,\n WidgetSchema,\n BorderRadiusOptions,\n BorderWidthOptions,\n ColorOptions,\n PaddingOptions,\n GapOptions,\n SectionLayoutType,\n BackgroundValue,\n} from \"@fluid-app/portal-core/types\";\nimport { sectionLayoutConfig } from \"@fluid-app/portal-core/types\";\nimport type { ComponentType } from \"react\";\nimport type React from \"react\";\nimport type { WidgetPropertySchema } from \"@fluid-app/portal-core/registries\";\nimport {\n getBorderRadiusField,\n getBorderWidthField,\n getBorderColorField,\n getGapField,\n getPaddingField,\n gapValues,\n borderWidthClasses,\n borderColorClasses,\n} from \"../core/fields\";\nimport { groupChildrenByColumn } from \"@fluid-app/portal-core/widget-utils\";\n\nconst DEFAULT_BACKGROUND: BackgroundValue = {\n type: \"solid\",\n color: \"background\",\n};\nconst DEFAULT_CHILDREN: (WidgetSchema | null)[] = [];\n\ntype LayoutProps<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n T extends Record<string, ComponentType<any>> = Record<\n string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ComponentType<any>\n >,\n> = {\n // Section layout type (masonry-style column configuration)\n sectionLayout?: SectionLayoutType;\n\n // Legacy props (deprecated, kept for backward compatibility)\n type?: \"flex\" | \"grid\";\n columns?: number;\n rows?: number;\n direction?: string;\n justify?: string;\n align?: string;\n wrap?: boolean;\n\n // Spacing\n gap?: number; // deprecated, use gapSize instead\n gapSize?: GapOptions;\n\n // Design\n background?: BackgroundValue;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n borderWidth?: BorderWidthOptions;\n borderColor?: ColorOptions;\n\n // Content - widgets with columnIndex property for masonry layout\n children: (TypedWidgetSchema<T> | null)[] | (WidgetSchema | null)[];\n\n // Widget registry (passed down from parent renderer)\n registry?: T;\n\n // Styling\n className?: string;\n minHeight?: number;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const LayoutWidget = <T extends Record<string, ComponentType<any>>>({\n sectionLayout = \"single-column\",\n gap = 4,\n gapSize,\n background = DEFAULT_BACKGROUND,\n padding = 0,\n borderRadius = \"md\",\n borderWidth = \"none\",\n borderColor = \"muted\",\n children = DEFAULT_CHILDREN,\n registry,\n className = \"\",\n minHeight,\n}: LayoutProps<T>): React.JSX.Element => {\n // Get registry from context if not provided as prop\n const contextRegistry = useRegistry();\n const effectiveRegistry = registry || contextRegistry;\n\n // Use ScreenRenderer from context (e.g. portal-builder's), fall back to local\n const ContextScreenRenderer = useScreenRenderer();\n const ScreenRenderer = ContextScreenRenderer ?? DefaultScreenRenderer;\n\n // Extract background values\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 // Get layout configuration\n const layoutConfig = sectionLayoutConfig[sectionLayout];\n const columnCount = layoutConfig.columns;\n\n // Calculate gap size\n const gapSizeValue = gapSize ? gapValues[gapSize] : gap;\n\n // Build CSS classes for masonry layout with responsive columns\n const layoutClasses = [\n \"grid\",\n \"grid-cols-1\", // Mobile: single column\n layoutConfig.gridClasses, // Desktop (@md+): configured columns\n `bg-${backgroundColor} p-${padding} rounded-${borderRadius} ${borderWidthClasses[borderWidth]} ${borderWidth !== \"none\" ? borderColorClasses[borderColor] : \"\"}`,\n `gap-${gapSizeValue}`,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n // Container style\n const containerStyle: React.CSSProperties = {\n ...(minHeight ? { minHeight: `${minHeight}px` } : {}),\n alignItems: \"start\", // Masonry-style: columns don't stretch to match height\n backgroundImage,\n };\n\n // If no registry is available, we can't render the children\n if (!effectiveRegistry) {\n console.warn(\"Layout widget: No registry provided, cannot render children\");\n return <div className={layoutClasses} style={containerStyle} />;\n }\n\n // Group children by column\n const columnGroups = groupChildrenByColumn(\n children as WidgetSchema[],\n columnCount,\n );\n\n // Regular render mode - render each column as a flex column\n return (\n <div className=\"@container\">\n <div className={layoutClasses} style={containerStyle}>\n {columnGroups.map((columnChildren, colIndex) => (\n <ScreenRenderer\n key={colIndex}\n screen={columnChildren}\n registry={effectiveRegistry}\n className={`flex flex-col gap-${gapSizeValue}`}\n />\n ))}\n </div>\n </div>\n );\n};\n\nexport const layoutWidgetPropertySchema: WidgetPropertySchema = {\n widgetType: \"LayoutWidget\",\n displayName: \"Layout\",\n fields: [\n // Layout Configuration - Visual selector matching Figma design\n {\n key: \"sectionLayout\",\n label: \"Layout Type\",\n type: \"sectionLayoutSelect\",\n description: \"Column layout configuration\",\n defaultValue: \"single-column\",\n group: \"Layout\",\n },\n\n // Design\n getGapField({\n key: \"gapSize\",\n label: \"Gap\",\n description: \"Gap between columns and widgets\",\n defaultValue: \"md\",\n group: \"Design\",\n }),\n {\n type: \"background\",\n key: \"background\",\n label: \"Background\",\n description: \"Background for the layout container\",\n defaultValue: \"background\",\n group: \"Design\",\n },\n getPaddingField({\n key: \"padding\",\n label: \"Padding\",\n description: \"Padding for the layout container\",\n defaultValue: 4,\n group: \"Design\",\n }),\n getBorderRadiusField({\n key: \"borderRadius\",\n label: \"Border Radius\",\n description: \"Border radius for the layout container\",\n defaultValue: \"md\",\n group: \"Design\",\n }),\n getBorderWidthField({\n key: \"borderWidth\",\n label: \"Border Width\",\n description: \"Border width for the widget\",\n defaultValue: \"none\",\n group: \"Design\",\n }),\n getBorderColorField({\n key: \"borderColor\",\n label: \"Border Color\",\n description: \"Border color for the widget\",\n defaultValue: \"muted\",\n group: \"Design\",\n }),\n ],\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"LayoutWidget-iKNNIRPq.mjs","names":["ScreenRenderer","DefaultScreenRenderer"],"sources":["../../core/src/types/field-types.ts","../../core/src/widget-utils/widget-utils.ts","../../widgets/src/widgets/LayoutWidget.tsx"],"sourcesContent":["import type { ShareableItem } from \"./shareable-item\";\n\n// ============================================================================\n// Color Options - Derive type from constant for single source of truth\n// ============================================================================\n\n/**\n * Color options constant - single source of truth for color values.\n * Use COLOR_OPTIONS.primary instead of \"primary\" for type-safe comparisons.\n */\nexport const COLOR_OPTIONS = {\n background: \"background\",\n foreground: \"foreground\",\n primary: \"primary\",\n secondary: \"secondary\",\n accent: \"accent\",\n muted: \"muted\",\n border: \"border\",\n destructive: \"destructive\",\n transparent: \"transparent\",\n} as const;\n\n/**\n * Union type of all color options, derived from COLOR_OPTIONS constant.\n * @see deriving-typeof-for-object-keys pattern\n */\nexport type ColorOptions = (typeof COLOR_OPTIONS)[keyof typeof COLOR_OPTIONS];\n\n// ============================================================================\n// Size Options - Derive types from constants for single source of truth\n// ============================================================================\n\nexport const FONT_SIZE_OPTIONS = {\n \"2xl\": \"2xl\",\n xl: \"xl\",\n lg: \"lg\",\n md: \"md\",\n sm: \"sm\",\n xs: \"xs\",\n} as const;\n\nexport type FontSizeOptions =\n (typeof FONT_SIZE_OPTIONS)[keyof typeof FONT_SIZE_OPTIONS];\n\nexport const FONT_WEIGHT_OPTIONS = {\n normal: \"normal\",\n medium: \"medium\",\n semibold: \"semibold\",\n bold: \"bold\",\n} as const;\n\nexport type FontWeightOptions =\n (typeof FONT_WEIGHT_OPTIONS)[keyof typeof FONT_WEIGHT_OPTIONS];\n\nexport const BORDER_RADIUS_OPTIONS = {\n none: \"none\",\n sm: \"sm\",\n md: \"md\",\n lg: \"lg\",\n xl: \"xl\",\n full: \"full\",\n} as const;\n\nexport type BorderRadiusOptions =\n (typeof BORDER_RADIUS_OPTIONS)[keyof typeof BORDER_RADIUS_OPTIONS];\n\nexport const BORDER_WIDTH_OPTIONS = {\n none: \"none\",\n thin: \"thin\",\n medium: \"medium\",\n thick: \"thick\",\n} as const;\n\nexport type BorderWidthOptions =\n (typeof BORDER_WIDTH_OPTIONS)[keyof typeof BORDER_WIDTH_OPTIONS];\n\n/** Padding values - numeric, so we use a tuple for derivation */\nexport const PADDING_VALUES = [0, 2, 4, 6, 8, 10] as const;\nexport type PaddingOptions = (typeof PADDING_VALUES)[number];\n\nexport const BUTTON_SIZE_OPTIONS = {\n sm: \"sm\",\n default: \"default\",\n lg: \"lg\",\n xl: \"xl\",\n} as const;\n\nexport type ButtonSizeOptions =\n (typeof BUTTON_SIZE_OPTIONS)[keyof typeof BUTTON_SIZE_OPTIONS];\n\nexport const GAP_OPTIONS = {\n none: \"none\",\n xs: \"xs\",\n sm: \"sm\",\n md: \"md\",\n lg: \"lg\",\n xl: \"xl\",\n} as const;\n\nexport type GapOptions = (typeof GAP_OPTIONS)[keyof typeof GAP_OPTIONS];\n\n// ============================================================================\n// Alignment Options - Derive from constants\n// ============================================================================\n\nexport const VERTICAL_ALIGN_OPTIONS = {\n top: \"top\",\n center: \"center\",\n bottom: \"bottom\",\n} as const;\n\nexport type VerticalAlign =\n (typeof VERTICAL_ALIGN_OPTIONS)[keyof typeof VERTICAL_ALIGN_OPTIONS];\n\nexport const HORIZONTAL_ALIGN_OPTIONS = {\n left: \"left\",\n center: \"center\",\n right: \"right\",\n} as const;\n\nexport type HorizontalAlign =\n (typeof HORIZONTAL_ALIGN_OPTIONS)[keyof typeof HORIZONTAL_ALIGN_OPTIONS];\n\nexport type AlignOptions = {\n vertical?: VerticalAlign;\n horizontal?: HorizontalAlign;\n};\n\n// ============================================================================\n// Background Options - Derive from constant\n// ============================================================================\n\nexport const BACKGROUND_TYPES = {\n solid: \"solid\",\n image: \"image\",\n} as const;\n\nexport type BackgroundType =\n (typeof BACKGROUND_TYPES)[keyof typeof BACKGROUND_TYPES];\nexport interface BackgroundValue {\n type: BackgroundType;\n color?: ColorOptions;\n resource?: ShareableItem;\n}\n\n// ============================================================================\n// Section Layout - Derive type from config keys (single source of truth)\n// ============================================================================\n\n/**\n * Section layout configuration - single source of truth for layout types.\n * SectionLayoutType is derived from these keys to prevent drift.\n */\nexport const SECTION_LAYOUT_CONFIG: {\n readonly \"single-column\": {\n readonly columns: 1;\n readonly widths: readonly [\"1fr\"];\n readonly gridClasses: \"\";\n };\n readonly \"2c-equal\": {\n readonly columns: 2;\n readonly widths: readonly [\"1fr\", \"1fr\"];\n readonly gridClasses: \"@md:grid-cols-2\";\n };\n readonly \"2c-left-wider\": {\n readonly columns: 2;\n readonly widths: readonly [\"2fr\", \"1fr\"];\n readonly gridClasses: \"@md:grid-cols-[2fr_1fr]\";\n };\n readonly \"2c-right-wider\": {\n readonly columns: 2;\n readonly widths: readonly [\"1fr\", \"2fr\"];\n readonly gridClasses: \"@md:grid-cols-[1fr_2fr]\";\n };\n readonly \"2c-left-narrow\": {\n readonly columns: 2;\n readonly widths: readonly [\"1fr\", \"3fr\"];\n readonly gridClasses: \"@md:grid-cols-[1fr_3fr]\";\n };\n readonly \"2c-right-narrow\": {\n readonly columns: 2;\n readonly widths: readonly [\"3fr\", \"1fr\"];\n readonly gridClasses: \"@md:grid-cols-[3fr_1fr]\";\n };\n readonly \"3c-equal\": {\n readonly columns: 3;\n readonly widths: readonly [\"1fr\", \"1fr\", \"1fr\"];\n readonly gridClasses: \"@md:grid-cols-3\";\n };\n readonly \"3c-middle-wider\": {\n readonly columns: 3;\n readonly widths: readonly [\"1fr\", \"2fr\", \"1fr\"];\n readonly gridClasses: \"@md:grid-cols-[1fr_2fr_1fr]\";\n };\n} = {\n \"single-column\": { columns: 1, widths: [\"1fr\"], gridClasses: \"\" },\n \"2c-equal\": {\n columns: 2,\n widths: [\"1fr\", \"1fr\"],\n gridClasses: \"@md:grid-cols-2\",\n },\n \"2c-left-wider\": {\n columns: 2,\n widths: [\"2fr\", \"1fr\"],\n gridClasses: \"@md:grid-cols-[2fr_1fr]\",\n },\n \"2c-right-wider\": {\n columns: 2,\n widths: [\"1fr\", \"2fr\"],\n gridClasses: \"@md:grid-cols-[1fr_2fr]\",\n },\n \"2c-left-narrow\": {\n columns: 2,\n widths: [\"1fr\", \"3fr\"],\n gridClasses: \"@md:grid-cols-[1fr_3fr]\",\n },\n \"2c-right-narrow\": {\n columns: 2,\n widths: [\"3fr\", \"1fr\"],\n gridClasses: \"@md:grid-cols-[3fr_1fr]\",\n },\n \"3c-equal\": {\n columns: 3,\n widths: [\"1fr\", \"1fr\", \"1fr\"],\n gridClasses: \"@md:grid-cols-3\",\n },\n \"3c-middle-wider\": {\n columns: 3,\n widths: [\"1fr\", \"2fr\", \"1fr\"],\n gridClasses: \"@md:grid-cols-[1fr_2fr_1fr]\",\n },\n} as const satisfies Record<\n string,\n {\n readonly columns: number;\n readonly widths: readonly string[];\n readonly gridClasses: string;\n }\n>;\n\n/**\n * Union type of all section layout types, derived from SECTION_LAYOUT_CONFIG keys.\n * @see deriving-typeof-for-object-keys pattern\n */\nexport type SectionLayoutType = keyof typeof SECTION_LAYOUT_CONFIG;\n\n/** @deprecated Use SECTION_LAYOUT_CONFIG instead */\nexport const sectionLayoutConfig: typeof SECTION_LAYOUT_CONFIG =\n SECTION_LAYOUT_CONFIG;\n","import type { WidgetSchema, WidgetPath } from \"../types\";\nimport { WIDGET_TYPE_NAMES, isWidgetType } from \"../types\";\n\n/**\n * Generates a unique ID for a widget\n */\nexport function generateWidgetId(type?: string): string {\n const uuid = crypto.randomUUID();\n return type ? `${type}-${uuid}` : uuid;\n}\n\n/**\n * Converts a widget path to a unique string identifier\n */\nexport function pathToId(path: WidgetPath): string {\n return path.join(\"-\");\n}\n\n/**\n * Converts a path string back to a WidgetPath array\n */\nexport function idToPath(id: string): WidgetPath {\n return id.split(\"-\").map((segment) => parseInt(segment, 10));\n}\n\n/**\n * Ensures all widgets in an array have valid IDs\n * Note: Handles null values for sparse arrays (e.g., grid layouts with empty cells)\n */\nexport function ensureWidgetIds(\n widgets: readonly (WidgetSchema | null)[],\n): (WidgetSchema | null)[] {\n return widgets?.map((widget, index) => {\n if (!widget) return null;\n return {\n ...widget,\n id: widget.id || `widget-${index}-${crypto.randomUUID()}`,\n };\n });\n}\n\n/**\n * Deep clones a widget and regenerates all IDs (including nested children)\n */\nexport function deepCloneWidget(widget: WidgetSchema): WidgetSchema {\n // Handle LayoutWidget children recursively\n // Use type guard for discriminated union narrowing (narrowing-discriminated-unions rule)\n if (\n isWidgetType(widget, WIDGET_TYPE_NAMES.Layout) &&\n Array.isArray(widget.props.children)\n ) {\n // Build cloned widget with recursively cloned children\n return {\n type: widget.type,\n props: {\n ...widget.props,\n children: (\n widget.props.children as readonly (WidgetSchema | null)[]\n ).map((child) => (child ? deepCloneWidget(child) : null)),\n },\n id: generateWidgetId(widget.type),\n };\n }\n\n // Clone non-container widget\n return {\n type: widget.type,\n props: { ...widget.props },\n id: generateWidgetId(widget.type),\n };\n}\n\n/**\n * Deep clones an array of widgets and regenerates all IDs\n */\nexport function deepCloneWidgets(\n widgets: readonly WidgetSchema[],\n): WidgetSchema[] {\n return widgets.map((widget) => deepCloneWidget(widget));\n}\n\n/**\n * Gets a widget at a specific path in the widget tree\n */\nexport function getWidgetByPath(\n screen: readonly (WidgetSchema | null)[],\n path: WidgetPath,\n): WidgetSchema | null {\n if (path.length === 0 || path[0] === undefined) return null;\n\n let current: WidgetSchema | null = screen[path[0]] ?? null;\n\n for (let i = 1; i < path.length; i++) {\n // Use type guard for discriminated union narrowing (narrowing-discriminated-unions rule)\n if (!isWidgetType(current, WIDGET_TYPE_NAMES.Layout)) return null;\n\n const children = (current.props.children ??\n []) as readonly (WidgetSchema | null)[];\n const index = path[i];\n if (index === undefined) return null;\n current = children[index] ?? null;\n }\n\n return current;\n}\n\n/**\n * Groups children by column index.\n * Accepts nullable children (sparse arrays from grid layouts) and filters them out.\n */\nexport function groupChildrenByColumn(\n children: readonly (WidgetSchema | null)[],\n columnCount: number,\n): WidgetSchema[][] {\n // Use explicit type annotation to avoid never[] inference (narrowing-empty-array-type rule)\n const columns: WidgetSchema[][] = Array.from(\n { length: columnCount },\n (): WidgetSchema[] => [],\n );\n\n // Filter out nulls first, then process (truthiness narrowing rule)\n // This avoids the narrowing-callback-scope issue since we work with non-null array\n const nonNullChildren = children.filter(\n (child): child is WidgetSchema => child !== null,\n );\n\n for (const child of nonNullChildren) {\n // Default to column 0 if no columnIndex specified\n const colIndex = Math.min(child.columnIndex ?? 0, columnCount - 1);\n const column = columns[colIndex];\n if (column) {\n column.push(child);\n }\n }\n\n return columns;\n}\n","import { ScreenRenderer as DefaultScreenRenderer } from \"../core/ScreenRenderer\";\nimport { useRegistry } from \"../contexts/RegistryContext\";\nimport { useScreenRenderer } from \"../contexts/ScreenRendererContext\";\nimport type {\n TypedWidgetSchema,\n WidgetSchema,\n BorderRadiusOptions,\n BorderWidthOptions,\n ColorOptions,\n PaddingOptions,\n GapOptions,\n SectionLayoutType,\n BackgroundValue,\n} from \"@fluid-app/portal-core/types\";\nimport { sectionLayoutConfig } from \"@fluid-app/portal-core/types\";\nimport type { ComponentType } from \"react\";\nimport type React from \"react\";\nimport type { WidgetPropertySchema } from \"@fluid-app/portal-core/registries\";\nimport {\n getBorderRadiusField,\n getBorderWidthField,\n getBorderColorField,\n getGapField,\n getPaddingField,\n gapValues,\n borderWidthClasses,\n borderColorClasses,\n} from \"../core/fields\";\nimport { groupChildrenByColumn } from \"@fluid-app/portal-core/widget-utils\";\n\nconst DEFAULT_BACKGROUND: BackgroundValue = {\n type: \"solid\",\n color: \"background\",\n};\nconst DEFAULT_CHILDREN: (WidgetSchema | null)[] = [];\n\ntype LayoutProps<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n T extends Record<string, ComponentType<any>> = Record<\n string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ComponentType<any>\n >,\n> = {\n // Section layout type (masonry-style column configuration)\n sectionLayout?: SectionLayoutType;\n\n // Legacy props (deprecated, kept for backward compatibility)\n type?: \"flex\" | \"grid\";\n columns?: number;\n rows?: number;\n direction?: string;\n justify?: string;\n align?: string;\n wrap?: boolean;\n\n // Spacing\n gap?: number; // deprecated, use gapSize instead\n gapSize?: GapOptions;\n\n // Design\n background?: BackgroundValue;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n borderWidth?: BorderWidthOptions;\n borderColor?: ColorOptions;\n\n // Content - widgets with columnIndex property for masonry layout\n children: (TypedWidgetSchema<T> | null)[] | (WidgetSchema | null)[];\n\n // Widget registry (passed down from parent renderer)\n registry?: T;\n\n // Styling\n className?: string;\n minHeight?: number;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const LayoutWidget = <T extends Record<string, ComponentType<any>>>({\n sectionLayout = \"single-column\",\n gap = 4,\n gapSize,\n background = DEFAULT_BACKGROUND,\n padding = 0,\n borderRadius = \"md\",\n borderWidth = \"none\",\n borderColor = \"muted\",\n children = DEFAULT_CHILDREN,\n registry,\n className = \"\",\n minHeight,\n}: LayoutProps<T>): React.JSX.Element => {\n // Get registry from context if not provided as prop\n const contextRegistry = useRegistry();\n const effectiveRegistry = registry || contextRegistry;\n\n // Use ScreenRenderer from context (e.g. portal-builder's), fall back to local\n const ContextScreenRenderer = useScreenRenderer();\n const ScreenRenderer = ContextScreenRenderer ?? DefaultScreenRenderer;\n\n // Extract background values\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 // Get layout configuration\n const layoutConfig = sectionLayoutConfig[sectionLayout];\n const columnCount = layoutConfig.columns;\n\n // Calculate gap size\n const gapSizeValue = gapSize ? gapValues[gapSize] : gap;\n\n // Build CSS classes for masonry layout with responsive columns\n const layoutClasses = [\n \"grid\",\n \"grid-cols-1\", // Mobile: single column\n layoutConfig.gridClasses, // Desktop (@md+): configured columns\n `bg-${backgroundColor} p-${padding} rounded-${borderRadius} ${borderWidthClasses[borderWidth]} ${borderWidth !== \"none\" ? borderColorClasses[borderColor] : \"\"}`,\n `gap-${gapSizeValue}`,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n // Container style\n const containerStyle: React.CSSProperties = {\n ...(minHeight ? { minHeight: `${minHeight}px` } : {}),\n alignItems: \"start\", // Masonry-style: columns don't stretch to match height\n backgroundImage,\n };\n\n // If no registry is available, we can't render the children\n if (!effectiveRegistry) {\n console.warn(\"Layout widget: No registry provided, cannot render children\");\n return <div className={layoutClasses} style={containerStyle} />;\n }\n\n // Group children by column\n const columnGroups = groupChildrenByColumn(\n children as WidgetSchema[],\n columnCount,\n );\n\n // Regular render mode - render each column as a flex column\n return (\n <div className=\"@container\">\n <div className={layoutClasses} style={containerStyle}>\n {columnGroups.map((columnChildren, colIndex) => (\n <ScreenRenderer\n key={colIndex}\n screen={columnChildren}\n registry={effectiveRegistry}\n className={`flex flex-col gap-${gapSizeValue}`}\n />\n ))}\n </div>\n </div>\n );\n};\n\nexport const layoutWidgetPropertySchema: WidgetPropertySchema = {\n widgetType: \"LayoutWidget\",\n displayName: \"Layout\",\n fields: [\n // Layout Configuration - Visual selector matching Figma design\n {\n key: \"sectionLayout\",\n label: \"Layout Type\",\n type: \"sectionLayoutSelect\",\n description: \"Column layout configuration\",\n defaultValue: \"single-column\",\n group: \"Layout\",\n },\n\n // Design\n getGapField({\n key: \"gapSize\",\n label: \"Gap\",\n description: \"Gap between columns and widgets\",\n defaultValue: \"md\",\n group: \"Design\",\n }),\n {\n type: \"background\",\n key: \"background\",\n label: \"Background\",\n description: \"Background for the layout container\",\n defaultValue: \"background\",\n group: \"Design\",\n },\n getPaddingField({\n key: \"padding\",\n label: \"Padding\",\n description: \"Padding for the layout container\",\n defaultValue: 4,\n group: \"Design\",\n }),\n getBorderRadiusField({\n key: \"borderRadius\",\n label: \"Border Radius\",\n description: \"Border radius for the layout container\",\n defaultValue: \"md\",\n group: \"Design\",\n }),\n getBorderWidthField({\n key: \"borderWidth\",\n label: \"Border Width\",\n description: \"Border width for the widget\",\n defaultValue: \"none\",\n group: \"Design\",\n }),\n getBorderColorField({\n key: \"borderColor\",\n label: \"Border Color\",\n description: \"Border color for the widget\",\n defaultValue: \"muted\",\n group: \"Design\",\n }),\n ],\n};\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { I as __exportAll } from "./portal_tenant_content-DPLnrtOG.mjs";
|
|
2
2
|
import { n as useWidgetInteraction } from "./WidgetInteractionContext-I716c8kj.mjs";
|
|
3
|
-
import { a as getBorderRadiusCompositeField, c as getButtonSizeField, i as getBorderColorField, m as getPaddingField, n as borderWidthClasses, s as getBorderWidthField, t as borderColorClasses, u as getFontSizeField } from "./registries-
|
|
3
|
+
import { a as getBorderRadiusCompositeField, c as getButtonSizeField, i as getBorderColorField, m as getPaddingField, n as borderWidthClasses, s as getBorderWidthField, t as borderColorClasses, u as getFontSizeField } from "./registries-6F90ZS1m.mjs";
|
|
4
4
|
import { En as Button } from "./src-B3W228vu.mjs";
|
|
5
5
|
import { useCallback } from "react";
|
|
6
6
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -379,4 +379,4 @@ const linkWidgetPropertySchema = {
|
|
|
379
379
|
//#endregion
|
|
380
380
|
export { LinkWidget_exports as n, linkWidgetPropertySchema as r, LinkWidget as t };
|
|
381
381
|
|
|
382
|
-
//# sourceMappingURL=LinkWidget-
|
|
382
|
+
//# sourceMappingURL=LinkWidget-BoVmB_zf.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LinkWidget-Dvb6WlaR.mjs","names":[],"sources":["../../widgets/src/widgets/LinkWidget.tsx"],"sourcesContent":["import type { WidgetPropertySchema } from \"@fluid-app/portal-core/registries\";\nimport { useCallback, type ComponentProps } from \"react\";\nimport type React from \"react\";\nimport { Button } from \"@fluid-app/ui-primitives\";\nimport { useWidgetInteraction } from \"../contexts/WidgetInteractionContext\";\nimport {\n getBorderRadiusCompositeField,\n getBorderWidthField,\n getBorderColorField,\n borderWidthClasses,\n borderColorClasses,\n getButtonSizeField,\n getFontSizeField,\n getPaddingField,\n} from \"../core/fields\";\nimport type {\n BorderRadiusOptions,\n BorderWidthOptions,\n ButtonSizeOptions,\n ColorOptions,\n FontSizeOptions,\n PaddingOptions,\n} from \"@fluid-app/portal-core/types\";\nimport { AlignCenter, AlignLeft, AlignRight } from \"lucide-react\";\nimport type { ShareableItem } from \"@fluid-app/portal-core/types\";\n\ntype LinkVariant =\n | \"default\"\n | \"outline\"\n | \"secondary\"\n | \"ghost\"\n | \"destructive\";\n\nconst borderRadiusTLClasses: Record<BorderRadiusOptions, string> = {\n none: \"rounded-tl-none\",\n sm: \"rounded-tl-sm\",\n md: \"rounded-tl-md\",\n lg: \"rounded-tl-lg\",\n xl: \"rounded-tl-xl\",\n full: \"rounded-tl-full\",\n};\n\nconst borderRadiusTRClasses: Record<BorderRadiusOptions, string> = {\n none: \"rounded-tr-none\",\n sm: \"rounded-tr-sm\",\n md: \"rounded-tr-md\",\n lg: \"rounded-tr-lg\",\n xl: \"rounded-tr-xl\",\n full: \"rounded-tr-full\",\n};\n\nconst borderRadiusBLClasses: Record<BorderRadiusOptions, string> = {\n none: \"rounded-bl-none\",\n sm: \"rounded-bl-sm\",\n md: \"rounded-bl-md\",\n lg: \"rounded-bl-lg\",\n xl: \"rounded-bl-xl\",\n full: \"rounded-bl-full\",\n};\n\nconst borderRadiusBRClasses: Record<BorderRadiusOptions, string> = {\n none: \"rounded-br-none\",\n sm: \"rounded-br-sm\",\n md: \"rounded-br-md\",\n lg: \"rounded-br-lg\",\n xl: \"rounded-br-xl\",\n full: \"rounded-br-full\",\n};\n\nfunction sanitizeHref(url: string): string | undefined {\n if (!url) return undefined;\n if (/^(https?:|mailto:|tel:|\\/)/i.test(url)) return url;\n return undefined;\n}\n\nexport type LinkType = \"url\" | \"screen\" | \"share\";\nexport type ShareSource = \"resource\" | \"url\";\n\ntype LinkWidgetProps = ComponentProps<\"div\"> & {\n text?: string;\n linkType?: LinkType;\n // URL mode\n href?: string;\n openInNewTab?: boolean;\n // Screen mode\n screenSlug?: string;\n // Share mode\n shareSource?: ShareSource;\n shareResource?: ShareableItem;\n shareUrl?: string;\n // Styling\n variant?: LinkVariant;\n size?: ButtonSizeOptions;\n fontSize?: FontSizeOptions;\n alignment?: \"left\" | \"center\" | \"right\";\n fullWidth?: boolean;\n padding?: PaddingOptions;\n /** @deprecated Use per-corner props instead */\n borderRadius?: BorderRadiusOptions;\n borderRadiusTL?: BorderRadiusOptions;\n borderRadiusTR?: BorderRadiusOptions;\n borderRadiusBL?: BorderRadiusOptions;\n borderRadiusBR?: BorderRadiusOptions;\n borderWidth?: BorderWidthOptions;\n borderColor?: ColorOptions;\n underline?: boolean;\n previewMode?: boolean;\n editMode?: boolean;\n};\n\nconst alignmentClasses = {\n left: \"justify-start\",\n center: \"justify-center\",\n right: \"justify-end\",\n} as const;\n\nexport function LinkWidget({\n text = \"Click Here\",\n linkType = \"url\",\n href = \"\",\n openInNewTab = true,\n screenSlug,\n shareSource,\n shareResource,\n shareUrl,\n variant = \"default\",\n size = \"default\",\n fontSize = \"sm\",\n alignment = \"center\",\n fullWidth = false,\n padding = 0,\n borderRadius,\n borderRadiusTL,\n borderRadiusTR,\n borderRadiusBL,\n borderRadiusBR,\n borderWidth = \"none\",\n borderColor = \"muted\",\n underline = false,\n previewMode = false,\n editMode = false,\n className,\n ...props\n}: LinkWidgetProps): React.JSX.Element {\n const { onNavigate, buildHref } = useWidgetInteraction();\n\n const handleShareClick = useCallback(async () => {\n const isResourceMode = shareSource === \"resource\" || shareSource == null;\n const url = isResourceMode\n ? (shareResource?.share_link ?? undefined)\n : (shareUrl ?? undefined);\n if (!url) return;\n\n if (navigator.share) {\n try {\n await navigator.share({\n url,\n ...(isResourceMode && shareResource?.title\n ? { title: shareResource.title }\n : {}),\n });\n return;\n } catch (e) {\n // User intentionally dismissed the share sheet — do not copy to clipboard\n if (e instanceof DOMException && e.name === \"AbortError\") return;\n // Other errors (e.g. NotAllowedError) — fall through to clipboard\n }\n }\n\n try {\n await navigator.clipboard.writeText(url);\n } catch {\n // Clipboard API not available\n }\n }, [shareSource, shareUrl, shareResource]);\n\n const handleScreenClick = useCallback(\n (e: React.MouseEvent) => {\n if (onNavigate && screenSlug) {\n e.preventDefault();\n onNavigate(screenSlug);\n }\n },\n [onNavigate, screenSlug],\n );\n\n const screenHref = screenSlug\n ? (buildHref?.(screenSlug) ?? screenSlug)\n : undefined;\n if (previewMode) {\n return (\n <div className={`flex justify-center p-4 ${className ?? \"\"}`} {...props}>\n <span\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"36px\",\n padding: \"0 16px\",\n borderRadius: \"6px\",\n backgroundColor: \"#18181b\",\n color: \"#ffffff\",\n fontSize: \"14px\",\n fontWeight: 500,\n }}\n >\n {text}\n </span>\n </div>\n );\n }\n\n const fallback = borderRadius ?? \"md\";\n const tl = borderRadiusTL ?? fallback;\n const tr = borderRadiusTR ?? fallback;\n const bl = borderRadiusBL ?? fallback;\n const br = borderRadiusBR ?? fallback;\n const borderRadiusClasses = `rounded-none ${borderRadiusTLClasses[tl]} ${borderRadiusTRClasses[tr]} ${borderRadiusBLClasses[bl]} ${borderRadiusBRClasses[br]}`;\n const buttonClasses = `text-${fontSize} ${borderRadiusClasses} ${fullWidth ? \"w-full\" : \"\"} ${underline ? \"underline\" : \"\"}`;\n\n return (\n <div\n className={`flex ${alignmentClasses[alignment]} p-${padding} ${borderWidthClasses[borderWidth]} ${borderWidth !== \"none\" ? borderColorClasses[borderColor] : \"\"} ${className ?? \"\"}`}\n {...props}\n >\n <Button asChild variant={variant} size={size} className={buttonClasses}>\n {editMode ? (\n <span className=\"cursor-default\">{text}</span>\n ) : linkType === \"share\" ? (\n <button type=\"button\" onClick={handleShareClick}>\n {text}\n </button>\n ) : linkType === \"screen\" ? (\n screenSlug ? (\n <a href={screenHref} onClick={handleScreenClick}>\n {text}\n </a>\n ) : (\n <span className=\"cursor-default\">{text}</span>\n )\n ) : (\n <a\n href={sanitizeHref(href)}\n {...(openInNewTab\n ? { target: \"_blank\", rel: \"noopener noreferrer\" }\n : {})}\n >\n {text}\n </a>\n )}\n </Button>\n </div>\n );\n}\n\nexport const linkWidgetPropertySchema: WidgetPropertySchema = {\n widgetType: \"LinkWidget\",\n displayName: \"Link Button\",\n fields: [\n // Link Group\n {\n key: \"linkType\",\n label: \"Link Type\",\n type: \"buttonGroup\",\n options: [\n { label: \"URL\", value: \"url\" },\n { label: \"Screen\", value: \"screen\" },\n { label: \"Share\", value: \"share\" },\n ],\n defaultValue: \"url\",\n group: \"Link\",\n },\n {\n key: \"text\",\n label: \"Text\",\n type: \"text\",\n description: \"The button label text\",\n defaultValue: \"Click Here\",\n group: \"Link\",\n },\n // URL mode fields\n {\n key: \"href\",\n label: \"URL\",\n type: \"text\",\n description: \"The destination URL\",\n defaultValue: \"\",\n group: \"Link\",\n requiresKeyValue: { key: \"linkType\", value: \"url\" },\n },\n {\n key: \"openInNewTab\",\n label: \"Open in New Tab\",\n type: \"boolean\",\n description: \"Whether to open the link in a new tab\",\n defaultValue: true,\n group: \"Link\",\n requiresKeyValue: { key: \"linkType\", value: \"url\" },\n },\n // Screen mode fields\n {\n key: \"screenSlug\",\n label: \"Screen\",\n type: \"screenPicker\",\n description: \"Select a screen to navigate to\",\n includeSystemItems: true,\n group: \"Link\",\n requiresKeyValue: { key: \"linkType\", value: \"screen\" },\n },\n // Share mode fields\n {\n key: \"shareSource\",\n label: \"Share Source\",\n type: \"buttonGroup\",\n options: [\n { label: \"Resource\", value: \"resource\" },\n { label: \"URL\", value: \"url\" },\n ],\n defaultValue: \"resource\",\n group: \"Link\",\n requiresKeyValue: { key: \"linkType\", value: \"share\" },\n },\n {\n key: \"shareResource\",\n label: \"Shareable Content\",\n type: \"resource\",\n description: \"Select content to share\",\n allowedTypes: [\"Product\", \"Medium\", \"Library\", \"Page\", \"EnrollmentPack\"],\n group: \"Link\",\n requiresKeyValue: [\n { key: \"linkType\", value: \"share\" },\n { key: \"shareSource\", value: \"resource\" },\n ],\n },\n {\n key: \"shareUrl\",\n label: \"Share URL\",\n type: \"text\",\n description: \"The URL to share\",\n defaultValue: \"\",\n group: \"Link\",\n requiresKeyValue: [\n { key: \"linkType\", value: \"share\" },\n { key: \"shareSource\", value: \"url\" },\n ],\n },\n // Button Style Group\n {\n key: \"variant\",\n label: \"Variant\",\n type: \"select\",\n description: \"The visual style of the button\",\n options: [\n { label: \"Default\", value: \"default\" },\n { label: \"Outline\", value: \"outline\" },\n { label: \"Secondary\", value: \"secondary\" },\n { label: \"Ghost\", value: \"ghost\" },\n { label: \"Destructive\", value: \"destructive\" },\n ],\n defaultValue: \"default\",\n group: \"Button Style\",\n },\n getButtonSizeField({\n key: \"size\",\n label: \"Size\",\n description: \"The size of the button\",\n defaultValue: \"default\",\n group: \"Button Style\",\n }),\n getFontSizeField({\n key: \"fontSize\",\n label: \"Text Size\",\n description: \"The font size of the button text\",\n defaultValue: \"sm\",\n group: \"Button Style\",\n }),\n {\n key: \"underline\",\n label: \"Underline\",\n type: \"boolean\",\n description: \"Underline the button text\",\n defaultValue: false,\n group: \"Button Style\",\n },\n // Layout Group\n {\n key: \"alignment\",\n label: \"Alignment\",\n type: \"buttonGroup\",\n description: \"Horizontal alignment of the button\",\n options: [\n { icon: AlignLeft, ariaLabel: \"Align left\", value: \"left\" },\n { icon: AlignCenter, ariaLabel: \"Align center\", value: \"center\" },\n { icon: AlignRight, ariaLabel: \"Align right\", value: \"right\" },\n ],\n defaultValue: \"center\",\n group: \"Layout\",\n },\n {\n key: \"fullWidth\",\n label: \"Full Width\",\n type: \"boolean\",\n description: \"Makes the button stretch to full container width\",\n defaultValue: false,\n group: \"Layout\",\n },\n getPaddingField({\n key: \"padding\",\n label: \"Padding\",\n description: \"Outer container padding\",\n defaultValue: 0,\n group: \"Layout\",\n }),\n // Design Group\n getBorderRadiusCompositeField({\n key: \"borderRadiusGroup\",\n label: \"Border Radius\",\n defaultValue: \"md\",\n group: \"Design\",\n }),\n getBorderWidthField({\n key: \"borderWidth\",\n label: \"Border Width\",\n description: \"Border width for the widget\",\n defaultValue: \"none\",\n group: \"Design\",\n }),\n getBorderColorField({\n key: \"borderColor\",\n label: \"Border Color\",\n description: \"Border color for the widget\",\n defaultValue: \"muted\",\n group: \"Design\",\n }),\n ],\n};\n"],"mappings":";;;;;;;;;;;;AAiCA,MAAM,wBAA6D;CACjE,MAAM;CACN,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,MAAM;CACP;AAED,MAAM,wBAA6D;CACjE,MAAM;CACN,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,MAAM;CACP;AAED,MAAM,wBAA6D;CACjE,MAAM;CACN,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,MAAM;CACP;AAED,MAAM,wBAA6D;CACjE,MAAM;CACN,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,MAAM;CACP;AAED,SAAS,aAAa,KAAiC;AACrD,KAAI,CAAC,IAAK,QAAO,KAAA;AACjB,KAAI,8BAA8B,KAAK,IAAI,CAAE,QAAO;;AAuCtD,MAAM,mBAAmB;CACvB,MAAM;CACN,QAAQ;CACR,OAAO;CACR;AAED,SAAgB,WAAW,EACzB,OAAO,cACP,WAAW,OACX,OAAO,IACP,eAAe,MACf,YACA,aACA,eACA,UACA,UAAU,WACV,OAAO,WACP,WAAW,MACX,YAAY,UACZ,YAAY,OACZ,UAAU,GACV,cACA,gBACA,gBACA,gBACA,gBACA,cAAc,QACd,cAAc,SACd,YAAY,OACZ,cAAc,OACd,WAAW,OACX,WACA,GAAG,SACkC;CACrC,MAAM,EAAE,YAAY,cAAc,sBAAsB;CAExD,MAAM,mBAAmB,YAAY,YAAY;EAC/C,MAAM,iBAAiB,gBAAgB,cAAc,eAAe;EACpE,MAAM,MAAM,iBACP,eAAe,cAAc,KAAA,IAC7B,YAAY,KAAA;AACjB,MAAI,CAAC,IAAK;AAEV,MAAI,UAAU,MACZ,KAAI;AACF,SAAM,UAAU,MAAM;IACpB;IACA,GAAI,kBAAkB,eAAe,QACjC,EAAE,OAAO,cAAc,OAAO,GAC9B,EAAE;IACP,CAAC;AACF;WACO,GAAG;AAEV,OAAI,aAAa,gBAAgB,EAAE,SAAS,aAAc;;AAK9D,MAAI;AACF,SAAM,UAAU,UAAU,UAAU,IAAI;UAClC;IAGP;EAAC;EAAa;EAAU;EAAc,CAAC;CAE1C,MAAM,oBAAoB,aACvB,MAAwB;AACvB,MAAI,cAAc,YAAY;AAC5B,KAAE,gBAAgB;AAClB,cAAW,WAAW;;IAG1B,CAAC,YAAY,WAAW,CACzB;CAED,MAAM,aAAa,aACd,YAAY,WAAW,IAAI,aAC5B,KAAA;AACJ,KAAI,YACF,QACE,oBAAC,OAAD;EAAK,WAAW,2BAA2B,aAAa;EAAM,GAAI;YAChE,oBAAC,QAAD;GACE,OAAO;IACL,SAAS;IACT,YAAY;IACZ,gBAAgB;IAChB,QAAQ;IACR,SAAS;IACT,cAAc;IACd,iBAAiB;IACjB,OAAO;IACP,UAAU;IACV,YAAY;IACb;aAEA;GACI,CAAA;EACH,CAAA;CAIV,MAAM,WAAW,gBAAgB;CACjC,MAAM,KAAK,kBAAkB;CAC7B,MAAM,KAAK,kBAAkB;CAC7B,MAAM,KAAK,kBAAkB;CAC7B,MAAM,KAAK,kBAAkB;CAE7B,MAAM,gBAAgB,QAAQ,SAAS,GADX,gBAAgB,sBAAsB,IAAI,GAAG,sBAAsB,IAAI,GAAG,sBAAsB,IAAI,GAAG,sBAAsB,MAC3F,GAAG,YAAY,WAAW,GAAG,GAAG,YAAY,cAAc;AAExH,QACE,oBAAC,OAAD;EACE,WAAW,QAAQ,iBAAiB,WAAW,KAAK,QAAQ,GAAG,mBAAmB,aAAa,GAAG,gBAAgB,SAAS,mBAAmB,eAAe,GAAG,GAAG,aAAa;EAChL,GAAI;YAEJ,oBAAC,QAAD;GAAQ,SAAA;GAAiB;GAAe;GAAM,WAAW;aACtD,WACC,oBAAC,QAAD;IAAM,WAAU;cAAkB;IAAY,CAAA,GAC5C,aAAa,UACf,oBAAC,UAAD;IAAQ,MAAK;IAAS,SAAS;cAC5B;IACM,CAAA,GACP,aAAa,WACf,aACE,oBAAC,KAAD;IAAG,MAAM;IAAY,SAAS;cAC3B;IACC,CAAA,GAEJ,oBAAC,QAAD;IAAM,WAAU;cAAkB;IAAY,CAAA,GAGhD,oBAAC,KAAD;IACE,MAAM,aAAa,KAAK;IACxB,GAAK,eACD;KAAE,QAAQ;KAAU,KAAK;KAAuB,GAChD,EAAE;cAEL;IACC,CAAA;GAEC,CAAA;EACL,CAAA;;AAIV,MAAa,2BAAiD;CAC5D,YAAY;CACZ,aAAa;CACb,QAAQ;EAEN;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,SAAS;IACP;KAAE,OAAO;KAAO,OAAO;KAAO;IAC9B;KAAE,OAAO;KAAU,OAAO;KAAU;IACpC;KAAE,OAAO;KAAS,OAAO;KAAS;IACnC;GACD,cAAc;GACd,OAAO;GACR;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,OAAO;GACR;EAED;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,OAAO;GACP,kBAAkB;IAAE,KAAK;IAAY,OAAO;IAAO;GACpD;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,OAAO;GACP,kBAAkB;IAAE,KAAK;IAAY,OAAO;IAAO;GACpD;EAED;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,oBAAoB;GACpB,OAAO;GACP,kBAAkB;IAAE,KAAK;IAAY,OAAO;IAAU;GACvD;EAED;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,SAAS,CACP;IAAE,OAAO;IAAY,OAAO;IAAY,EACxC;IAAE,OAAO;IAAO,OAAO;IAAO,CAC/B;GACD,cAAc;GACd,OAAO;GACP,kBAAkB;IAAE,KAAK;IAAY,OAAO;IAAS;GACtD;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;IAAC;IAAW;IAAU;IAAW;IAAQ;IAAiB;GACxE,OAAO;GACP,kBAAkB,CAChB;IAAE,KAAK;IAAY,OAAO;IAAS,EACnC;IAAE,KAAK;IAAe,OAAO;IAAY,CAC1C;GACF;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,OAAO;GACP,kBAAkB,CAChB;IAAE,KAAK;IAAY,OAAO;IAAS,EACnC;IAAE,KAAK;IAAe,OAAO;IAAO,CACrC;GACF;EAED;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,SAAS;IACP;KAAE,OAAO;KAAW,OAAO;KAAW;IACtC;KAAE,OAAO;KAAW,OAAO;KAAW;IACtC;KAAE,OAAO;KAAa,OAAO;KAAa;IAC1C;KAAE,OAAO;KAAS,OAAO;KAAS;IAClC;KAAE,OAAO;KAAe,OAAO;KAAe;IAC/C;GACD,cAAc;GACd,OAAO;GACR;EACD,mBAAmB;GACjB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,OAAO;GACR,CAAC;EACF,iBAAiB;GACf,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,OAAO;GACR,CAAC;EACF;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,OAAO;GACR;EAED;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,SAAS;IACP;KAAE,MAAM;KAAW,WAAW;KAAc,OAAO;KAAQ;IAC3D;KAAE,MAAM;KAAa,WAAW;KAAgB,OAAO;KAAU;IACjE;KAAE,MAAM;KAAY,WAAW;KAAe,OAAO;KAAS;IAC/D;GACD,cAAc;GACd,OAAO;GACR;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,OAAO;GACR;EACD,gBAAgB;GACd,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,OAAO;GACR,CAAC;EAEF,8BAA8B;GAC5B,KAAK;GACL,OAAO;GACP,cAAc;GACd,OAAO;GACR,CAAC;EACF,oBAAoB;GAClB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,OAAO;GACR,CAAC;EACF,oBAAoB;GAClB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,OAAO;GACR,CAAC;EACH;CACF"}
|
|
1
|
+
{"version":3,"file":"LinkWidget-BoVmB_zf.mjs","names":[],"sources":["../../widgets/src/widgets/LinkWidget.tsx"],"sourcesContent":["import type { WidgetPropertySchema } from \"@fluid-app/portal-core/registries\";\nimport { useCallback, type ComponentProps } from \"react\";\nimport type React from \"react\";\nimport { Button } from \"@fluid-app/ui-primitives\";\nimport { useWidgetInteraction } from \"../contexts/WidgetInteractionContext\";\nimport {\n getBorderRadiusCompositeField,\n getBorderWidthField,\n getBorderColorField,\n borderWidthClasses,\n borderColorClasses,\n getButtonSizeField,\n getFontSizeField,\n getPaddingField,\n} from \"../core/fields\";\nimport type {\n BorderRadiusOptions,\n BorderWidthOptions,\n ButtonSizeOptions,\n ColorOptions,\n FontSizeOptions,\n PaddingOptions,\n} from \"@fluid-app/portal-core/types\";\nimport { AlignCenter, AlignLeft, AlignRight } from \"lucide-react\";\nimport type { ShareableItem } from \"@fluid-app/portal-core/types\";\n\ntype LinkVariant =\n | \"default\"\n | \"outline\"\n | \"secondary\"\n | \"ghost\"\n | \"destructive\";\n\nconst borderRadiusTLClasses: Record<BorderRadiusOptions, string> = {\n none: \"rounded-tl-none\",\n sm: \"rounded-tl-sm\",\n md: \"rounded-tl-md\",\n lg: \"rounded-tl-lg\",\n xl: \"rounded-tl-xl\",\n full: \"rounded-tl-full\",\n};\n\nconst borderRadiusTRClasses: Record<BorderRadiusOptions, string> = {\n none: \"rounded-tr-none\",\n sm: \"rounded-tr-sm\",\n md: \"rounded-tr-md\",\n lg: \"rounded-tr-lg\",\n xl: \"rounded-tr-xl\",\n full: \"rounded-tr-full\",\n};\n\nconst borderRadiusBLClasses: Record<BorderRadiusOptions, string> = {\n none: \"rounded-bl-none\",\n sm: \"rounded-bl-sm\",\n md: \"rounded-bl-md\",\n lg: \"rounded-bl-lg\",\n xl: \"rounded-bl-xl\",\n full: \"rounded-bl-full\",\n};\n\nconst borderRadiusBRClasses: Record<BorderRadiusOptions, string> = {\n none: \"rounded-br-none\",\n sm: \"rounded-br-sm\",\n md: \"rounded-br-md\",\n lg: \"rounded-br-lg\",\n xl: \"rounded-br-xl\",\n full: \"rounded-br-full\",\n};\n\nfunction sanitizeHref(url: string): string | undefined {\n if (!url) return undefined;\n if (/^(https?:|mailto:|tel:|\\/)/i.test(url)) return url;\n return undefined;\n}\n\nexport type LinkType = \"url\" | \"screen\" | \"share\";\nexport type ShareSource = \"resource\" | \"url\";\n\ntype LinkWidgetProps = ComponentProps<\"div\"> & {\n text?: string;\n linkType?: LinkType;\n // URL mode\n href?: string;\n openInNewTab?: boolean;\n // Screen mode\n screenSlug?: string;\n // Share mode\n shareSource?: ShareSource;\n shareResource?: ShareableItem;\n shareUrl?: string;\n // Styling\n variant?: LinkVariant;\n size?: ButtonSizeOptions;\n fontSize?: FontSizeOptions;\n alignment?: \"left\" | \"center\" | \"right\";\n fullWidth?: boolean;\n padding?: PaddingOptions;\n /** @deprecated Use per-corner props instead */\n borderRadius?: BorderRadiusOptions;\n borderRadiusTL?: BorderRadiusOptions;\n borderRadiusTR?: BorderRadiusOptions;\n borderRadiusBL?: BorderRadiusOptions;\n borderRadiusBR?: BorderRadiusOptions;\n borderWidth?: BorderWidthOptions;\n borderColor?: ColorOptions;\n underline?: boolean;\n previewMode?: boolean;\n editMode?: boolean;\n};\n\nconst alignmentClasses = {\n left: \"justify-start\",\n center: \"justify-center\",\n right: \"justify-end\",\n} as const;\n\nexport function LinkWidget({\n text = \"Click Here\",\n linkType = \"url\",\n href = \"\",\n openInNewTab = true,\n screenSlug,\n shareSource,\n shareResource,\n shareUrl,\n variant = \"default\",\n size = \"default\",\n fontSize = \"sm\",\n alignment = \"center\",\n fullWidth = false,\n padding = 0,\n borderRadius,\n borderRadiusTL,\n borderRadiusTR,\n borderRadiusBL,\n borderRadiusBR,\n borderWidth = \"none\",\n borderColor = \"muted\",\n underline = false,\n previewMode = false,\n editMode = false,\n className,\n ...props\n}: LinkWidgetProps): React.JSX.Element {\n const { onNavigate, buildHref } = useWidgetInteraction();\n\n const handleShareClick = useCallback(async () => {\n const isResourceMode = shareSource === \"resource\" || shareSource == null;\n const url = isResourceMode\n ? (shareResource?.share_link ?? undefined)\n : (shareUrl ?? undefined);\n if (!url) return;\n\n if (navigator.share) {\n try {\n await navigator.share({\n url,\n ...(isResourceMode && shareResource?.title\n ? { title: shareResource.title }\n : {}),\n });\n return;\n } catch (e) {\n // User intentionally dismissed the share sheet — do not copy to clipboard\n if (e instanceof DOMException && e.name === \"AbortError\") return;\n // Other errors (e.g. NotAllowedError) — fall through to clipboard\n }\n }\n\n try {\n await navigator.clipboard.writeText(url);\n } catch {\n // Clipboard API not available\n }\n }, [shareSource, shareUrl, shareResource]);\n\n const handleScreenClick = useCallback(\n (e: React.MouseEvent) => {\n if (onNavigate && screenSlug) {\n e.preventDefault();\n onNavigate(screenSlug);\n }\n },\n [onNavigate, screenSlug],\n );\n\n const screenHref = screenSlug\n ? (buildHref?.(screenSlug) ?? screenSlug)\n : undefined;\n if (previewMode) {\n return (\n <div className={`flex justify-center p-4 ${className ?? \"\"}`} {...props}>\n <span\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"36px\",\n padding: \"0 16px\",\n borderRadius: \"6px\",\n backgroundColor: \"#18181b\",\n color: \"#ffffff\",\n fontSize: \"14px\",\n fontWeight: 500,\n }}\n >\n {text}\n </span>\n </div>\n );\n }\n\n const fallback = borderRadius ?? \"md\";\n const tl = borderRadiusTL ?? fallback;\n const tr = borderRadiusTR ?? fallback;\n const bl = borderRadiusBL ?? fallback;\n const br = borderRadiusBR ?? fallback;\n const borderRadiusClasses = `rounded-none ${borderRadiusTLClasses[tl]} ${borderRadiusTRClasses[tr]} ${borderRadiusBLClasses[bl]} ${borderRadiusBRClasses[br]}`;\n const buttonClasses = `text-${fontSize} ${borderRadiusClasses} ${fullWidth ? \"w-full\" : \"\"} ${underline ? \"underline\" : \"\"}`;\n\n return (\n <div\n className={`flex ${alignmentClasses[alignment]} p-${padding} ${borderWidthClasses[borderWidth]} ${borderWidth !== \"none\" ? borderColorClasses[borderColor] : \"\"} ${className ?? \"\"}`}\n {...props}\n >\n <Button asChild variant={variant} size={size} className={buttonClasses}>\n {editMode ? (\n <span className=\"cursor-default\">{text}</span>\n ) : linkType === \"share\" ? (\n <button type=\"button\" onClick={handleShareClick}>\n {text}\n </button>\n ) : linkType === \"screen\" ? (\n screenSlug ? (\n <a href={screenHref} onClick={handleScreenClick}>\n {text}\n </a>\n ) : (\n <span className=\"cursor-default\">{text}</span>\n )\n ) : (\n <a\n href={sanitizeHref(href)}\n {...(openInNewTab\n ? { target: \"_blank\", rel: \"noopener noreferrer\" }\n : {})}\n >\n {text}\n </a>\n )}\n </Button>\n </div>\n );\n}\n\nexport const linkWidgetPropertySchema: WidgetPropertySchema = {\n widgetType: \"LinkWidget\",\n displayName: \"Link Button\",\n fields: [\n // Link Group\n {\n key: \"linkType\",\n label: \"Link Type\",\n type: \"buttonGroup\",\n options: [\n { label: \"URL\", value: \"url\" },\n { label: \"Screen\", value: \"screen\" },\n { label: \"Share\", value: \"share\" },\n ],\n defaultValue: \"url\",\n group: \"Link\",\n },\n {\n key: \"text\",\n label: \"Text\",\n type: \"text\",\n description: \"The button label text\",\n defaultValue: \"Click Here\",\n group: \"Link\",\n },\n // URL mode fields\n {\n key: \"href\",\n label: \"URL\",\n type: \"text\",\n description: \"The destination URL\",\n defaultValue: \"\",\n group: \"Link\",\n requiresKeyValue: { key: \"linkType\", value: \"url\" },\n },\n {\n key: \"openInNewTab\",\n label: \"Open in New Tab\",\n type: \"boolean\",\n description: \"Whether to open the link in a new tab\",\n defaultValue: true,\n group: \"Link\",\n requiresKeyValue: { key: \"linkType\", value: \"url\" },\n },\n // Screen mode fields\n {\n key: \"screenSlug\",\n label: \"Screen\",\n type: \"screenPicker\",\n description: \"Select a screen to navigate to\",\n includeSystemItems: true,\n group: \"Link\",\n requiresKeyValue: { key: \"linkType\", value: \"screen\" },\n },\n // Share mode fields\n {\n key: \"shareSource\",\n label: \"Share Source\",\n type: \"buttonGroup\",\n options: [\n { label: \"Resource\", value: \"resource\" },\n { label: \"URL\", value: \"url\" },\n ],\n defaultValue: \"resource\",\n group: \"Link\",\n requiresKeyValue: { key: \"linkType\", value: \"share\" },\n },\n {\n key: \"shareResource\",\n label: \"Shareable Content\",\n type: \"resource\",\n description: \"Select content to share\",\n allowedTypes: [\"Product\", \"Medium\", \"Library\", \"Page\", \"EnrollmentPack\"],\n group: \"Link\",\n requiresKeyValue: [\n { key: \"linkType\", value: \"share\" },\n { key: \"shareSource\", value: \"resource\" },\n ],\n },\n {\n key: \"shareUrl\",\n label: \"Share URL\",\n type: \"text\",\n description: \"The URL to share\",\n defaultValue: \"\",\n group: \"Link\",\n requiresKeyValue: [\n { key: \"linkType\", value: \"share\" },\n { key: \"shareSource\", value: \"url\" },\n ],\n },\n // Button Style Group\n {\n key: \"variant\",\n label: \"Variant\",\n type: \"select\",\n description: \"The visual style of the button\",\n options: [\n { label: \"Default\", value: \"default\" },\n { label: \"Outline\", value: \"outline\" },\n { label: \"Secondary\", value: \"secondary\" },\n { label: \"Ghost\", value: \"ghost\" },\n { label: \"Destructive\", value: \"destructive\" },\n ],\n defaultValue: \"default\",\n group: \"Button Style\",\n },\n getButtonSizeField({\n key: \"size\",\n label: \"Size\",\n description: \"The size of the button\",\n defaultValue: \"default\",\n group: \"Button Style\",\n }),\n getFontSizeField({\n key: \"fontSize\",\n label: \"Text Size\",\n description: \"The font size of the button text\",\n defaultValue: \"sm\",\n group: \"Button Style\",\n }),\n {\n key: \"underline\",\n label: \"Underline\",\n type: \"boolean\",\n description: \"Underline the button text\",\n defaultValue: false,\n group: \"Button Style\",\n },\n // Layout Group\n {\n key: \"alignment\",\n label: \"Alignment\",\n type: \"buttonGroup\",\n description: \"Horizontal alignment of the button\",\n options: [\n { icon: AlignLeft, ariaLabel: \"Align left\", value: \"left\" },\n { icon: AlignCenter, ariaLabel: \"Align center\", value: \"center\" },\n { icon: AlignRight, ariaLabel: \"Align right\", value: \"right\" },\n ],\n defaultValue: \"center\",\n group: \"Layout\",\n },\n {\n key: \"fullWidth\",\n label: \"Full Width\",\n type: \"boolean\",\n description: \"Makes the button stretch to full container width\",\n defaultValue: false,\n group: \"Layout\",\n },\n getPaddingField({\n key: \"padding\",\n label: \"Padding\",\n description: \"Outer container padding\",\n defaultValue: 0,\n group: \"Layout\",\n }),\n // Design Group\n getBorderRadiusCompositeField({\n key: \"borderRadiusGroup\",\n label: \"Border Radius\",\n defaultValue: \"md\",\n group: \"Design\",\n }),\n getBorderWidthField({\n key: \"borderWidth\",\n label: \"Border Width\",\n description: \"Border width for the widget\",\n defaultValue: \"none\",\n group: \"Design\",\n }),\n getBorderColorField({\n key: \"borderColor\",\n label: \"Border Color\",\n description: \"Border color for the widget\",\n defaultValue: \"muted\",\n group: \"Design\",\n }),\n ],\n};\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require("./chunk-9hOWP6kD.cjs");
|
|
2
2
|
require("./WidgetInteractionContext-DUJhDVnC.cjs");
|
|
3
|
-
require("./registries-
|
|
3
|
+
require("./registries-CVsthTnW.cjs");
|
|
4
4
|
require("./fields-COJ84ouS.cjs");
|
|
5
5
|
require("./src-BFJg9F_s.cjs");
|
|
6
|
-
const require_LinkWidget = require("./LinkWidget-
|
|
6
|
+
const require_LinkWidget = require("./LinkWidget-DpylGthu.cjs");
|
|
7
7
|
exports.linkWidgetPropertySchema = require_LinkWidget.linkWidgetPropertySchema;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require("./chunk-9hOWP6kD.cjs");
|
|
2
2
|
const require_WidgetInteractionContext = require("./WidgetInteractionContext-DUJhDVnC.cjs");
|
|
3
|
-
const require_registries = require("./registries-
|
|
3
|
+
const require_registries = require("./registries-CVsthTnW.cjs");
|
|
4
4
|
const require_src = require("./src-BFJg9F_s.cjs");
|
|
5
5
|
let react = require("react");
|
|
6
6
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
@@ -386,4 +386,4 @@ Object.defineProperty(exports, "linkWidgetPropertySchema", {
|
|
|
386
386
|
}
|
|
387
387
|
});
|
|
388
388
|
|
|
389
|
-
//# sourceMappingURL=LinkWidget-
|
|
389
|
+
//# sourceMappingURL=LinkWidget-DpylGthu.cjs.map
|