@fluid-app/portal-sdk 0.1.371 → 0.1.373
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/{ContainerWidget-mSWihekF.mjs → ContainerWidget-C1Nk6GPZ.mjs} +2 -2
- package/dist/{ContainerWidget-mSWihekF.mjs.map → ContainerWidget-C1Nk6GPZ.mjs.map} +1 -1
- package/dist/{ContainerWidget-bMMdFhLg.cjs → ContainerWidget-DVQxqY3k.cjs} +2 -2
- package/dist/{ContainerWidget-bMMdFhLg.cjs.map → ContainerWidget-DVQxqY3k.cjs.map} +1 -1
- package/dist/{ContainerWidget-C2LMzXVj.cjs → ContainerWidget-fhiIAoZA.cjs} +2 -2
- package/dist/{FluidProvider-C80gc4Yi.mjs → FluidProvider-Bu9N22BI.mjs} +5 -5
- package/dist/{FluidProvider-C80gc4Yi.mjs.map → FluidProvider-Bu9N22BI.mjs.map} +1 -1
- package/dist/{FluidProvider-C6d1TUVm.cjs → FluidProvider-CURmntkw.cjs} +5 -5
- package/dist/{FluidProvider-C6d1TUVm.cjs.map → FluidProvider-CURmntkw.cjs.map} +1 -1
- package/dist/{LayoutWidget-BqUbneWw.cjs → LayoutWidget-CzM4gn1-.cjs} +12 -10
- package/dist/LayoutWidget-CzM4gn1-.cjs.map +1 -0
- package/dist/{LayoutWidget-C1BzDeQI.cjs → LayoutWidget-D-wlt7T1.cjs} +1 -1
- package/dist/{LayoutWidget-D3qYKt9F.mjs → LayoutWidget-DXPXYYd_.mjs} +12 -10
- package/dist/LayoutWidget-DXPXYYd_.mjs.map +1 -0
- package/dist/{MessagingScreen-DKzYThAY.mjs → MessagingScreen-D8_oGy_k.mjs} +2 -2
- package/dist/{MessagingScreen-DKzYThAY.mjs.map → MessagingScreen-D8_oGy_k.mjs.map} +1 -1
- package/dist/{MessagingScreen-D3si8TPx.mjs → MessagingScreen-DwmciO1o.mjs} +4 -4
- package/dist/{MessagingScreen-PZyO11S1.cjs → MessagingScreen-NE1Na8rN.cjs} +4 -4
- package/dist/{MessagingScreen-DqxRu2x3.cjs → MessagingScreen-YvwfkYbW.cjs} +2 -2
- package/dist/{MessagingScreen-DqxRu2x3.cjs.map → MessagingScreen-YvwfkYbW.cjs.map} +1 -1
- package/dist/{OrdersScreen-CpNvxRDC.cjs → OrdersScreen-B81SHSOU.cjs} +29 -20
- package/dist/OrdersScreen-B81SHSOU.cjs.map +1 -0
- package/dist/{OrdersScreen-BuX5aWgx.cjs → OrdersScreen-BtgUuBky.cjs} +4 -4
- package/dist/{OrdersScreen-B2htbQ2Q.mjs → OrdersScreen-BycEvuSw.mjs} +29 -20
- package/dist/OrdersScreen-BycEvuSw.mjs.map +1 -0
- package/dist/{OrdersScreen-Cgjfo2Fs.mjs → OrdersScreen-DYjOpQa2.mjs} +4 -4
- package/dist/{ProfileScreen-DlIXDIeu.cjs → ProfileScreen-B0yVzqyg.cjs} +3 -3
- package/dist/{ProfileScreen-DlIXDIeu.cjs.map → ProfileScreen-B0yVzqyg.cjs.map} +1 -1
- package/dist/{ProfileScreen-BCwdwO_p.mjs → ProfileScreen-BVRnPuRm.mjs} +3 -3
- package/dist/{ProfileScreen-BCwdwO_p.mjs.map → ProfileScreen-BVRnPuRm.mjs.map} +1 -1
- package/dist/{ProfileScreen-D7UA604p.mjs → ProfileScreen-Ckf1a-zh.mjs} +5 -5
- package/dist/{ProfileScreen-MypXufrO.cjs → ProfileScreen-DisEMe-1.cjs} +5 -5
- package/dist/{ShopScreen-29SZwMWF.cjs → ShopScreen-B9uHdQP7.cjs} +2 -2
- package/dist/{ShopScreen-29SZwMWF.cjs.map → ShopScreen-B9uHdQP7.cjs.map} +1 -1
- package/dist/{ShopScreen-BC9NDysQ.cjs → ShopScreen-CEB0iwmF.cjs} +4 -4
- package/dist/{ShopScreen-CgN-6gic.mjs → ShopScreen-CPpJB-Kt.mjs} +2 -2
- package/dist/{ShopScreen-CgN-6gic.mjs.map → ShopScreen-CPpJB-Kt.mjs.map} +1 -1
- package/dist/{ShopScreen-BKVNW6ya.mjs → ShopScreen-DN5Y1HQ7.mjs} +4 -4
- package/dist/{SubscriptionsScreen-Dz6Y_1oD.cjs → SubscriptionsScreen-BTQuJNaY.cjs} +3 -3
- package/dist/{SubscriptionsScreen-Dz6Y_1oD.cjs.map → SubscriptionsScreen-BTQuJNaY.cjs.map} +1 -1
- package/dist/{SubscriptionsScreen-dN42J-MR.cjs → SubscriptionsScreen-C_7vhN3q.cjs} +5 -5
- package/dist/{SubscriptionsScreen-M2WaVHH7.mjs → SubscriptionsScreen-DdazqD1V.mjs} +3 -3
- package/dist/{SubscriptionsScreen-M2WaVHH7.mjs.map → SubscriptionsScreen-DdazqD1V.mjs.map} +1 -1
- package/dist/{SubscriptionsScreen-CPiLzWhm.mjs → SubscriptionsScreen-ZkjeOBHH.mjs} +5 -5
- package/dist/{authoring-V0sXg_j4.d.mts → authoring-D0yimRFr.d.mts} +2 -2
- package/dist/{authoring-V0sXg_j4.d.mts.map → authoring-D0yimRFr.d.mts.map} +1 -1
- package/dist/{authoring--rXPyZca.d.cts → authoring-Di7OJapg.d.cts} +2 -2
- package/dist/{authoring--rXPyZca.d.cts.map → authoring-Di7OJapg.d.cts.map} +1 -1
- package/dist/index.cjs +20 -20
- package/dist/index.d.cts +2 -2
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +20 -20
- package/dist/preview/preview-entry.cjs +4 -4
- package/dist/preview/preview-entry.d.cts +1 -1
- package/dist/preview/preview-entry.d.mts +1 -1
- package/dist/preview/preview-entry.mjs +4 -4
- package/dist/{use-portal-card-add-3ds-flow-C0YUg213.cjs → use-portal-card-add-3ds-flow-BxFF4Wew.cjs} +2 -2
- package/dist/{use-portal-card-add-3ds-flow-C0YUg213.cjs.map → use-portal-card-add-3ds-flow-BxFF4Wew.cjs.map} +1 -1
- package/dist/{use-portal-card-add-3ds-flow-DKXraYw-.mjs → use-portal-card-add-3ds-flow-CphCh5cu.mjs} +2 -2
- package/dist/{use-portal-card-add-3ds-flow-DKXraYw-.mjs.map → use-portal-card-add-3ds-flow-CphCh5cu.mjs.map} +1 -1
- package/dist/{widget-package-descriptor-ByCz_FNh.d.cts → widget-package-descriptor-Chc8Gb6V.d.cts} +8 -8
- package/dist/widget-package-descriptor-Chc8Gb6V.d.cts.map +1 -0
- package/dist/{widget-package-descriptor-CPIPAdUO.d.mts → widget-package-descriptor-fjHqObKE.d.mts} +8 -8
- package/dist/{widget-package-descriptor-CPIPAdUO.d.mts.map → widget-package-descriptor-fjHqObKE.d.mts.map} +1 -1
- package/dist/{widget-package-utils-BdS0B0pI.mjs → widget-package-utils-BS8mCzgZ.mjs} +2 -2
- package/dist/{widget-package-utils-BdS0B0pI.mjs.map → widget-package-utils-BS8mCzgZ.mjs.map} +1 -1
- package/dist/{widget-package-utils-BWn56ZFw.cjs → widget-package-utils-C0WYunNq.cjs} +2 -2
- package/dist/{widget-package-utils-BWn56ZFw.cjs.map → widget-package-utils-C0WYunNq.cjs.map} +1 -1
- package/dist/widgets/authoring.d.cts +1 -1
- package/dist/widgets/authoring.d.mts +1 -1
- package/package.json +18 -18
- package/dist/LayoutWidget-BqUbneWw.cjs.map +0 -1
- package/dist/LayoutWidget-D3qYKt9F.mjs.map +0 -1
- package/dist/OrdersScreen-B2htbQ2Q.mjs.map +0 -1
- package/dist/OrdersScreen-CpNvxRDC.cjs.map +0 -1
- package/dist/widget-package-descriptor-ByCz_FNh.d.cts.map +0 -1
|
@@ -12,27 +12,27 @@ const sectionLayoutConfig = {
|
|
|
12
12
|
"2c-equal": {
|
|
13
13
|
columns: 2,
|
|
14
14
|
widths: ["1fr", "1fr"],
|
|
15
|
-
gridClasses: "@md:grid-cols-
|
|
15
|
+
gridClasses: "@md:grid-cols-[minmax(0,1fr)_minmax(0,1fr)]"
|
|
16
16
|
},
|
|
17
17
|
"2c-left-wider": {
|
|
18
18
|
columns: 2,
|
|
19
19
|
widths: ["2fr", "1fr"],
|
|
20
|
-
gridClasses: "@md:grid-cols-[
|
|
20
|
+
gridClasses: "@md:grid-cols-[minmax(0,2fr)_minmax(0,1fr)]"
|
|
21
21
|
},
|
|
22
22
|
"2c-right-wider": {
|
|
23
23
|
columns: 2,
|
|
24
24
|
widths: ["1fr", "2fr"],
|
|
25
|
-
gridClasses: "@md:grid-cols-[
|
|
25
|
+
gridClasses: "@md:grid-cols-[minmax(0,1fr)_minmax(0,2fr)]"
|
|
26
26
|
},
|
|
27
27
|
"2c-left-narrow": {
|
|
28
28
|
columns: 2,
|
|
29
29
|
widths: ["1fr", "3fr"],
|
|
30
|
-
gridClasses: "@md:grid-cols-[
|
|
30
|
+
gridClasses: "@md:grid-cols-[minmax(0,1fr)_minmax(0,3fr)]"
|
|
31
31
|
},
|
|
32
32
|
"2c-right-narrow": {
|
|
33
33
|
columns: 2,
|
|
34
34
|
widths: ["3fr", "1fr"],
|
|
35
|
-
gridClasses: "@md:grid-cols-[
|
|
35
|
+
gridClasses: "@md:grid-cols-[minmax(0,3fr)_minmax(0,1fr)]"
|
|
36
36
|
},
|
|
37
37
|
"3c-equal": {
|
|
38
38
|
columns: 3,
|
|
@@ -41,7 +41,7 @@ const sectionLayoutConfig = {
|
|
|
41
41
|
"1fr",
|
|
42
42
|
"1fr"
|
|
43
43
|
],
|
|
44
|
-
gridClasses: "@md:grid-cols-
|
|
44
|
+
gridClasses: "@md:grid-cols-[minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)]"
|
|
45
45
|
},
|
|
46
46
|
"3c-middle-wider": {
|
|
47
47
|
columns: 3,
|
|
@@ -50,7 +50,7 @@ const sectionLayoutConfig = {
|
|
|
50
50
|
"2fr",
|
|
51
51
|
"1fr"
|
|
52
52
|
],
|
|
53
|
-
gridClasses: "@md:grid-cols-[
|
|
53
|
+
gridClasses: "@md:grid-cols-[minmax(0,1fr)_minmax(0,2fr)_minmax(0,1fr)]"
|
|
54
54
|
}
|
|
55
55
|
};
|
|
56
56
|
//#endregion
|
|
@@ -86,6 +86,8 @@ const LayoutWidget = ({ sectionLayout = "single-column", gap = 4, gapSize, backg
|
|
|
86
86
|
const gapSizeValue = gapSize ? require_registries.gapValues[gapSize] : gap;
|
|
87
87
|
const layoutClasses = [
|
|
88
88
|
"grid",
|
|
89
|
+
"w-full",
|
|
90
|
+
"min-w-0",
|
|
89
91
|
"grid-cols-1",
|
|
90
92
|
layoutConfig.gridClasses,
|
|
91
93
|
`bg-${backgroundColor} p-${padding} rounded-${borderRadius} ${require_registries.borderWidthClasses[borderWidth]} ${borderWidth !== "none" ? require_registries.borderColorClasses[borderColor] : ""}`,
|
|
@@ -105,14 +107,14 @@ const LayoutWidget = ({ sectionLayout = "single-column", gap = 4, gapSize, backg
|
|
|
105
107
|
});
|
|
106
108
|
}
|
|
107
109
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
108
|
-
className: "@container",
|
|
110
|
+
className: "@container w-full min-w-0",
|
|
109
111
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
110
112
|
className: layoutClasses,
|
|
111
113
|
style: containerStyle,
|
|
112
114
|
children: groupChildrenByColumn(children, columnCount).map((columnChildren, colIndex) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ScreenRenderer$1, {
|
|
113
115
|
screen: columnChildren,
|
|
114
116
|
registry: effectiveRegistry,
|
|
115
|
-
className: `flex flex-col gap-${gapSizeValue}`
|
|
117
|
+
className: `flex w-full min-w-0 flex-col gap-${gapSizeValue}`
|
|
116
118
|
}, colIndex))
|
|
117
119
|
})
|
|
118
120
|
});
|
|
@@ -200,4 +202,4 @@ Object.defineProperty(exports, "sectionLayoutConfig", {
|
|
|
200
202
|
}
|
|
201
203
|
});
|
|
202
204
|
|
|
203
|
-
//# sourceMappingURL=LayoutWidget-
|
|
205
|
+
//# sourceMappingURL=LayoutWidget-CzM4gn1-.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LayoutWidget-CzM4gn1-.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 \"single-column\": { columns: 1, widths: [\"1fr\"], gridClasses: \"\" },\n \"2c-equal\": {\n columns: 2,\n widths: [\"1fr\", \"1fr\"],\n gridClasses: \"@md:grid-cols-[minmax(0,1fr)_minmax(0,1fr)]\",\n },\n \"2c-left-wider\": {\n columns: 2,\n widths: [\"2fr\", \"1fr\"],\n gridClasses: \"@md:grid-cols-[minmax(0,2fr)_minmax(0,1fr)]\",\n },\n \"2c-right-wider\": {\n columns: 2,\n widths: [\"1fr\", \"2fr\"],\n gridClasses: \"@md:grid-cols-[minmax(0,1fr)_minmax(0,2fr)]\",\n },\n \"2c-left-narrow\": {\n columns: 2,\n widths: [\"1fr\", \"3fr\"],\n gridClasses: \"@md:grid-cols-[minmax(0,1fr)_minmax(0,3fr)]\",\n },\n \"2c-right-narrow\": {\n columns: 2,\n widths: [\"3fr\", \"1fr\"],\n gridClasses: \"@md:grid-cols-[minmax(0,3fr)_minmax(0,1fr)]\",\n },\n \"3c-equal\": {\n columns: 3,\n widths: [\"1fr\", \"1fr\", \"1fr\"],\n gridClasses: \"@md:grid-cols-[minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)]\",\n },\n \"3c-middle-wider\": {\n columns: 3,\n widths: [\"1fr\", \"2fr\", \"1fr\"],\n gridClasses: \"@md:grid-cols-[minmax(0,1fr)_minmax(0,2fr)_minmax(0,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 \"w-full\",\n \"min-w-0\",\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 w-full min-w-0\">\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 w-full min-w-0 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":";;;;;AA8MA,MAAa,sBArDwB;CACnC,iBAAiB;EAAE,SAAS;EAAG,QAAQ,CAAC,MAAM;EAAE,aAAa;EAAI;CACjE,YAAY;EACV,SAAS;EACT,QAAQ,CAAC,OAAO,MAAM;EACtB,aAAa;EACd;CACD,iBAAiB;EACf,SAAS;EACT,QAAQ,CAAC,OAAO,MAAM;EACtB,aAAa;EACd;CACD,kBAAkB;EAChB,SAAS;EACT,QAAQ,CAAC,OAAO,MAAM;EACtB,aAAa;EACd;CACD,kBAAkB;EAChB,SAAS;EACT,QAAQ,CAAC,OAAO,MAAM;EACtB,aAAa;EACd;CACD,mBAAmB;EACjB,SAAS;EACT,QAAQ,CAAC,OAAO,MAAM;EACtB,aAAa;EACd;CACD,YAAY;EACV,SAAS;EACT,QAAQ;GAAC;GAAO;GAAO;GAAM;EAC7B,aAAa;EACd;CACD,mBAAmB;EACjB,SAAS;EACT,QAAQ;GAAC;GAAO;GAAO;GAAM;EAC7B,aAAa;EACd;CACF;;;;;;;AChFD,SAAgB,sBACd,UACA,aACkB;CAElB,MAAM,UAA4B,MAAM,KACtC,EAAE,QAAQ,aAAa,QACD,EAAE,CACzB;CAID,MAAM,kBAAkB,SAAS,QAC9B,UAAiC,UAAU,KAC7C;AAED,MAAK,MAAM,SAAS,iBAAiB;EAGnC,MAAM,SAAS,QADE,KAAK,IAAI,MAAM,eAAe,GAAG,cAAc,EAAE;AAElE,MAAI,OACF,QAAO,KAAK,MAAM;;AAItB,QAAO;;;;ACzGT,MAAM,qBAAsC;CAC1C,MAAM;CACN,OAAO;CACR;AACD,MAAM,mBAA4C,EAAE;AA6CpD,MAAa,gBAA8D,EACzE,gBAAgB,iBAChB,MAAM,GACN,SACA,aAAa,oBACb,UAAU,GACV,eAAe,MACf,cAAc,QACd,cAAc,SACd,WAAW,kBACX,UACA,YAAY,IACZ,gBACuC;CAEvC,MAAM,kBAAkBA,uBAAAA,aAAa;CACrC,MAAM,oBAAoB,YAAY;CAItC,MAAMC,mBADwBC,uBAAAA,mBAAmB,IACDC,uBAAAA;CAGhD,MAAM,kBAAkB,WAAW,SAAS;CAC5C,MAAM,mBACH,WAAW,UAAU,aAAa,WAAW,UAAU,aACxD,WAAW,SAAS,UAChB,OAAO,WAAW,SAAS,aAAa,WAAW,SAAS,SAAS,KACrE;CAGN,MAAM,eAAe,oBAAoB;CACzC,MAAM,cAAc,aAAa;CAGjC,MAAM,eAAe,UAAUC,mBAAAA,UAAU,WAAW;CAGpD,MAAM,gBAAgB;EACpB;EACA;EACA;EACA;EACA,aAAa;EACb,MAAM,gBAAgB,KAAK,QAAQ,WAAW,aAAa,GAAGC,mBAAAA,mBAAmB,aAAa,GAAG,gBAAgB,SAASC,mBAAAA,mBAAmB,eAAe;EAC5J,OAAO;EACP;EACD,CACE,OAAO,QAAQ,CACf,KAAK,IAAI;CAGZ,MAAM,iBAAsC;EAC1C,GAAI,YAAY,EAAE,WAAW,GAAG,UAAU,KAAK,GAAG,EAAE;EACpD,YAAY;EACZ;EACD;AAGD,KAAI,CAAC,mBAAmB;AACtB,UAAQ,KAAK,8DAA8D;AAC3E,SAAO,iBAAA,GAAA,kBAAA,KAAC,OAAD;GAAK,WAAW;GAAe,OAAO;GAAkB,CAAA;;AAUjE,QACE,iBAAA,GAAA,kBAAA,KAAC,OAAD;EAAK,WAAU;YACb,iBAAA,GAAA,kBAAA,KAAC,OAAD;GAAK,WAAW;GAAe,OAAO;aARrB,sBACnB,UACA,YACD,CAMmB,KAAK,gBAAgB,aACjC,iBAAA,GAAA,kBAAA,KAACL,kBAAD;IAEE,QAAQ;IACR,UAAU;IACV,WAAW,oCAAoC;IAC/C,EAJK,SAIL,CACF;GACE,CAAA;EACF,CAAA;;AAIV,MAAa,6BAAmD;CAC9D,YAAY;CACZ,aAAa;CACb,QAAQ;EAEN;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,OAAO;GACR;EAGDM,mBAAAA,YAAY;GACV,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,OAAO;GACR,CAAC;EACF;GACE,MAAM;GACN,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,OAAO;GACR;EACDC,mBAAAA,gBAAgB;GACd,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,OAAO;GACR,CAAC;EACFC,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;EACH;CACF"}
|
|
@@ -3,7 +3,7 @@ require("./ScreenRenderer-Ce8MJPnR.cjs");
|
|
|
3
3
|
require("./registry-context-Ds0_y48D.cjs");
|
|
4
4
|
require("./translation-api-context-factory-B6BS_JmA.cjs");
|
|
5
5
|
require("./shell-translation-api-context-uGur0Kah.cjs");
|
|
6
|
-
const require_LayoutWidget = require("./LayoutWidget-
|
|
6
|
+
const require_LayoutWidget = require("./LayoutWidget-CzM4gn1-.cjs");
|
|
7
7
|
require("./registries-DiCQ4oFx.cjs");
|
|
8
8
|
require("./fields-D__8kJeJ.cjs");
|
|
9
9
|
exports.layoutWidgetPropertySchema = require_LayoutWidget.layoutWidgetPropertySchema;
|
|
@@ -12,27 +12,27 @@ const sectionLayoutConfig = {
|
|
|
12
12
|
"2c-equal": {
|
|
13
13
|
columns: 2,
|
|
14
14
|
widths: ["1fr", "1fr"],
|
|
15
|
-
gridClasses: "@md:grid-cols-
|
|
15
|
+
gridClasses: "@md:grid-cols-[minmax(0,1fr)_minmax(0,1fr)]"
|
|
16
16
|
},
|
|
17
17
|
"2c-left-wider": {
|
|
18
18
|
columns: 2,
|
|
19
19
|
widths: ["2fr", "1fr"],
|
|
20
|
-
gridClasses: "@md:grid-cols-[
|
|
20
|
+
gridClasses: "@md:grid-cols-[minmax(0,2fr)_minmax(0,1fr)]"
|
|
21
21
|
},
|
|
22
22
|
"2c-right-wider": {
|
|
23
23
|
columns: 2,
|
|
24
24
|
widths: ["1fr", "2fr"],
|
|
25
|
-
gridClasses: "@md:grid-cols-[
|
|
25
|
+
gridClasses: "@md:grid-cols-[minmax(0,1fr)_minmax(0,2fr)]"
|
|
26
26
|
},
|
|
27
27
|
"2c-left-narrow": {
|
|
28
28
|
columns: 2,
|
|
29
29
|
widths: ["1fr", "3fr"],
|
|
30
|
-
gridClasses: "@md:grid-cols-[
|
|
30
|
+
gridClasses: "@md:grid-cols-[minmax(0,1fr)_minmax(0,3fr)]"
|
|
31
31
|
},
|
|
32
32
|
"2c-right-narrow": {
|
|
33
33
|
columns: 2,
|
|
34
34
|
widths: ["3fr", "1fr"],
|
|
35
|
-
gridClasses: "@md:grid-cols-[
|
|
35
|
+
gridClasses: "@md:grid-cols-[minmax(0,3fr)_minmax(0,1fr)]"
|
|
36
36
|
},
|
|
37
37
|
"3c-equal": {
|
|
38
38
|
columns: 3,
|
|
@@ -41,7 +41,7 @@ const sectionLayoutConfig = {
|
|
|
41
41
|
"1fr",
|
|
42
42
|
"1fr"
|
|
43
43
|
],
|
|
44
|
-
gridClasses: "@md:grid-cols-
|
|
44
|
+
gridClasses: "@md:grid-cols-[minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)]"
|
|
45
45
|
},
|
|
46
46
|
"3c-middle-wider": {
|
|
47
47
|
columns: 3,
|
|
@@ -50,7 +50,7 @@ const sectionLayoutConfig = {
|
|
|
50
50
|
"2fr",
|
|
51
51
|
"1fr"
|
|
52
52
|
],
|
|
53
|
-
gridClasses: "@md:grid-cols-[
|
|
53
|
+
gridClasses: "@md:grid-cols-[minmax(0,1fr)_minmax(0,2fr)_minmax(0,1fr)]"
|
|
54
54
|
}
|
|
55
55
|
};
|
|
56
56
|
//#endregion
|
|
@@ -90,6 +90,8 @@ const LayoutWidget = ({ sectionLayout = "single-column", gap = 4, gapSize, backg
|
|
|
90
90
|
const gapSizeValue = gapSize ? gapValues[gapSize] : gap;
|
|
91
91
|
const layoutClasses = [
|
|
92
92
|
"grid",
|
|
93
|
+
"w-full",
|
|
94
|
+
"min-w-0",
|
|
93
95
|
"grid-cols-1",
|
|
94
96
|
layoutConfig.gridClasses,
|
|
95
97
|
`bg-${backgroundColor} p-${padding} rounded-${borderRadius} ${borderWidthClasses[borderWidth]} ${borderWidth !== "none" ? borderColorClasses[borderColor] : ""}`,
|
|
@@ -109,14 +111,14 @@ const LayoutWidget = ({ sectionLayout = "single-column", gap = 4, gapSize, backg
|
|
|
109
111
|
});
|
|
110
112
|
}
|
|
111
113
|
return /* @__PURE__ */ jsx("div", {
|
|
112
|
-
className: "@container",
|
|
114
|
+
className: "@container w-full min-w-0",
|
|
113
115
|
children: /* @__PURE__ */ jsx("div", {
|
|
114
116
|
className: layoutClasses,
|
|
115
117
|
style: containerStyle,
|
|
116
118
|
children: groupChildrenByColumn(children, columnCount).map((columnChildren, colIndex) => /* @__PURE__ */ jsx(ScreenRenderer$1, {
|
|
117
119
|
screen: columnChildren,
|
|
118
120
|
registry: effectiveRegistry,
|
|
119
|
-
className: `flex flex-col gap-${gapSizeValue}`
|
|
121
|
+
className: `flex w-full min-w-0 flex-col gap-${gapSizeValue}`
|
|
120
122
|
}, colIndex))
|
|
121
123
|
})
|
|
122
124
|
});
|
|
@@ -181,4 +183,4 @@ const layoutWidgetPropertySchema = {
|
|
|
181
183
|
//#endregion
|
|
182
184
|
export { sectionLayoutConfig as a, groupChildrenByColumn as i, LayoutWidget_exports as n, layoutWidgetPropertySchema as r, LayoutWidget as t };
|
|
183
185
|
|
|
184
|
-
//# sourceMappingURL=LayoutWidget-
|
|
186
|
+
//# sourceMappingURL=LayoutWidget-DXPXYYd_.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LayoutWidget-DXPXYYd_.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 \"single-column\": { columns: 1, widths: [\"1fr\"], gridClasses: \"\" },\n \"2c-equal\": {\n columns: 2,\n widths: [\"1fr\", \"1fr\"],\n gridClasses: \"@md:grid-cols-[minmax(0,1fr)_minmax(0,1fr)]\",\n },\n \"2c-left-wider\": {\n columns: 2,\n widths: [\"2fr\", \"1fr\"],\n gridClasses: \"@md:grid-cols-[minmax(0,2fr)_minmax(0,1fr)]\",\n },\n \"2c-right-wider\": {\n columns: 2,\n widths: [\"1fr\", \"2fr\"],\n gridClasses: \"@md:grid-cols-[minmax(0,1fr)_minmax(0,2fr)]\",\n },\n \"2c-left-narrow\": {\n columns: 2,\n widths: [\"1fr\", \"3fr\"],\n gridClasses: \"@md:grid-cols-[minmax(0,1fr)_minmax(0,3fr)]\",\n },\n \"2c-right-narrow\": {\n columns: 2,\n widths: [\"3fr\", \"1fr\"],\n gridClasses: \"@md:grid-cols-[minmax(0,3fr)_minmax(0,1fr)]\",\n },\n \"3c-equal\": {\n columns: 3,\n widths: [\"1fr\", \"1fr\", \"1fr\"],\n gridClasses: \"@md:grid-cols-[minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)]\",\n },\n \"3c-middle-wider\": {\n columns: 3,\n widths: [\"1fr\", \"2fr\", \"1fr\"],\n gridClasses: \"@md:grid-cols-[minmax(0,1fr)_minmax(0,2fr)_minmax(0,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 \"w-full\",\n \"min-w-0\",\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 w-full min-w-0\">\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 w-full min-w-0 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,5 +1,5 @@
|
|
|
1
1
|
import { dt as __require, ft as __toESM, lt as __commonJSMin, t as useAccount, ut as __exportAll } from "./use-account-D70N5avv.mjs";
|
|
2
|
-
import { K as ApiError, a as messagingDomain, i as createMessagingTranslationAdapter, n as useFluidContext } from "./FluidProvider-
|
|
2
|
+
import { K as ApiError, a as messagingDomain, i as createMessagingTranslationAdapter, n as useFluidContext } from "./FluidProvider-Bu9N22BI.mjs";
|
|
3
3
|
import { a as useActiveLocale, r as useDomainDict } from "./static-dict-adapter-B8kVuZyL.mjs";
|
|
4
4
|
import { t as createTranslationContext } from "./translation-api-context-factory-hfY7ipc0.mjs";
|
|
5
5
|
import { $ as Dialog, $t as differenceInCalendarDays, Ft as subDays, G as DropdownMenuLabel, H as DropdownMenu, It as isSameYear, J as DropdownMenuSeparator, Jt as endOfMonth, Kn as cn, Lt as isBefore, M as Input, N as IconToggle, P as IconButton, Pt as Calendar$1, Q as DropdownMenuTrigger, Rt as isAfter, U as DropdownMenuContent, W as DropdownMenuItem, Xt as isSameDay, Yt as differenceInCalendarMonths, cn as toDate, ct as Popover, d as SpinnerWithText, dn as millisecondsInMinute, dt as PopoverTrigger, en as startOfDay, et as DialogClose, i as TooltipTrigger, jn as Button, ln as constructFrom, n as TooltipContent, on as addMonths, p as fluidToast, r as TooltipProvider, sn as addDays, t as Tooltip, tn as normalizeDates, tt as DialogContent, un as millisecondsInHour, ut as PopoverContent, zt as format$1 } from "./src-BPYu8cbo.mjs";
|
|
@@ -53754,4 +53754,4 @@ const messagingScreenPropertySchema = {
|
|
|
53754
53754
|
//#endregion
|
|
53755
53755
|
export { useMessagingAuth as i, messagingScreenPropertySchema as n, useMessagingConfig as r, MessagingScreen as t };
|
|
53756
53756
|
|
|
53757
|
-
//# sourceMappingURL=MessagingScreen-
|
|
53757
|
+
//# sourceMappingURL=MessagingScreen-D8_oGy_k.mjs.map
|