@sudobility/building_blocks 0.0.143 → 0.0.145
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.
|
@@ -1,19 +1,41 @@
|
|
|
1
1
|
import React, { type ReactNode } from 'react';
|
|
2
2
|
import { type VariantProps } from 'class-variance-authority';
|
|
3
3
|
import { type AppBreadcrumbsProps } from '../breadcrumbs/app-breadcrumbs';
|
|
4
|
+
import { type AppTopBarProps } from '../topbar/app-topbar';
|
|
5
|
+
import { type AppTopBarWithFirebaseAuthProps } from '../topbar/app-topbar-with-firebase-auth';
|
|
6
|
+
import { type AppTopBarWithWalletProps } from '../topbar/app-topbar-with-wallet';
|
|
7
|
+
import { type AppFooterProps } from '../footer/app-footer';
|
|
8
|
+
import { type AppFooterForHomePageProps } from '../footer/app-footer-for-home-page';
|
|
4
9
|
import type { MaxWidth, ContentPadding, BackgroundVariant } from '../../types';
|
|
5
10
|
declare const layoutVariants: (props?: ({
|
|
6
11
|
background?: "default" | "white" | "gradient" | null | undefined;
|
|
7
12
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
13
|
+
/** Discriminated union for selecting which TopBar component to render. */
|
|
14
|
+
export type TopBarConfig = ({
|
|
15
|
+
variant: 'base';
|
|
16
|
+
topBarVariant?: 'default' | 'app';
|
|
17
|
+
} & Omit<AppTopBarProps, 'variant'>) | ({
|
|
18
|
+
variant: 'firebase';
|
|
19
|
+
topBarVariant?: 'default' | 'app';
|
|
20
|
+
} & Omit<AppTopBarWithFirebaseAuthProps, 'variant'>) | ({
|
|
21
|
+
variant: 'wallet';
|
|
22
|
+
topBarVariant?: 'default' | 'app';
|
|
23
|
+
} & Omit<AppTopBarWithWalletProps, 'variant'>);
|
|
24
|
+
/** Discriminated union for selecting which Footer component to render. */
|
|
25
|
+
export type FooterConfig = ({
|
|
26
|
+
variant: 'compact';
|
|
27
|
+
} & AppFooterProps) | ({
|
|
28
|
+
variant: 'full';
|
|
29
|
+
} & AppFooterForHomePageProps);
|
|
8
30
|
export interface AppPageLayoutProps extends VariantProps<typeof layoutVariants> {
|
|
9
31
|
/** Page content */
|
|
10
32
|
children: ReactNode;
|
|
11
|
-
/** TopBar
|
|
12
|
-
topBar:
|
|
33
|
+
/** TopBar configuration - selects which TopBar component to render */
|
|
34
|
+
topBar: TopBarConfig;
|
|
13
35
|
/** Breadcrumbs configuration (optional) */
|
|
14
36
|
breadcrumbs?: AppBreadcrumbsProps;
|
|
15
|
-
/** Footer
|
|
16
|
-
footer?:
|
|
37
|
+
/** Footer configuration - selects which Footer component to render */
|
|
38
|
+
footer?: FooterConfig;
|
|
17
39
|
/** Max width for content area (default: '7xl') */
|
|
18
40
|
maxWidth?: MaxWidth;
|
|
19
41
|
/** Content padding (default: 'md') */
|
|
@@ -35,35 +57,33 @@ export interface AppPageLayoutProps extends VariantProps<typeof layoutVariants>
|
|
|
35
57
|
* AppPageLayout - Layout wrapper combining TopBar, Breadcrumbs, Content, and Footer.
|
|
36
58
|
*
|
|
37
59
|
* Features:
|
|
38
|
-
* -
|
|
60
|
+
* - Props-based TopBar and Footer via discriminated unions
|
|
39
61
|
* - Optional breadcrumbs with share and "Talk to Founder"
|
|
40
62
|
* - Configurable content max-width and padding
|
|
41
63
|
* - Background variants
|
|
42
64
|
* - Dark mode support
|
|
43
|
-
* - Sticky footer behavior
|
|
65
|
+
* - Sticky footer behavior (automatic for compact footer)
|
|
44
66
|
*
|
|
45
67
|
* @example
|
|
46
68
|
* ```tsx
|
|
47
69
|
* <AppPageLayout
|
|
48
|
-
* topBar={
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* }
|
|
70
|
+
* topBar={{
|
|
71
|
+
* variant: 'firebase',
|
|
72
|
+
* logo: { src: '/logo.png', appName: 'My App' },
|
|
73
|
+
* menuItems: menuItems,
|
|
74
|
+
* AuthActionComponent: AuthAction,
|
|
75
|
+
* onLoginClick: () => navigate('/login'),
|
|
76
|
+
* }}
|
|
56
77
|
* breadcrumbs={{
|
|
57
78
|
* items: breadcrumbItems,
|
|
58
79
|
* shareConfig: { title: 'Page', description: 'Description', hashtags: [] },
|
|
59
80
|
* }}
|
|
60
|
-
* footer={
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
* }
|
|
81
|
+
* footer={{
|
|
82
|
+
* variant: 'compact',
|
|
83
|
+
* version: '1.0.0',
|
|
84
|
+
* companyName: 'My Company',
|
|
85
|
+
* links: [{ label: 'Privacy', href: '/privacy' }],
|
|
86
|
+
* }}
|
|
67
87
|
* maxWidth="7xl"
|
|
68
88
|
* background="default"
|
|
69
89
|
* >
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { AppPageLayout, type AppPageLayoutProps } from './app-page-layout';
|
|
1
|
+
export { AppPageLayout, type AppPageLayoutProps, type TopBarConfig, type FooterConfig, } from './app-page-layout';
|
package/dist/index.js
CHANGED
|
@@ -1065,6 +1065,44 @@ const paddingClasses = {
|
|
|
1065
1065
|
md: "px-4 py-8",
|
|
1066
1066
|
lg: "px-4 py-12"
|
|
1067
1067
|
};
|
|
1068
|
+
function renderTopBar(config) {
|
|
1069
|
+
const { variant, topBarVariant, ...rest } = config;
|
|
1070
|
+
switch (variant) {
|
|
1071
|
+
case "base":
|
|
1072
|
+
return /* @__PURE__ */ jsx(
|
|
1073
|
+
AppTopBar,
|
|
1074
|
+
{
|
|
1075
|
+
variant: topBarVariant,
|
|
1076
|
+
...rest
|
|
1077
|
+
}
|
|
1078
|
+
);
|
|
1079
|
+
case "firebase":
|
|
1080
|
+
return /* @__PURE__ */ jsx(
|
|
1081
|
+
AppTopBarWithFirebaseAuth,
|
|
1082
|
+
{
|
|
1083
|
+
variant: topBarVariant,
|
|
1084
|
+
...rest
|
|
1085
|
+
}
|
|
1086
|
+
);
|
|
1087
|
+
case "wallet":
|
|
1088
|
+
return /* @__PURE__ */ jsx(
|
|
1089
|
+
AppTopBarWithWallet,
|
|
1090
|
+
{
|
|
1091
|
+
variant: topBarVariant,
|
|
1092
|
+
...rest
|
|
1093
|
+
}
|
|
1094
|
+
);
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
function renderFooter(config) {
|
|
1098
|
+
const { variant, ...rest } = config;
|
|
1099
|
+
switch (variant) {
|
|
1100
|
+
case "compact":
|
|
1101
|
+
return /* @__PURE__ */ jsx(AppFooter, { ...rest });
|
|
1102
|
+
case "full":
|
|
1103
|
+
return /* @__PURE__ */ jsx(AppFooterForHomePage, { ...rest });
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1068
1106
|
const AppPageLayout = ({
|
|
1069
1107
|
children,
|
|
1070
1108
|
topBar,
|
|
@@ -1079,16 +1117,10 @@ const AppPageLayout = ({
|
|
|
1079
1117
|
mainClassName,
|
|
1080
1118
|
aspectRatio
|
|
1081
1119
|
}) => {
|
|
1082
|
-
|
|
1083
|
-
if (!topBar) {
|
|
1084
|
-
console.warn(
|
|
1085
|
-
"[AppPageLayout] No topBar provided. The layout will render without a navigation bar. Pass an AppTopBar variant or custom component via the topBar prop."
|
|
1086
|
-
);
|
|
1087
|
-
}
|
|
1088
|
-
}
|
|
1120
|
+
const isCompactFooter = (footer == null ? void 0 : footer.variant) === "compact";
|
|
1089
1121
|
const content = aspectRatio ? /* @__PURE__ */ jsx(AspectFitView, { aspectRatio, children }) : children;
|
|
1090
1122
|
return /* @__PURE__ */ jsx(LayoutProvider, { mode: layoutMode, children: /* @__PURE__ */ jsxs("div", { className: cn(layoutVariants({ background }), className), children: [
|
|
1091
|
-
/* @__PURE__ */ jsx("header", { children: topBar }),
|
|
1123
|
+
/* @__PURE__ */ jsx("header", { children: renderTopBar(topBar) }),
|
|
1092
1124
|
breadcrumbs && breadcrumbs.items && breadcrumbs.items.length > 0 && /* @__PURE__ */ jsx(AppBreadcrumbs, { ...breadcrumbs }),
|
|
1093
1125
|
/* @__PURE__ */ jsx("main", { className: cn("flex-1 overflow-auto", mainClassName), children: /* @__PURE__ */ jsx(
|
|
1094
1126
|
"div",
|
|
@@ -1102,7 +1134,13 @@ const AppPageLayout = ({
|
|
|
1102
1134
|
children: content
|
|
1103
1135
|
}
|
|
1104
1136
|
) }),
|
|
1105
|
-
footer && /* @__PURE__ */ jsx(
|
|
1137
|
+
footer && /* @__PURE__ */ jsx(
|
|
1138
|
+
"footer",
|
|
1139
|
+
{
|
|
1140
|
+
className: isCompactFooter ? "sticky bottom-0 z-10" : void 0,
|
|
1141
|
+
children: renderFooter(footer)
|
|
1142
|
+
}
|
|
1143
|
+
)
|
|
1106
1144
|
] }) });
|
|
1107
1145
|
};
|
|
1108
1146
|
var Theme = /* @__PURE__ */ ((Theme2) => {
|