@fluid-app/portal-sdk 0.1.89 → 0.1.91
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/{AppDownloadScreen--gGSPUDm.cjs → AppDownloadScreen-BtvcE4pE.cjs} +2 -2
- package/dist/{AppDownloadScreen--gGSPUDm.cjs.map → AppDownloadScreen-BtvcE4pE.cjs.map} +1 -1
- package/dist/{AppDownloadScreen-CDMvuvsQ.cjs → AppDownloadScreen-Dx2nilnX.cjs} +3 -3
- package/dist/{AppDownloadScreen-Bt--8jSo.mjs → AppDownloadScreen-RX8GSAyq.mjs} +2 -2
- package/dist/{AppDownloadScreen-Bt--8jSo.mjs.map → AppDownloadScreen-RX8GSAyq.mjs.map} +1 -1
- package/dist/{ContactsScreen-BZOjocjS.cjs → ContactsScreen-CKMZIQlF.cjs} +3 -3
- package/dist/{ContactsScreen-21VYWIsO.mjs → ContactsScreen-DOz11uQ_.mjs} +2 -2
- package/dist/{ContactsScreen-21VYWIsO.mjs.map → ContactsScreen-DOz11uQ_.mjs.map} +1 -1
- package/dist/{ContactsScreen-DH3K85c6.cjs → ContactsScreen-DttcI388.cjs} +2 -2
- package/dist/{ContactsScreen-DH3K85c6.cjs.map → ContactsScreen-DttcI388.cjs.map} +1 -1
- package/dist/{FluidProvider-CRiIzR8g.mjs → FluidProvider-Eohedipr.mjs} +3 -3
- package/dist/{FluidProvider-CRiIzR8g.mjs.map → FluidProvider-Eohedipr.mjs.map} +1 -1
- package/dist/{FluidProvider-Cwh9D2D_.cjs → FluidProvider-Sc51VlLw.cjs} +3 -3
- package/dist/{FluidProvider-Cwh9D2D_.cjs.map → FluidProvider-Sc51VlLw.cjs.map} +1 -1
- package/dist/{MessagingScreen-68mp7aIc.mjs → MessagingScreen-CMxjIURw.mjs} +3 -3
- package/dist/{MessagingScreen-68mp7aIc.mjs.map → MessagingScreen-CMxjIURw.mjs.map} +1 -1
- package/dist/{MessagingScreen-BIFFfpwv.cjs → MessagingScreen-CdHBUykK.cjs} +3 -3
- package/dist/{MessagingScreen-DbXef2ee.mjs → MessagingScreen-Cx0bbvfs.mjs} +3 -3
- package/dist/{MessagingScreen-Cljq2xIQ.cjs → MessagingScreen-r67FUDf1.cjs} +3 -3
- package/dist/{MessagingScreen-Cljq2xIQ.cjs.map → MessagingScreen-r67FUDf1.cjs.map} +1 -1
- package/dist/{MySiteScreen-D5yvFmK3.cjs → MySiteScreen-8lZTZzo0.cjs} +4 -4
- package/dist/{MySiteScreen-YujACNSf.mjs → MySiteScreen-BhdmPFar.mjs} +3 -3
- package/dist/{MySiteScreen-YujACNSf.mjs.map → MySiteScreen-BhdmPFar.mjs.map} +1 -1
- package/dist/{MySiteScreen-C4Ut8wxE.cjs → MySiteScreen-Cy7HpS3z.cjs} +3 -3
- package/dist/{MySiteScreen-C4Ut8wxE.cjs.map → MySiteScreen-Cy7HpS3z.cjs.map} +1 -1
- package/dist/{NestedWidget-zn_USrld.cjs → NestedWidget-BXbQcApb.cjs} +1 -1
- package/dist/{NestedWidget-L8ppxJib.mjs → NestedWidget-CzSHHhEl.mjs} +2 -2
- package/dist/NestedWidget-CzSHHhEl.mjs.map +1 -0
- package/dist/{NestedWidget-BGY4LSQq.cjs → NestedWidget-iootjKIl.cjs} +2 -2
- package/dist/NestedWidget-iootjKIl.cjs.map +1 -0
- package/dist/{OrdersScreen-CPJX2XiN.cjs → OrdersScreen-BaqQzT1F.cjs} +3 -3
- package/dist/{OrdersScreen-CPJX2XiN.cjs.map → OrdersScreen-BaqQzT1F.cjs.map} +1 -1
- package/dist/{OrdersScreen-BkxKQpwS.mjs → OrdersScreen-D0TnBQc5.mjs} +3 -3
- package/dist/{OrdersScreen-BkxKQpwS.mjs.map → OrdersScreen-D0TnBQc5.mjs.map} +1 -1
- package/dist/{OrdersScreen-BiuWTsM3.cjs → OrdersScreen-DCOzHNIy.cjs} +3 -3
- package/dist/{ProductsScreen-BPgkn9BH.mjs → ProductsScreen-2pUHZJop.mjs} +17 -12
- package/dist/ProductsScreen-2pUHZJop.mjs.map +1 -0
- package/dist/{ProductsScreen-DY6tKX9Q.mjs → ProductsScreen-2tlHXemg.mjs} +5 -5
- package/dist/{ProductsScreen-DiaGPT_Q.cjs → ProductsScreen-Ch6f5P2w.cjs} +5 -5
- package/dist/{ProductsScreen-B2BS6FY_.cjs → ProductsScreen-ueEJP0MJ.cjs} +17 -12
- package/dist/ProductsScreen-ueEJP0MJ.cjs.map +1 -0
- package/dist/{ProfileScreen-DKJrpeMw.mjs → ProfileScreen-Age0TtEY.mjs} +3 -3
- package/dist/{ProfileScreen-DKJrpeMw.mjs.map → ProfileScreen-Age0TtEY.mjs.map} +1 -1
- package/dist/{ProfileScreen-ueK01fjb.cjs → ProfileScreen-C8fpr9c3.cjs} +3 -3
- package/dist/{ProfileScreen-ueK01fjb.cjs.map → ProfileScreen-C8fpr9c3.cjs.map} +1 -1
- package/dist/{ProfileScreen-C6qbR0YJ.cjs → ProfileScreen-DEtgeBnE.cjs} +3 -3
- package/dist/{ShareablesScreen-o1VYr_1K.cjs → ShareablesScreen-B6uPSvvK.cjs} +21 -16
- package/dist/ShareablesScreen-B6uPSvvK.cjs.map +1 -0
- package/dist/{ShareablesScreen-CR3YKwZC.cjs → ShareablesScreen-CoPFz5ZB.cjs} +5 -5
- package/dist/{ShareablesScreen-BrLq61Q7.mjs → ShareablesScreen-DBdNgtV1.mjs} +5 -5
- package/dist/{ShareablesScreen-4hhIcSYA.mjs → ShareablesScreen-vFbWhVGF.mjs} +21 -16
- package/dist/ShareablesScreen-vFbWhVGF.mjs.map +1 -0
- package/dist/{ShopScreen-D8z0KYfh.cjs → ShopScreen-BKBaNPsG.cjs} +5 -5
- package/dist/{ShopScreen-D8z0KYfh.cjs.map → ShopScreen-BKBaNPsG.cjs.map} +1 -1
- package/dist/{ShopScreen-CfxPQVZD.mjs → ShopScreen-D-TXRWZR.mjs} +5 -5
- package/dist/{ShopScreen-CfxPQVZD.mjs.map → ShopScreen-D-TXRWZR.mjs.map} +1 -1
- package/dist/{ShopScreen-BVABhBmJ.cjs → ShopScreen-DPZSXS99.cjs} +3 -3
- package/dist/{SubscriptionsScreen-BF4NqbpU.cjs → SubscriptionsScreen-BvS7o_XP.cjs} +3 -3
- package/dist/{SubscriptionsScreen-BF4NqbpU.cjs.map → SubscriptionsScreen-BvS7o_XP.cjs.map} +1 -1
- package/dist/{SubscriptionsScreen-BSDYjJvj.mjs → SubscriptionsScreen-CBqgpat5.mjs} +3 -3
- package/dist/{SubscriptionsScreen-BSDYjJvj.mjs.map → SubscriptionsScreen-CBqgpat5.mjs.map} +1 -1
- package/dist/{SubscriptionsScreen-BRx_ocC3.cjs → SubscriptionsScreen-IbsNz0Ki.cjs} +3 -3
- package/dist/{dist-lO2OG0T5.cjs → dist-BF_4vk1z.cjs} +1 -1
- package/dist/{dist-lO2OG0T5.cjs.map → dist-BF_4vk1z.cjs.map} +1 -1
- package/dist/index.cjs +37 -37
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +37 -37
- package/dist/{products-CjZof7c2.cjs → products-BKZ1siXg.cjs} +1 -1
- package/dist/{products-CjZof7c2.cjs.map → products-BKZ1siXg.cjs.map} +1 -1
- package/dist/{products-Dkwd_Bh0.mjs → products-DOO1TBcm.mjs} +1 -1
- package/dist/{products-Dkwd_Bh0.mjs.map → products-DOO1TBcm.mjs.map} +1 -1
- package/dist/{sortable.esm-CzzU6kIR.mjs → sortable.esm-Cz-CP2N8.mjs} +1 -1
- package/dist/{sortable.esm-CzzU6kIR.mjs.map → sortable.esm-Cz-CP2N8.mjs.map} +1 -1
- package/dist/{src-bzRRiTN4.cjs → src-BbJs882O.cjs} +58 -41
- package/dist/src-BbJs882O.cjs.map +1 -0
- package/dist/{src-p8DA1dH0.mjs → src-CN7diUEw.mjs} +102 -50
- package/dist/src-CN7diUEw.mjs.map +1 -0
- package/dist/{src-BjmyVJoe.mjs → src-Ih5vEO6p.mjs} +57 -44
- package/dist/src-Ih5vEO6p.mjs.map +1 -0
- package/dist/{src-Dt66UB0B.cjs → src-Zv3-NSUf.cjs} +103 -117
- package/dist/src-Zv3-NSUf.cjs.map +1 -0
- package/dist/{use-account-clients-Bg1xqjMk.mjs → use-account-clients-CSWgrCKK.mjs} +2 -2
- package/dist/{use-account-clients-Bg1xqjMk.mjs.map → use-account-clients-CSWgrCKK.mjs.map} +1 -1
- package/dist/{use-account-clients-BVb_nhg7.cjs → use-account-clients-DaliJYMa.cjs} +2 -2
- package/dist/{use-account-clients-BVb_nhg7.cjs.map → use-account-clients-DaliJYMa.cjs.map} +1 -1
- package/dist/{use-current-user-DFQ8gYkR.cjs → use-current-user-5erIFUd6.cjs} +3 -3
- package/dist/{use-current-user-DFQ8gYkR.cjs.map → use-current-user-5erIFUd6.cjs.map} +1 -1
- package/dist/{use-current-user-DqLNoj-3.mjs → use-current-user-BBQg1iYf.mjs} +3 -3
- package/dist/{use-current-user-DqLNoj-3.mjs.map → use-current-user-BBQg1iYf.mjs.map} +1 -1
- package/dist/{use-customer-account-CY9HqWvJ.mjs → use-customer-account-CRYpHpFM.mjs} +3 -3
- package/dist/{use-customer-account-CY9HqWvJ.mjs.map → use-customer-account-CRYpHpFM.mjs.map} +1 -1
- package/dist/{use-customer-account-D599KeSp.cjs → use-customer-account-Dzdps4By.cjs} +3 -3
- package/dist/{use-customer-account-D599KeSp.cjs.map → use-customer-account-Dzdps4By.cjs.map} +1 -1
- package/dist/{use-fluid-api-DHF7svon.cjs → use-fluid-api-BUitsoDu.cjs} +2 -2
- package/dist/{use-fluid-api-DHF7svon.cjs.map → use-fluid-api-BUitsoDu.cjs.map} +1 -1
- package/dist/{use-fluid-api-CyK8Yoj-.mjs → use-fluid-api-C5ZLs2TP.mjs} +2 -2
- package/dist/{use-fluid-api-CyK8Yoj-.mjs.map → use-fluid-api-C5ZLs2TP.mjs.map} +1 -1
- package/package.json +15 -15
- package/dist/NestedWidget-BGY4LSQq.cjs.map +0 -1
- package/dist/NestedWidget-L8ppxJib.mjs.map +0 -1
- package/dist/ProductsScreen-B2BS6FY_.cjs.map +0 -1
- package/dist/ProductsScreen-BPgkn9BH.mjs.map +0 -1
- package/dist/ShareablesScreen-4hhIcSYA.mjs.map +0 -1
- package/dist/ShareablesScreen-o1VYr_1K.cjs.map +0 -1
- package/dist/src-BjmyVJoe.mjs.map +0 -1
- package/dist/src-Dt66UB0B.cjs.map +0 -1
- package/dist/src-bzRRiTN4.cjs.map +0 -1
- package/dist/src-p8DA1dH0.mjs.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluid-app/portal-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.91",
|
|
4
4
|
"description": "SDK for building custom Fluid portals",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -65,46 +65,46 @@
|
|
|
65
65
|
"tsdown": "^0.21.0",
|
|
66
66
|
"typescript": "^5",
|
|
67
67
|
"zod": "4.3.5",
|
|
68
|
-
"@fluid-app/auth": "0.1.0",
|
|
69
68
|
"@fluid-app/api-client-core": "0.1.0",
|
|
70
|
-
"@fluid-app/
|
|
69
|
+
"@fluid-app/auth": "0.1.0",
|
|
71
70
|
"@fluid-app/company-switcher-ui": "0.1.0",
|
|
72
|
-
"@fluid-app/contacts-ui": "0.1.0",
|
|
73
71
|
"@fluid-app/company-switcher-core": "0.1.0",
|
|
72
|
+
"@fluid-app/cart-ui": "0.1.12",
|
|
73
|
+
"@fluid-app/contacts-ui": "0.1.0",
|
|
74
74
|
"@fluid-app/file-picker-api-client": "0.1.0",
|
|
75
75
|
"@fluid-app/fluid-pay-api-client": "0.1.0",
|
|
76
76
|
"@fluid-app/fluidos-api-client": "0.1.0",
|
|
77
|
-
"@fluid-app/messaging-api-client": "0.1.0",
|
|
78
|
-
"@fluid-app/messaging-core": "0.1.0",
|
|
79
77
|
"@fluid-app/messaging-ui": "0.1.0",
|
|
78
|
+
"@fluid-app/messaging-api-client": "0.1.0",
|
|
80
79
|
"@fluid-app/mysite-ui": "0.1.0",
|
|
81
|
-
"@fluid-app/orders-api-client": "0.1.0",
|
|
82
80
|
"@fluid-app/orders-core": "0.1.0",
|
|
81
|
+
"@fluid-app/messaging-core": "0.1.0",
|
|
82
|
+
"@fluid-app/orders-api-client": "0.1.0",
|
|
83
83
|
"@fluid-app/orders-ui": "0.1.0",
|
|
84
|
-
"@fluid-app/portal-app-download-ui": "0.1.0",
|
|
85
84
|
"@fluid-app/permissions": "0.1.0",
|
|
85
|
+
"@fluid-app/portal-app-download-ui": "0.1.0",
|
|
86
86
|
"@fluid-app/portal-core": "0.1.23",
|
|
87
87
|
"@fluid-app/portal-preview": "0.1.0",
|
|
88
88
|
"@fluid-app/portal-pro-upgrade-ui": "0.1.0",
|
|
89
89
|
"@fluid-app/portal-widgets": "0.1.22",
|
|
90
|
-
"@fluid-app/
|
|
90
|
+
"@fluid-app/products-core": "0.1.0",
|
|
91
91
|
"@fluid-app/products-api-client": "0.1.0",
|
|
92
|
+
"@fluid-app/portal-react": "0.1.0",
|
|
92
93
|
"@fluid-app/profile-core": "0.1.0",
|
|
93
|
-
"@fluid-app/products-core": "0.1.0",
|
|
94
|
-
"@fluid-app/profile-ui": "0.1.0",
|
|
95
94
|
"@fluid-app/query-persister": "0.1.0",
|
|
96
95
|
"@fluid-app/shareables-api-client": "0.1.0",
|
|
96
|
+
"@fluid-app/profile-ui": "0.1.0",
|
|
97
97
|
"@fluid-app/shareables-core": "0.1.0",
|
|
98
98
|
"@fluid-app/shareables-ui": "0.1.0",
|
|
99
99
|
"@fluid-app/shop-ui": "0.1.0",
|
|
100
|
+
"@fluid-app/subscriptions-core": "0.1.0",
|
|
100
101
|
"@fluid-app/subscriptions-api-client": "0.1.0",
|
|
101
102
|
"@fluid-app/subscriptions-ui": "0.1.0",
|
|
102
|
-
"@fluid-app/subscriptions-core": "0.1.0",
|
|
103
|
-
"@fluid-app/ui-primitives": "0.1.13",
|
|
104
|
-
"@fluid-app/typescript-config": "0.0.0",
|
|
105
103
|
"@fluid-app/user-contacts-api-client": "0.1.0",
|
|
104
|
+
"@fluid-app/user-tasks-api-client": "0.1.0",
|
|
106
105
|
"@fluid-app/user-notes-api-client": "0.1.0",
|
|
107
|
-
"@fluid-app/
|
|
106
|
+
"@fluid-app/ui-primitives": "0.1.13",
|
|
107
|
+
"@fluid-app/typescript-config": "0.0.0"
|
|
108
108
|
},
|
|
109
109
|
"peerDependencies": {
|
|
110
110
|
"@hookform/resolvers": "^5.2.2",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"NestedWidget-BGY4LSQq.cjs","names":["useWidgetInteraction","borderWidthClasses","borderColorClasses","MediaRenderer","getMediaPropsFromShareable","gapValues","ScrollArrows","getFontSizeField","getColorField","getHeightField","getPaddingField","getBorderRadiusField","getBorderWidthField","getBorderColorField","getGapField"],"sources":["../../widgets/src/widgets/NestedWidget.tsx"],"sourcesContent":["import { useRef, type ComponentProps } from \"react\";\nimport type React from \"react\";\nimport {\n MediaRenderer,\n getMediaPropsFromShareable,\n} from \"../components/MediaRenderer\";\nimport type {\n BorderRadiusOptions,\n BorderWidthOptions,\n ColorOptions,\n FontSizeOptions,\n PaddingOptions,\n AlignOptions,\n GapOptions,\n BackgroundValue,\n} from \"@fluid-app/portal-core/types\";\nimport {\n getHeightField,\n type WidgetPropertySchema,\n} from \"@fluid-app/portal-core/registries\";\nimport {\n getBorderRadiusField,\n getBorderWidthField,\n getBorderColorField,\n borderWidthClasses,\n borderColorClasses,\n getColorField,\n getFontSizeField,\n getGapField,\n getPaddingField,\n gapValues,\n} from \"../core/fields\";\nimport { ScrollArrows } from \"../ui/scroll-arrows\";\nimport { type ShareableItem } from \"@fluid-app/portal-core/types\";\nimport { useWidgetInteraction } from \"../contexts/WidgetInteractionContext\";\n\nconst DEFAULT_SHAREABLES: ShareableItem[] = [];\n\ntype NestedWidgetProps = ComponentProps<\"div\"> & {\n // Content\n resource?: ShareableItem;\n titleEnabled?: boolean;\n titleText?: string;\n shareables?: ShareableItem[];\n\n // Layout\n gap?: GapOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n borderWidth?: BorderWidthOptions;\n borderColor?: ColorOptions;\n primaryMediaHeight?: string;\n\n // Title styling\n titleFontSize?: FontSizeOptions;\n titleColor?: ColorOptions;\n titleAlignment?: AlignOptions;\n\n // Nested media styling\n nestedTextColor?: ColorOptions;\n background?: BackgroundValue;\n\n // Overlay\n overlayEnabled?: boolean;\n overlayType?: \"solid\" | \"gradient\";\n overlayIntensity?: number;\n};\n\nexport function NestedWidget({\n resource,\n titleEnabled = true,\n titleText = \"Featured Collection\",\n shareables = DEFAULT_SHAREABLES,\n gap = \"md\",\n padding = 4,\n borderRadius = \"md\",\n borderWidth = \"none\",\n borderColor = \"muted\",\n primaryMediaHeight = \"400px\",\n titleFontSize = \"xl\",\n titleColor = \"background\",\n titleAlignment = { horizontal: \"left\", vertical: \"bottom\" },\n nestedTextColor = \"foreground\",\n background = {\n type: \"solid\",\n color: \"background\",\n },\n overlayEnabled = true,\n overlayType = \"gradient\",\n overlayIntensity = 50,\n className,\n ...props\n}: NestedWidgetProps): React.JSX.Element {\n const scrollContainerRef = useRef<HTMLDivElement>(null);\n\n const scrollByAmount = (direction: \"prev\" | \"next\") => {\n const container = scrollContainerRef.current;\n if (!container) return;\n\n const computedGap = parseFloat(getComputedStyle(container).gap) || 0;\n const firstItem = container.firstElementChild as HTMLElement | null;\n const itemWidth = firstItem?.offsetWidth ?? 0;\n const scrollAmount = itemWidth + computedGap;\n\n container.scrollTo({\n left:\n container.scrollLeft +\n (direction === \"next\" ? scrollAmount : -scrollAmount),\n behavior: \"smooth\",\n });\n };\n\n // Cap border radius for the primary media container: \"full\" creates a circle that clips\n // the absolutely-positioned title overlay to the narrow bottom of the circle.\n const primaryMediaRadius = borderRadius === \"full\" ? \"2xl\" : borderRadius;\n\n const { onItemClick } = useWidgetInteraction();\n\n const hasNestedMedia = shareables.length > 0;\n\n const titleAlignmentClasses = {\n left: \"text-left\",\n center: \"text-center\",\n right: \"text-right\",\n };\n\n const backgroundColor = background.color || \"background\";\n const backgroundImage =\n (background.resource?.image_url || background.resource?.imageUrl) &&\n background.type === \"image\"\n ? `url(${background.resource.image_url || background.resource.imageUrl})`\n : \"none\";\n\n return (\n <div\n className={`@container flex w-full overflow-hidden p-${padding} rounded-${borderRadius} ${borderWidthClasses[borderWidth]} ${borderWidth !== \"none\" ? borderColorClasses[borderColor] : \"\"} bg-${backgroundColor} ${className}`}\n {...props}\n style={{\n maxHeight: primaryMediaHeight,\n backgroundImage: backgroundImage,\n }}\n >\n {/* Primary Media Container - Full width on mobile, fixed on desktop */}\n <div\n className={`relative @md:flex-none`}\n style={{\n width: primaryMediaHeight,\n }}\n >\n {/* Media + overlay clipped to rounded shape — title is a sibling so it isn't clipped */}\n <div\n className={`overflow-hidden rounded-${primaryMediaRadius} absolute inset-0`}\n >\n <MediaRenderer\n {...(resource ? getMediaPropsFromShareable(resource) : {})}\n autoplay\n loop\n muted\n />\n\n {/* Overlay */}\n {overlayEnabled && (\n <div\n className={`pointer-events-none absolute inset-0 z-10 ${\n overlayType === \"gradient\"\n ? \"bg-gradient-to-t from-black to-transparent\"\n : \"bg-black\"\n }`}\n style={{\n opacity:\n (Number(String(overlayIntensity).replace(\"%\", \"\")) || 50) /\n 100,\n }}\n />\n )}\n </div>\n\n {/* Title and Mobile Nested Media — outside the overflow-hidden clip */}\n {((titleEnabled && titleText) || hasNestedMedia) && (\n <div\n className={`absolute z-20 w-full ${titleAlignmentClasses[titleAlignment?.horizontal ?? \"left\"]} p-${padding} ${\n titleAlignment.vertical === \"top\"\n ? `top-0 pt-${padding}`\n : titleAlignment.vertical === \"center\"\n ? \"top-1/2 -translate-y-1/2\"\n : `bottom-0 pb-${padding}`\n }`}\n >\n {titleEnabled && titleText && (\n <h2\n className={`font-header leading-tight font-bold text-${titleColor} text-${titleFontSize === \"md\" ? \"base\" : titleFontSize}`}\n >\n {titleText}\n </h2>\n )}\n\n {/* Mobile: Products overlay inside primary media */}\n {hasNestedMedia && (\n <div className={`pt-${padding} @md:hidden`}>\n <div\n className={`flex overflow-x-auto gap-${gapValues[gap]} bg-transparent`}\n >\n {shareables.map((shareable) => (\n <div\n key={shareable.id}\n className={`flex shrink-0 flex-col items-center ${onItemClick ? \"cursor-pointer\" : \"\"}`}\n {...(onItemClick\n ? {\n role: \"button\",\n tabIndex: 0,\n onClick: () => onItemClick(shareable),\n onKeyDown: (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onItemClick(shareable);\n }\n },\n }\n : {})}\n >\n <div\n className={`aspect-3/4 h-40 overflow-hidden rounded-${borderRadius}`}\n >\n <MediaRenderer\n {...getMediaPropsFromShareable(shareable)}\n />\n </div>\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n )}\n </div>\n\n {/* Desktop: Products Container - Single row beside primary media */}\n {hasNestedMedia && (\n <div\n className={`relative hidden min-w-0 self-stretch @md:flex @md:flex-1 px-${padding}`}\n >\n <div\n ref={scrollContainerRef}\n className={`flex h-full flex-row overflow-x-auto gap-${gapValues[gap]}`}\n style={{ scrollSnapType: \"x mandatory\" }}\n >\n {shareables.map((shareable) => (\n <div\n key={shareable.id}\n className={`flex flex-col gap-1 ${onItemClick ? \"cursor-pointer\" : \"\"}`}\n style={{\n width: `calc(${primaryMediaHeight} * 0.75)`,\n scrollSnapAlign: \"start\",\n }}\n {...(onItemClick\n ? {\n role: \"button\",\n tabIndex: 0,\n onClick: () => onItemClick(shareable),\n onKeyDown: (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onItemClick(shareable);\n }\n },\n }\n : {})}\n >\n <div\n className={`aspect-3/4 h-full rounded-${borderRadius} overflow-hidden`}\n >\n <MediaRenderer {...getMediaPropsFromShareable(shareable)} />\n </div>\n <span className={`flex-none text-sm text-${nestedTextColor}`}>\n <p className=\"truncate\">{shareable.title || \"\"}</p>\n <p className=\"truncate\">\n {((shareable.display_price as string) ?? shareable.price) ||\n \"\"}\n </p>\n </span>\n </div>\n ))}\n </div>\n\n {/* Navigation arrows */}\n <div\n className={`absolute inset-x-0 top-1/2 flex w-full -translate-y-1/2 items-center justify-between px-8`}\n >\n <ScrollArrows\n onPrevious={() => scrollByAmount(\"prev\")}\n onNext={() => scrollByAmount(\"next\")}\n />\n </div>\n </div>\n )}\n </div>\n );\n}\n\nexport const nestedWidgetPropertySchema: WidgetPropertySchema = {\n widgetType: \"NestedWidget\",\n displayName: \"Nested Widget\",\n tabsConfig: [\n { id: \"styling\", label: \"Styling\" },\n { id: \"data\", label: \"Data\" },\n ],\n dataSourceTargetProps: [\"shareables\"],\n fields: [\n // Content tab - Resource group\n {\n key: \"resource\",\n label: \"Primary Media\",\n type: \"resource\",\n description: \"Select the primary media displayed in the large panel\",\n allowedTypes: [\"Medium\"],\n tab: \"styling\",\n group: \"Content\",\n },\n // Content tab - Title group\n {\n key: \"titleEnabled\",\n label: \"Widget Title\",\n type: \"boolean\",\n description: \"Enable the title displayed over the primary media\",\n defaultValue: true,\n tab: \"styling\",\n group: \"Title\",\n },\n {\n key: \"titleText\",\n label: \"Title\",\n type: \"text\",\n description: \"Main title displayed over the primary media\",\n defaultValue: \"Featured Collection\",\n tab: \"styling\",\n group: \"Title\",\n requiresKeyToBeTrue: \"titleEnabled\",\n },\n getFontSizeField({\n label: \"Title Font Size\",\n defaultValue: \"xl\",\n key: \"titleFontSize\",\n description: \"Font size for the widget title\",\n tab: \"styling\",\n group: \"Title\",\n requiresKeyToBeTrue: \"titleEnabled\",\n }),\n getColorField({\n defaultValue: \"background\",\n key: \"titleColor\",\n label: \"Title Color\",\n description: \"Color for the widget title\",\n tab: \"styling\",\n group: \"Title\",\n requiresKeyToBeTrue: \"titleEnabled\",\n }),\n // Styling tab - Design group\n getHeightField({\n key: \"primaryMediaHeight\",\n label: \"Primary Media Height\",\n description: \"Height of the primary media container\",\n defaultValue: \"400px\",\n tab: \"styling\",\n group: \"Design\",\n }),\n {\n key: \"separator\",\n type: \"separator\",\n label: \"Separator\",\n tab: \"styling\",\n group: \"Design\",\n },\n {\n key: \"titleAlignment\",\n label: \"Content Alignment\",\n type: \"alignment\",\n description: \"Alignment of the content inside the primary media\",\n defaultValue: { horizontal: \"left\", vertical: \"bottom\" },\n options: {\n horizontalEnabled: true,\n verticalEnabled: true,\n },\n tab: \"styling\",\n group: \"Design\",\n },\n {\n key: \"separator2\",\n type: \"separator\",\n label: \"Separator\",\n tab: \"styling\",\n group: \"Design\",\n },\n getPaddingField({\n defaultValue: 4,\n key: \"padding\",\n label: \"Padding\",\n description: \"Padding used throughout the widget\",\n tab: \"styling\",\n group: \"Design\",\n }),\n getBorderRadiusField({\n defaultValue: \"md\",\n label: \"Border Radius\",\n key: \"borderRadius\",\n description: \"Rounded corners for the widget\",\n tab: \"styling\",\n group: \"Design\",\n }),\n getBorderWidthField({\n key: \"borderWidth\",\n label: \"Border Width\",\n description: \"Border width for the widget\",\n defaultValue: \"none\",\n tab: \"styling\",\n group: \"Design\",\n }),\n getBorderColorField({\n key: \"borderColor\",\n label: \"Border Color\",\n description: \"Border color for the widget\",\n defaultValue: \"muted\",\n tab: \"styling\",\n group: \"Design\",\n }),\n {\n key: \"overlayEnabled\",\n label: \"Enable Overlay\",\n type: \"boolean\",\n description:\n \"Add a dark overlay to the primary media for better text readability\",\n defaultValue: true,\n tab: \"styling\",\n group: \"Design\",\n },\n {\n key: \"overlayType\",\n label: \"Overlay Type\",\n type: \"buttonGroup\",\n description: \"Type of overlay effect\",\n defaultValue: \"gradient\",\n options: [\n { label: \"Solid\", value: \"solid\" },\n { label: \"Gradient\", value: \"gradient\" },\n ],\n tab: \"styling\",\n group: \"Design\",\n requiresKeyToBeTrue: \"overlayEnabled\",\n },\n {\n key: \"overlayIntensity\",\n label: \"Overlay Intensity\",\n type: \"slider\",\n description: \"Opacity of the overlay (0-100)\",\n min: 0,\n max: 100,\n step: 5,\n defaultValue: 50,\n unit: \"%\",\n tab: \"styling\",\n group: \"Design\",\n requiresKeyToBeTrue: \"overlayEnabled\",\n },\n // Styling tab - Nested Media Styling group\n getGapField({\n label: \"Gap\",\n defaultValue: \"md\",\n key: \"gap\",\n description: \"Gap between nested media items\",\n tab: \"styling\",\n group: \"Nested Design\",\n }),\n getColorField({\n defaultValue: \"foreground\",\n key: \"nestedTextColor\",\n label: \"Nested Text Color\",\n description: \"Color for nested media labels\",\n tab: \"styling\",\n group: \"Nested Design\",\n }),\n {\n type: \"background\",\n defaultValue: \"background\",\n key: \"background\",\n label: \"Background\",\n description: \"Background color for nested media container\",\n tab: \"styling\",\n group: \"Nested Design\",\n },\n // Data tab\n {\n key: \"dataSource\",\n label: \"Data Source\",\n type: \"dataSource\",\n description: \"Configure dynamic data fetching from an API\",\n tab: \"data\",\n group: \"Data Configuration\",\n },\n ],\n // Per-item configuration schema for custom data sources\n itemConfigSchema: {\n description: \"Configure settings for this item\",\n fields: [\n {\n key: \"title\",\n label: \"Custom Title\",\n type: \"text\",\n description: \"Override the item's title for this widget\",\n },\n ],\n },\n} as const satisfies WidgetPropertySchema;\n"],"mappings":"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;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACP,qBAAqB;GACtB;EACDC,mBAAAA,iBAAiB;GACf,OAAO;GACP,cAAc;GACd,KAAK;GACL,aAAa;GACb,KAAK;GACL,OAAO;GACP,qBAAqB;GACtB,CAAC;EACFC,mBAAAA,cAAc;GACZ,cAAc;GACd,KAAK;GACL,OAAO;GACP,aAAa;GACb,KAAK;GACL,OAAO;GACP,qBAAqB;GACtB,CAAC;EAEFC,mBAAAA,eAAe;GACb,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACF;GACE,KAAK;GACL,MAAM;GACN,OAAO;GACP,KAAK;GACL,OAAO;GACR;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;IAAE,YAAY;IAAQ,UAAU;IAAU;GACxD,SAAS;IACP,mBAAmB;IACnB,iBAAiB;IAClB;GACD,KAAK;GACL,OAAO;GACR;EACD;GACE,KAAK;GACL,MAAM;GACN,OAAO;GACP,KAAK;GACL,OAAO;GACR;EACDC,mBAAAA,gBAAgB;GACd,cAAc;GACd,KAAK;GACL,OAAO;GACP,aAAa;GACb,KAAK;GACL,OAAO;GACR,CAAC;EACFC,mBAAAA,qBAAqB;GACnB,cAAc;GACd,OAAO;GACP,KAAK;GACL,aAAa;GACb,KAAK;GACL,OAAO;GACR,CAAC;EACFC,mBAAAA,oBAAoB;GAClB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACFC,mBAAAA,oBAAoB;GAClB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACF;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aACE;GACF,cAAc;GACd,KAAK;GACL,OAAO;GACR;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,SAAS,CACP;IAAE,OAAO;IAAS,OAAO;IAAS,EAClC;IAAE,OAAO;IAAY,OAAO;IAAY,CACzC;GACD,KAAK;GACL,OAAO;GACP,qBAAqB;GACtB;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,KAAK;GACL,KAAK;GACL,MAAM;GACN,cAAc;GACd,MAAM;GACN,KAAK;GACL,OAAO;GACP,qBAAqB;GACtB;EAEDC,mBAAAA,YAAY;GACV,OAAO;GACP,cAAc;GACd,KAAK;GACL,aAAa;GACb,KAAK;GACL,OAAO;GACR,CAAC;EACFN,mBAAAA,cAAc;GACZ,cAAc;GACd,KAAK;GACL,OAAO;GACP,aAAa;GACb,KAAK;GACL,OAAO;GACR,CAAC;EACF;GACE,MAAM;GACN,cAAc;GACd,KAAK;GACL,OAAO;GACP,aAAa;GACb,KAAK;GACL,OAAO;GACR;EAED;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,KAAK;GACL,OAAO;GACR;EACF;CAED,kBAAkB;EAChB,aAAa;EACb,QAAQ,CACN;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACd,CACF;EACF;CACF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"NestedWidget-L8ppxJib.mjs","names":[],"sources":["../../widgets/src/widgets/NestedWidget.tsx"],"sourcesContent":["import { useRef, type ComponentProps } from \"react\";\nimport type React from \"react\";\nimport {\n MediaRenderer,\n getMediaPropsFromShareable,\n} from \"../components/MediaRenderer\";\nimport type {\n BorderRadiusOptions,\n BorderWidthOptions,\n ColorOptions,\n FontSizeOptions,\n PaddingOptions,\n AlignOptions,\n GapOptions,\n BackgroundValue,\n} from \"@fluid-app/portal-core/types\";\nimport {\n getHeightField,\n type WidgetPropertySchema,\n} from \"@fluid-app/portal-core/registries\";\nimport {\n getBorderRadiusField,\n getBorderWidthField,\n getBorderColorField,\n borderWidthClasses,\n borderColorClasses,\n getColorField,\n getFontSizeField,\n getGapField,\n getPaddingField,\n gapValues,\n} from \"../core/fields\";\nimport { ScrollArrows } from \"../ui/scroll-arrows\";\nimport { type ShareableItem } from \"@fluid-app/portal-core/types\";\nimport { useWidgetInteraction } from \"../contexts/WidgetInteractionContext\";\n\nconst DEFAULT_SHAREABLES: ShareableItem[] = [];\n\ntype NestedWidgetProps = ComponentProps<\"div\"> & {\n // Content\n resource?: ShareableItem;\n titleEnabled?: boolean;\n titleText?: string;\n shareables?: ShareableItem[];\n\n // Layout\n gap?: GapOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n borderWidth?: BorderWidthOptions;\n borderColor?: ColorOptions;\n primaryMediaHeight?: string;\n\n // Title styling\n titleFontSize?: FontSizeOptions;\n titleColor?: ColorOptions;\n titleAlignment?: AlignOptions;\n\n // Nested media styling\n nestedTextColor?: ColorOptions;\n background?: BackgroundValue;\n\n // Overlay\n overlayEnabled?: boolean;\n overlayType?: \"solid\" | \"gradient\";\n overlayIntensity?: number;\n};\n\nexport function NestedWidget({\n resource,\n titleEnabled = true,\n titleText = \"Featured Collection\",\n shareables = DEFAULT_SHAREABLES,\n gap = \"md\",\n padding = 4,\n borderRadius = \"md\",\n borderWidth = \"none\",\n borderColor = \"muted\",\n primaryMediaHeight = \"400px\",\n titleFontSize = \"xl\",\n titleColor = \"background\",\n titleAlignment = { horizontal: \"left\", vertical: \"bottom\" },\n nestedTextColor = \"foreground\",\n background = {\n type: \"solid\",\n color: \"background\",\n },\n overlayEnabled = true,\n overlayType = \"gradient\",\n overlayIntensity = 50,\n className,\n ...props\n}: NestedWidgetProps): React.JSX.Element {\n const scrollContainerRef = useRef<HTMLDivElement>(null);\n\n const scrollByAmount = (direction: \"prev\" | \"next\") => {\n const container = scrollContainerRef.current;\n if (!container) return;\n\n const computedGap = parseFloat(getComputedStyle(container).gap) || 0;\n const firstItem = container.firstElementChild as HTMLElement | null;\n const itemWidth = firstItem?.offsetWidth ?? 0;\n const scrollAmount = itemWidth + computedGap;\n\n container.scrollTo({\n left:\n container.scrollLeft +\n (direction === \"next\" ? scrollAmount : -scrollAmount),\n behavior: \"smooth\",\n });\n };\n\n // Cap border radius for the primary media container: \"full\" creates a circle that clips\n // the absolutely-positioned title overlay to the narrow bottom of the circle.\n const primaryMediaRadius = borderRadius === \"full\" ? \"2xl\" : borderRadius;\n\n const { onItemClick } = useWidgetInteraction();\n\n const hasNestedMedia = shareables.length > 0;\n\n const titleAlignmentClasses = {\n left: \"text-left\",\n center: \"text-center\",\n right: \"text-right\",\n };\n\n const backgroundColor = background.color || \"background\";\n const backgroundImage =\n (background.resource?.image_url || background.resource?.imageUrl) &&\n background.type === \"image\"\n ? `url(${background.resource.image_url || background.resource.imageUrl})`\n : \"none\";\n\n return (\n <div\n className={`@container flex w-full overflow-hidden p-${padding} rounded-${borderRadius} ${borderWidthClasses[borderWidth]} ${borderWidth !== \"none\" ? borderColorClasses[borderColor] : \"\"} bg-${backgroundColor} ${className}`}\n {...props}\n style={{\n maxHeight: primaryMediaHeight,\n backgroundImage: backgroundImage,\n }}\n >\n {/* Primary Media Container - Full width on mobile, fixed on desktop */}\n <div\n className={`relative @md:flex-none`}\n style={{\n width: primaryMediaHeight,\n }}\n >\n {/* Media + overlay clipped to rounded shape — title is a sibling so it isn't clipped */}\n <div\n className={`overflow-hidden rounded-${primaryMediaRadius} absolute inset-0`}\n >\n <MediaRenderer\n {...(resource ? getMediaPropsFromShareable(resource) : {})}\n autoplay\n loop\n muted\n />\n\n {/* Overlay */}\n {overlayEnabled && (\n <div\n className={`pointer-events-none absolute inset-0 z-10 ${\n overlayType === \"gradient\"\n ? \"bg-gradient-to-t from-black to-transparent\"\n : \"bg-black\"\n }`}\n style={{\n opacity:\n (Number(String(overlayIntensity).replace(\"%\", \"\")) || 50) /\n 100,\n }}\n />\n )}\n </div>\n\n {/* Title and Mobile Nested Media — outside the overflow-hidden clip */}\n {((titleEnabled && titleText) || hasNestedMedia) && (\n <div\n className={`absolute z-20 w-full ${titleAlignmentClasses[titleAlignment?.horizontal ?? \"left\"]} p-${padding} ${\n titleAlignment.vertical === \"top\"\n ? `top-0 pt-${padding}`\n : titleAlignment.vertical === \"center\"\n ? \"top-1/2 -translate-y-1/2\"\n : `bottom-0 pb-${padding}`\n }`}\n >\n {titleEnabled && titleText && (\n <h2\n className={`font-header leading-tight font-bold text-${titleColor} text-${titleFontSize === \"md\" ? \"base\" : titleFontSize}`}\n >\n {titleText}\n </h2>\n )}\n\n {/* Mobile: Products overlay inside primary media */}\n {hasNestedMedia && (\n <div className={`pt-${padding} @md:hidden`}>\n <div\n className={`flex overflow-x-auto gap-${gapValues[gap]} bg-transparent`}\n >\n {shareables.map((shareable) => (\n <div\n key={shareable.id}\n className={`flex shrink-0 flex-col items-center ${onItemClick ? \"cursor-pointer\" : \"\"}`}\n {...(onItemClick\n ? {\n role: \"button\",\n tabIndex: 0,\n onClick: () => onItemClick(shareable),\n onKeyDown: (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onItemClick(shareable);\n }\n },\n }\n : {})}\n >\n <div\n className={`aspect-3/4 h-40 overflow-hidden rounded-${borderRadius}`}\n >\n <MediaRenderer\n {...getMediaPropsFromShareable(shareable)}\n />\n </div>\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n )}\n </div>\n\n {/* Desktop: Products Container - Single row beside primary media */}\n {hasNestedMedia && (\n <div\n className={`relative hidden min-w-0 self-stretch @md:flex @md:flex-1 px-${padding}`}\n >\n <div\n ref={scrollContainerRef}\n className={`flex h-full flex-row overflow-x-auto gap-${gapValues[gap]}`}\n style={{ scrollSnapType: \"x mandatory\" }}\n >\n {shareables.map((shareable) => (\n <div\n key={shareable.id}\n className={`flex flex-col gap-1 ${onItemClick ? \"cursor-pointer\" : \"\"}`}\n style={{\n width: `calc(${primaryMediaHeight} * 0.75)`,\n scrollSnapAlign: \"start\",\n }}\n {...(onItemClick\n ? {\n role: \"button\",\n tabIndex: 0,\n onClick: () => onItemClick(shareable),\n onKeyDown: (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onItemClick(shareable);\n }\n },\n }\n : {})}\n >\n <div\n className={`aspect-3/4 h-full rounded-${borderRadius} overflow-hidden`}\n >\n <MediaRenderer {...getMediaPropsFromShareable(shareable)} />\n </div>\n <span className={`flex-none text-sm text-${nestedTextColor}`}>\n <p className=\"truncate\">{shareable.title || \"\"}</p>\n <p className=\"truncate\">\n {((shareable.display_price as string) ?? shareable.price) ||\n \"\"}\n </p>\n </span>\n </div>\n ))}\n </div>\n\n {/* Navigation arrows */}\n <div\n className={`absolute inset-x-0 top-1/2 flex w-full -translate-y-1/2 items-center justify-between px-8`}\n >\n <ScrollArrows\n onPrevious={() => scrollByAmount(\"prev\")}\n onNext={() => scrollByAmount(\"next\")}\n />\n </div>\n </div>\n )}\n </div>\n );\n}\n\nexport const nestedWidgetPropertySchema: WidgetPropertySchema = {\n widgetType: \"NestedWidget\",\n displayName: \"Nested Widget\",\n tabsConfig: [\n { id: \"styling\", label: \"Styling\" },\n { id: \"data\", label: \"Data\" },\n ],\n dataSourceTargetProps: [\"shareables\"],\n fields: [\n // Content tab - Resource group\n {\n key: \"resource\",\n label: \"Primary Media\",\n type: \"resource\",\n description: \"Select the primary media displayed in the large panel\",\n allowedTypes: [\"Medium\"],\n tab: \"styling\",\n group: \"Content\",\n },\n // Content tab - Title group\n {\n key: \"titleEnabled\",\n label: \"Widget Title\",\n type: \"boolean\",\n description: \"Enable the title displayed over the primary media\",\n defaultValue: true,\n tab: \"styling\",\n group: \"Title\",\n },\n {\n key: \"titleText\",\n label: \"Title\",\n type: \"text\",\n description: \"Main title displayed over the primary media\",\n defaultValue: \"Featured Collection\",\n tab: \"styling\",\n group: \"Title\",\n requiresKeyToBeTrue: \"titleEnabled\",\n },\n getFontSizeField({\n label: \"Title Font Size\",\n defaultValue: \"xl\",\n key: \"titleFontSize\",\n description: \"Font size for the widget title\",\n tab: \"styling\",\n group: \"Title\",\n requiresKeyToBeTrue: \"titleEnabled\",\n }),\n getColorField({\n defaultValue: \"background\",\n key: \"titleColor\",\n label: \"Title Color\",\n description: \"Color for the widget title\",\n tab: \"styling\",\n group: \"Title\",\n requiresKeyToBeTrue: \"titleEnabled\",\n }),\n // Styling tab - Design group\n getHeightField({\n key: \"primaryMediaHeight\",\n label: \"Primary Media Height\",\n description: \"Height of the primary media container\",\n defaultValue: \"400px\",\n tab: \"styling\",\n group: \"Design\",\n }),\n {\n key: \"separator\",\n type: \"separator\",\n label: \"Separator\",\n tab: \"styling\",\n group: \"Design\",\n },\n {\n key: \"titleAlignment\",\n label: \"Content Alignment\",\n type: \"alignment\",\n description: \"Alignment of the content inside the primary media\",\n defaultValue: { horizontal: \"left\", vertical: \"bottom\" },\n options: {\n horizontalEnabled: true,\n verticalEnabled: true,\n },\n tab: \"styling\",\n group: \"Design\",\n },\n {\n key: \"separator2\",\n type: \"separator\",\n label: \"Separator\",\n tab: \"styling\",\n group: \"Design\",\n },\n getPaddingField({\n defaultValue: 4,\n key: \"padding\",\n label: \"Padding\",\n description: \"Padding used throughout the widget\",\n tab: \"styling\",\n group: \"Design\",\n }),\n getBorderRadiusField({\n defaultValue: \"md\",\n label: \"Border Radius\",\n key: \"borderRadius\",\n description: \"Rounded corners for the widget\",\n tab: \"styling\",\n group: \"Design\",\n }),\n getBorderWidthField({\n key: \"borderWidth\",\n label: \"Border Width\",\n description: \"Border width for the widget\",\n defaultValue: \"none\",\n tab: \"styling\",\n group: \"Design\",\n }),\n getBorderColorField({\n key: \"borderColor\",\n label: \"Border Color\",\n description: \"Border color for the widget\",\n defaultValue: \"muted\",\n tab: \"styling\",\n group: \"Design\",\n }),\n {\n key: \"overlayEnabled\",\n label: \"Enable Overlay\",\n type: \"boolean\",\n description:\n \"Add a dark overlay to the primary media for better text readability\",\n defaultValue: true,\n tab: \"styling\",\n group: \"Design\",\n },\n {\n key: \"overlayType\",\n label: \"Overlay Type\",\n type: \"buttonGroup\",\n description: \"Type of overlay effect\",\n defaultValue: \"gradient\",\n options: [\n { label: \"Solid\", value: \"solid\" },\n { label: \"Gradient\", value: \"gradient\" },\n ],\n tab: \"styling\",\n group: \"Design\",\n requiresKeyToBeTrue: \"overlayEnabled\",\n },\n {\n key: \"overlayIntensity\",\n label: \"Overlay Intensity\",\n type: \"slider\",\n description: \"Opacity of the overlay (0-100)\",\n min: 0,\n max: 100,\n step: 5,\n defaultValue: 50,\n unit: \"%\",\n tab: \"styling\",\n group: \"Design\",\n requiresKeyToBeTrue: \"overlayEnabled\",\n },\n // Styling tab - Nested Media Styling group\n getGapField({\n label: \"Gap\",\n defaultValue: \"md\",\n key: \"gap\",\n description: \"Gap between nested media items\",\n tab: \"styling\",\n group: \"Nested Design\",\n }),\n getColorField({\n defaultValue: \"foreground\",\n key: \"nestedTextColor\",\n label: \"Nested Text Color\",\n description: \"Color for nested media labels\",\n tab: \"styling\",\n group: \"Nested Design\",\n }),\n {\n type: \"background\",\n defaultValue: \"background\",\n key: \"background\",\n label: \"Background\",\n description: \"Background color for nested media container\",\n tab: \"styling\",\n group: \"Nested Design\",\n },\n // Data tab\n {\n key: \"dataSource\",\n label: \"Data Source\",\n type: \"dataSource\",\n description: \"Configure dynamic data fetching from an API\",\n tab: \"data\",\n group: \"Data Configuration\",\n },\n ],\n // Per-item configuration schema for custom data sources\n itemConfigSchema: {\n description: \"Configure settings for this item\",\n fields: [\n {\n key: \"title\",\n label: \"Custom Title\",\n type: \"text\",\n description: \"Override the item's title for this widget\",\n },\n ],\n },\n} as const satisfies WidgetPropertySchema;\n"],"mappings":"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ACL,MAAM;GACN,OAAO;GACP,KAAK;GACL,OAAO;GACR;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;IAAE,YAAY;IAAQ,UAAU;IAAU;GACxD,SAAS;IACP,mBAAmB;IACnB,iBAAiB;IAClB;GACD,KAAK;GACL,OAAO;GACR;EACD;GACE,KAAK;GACL,MAAM;GACN,OAAO;GACP,KAAK;GACL,OAAO;GACR;EACD,gBAAgB;GACd,cAAc;GACd,KAAK;GACL,OAAO;GACP,aAAa;GACb,KAAK;GACL,OAAO;GACR,CAAC;EACF,qBAAqB;GACnB,cAAc;GACd,OAAO;GACP,KAAK;GACL,aAAa;GACb,KAAK;GACL,OAAO;GACR,CAAC;EACF,oBAAoB;GAClB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACF,oBAAoB;GAClB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACF;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aACE;GACF,cAAc;GACd,KAAK;GACL,OAAO;GACR;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,SAAS,CACP;IAAE,OAAO;IAAS,OAAO;IAAS,EAClC;IAAE,OAAO;IAAY,OAAO;IAAY,CACzC;GACD,KAAK;GACL,OAAO;GACP,qBAAqB;GACtB;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,KAAK;GACL,KAAK;GACL,MAAM;GACN,cAAc;GACd,MAAM;GACN,KAAK;GACL,OAAO;GACP,qBAAqB;GACtB;EAED,YAAY;GACV,OAAO;GACP,cAAc;GACd,KAAK;GACL,aAAa;GACb,KAAK;GACL,OAAO;GACR,CAAC;EACF,cAAc;GACZ,cAAc;GACd,KAAK;GACL,OAAO;GACP,aAAa;GACb,KAAK;GACL,OAAO;GACR,CAAC;EACF;GACE,MAAM;GACN,cAAc;GACd,KAAK;GACL,OAAO;GACP,aAAa;GACb,KAAK;GACL,OAAO;GACR;EAED;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,KAAK;GACL,OAAO;GACR;EACF;CAED,kBAAkB;EAChB,aAAa;EACb,QAAQ,CACN;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACd,CACF;EACF;CACF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ProductsScreen-B2BS6FY_.cjs","names":["useSdkClient","useCurrentUser","useAppNavigation","ShareablesCoreProvider","ShareablesUIProvider","ProductsApp"],"sources":["../src/screens/ProductsScreen.tsx"],"sourcesContent":["import { useCallback, useMemo, type ComponentProps } from \"react\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"../types\";\nimport type { WidgetPropertySchema } from \"../registries/property-schema-types\";\nimport { ShareablesCoreProvider } from \"@fluid-app/shareables-core\";\nimport { ShareablesUIProvider, ProductsApp } from \"@fluid-app/shareables-ui\";\nimport { useCurrentUser } from \"../hooks/use-current-user\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\nimport { useSdkClient } from \"../account/use-account-clients\";\n\ntype ProductsScreenProps = ComponentProps<\"div\"> & {\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n};\n\nexport function ProductsScreen({\n /* eslint-disable @typescript-eslint/no-unused-vars -- destructured to exclude from divProps spread */\n background,\n textColor,\n accentColor,\n padding,\n borderRadius,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n ...divProps\n}: ProductsScreenProps): React.JSX.Element {\n const domainClient = useSdkClient();\n const { data: userData } = useCurrentUser();\n const { currentSlug, navigate } = useAppNavigation();\n\n // Extract product ID from slug: \"products/123\" → \"123\"\n const productId = useMemo(() => {\n const match = currentSlug.match(/^products\\/(.+)/);\n return match?.[1] ?? null;\n }, [currentSlug]);\n\n const handleSelectProduct = useCallback(\n (id: string) => {\n navigate(`products/${id}`);\n },\n [navigate],\n );\n\n const handleBack = useCallback(() => {\n navigate(\"products\");\n }, [navigate]);\n\n const coreConfig = useMemo(\n () => ({\n client: domainClient,\n user: userData ? { id: userData.id } : null,\n }),\n [domainClient, userData],\n );\n\n const uiConfig = useMemo(\n () => ({\n user: userData\n ? {\n id: userData.id,\n company: userData.company\n ? { logo_url: userData.company.logo_url }\n : null,\n }\n : undefined,\n basePath: \"\",\n navigate: (path: string) => {\n navigate(path);\n },\n showToast: (opts: {\n title: string;\n type: \"success\" | \"error\" | \"warning\";\n }) => {\n console.log(`[Products] ${opts.type}: ${opts.title}`);\n },\n }),\n [userData, navigate],\n );\n\n return (\n <div {...divProps} className={`h-full ${divProps.className ?? \"\"}`}>\n <ShareablesCoreProvider config={coreConfig}>\n <ShareablesUIProvider config={uiConfig}>\n <ProductsApp\n countryCode={userData?.country?.iso}\n companyLogoUrl={userData?.company?.logo_url}\n productId={productId}\n onSelectProduct={handleSelectProduct}\n onBack={handleBack}\n />\n </ShareablesUIProvider>\n </ShareablesCoreProvider>\n </div>\n );\n}\n\nexport const productsScreenPropertySchema: WidgetPropertySchema = {\n widgetType: \"ProductsScreen\",\n displayName: \"Products Screen\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":";;;;;;;;AAsBA,SAAgB,eAAe,EAE7B,YACA,WACA,aACA,SACA,cAEA,GAAG,YACsC;CACzC,MAAM,eAAeA,4BAAAA,cAAc;CACnC,MAAM,EAAE,MAAM,aAAaC,yBAAAA,gBAAgB;CAC3C,MAAM,EAAE,aAAa,aAAaC,6BAAAA,kBAAkB;CAGpD,MAAM,aAAA,GAAA,MAAA,eAA0B;AAE9B,SADc,YAAY,MAAM,kBAAkB,GACnC,MAAM;IACpB,CAAC,YAAY,CAAC;CAEjB,MAAM,uBAAA,GAAA,MAAA,cACH,OAAe;AACd,WAAS,YAAY,KAAK;IAE5B,CAAC,SAAS,CACX;CAED,MAAM,cAAA,GAAA,MAAA,mBAA+B;AACnC,WAAS,WAAW;IACnB,CAAC,SAAS,CAAC;CAEd,MAAM,cAAA,GAAA,MAAA,gBACG;EACL,QAAQ;EACR,MAAM,WAAW,EAAE,IAAI,SAAS,IAAI,GAAG;EACxC,GACD,CAAC,cAAc,SAAS,CACzB;CAED,MAAM,YAAA,GAAA,MAAA,gBACG;EACL,MAAM,WACF;GACE,IAAI,SAAS;GACb,SAAS,SAAS,UACd,EAAE,UAAU,SAAS,QAAQ,UAAU,GACvC;GACL,GACD,KAAA;EACJ,UAAU;EACV,WAAW,SAAiB;AAC1B,YAAS,KAAK;;EAEhB,YAAY,SAGN;AACJ,WAAQ,IAAI,cAAc,KAAK,KAAK,IAAI,KAAK,QAAQ;;EAExD,GACD,CAAC,UAAU,SAAS,CACrB;AAED,QACE,iBAAA,GAAA,kBAAA,KAAC,OAAD;EAAK,GAAI;EAAU,WAAW,UAAU,SAAS,aAAa;YAC5D,iBAAA,GAAA,kBAAA,KAACC,YAAAA,wBAAD;GAAwB,QAAQ;aAC9B,iBAAA,GAAA,kBAAA,KAACC,YAAAA,sBAAD;IAAsB,QAAQ;cAC5B,iBAAA,GAAA,kBAAA,KAACC,YAAAA,aAAD;KACE,aAAa,UAAU,SAAS;KAChC,gBAAgB,UAAU,SAAS;KACxB;KACX,iBAAiB;KACjB,QAAQ;KACR,CAAA;IACmB,CAAA;GACA,CAAA;EACrB,CAAA;;AAIV,MAAa,+BAAqD;CAChE,YAAY;CACZ,aAAa;CACb,YAAY,CAAC;EAAE,IAAI;EAAW,OAAO;EAAW,CAAC;CACjD,QAAQ,EAAE;CACX"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ProductsScreen-BPgkn9BH.mjs","names":[],"sources":["../src/screens/ProductsScreen.tsx"],"sourcesContent":["import { useCallback, useMemo, type ComponentProps } from \"react\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"../types\";\nimport type { WidgetPropertySchema } from \"../registries/property-schema-types\";\nimport { ShareablesCoreProvider } from \"@fluid-app/shareables-core\";\nimport { ShareablesUIProvider, ProductsApp } from \"@fluid-app/shareables-ui\";\nimport { useCurrentUser } from \"../hooks/use-current-user\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\nimport { useSdkClient } from \"../account/use-account-clients\";\n\ntype ProductsScreenProps = ComponentProps<\"div\"> & {\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n};\n\nexport function ProductsScreen({\n /* eslint-disable @typescript-eslint/no-unused-vars -- destructured to exclude from divProps spread */\n background,\n textColor,\n accentColor,\n padding,\n borderRadius,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n ...divProps\n}: ProductsScreenProps): React.JSX.Element {\n const domainClient = useSdkClient();\n const { data: userData } = useCurrentUser();\n const { currentSlug, navigate } = useAppNavigation();\n\n // Extract product ID from slug: \"products/123\" → \"123\"\n const productId = useMemo(() => {\n const match = currentSlug.match(/^products\\/(.+)/);\n return match?.[1] ?? null;\n }, [currentSlug]);\n\n const handleSelectProduct = useCallback(\n (id: string) => {\n navigate(`products/${id}`);\n },\n [navigate],\n );\n\n const handleBack = useCallback(() => {\n navigate(\"products\");\n }, [navigate]);\n\n const coreConfig = useMemo(\n () => ({\n client: domainClient,\n user: userData ? { id: userData.id } : null,\n }),\n [domainClient, userData],\n );\n\n const uiConfig = useMemo(\n () => ({\n user: userData\n ? {\n id: userData.id,\n company: userData.company\n ? { logo_url: userData.company.logo_url }\n : null,\n }\n : undefined,\n basePath: \"\",\n navigate: (path: string) => {\n navigate(path);\n },\n showToast: (opts: {\n title: string;\n type: \"success\" | \"error\" | \"warning\";\n }) => {\n console.log(`[Products] ${opts.type}: ${opts.title}`);\n },\n }),\n [userData, navigate],\n );\n\n return (\n <div {...divProps} className={`h-full ${divProps.className ?? \"\"}`}>\n <ShareablesCoreProvider config={coreConfig}>\n <ShareablesUIProvider config={uiConfig}>\n <ProductsApp\n countryCode={userData?.country?.iso}\n companyLogoUrl={userData?.company?.logo_url}\n productId={productId}\n onSelectProduct={handleSelectProduct}\n onBack={handleBack}\n />\n </ShareablesUIProvider>\n </ShareablesCoreProvider>\n </div>\n );\n}\n\nexport const productsScreenPropertySchema: WidgetPropertySchema = {\n widgetType: \"ProductsScreen\",\n displayName: \"Products Screen\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":";;;;;;;AAsBA,SAAgB,eAAe,EAE7B,YACA,WACA,aACA,SACA,cAEA,GAAG,YACsC;CACzC,MAAM,eAAe,cAAc;CACnC,MAAM,EAAE,MAAM,aAAa,gBAAgB;CAC3C,MAAM,EAAE,aAAa,aAAa,kBAAkB;CAGpD,MAAM,YAAY,cAAc;AAE9B,SADc,YAAY,MAAM,kBAAkB,GACnC,MAAM;IACpB,CAAC,YAAY,CAAC;CAEjB,MAAM,sBAAsB,aACzB,OAAe;AACd,WAAS,YAAY,KAAK;IAE5B,CAAC,SAAS,CACX;CAED,MAAM,aAAa,kBAAkB;AACnC,WAAS,WAAW;IACnB,CAAC,SAAS,CAAC;CAEd,MAAM,aAAa,eACV;EACL,QAAQ;EACR,MAAM,WAAW,EAAE,IAAI,SAAS,IAAI,GAAG;EACxC,GACD,CAAC,cAAc,SAAS,CACzB;CAED,MAAM,WAAW,eACR;EACL,MAAM,WACF;GACE,IAAI,SAAS;GACb,SAAS,SAAS,UACd,EAAE,UAAU,SAAS,QAAQ,UAAU,GACvC;GACL,GACD,KAAA;EACJ,UAAU;EACV,WAAW,SAAiB;AAC1B,YAAS,KAAK;;EAEhB,YAAY,SAGN;AACJ,WAAQ,IAAI,cAAc,KAAK,KAAK,IAAI,KAAK,QAAQ;;EAExD,GACD,CAAC,UAAU,SAAS,CACrB;AAED,QACE,oBAAC,OAAD;EAAK,GAAI;EAAU,WAAW,UAAU,SAAS,aAAa;YAC5D,oBAAC,wBAAD;GAAwB,QAAQ;aAC9B,oBAAC,sBAAD;IAAsB,QAAQ;cAC5B,oBAAC,aAAD;KACE,aAAa,UAAU,SAAS;KAChC,gBAAgB,UAAU,SAAS;KACxB;KACX,iBAAiB;KACjB,QAAQ;KACR,CAAA;IACmB,CAAA;GACA,CAAA;EACrB,CAAA;;AAIV,MAAa,+BAAqD;CAChE,YAAY;CACZ,aAAa;CACb,YAAY,CAAC;EAAE,IAAI;EAAW,OAAO;EAAW,CAAC;CACjD,QAAQ,EAAE;CACX"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ShareablesScreen-4hhIcSYA.mjs","names":[],"sources":["../src/hooks/use-user-type.ts","../../../file-picker/api-client/src/client.ts","../src/screens/ShareablesScreen.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport { useFluidAuth } from \"./use-fluid-auth\";\nimport { USER_TYPES, type UserType } from \"../auth/types\";\n\nexport interface UseUserTypeResult {\n userType: UserType | null;\n isCustomer: boolean;\n isRep: boolean;\n isAdmin: boolean;\n}\n\n/**\n * Convenience hook for user-type checks in the portal SDK.\n */\nexport function useUserType(): UseUserTypeResult {\n const { user } = useFluidAuth();\n\n return useMemo(() => {\n const userType = user?.user_type ?? null;\n return {\n userType,\n isCustomer: userType === USER_TYPES.customer,\n isRep: userType === USER_TYPES.rep,\n isAdmin:\n userType === USER_TYPES.admin || userType === USER_TYPES.root_admin,\n };\n }, [user?.user_type]);\n}\n","import type { FetchClientInstance } from \"@fluid-app/api-client-core\";\nimport type { DamAssetCreateResponse } from \"@fluid-app/file-picker-core\";\n\nexport interface DamUploadStrategy {\n uploadFile(params: {\n file: File;\n name: string;\n description?: string;\n tags?: string[];\n onProgress?: (progress: number) => void;\n companyId?: number;\n }): Promise<DamAssetCreateResponse>;\n}\n\nexport interface FilePickerClientConfig {\n fetchClient: FetchClientInstance;\n uploadStrategy?: DamUploadStrategy;\n unsplashAccessKey?: string;\n proxyEndpoint?: string; // defaults to \"/api/proxy-url\"\n}\n\nexport interface FilePickerClient {\n fetchClient: FetchClientInstance;\n uploadStrategy?: DamUploadStrategy;\n unsplashAccessKey?: string;\n proxyEndpoint: string;\n}\n\nexport function createFilePickerClient(\n config: FilePickerClientConfig,\n): FilePickerClient {\n return {\n fetchClient: config.fetchClient,\n uploadStrategy: config.uploadStrategy,\n unsplashAccessKey: config.unsplashAccessKey,\n proxyEndpoint: config.proxyEndpoint ?? \"/api/proxy-url\",\n };\n}\n","import { useCallback, useMemo, type ComponentProps } from \"react\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"../types\";\nimport type { WidgetPropertySchema } from \"../registries/property-schema-types\";\nimport { ShareablesCoreProvider } from \"@fluid-app/shareables-core\";\nimport { ShareablesUIProvider, ShareablesApp } from \"@fluid-app/shareables-ui\";\nimport { createFilePickerClient } from \"@fluid-app/file-picker-api-client\";\nimport { useCurrentUser } from \"../hooks/use-current-user\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\nimport { useSdkClient } from \"../account/use-account-clients\";\nimport { useUserType } from \"../hooks/use-user-type\";\n\ntype ShareablesScreenProps = ComponentProps<\"div\"> & {\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n};\n\n/**\n * Parse the current shareables sub-route from the full slug.\n *\n * System nav slugs are \"share/products\", \"share/media\", \"share/playlists\".\n * Detail pages append an ID: \"share/products/123\", \"share/media/456\".\n *\n * \"share/products\" → screen=\"products\", detailId=null\n * \"share/products/123\" → screen=\"products\", detailId=\"123\"\n * \"share/media/456\" → screen=\"media\", detailId=\"456\"\n * \"share/playlists\" → screen=\"playlists\", detailId=null\n * \"share/playlists/789\" → screen=\"playlists\", detailId=\"789\"\n * \"share/files\" → screen=\"files\", detailId=null\n * \"share\" → screen=null (default to products)\n */\nfunction parseShareablesRoute(currentSlug: string): {\n screen: string | null;\n detailId: string | null;\n action: string | null;\n} {\n // Strip the \"share\" prefix\n const slugWithoutPrefix = currentSlug.replace(/^share\\/?/, \"\");\n if (!slugWithoutPrefix) {\n return { screen: null, detailId: null, action: null };\n }\n\n const parts = slugWithoutPrefix.split(\"/\");\n const screen = parts[0] || null;\n const detailId = parts[1] || null;\n const action = parts[2] || null;\n return { screen, detailId, action };\n}\n\nexport function ShareablesScreen({\n /* eslint-disable @typescript-eslint/no-unused-vars -- destructured to exclude from divProps spread */\n background,\n textColor,\n accentColor,\n padding,\n borderRadius,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n ...divProps\n}: ShareablesScreenProps): React.JSX.Element {\n const domainClient = useSdkClient();\n const { data: userData } = useCurrentUser();\n const { currentSlug, navigate } = useAppNavigation();\n const { isCustomer } = useUserType();\n\n const { screen, detailId, action } = parseShareablesRoute(currentSlug);\n\n const handleNavigate = useCallback(\n (subScreen: string, id?: string) => {\n const path = id ? `share/${subScreen}/${id}` : `share/${subScreen}`;\n navigate(path);\n },\n [navigate],\n );\n\n const handleBack = useCallback(() => {\n if (detailId && screen) {\n // Navigate back to the listing for the current screen\n navigate(`share/${screen}`);\n } else {\n // Navigate to the default shareables screen\n navigate(\"share/products\");\n }\n }, [navigate, detailId, screen]);\n\n const coreConfig = useMemo(\n () => ({\n client: domainClient,\n user: userData ? { id: userData.id } : null,\n repContext: true,\n }),\n [domainClient, userData],\n );\n\n const filePickerClient = useMemo(\n () => createFilePickerClient({ fetchClient: domainClient }),\n [domainClient],\n );\n\n const uiConfig = useMemo(\n () => ({\n user: userData\n ? {\n id: userData.id,\n company: userData.company\n ? { logo_url: userData.company.logo_url }\n : null,\n }\n : undefined,\n affiliateId:\n (userData as { affiliate_id?: number } | undefined)?.affiliate_id ??\n null,\n basePath: \"\",\n navigate: (path: string) => {\n // Strip leading slash — cards generate paths like \"/share/product/123\"\n const cleanPath = path.replace(/^\\//, \"\");\n // Ensure share/ prefix — screen components pass relative paths like \"media/new\"\n const prefixed = cleanPath.startsWith(\"share/\")\n ? cleanPath\n : `share/${cleanPath}`;\n navigate(prefixed);\n },\n showToast: (opts: {\n title: string;\n type: \"success\" | \"error\" | \"warning\";\n }) => {\n console.warn(`[Shareables] ${opts.type}: ${opts.title}`);\n },\n filePickerClient,\n onToggleFavorite: async (params: {\n favoriteableId: number;\n favoriteableType: string;\n }) => {\n const affiliateId = (userData as { affiliate_id?: number } | undefined)\n ?.affiliate_id;\n if (!affiliateId) throw new Error(\"No affiliate ID\");\n return domainClient.post<{ is_favorited: boolean }>(\n `/user_companies/${affiliateId}/favorites/toggle.json`,\n {\n favoriteable_id: params.favoriteableId,\n favoriteable_type: params.favoriteableType,\n },\n );\n },\n onDeletePlaylist: isCustomer\n ? undefined\n : async (playlistId: number) => {\n const { playlists: playlistsApi } =\n await import(\"@fluid-app/shareables-api-client\");\n await playlistsApi.deletePlaylist(domainClient, playlistId);\n },\n readOnly: isCustomer,\n }),\n [userData, navigate, filePickerClient, domainClient, isCustomer],\n );\n\n return (\n <div {...divProps} className={`h-full ${divProps.className ?? \"\"}`}>\n <ShareablesCoreProvider config={coreConfig}>\n <ShareablesUIProvider config={uiConfig}>\n <ShareablesApp\n screen={screen}\n detailId={detailId}\n action={action}\n companyLogoUrl={userData?.company?.logo_url}\n countryCode={userData?.country?.iso}\n onNavigate={handleNavigate}\n onBack={handleBack}\n />\n </ShareablesUIProvider>\n </ShareablesCoreProvider>\n </div>\n );\n}\n\nexport const shareablesScreenPropertySchema: WidgetPropertySchema = {\n widgetType: \"ShareablesScreen\",\n displayName: \"Shareables Screen\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ShareablesScreen-o1VYr_1K.cjs","names":["useFluidAuth","USER_TYPES","useSdkClient","useCurrentUser","useAppNavigation","ShareablesCoreProvider","ShareablesUIProvider","ShareablesApp"],"sources":["../src/hooks/use-user-type.ts","../../../file-picker/api-client/src/client.ts","../src/screens/ShareablesScreen.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport { useFluidAuth } from \"./use-fluid-auth\";\nimport { USER_TYPES, type UserType } from \"../auth/types\";\n\nexport interface UseUserTypeResult {\n userType: UserType | null;\n isCustomer: boolean;\n isRep: boolean;\n isAdmin: boolean;\n}\n\n/**\n * Convenience hook for user-type checks in the portal SDK.\n */\nexport function useUserType(): UseUserTypeResult {\n const { user } = useFluidAuth();\n\n return useMemo(() => {\n const userType = user?.user_type ?? null;\n return {\n userType,\n isCustomer: userType === USER_TYPES.customer,\n isRep: userType === USER_TYPES.rep,\n isAdmin:\n userType === USER_TYPES.admin || userType === USER_TYPES.root_admin,\n };\n }, [user?.user_type]);\n}\n","import type { FetchClientInstance } from \"@fluid-app/api-client-core\";\nimport type { DamAssetCreateResponse } from \"@fluid-app/file-picker-core\";\n\nexport interface DamUploadStrategy {\n uploadFile(params: {\n file: File;\n name: string;\n description?: string;\n tags?: string[];\n onProgress?: (progress: number) => void;\n companyId?: number;\n }): Promise<DamAssetCreateResponse>;\n}\n\nexport interface FilePickerClientConfig {\n fetchClient: FetchClientInstance;\n uploadStrategy?: DamUploadStrategy;\n unsplashAccessKey?: string;\n proxyEndpoint?: string; // defaults to \"/api/proxy-url\"\n}\n\nexport interface FilePickerClient {\n fetchClient: FetchClientInstance;\n uploadStrategy?: DamUploadStrategy;\n unsplashAccessKey?: string;\n proxyEndpoint: string;\n}\n\nexport function createFilePickerClient(\n config: FilePickerClientConfig,\n): FilePickerClient {\n return {\n fetchClient: config.fetchClient,\n uploadStrategy: config.uploadStrategy,\n unsplashAccessKey: config.unsplashAccessKey,\n proxyEndpoint: config.proxyEndpoint ?? \"/api/proxy-url\",\n };\n}\n","import { useCallback, useMemo, type ComponentProps } from \"react\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"../types\";\nimport type { WidgetPropertySchema } from \"../registries/property-schema-types\";\nimport { ShareablesCoreProvider } from \"@fluid-app/shareables-core\";\nimport { ShareablesUIProvider, ShareablesApp } from \"@fluid-app/shareables-ui\";\nimport { createFilePickerClient } from \"@fluid-app/file-picker-api-client\";\nimport { useCurrentUser } from \"../hooks/use-current-user\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\nimport { useSdkClient } from \"../account/use-account-clients\";\nimport { useUserType } from \"../hooks/use-user-type\";\n\ntype ShareablesScreenProps = ComponentProps<\"div\"> & {\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n};\n\n/**\n * Parse the current shareables sub-route from the full slug.\n *\n * System nav slugs are \"share/products\", \"share/media\", \"share/playlists\".\n * Detail pages append an ID: \"share/products/123\", \"share/media/456\".\n *\n * \"share/products\" → screen=\"products\", detailId=null\n * \"share/products/123\" → screen=\"products\", detailId=\"123\"\n * \"share/media/456\" → screen=\"media\", detailId=\"456\"\n * \"share/playlists\" → screen=\"playlists\", detailId=null\n * \"share/playlists/789\" → screen=\"playlists\", detailId=\"789\"\n * \"share/files\" → screen=\"files\", detailId=null\n * \"share\" → screen=null (default to products)\n */\nfunction parseShareablesRoute(currentSlug: string): {\n screen: string | null;\n detailId: string | null;\n action: string | null;\n} {\n // Strip the \"share\" prefix\n const slugWithoutPrefix = currentSlug.replace(/^share\\/?/, \"\");\n if (!slugWithoutPrefix) {\n return { screen: null, detailId: null, action: null };\n }\n\n const parts = slugWithoutPrefix.split(\"/\");\n const screen = parts[0] || null;\n const detailId = parts[1] || null;\n const action = parts[2] || null;\n return { screen, detailId, action };\n}\n\nexport function ShareablesScreen({\n /* eslint-disable @typescript-eslint/no-unused-vars -- destructured to exclude from divProps spread */\n background,\n textColor,\n accentColor,\n padding,\n borderRadius,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n ...divProps\n}: ShareablesScreenProps): React.JSX.Element {\n const domainClient = useSdkClient();\n const { data: userData } = useCurrentUser();\n const { currentSlug, navigate } = useAppNavigation();\n const { isCustomer } = useUserType();\n\n const { screen, detailId, action } = parseShareablesRoute(currentSlug);\n\n const handleNavigate = useCallback(\n (subScreen: string, id?: string) => {\n const path = id ? `share/${subScreen}/${id}` : `share/${subScreen}`;\n navigate(path);\n },\n [navigate],\n );\n\n const handleBack = useCallback(() => {\n if (detailId && screen) {\n // Navigate back to the listing for the current screen\n navigate(`share/${screen}`);\n } else {\n // Navigate to the default shareables screen\n navigate(\"share/products\");\n }\n }, [navigate, detailId, screen]);\n\n const coreConfig = useMemo(\n () => ({\n client: domainClient,\n user: userData ? { id: userData.id } : null,\n repContext: true,\n }),\n [domainClient, userData],\n );\n\n const filePickerClient = useMemo(\n () => createFilePickerClient({ fetchClient: domainClient }),\n [domainClient],\n );\n\n const uiConfig = useMemo(\n () => ({\n user: userData\n ? {\n id: userData.id,\n company: userData.company\n ? { logo_url: userData.company.logo_url }\n : null,\n }\n : undefined,\n affiliateId:\n (userData as { affiliate_id?: number } | undefined)?.affiliate_id ??\n null,\n basePath: \"\",\n navigate: (path: string) => {\n // Strip leading slash — cards generate paths like \"/share/product/123\"\n const cleanPath = path.replace(/^\\//, \"\");\n // Ensure share/ prefix — screen components pass relative paths like \"media/new\"\n const prefixed = cleanPath.startsWith(\"share/\")\n ? cleanPath\n : `share/${cleanPath}`;\n navigate(prefixed);\n },\n showToast: (opts: {\n title: string;\n type: \"success\" | \"error\" | \"warning\";\n }) => {\n console.warn(`[Shareables] ${opts.type}: ${opts.title}`);\n },\n filePickerClient,\n onToggleFavorite: async (params: {\n favoriteableId: number;\n favoriteableType: string;\n }) => {\n const affiliateId = (userData as { affiliate_id?: number } | undefined)\n ?.affiliate_id;\n if (!affiliateId) throw new Error(\"No affiliate ID\");\n return domainClient.post<{ is_favorited: boolean }>(\n `/user_companies/${affiliateId}/favorites/toggle.json`,\n {\n favoriteable_id: params.favoriteableId,\n favoriteable_type: params.favoriteableType,\n },\n );\n },\n onDeletePlaylist: isCustomer\n ? undefined\n : async (playlistId: number) => {\n const { playlists: playlistsApi } =\n await import(\"@fluid-app/shareables-api-client\");\n await playlistsApi.deletePlaylist(domainClient, playlistId);\n },\n readOnly: isCustomer,\n }),\n [userData, navigate, filePickerClient, domainClient, isCustomer],\n );\n\n return (\n <div {...divProps} className={`h-full ${divProps.className ?? \"\"}`}>\n <ShareablesCoreProvider config={coreConfig}>\n <ShareablesUIProvider config={uiConfig}>\n <ShareablesApp\n screen={screen}\n detailId={detailId}\n action={action}\n companyLogoUrl={userData?.company?.logo_url}\n countryCode={userData?.country?.iso}\n onNavigate={handleNavigate}\n onBack={handleBack}\n />\n </ShareablesUIProvider>\n </ShareablesCoreProvider>\n </div>\n );\n}\n\nexport const shareablesScreenPropertySchema: WidgetPropertySchema = {\n widgetType: \"ShareablesScreen\",\n displayName: \"Shareables Screen\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":";;;;;;;;;;;;AAcA,SAAgB,cAAiC;CAC/C,MAAM,EAAE,SAASA,4BAAAA,cAAc;AAE/B,SAAA,GAAA,MAAA,eAAqB;EACnB,MAAM,WAAW,MAAM,aAAa;AACpC,SAAO;GACL;GACA,YAAY,aAAaC,sBAAAA,WAAW;GACpC,OAAO,aAAaA,sBAAAA,WAAW;GAC/B,SACE,aAAaA,sBAAAA,WAAW,SAAS,aAAaA,sBAAAA,WAAW;GAC5D;IACA,CAAC,MAAM,UAAU,CAAC;;;;ACEvB,SAAgB,uBACd,QACkB;AAClB,QAAO;EACL,aAAa,OAAO;EACpB,gBAAgB,OAAO;EACvB,mBAAmB,OAAO;EAC1B,eAAe,OAAO,iBAAiB;EACxC;;;;;;;;;;;;;;;;;;ACEH,SAAS,qBAAqB,aAI5B;CAEA,MAAM,oBAAoB,YAAY,QAAQ,aAAa,GAAG;AAC9D,KAAI,CAAC,kBACH,QAAO;EAAE,QAAQ;EAAM,UAAU;EAAM,QAAQ;EAAM;CAGvD,MAAM,QAAQ,kBAAkB,MAAM,IAAI;AAI1C,QAAO;EAAE,QAHM,MAAM,MAAM;EAGV,UAFA,MAAM,MAAM;EAEF,QADZ,MAAM,MAAM;EACQ;;AAGrC,SAAgB,iBAAiB,EAE/B,YACA,WACA,aACA,SACA,cAEA,GAAG,YACwC;CAC3C,MAAM,eAAeC,4BAAAA,cAAc;CACnC,MAAM,EAAE,MAAM,aAAaC,yBAAAA,gBAAgB;CAC3C,MAAM,EAAE,aAAa,aAAaC,6BAAAA,kBAAkB;CACpD,MAAM,EAAE,eAAe,aAAa;CAEpC,MAAM,EAAE,QAAQ,UAAU,WAAW,qBAAqB,YAAY;CAEtE,MAAM,kBAAA,GAAA,MAAA,cACH,WAAmB,OAAgB;AAElC,WADa,KAAK,SAAS,UAAU,GAAG,OAAO,SAAS,YAC1C;IAEhB,CAAC,SAAS,CACX;CAED,MAAM,cAAA,GAAA,MAAA,mBAA+B;AACnC,MAAI,YAAY,OAEd,UAAS,SAAS,SAAS;MAG3B,UAAS,iBAAiB;IAE3B;EAAC;EAAU;EAAU;EAAO,CAAC;CAEhC,MAAM,cAAA,GAAA,MAAA,gBACG;EACL,QAAQ;EACR,MAAM,WAAW,EAAE,IAAI,SAAS,IAAI,GAAG;EACvC,YAAY;EACb,GACD,CAAC,cAAc,SAAS,CACzB;CAED,MAAM,oBAAA,GAAA,MAAA,eACE,uBAAuB,EAAE,aAAa,cAAc,CAAC,EAC3D,CAAC,aAAa,CACf;CAED,MAAM,YAAA,GAAA,MAAA,gBACG;EACL,MAAM,WACF;GACE,IAAI,SAAS;GACb,SAAS,SAAS,UACd,EAAE,UAAU,SAAS,QAAQ,UAAU,GACvC;GACL,GACD,KAAA;EACJ,aACG,UAAoD,gBACrD;EACF,UAAU;EACV,WAAW,SAAiB;GAE1B,MAAM,YAAY,KAAK,QAAQ,OAAO,GAAG;AAKzC,YAHiB,UAAU,WAAW,SAAS,GAC3C,YACA,SAAS,YACK;;EAEpB,YAAY,SAGN;AACJ,WAAQ,KAAK,gBAAgB,KAAK,KAAK,IAAI,KAAK,QAAQ;;EAE1D;EACA,kBAAkB,OAAO,WAGnB;GACJ,MAAM,cAAe,UACjB;AACJ,OAAI,CAAC,YAAa,OAAM,IAAI,MAAM,kBAAkB;AACpD,UAAO,aAAa,KAClB,mBAAmB,YAAY,yBAC/B;IACE,iBAAiB,OAAO;IACxB,mBAAmB,OAAO;IAC3B,CACF;;EAEH,kBAAkB,aACd,KAAA,IACA,OAAO,eAAuB;GAC5B,MAAM,EAAE,WAAW,iBACjB,MAAA,QAAA,SAAA,CAAA,WAAA,QAAM,qBAAA,CAAA,CAAA,MAAA,MAAA,EAAA,YAAA;AACR,SAAM,aAAa,eAAe,cAAc,WAAW;;EAEjE,UAAU;EACX,GACD;EAAC;EAAU;EAAU;EAAkB;EAAc;EAAW,CACjE;AAED,QACE,iBAAA,GAAA,kBAAA,KAAC,OAAD;EAAK,GAAI;EAAU,WAAW,UAAU,SAAS,aAAa;YAC5D,iBAAA,GAAA,kBAAA,KAACC,YAAAA,wBAAD;GAAwB,QAAQ;aAC9B,iBAAA,GAAA,kBAAA,KAACC,YAAAA,sBAAD;IAAsB,QAAQ;cAC5B,iBAAA,GAAA,kBAAA,KAACC,YAAAA,eAAD;KACU;KACE;KACF;KACR,gBAAgB,UAAU,SAAS;KACnC,aAAa,UAAU,SAAS;KAChC,YAAY;KACZ,QAAQ;KACR,CAAA;IACmB,CAAA;GACA,CAAA;EACrB,CAAA;;AAIV,MAAa,iCAAuD;CAClE,YAAY;CACZ,aAAa;CACb,YAAY,CAAC;EAAE,IAAI;EAAW,OAAO;EAAW,CAAC;CACjD,QAAQ,EAAE;CACX"}
|