@ttoss/layouts 0.5.0 → 0.5.2
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/README.md +57 -32
- package/dist/esm/index.js +45 -36
- package/dist/index.d.ts +4 -0
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -37,9 +37,11 @@ const Dashboard = () => (
|
|
|
37
37
|
<SidebarCollapseLayout>
|
|
38
38
|
<Layout.Header showSidebarButton>App Header with Menu Toggle</Layout.Header>
|
|
39
39
|
<Layout.Sidebar>Navigation Menu</Layout.Sidebar>
|
|
40
|
-
<Layout.Main
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
<Layout.Main>
|
|
41
|
+
<Layout.Main.Header>Page Title & Actions</Layout.Main.Header>
|
|
42
|
+
<Layout.Main.Body>Dashboard Content</Layout.Main.Body>
|
|
43
|
+
<Layout.Main.Footer>Status Bar</Layout.Main.Footer>
|
|
44
|
+
</Layout.Main>
|
|
43
45
|
</SidebarCollapseLayout>
|
|
44
46
|
);
|
|
45
47
|
```
|
|
@@ -48,23 +50,38 @@ const Dashboard = () => (
|
|
|
48
50
|
|
|
49
51
|
### Layout.Main Sub-Components
|
|
50
52
|
|
|
51
|
-
|
|
53
|
+
The Main component provides a structured content area with three distinct sections:
|
|
52
54
|
|
|
53
55
|
```tsx
|
|
54
|
-
<Layout.Main.Header>
|
|
55
|
-
<h1>Page Title</h1>
|
|
56
|
-
<button>Action Button</button>
|
|
57
|
-
</Layout.Main.Header>
|
|
58
|
-
|
|
59
56
|
<Layout.Main>
|
|
60
|
-
Main
|
|
57
|
+
<Layout.Main.Header>
|
|
58
|
+
<h1>Page Title</h1>
|
|
59
|
+
<button>Action Button</button>
|
|
60
|
+
</Layout.Main.Header>
|
|
61
|
+
|
|
62
|
+
<Layout.Main.Body>
|
|
63
|
+
Main content with consistent padding and scroll handling
|
|
64
|
+
</Layout.Main.Body>
|
|
65
|
+
|
|
66
|
+
<Layout.Main.Footer>
|
|
67
|
+
<span>Last updated: Today</span>
|
|
68
|
+
</Layout.Main.Footer>
|
|
61
69
|
</Layout.Main>
|
|
62
|
-
|
|
63
|
-
<Layout.Main.Footer>
|
|
64
|
-
<span>Last updated: Today</span>
|
|
65
|
-
</Layout.Main.Footer>
|
|
66
70
|
```
|
|
67
71
|
|
|
72
|
+
**Key Features:**
|
|
73
|
+
|
|
74
|
+
- **Main.Header**: Page-level header with title and actions
|
|
75
|
+
- **Main.Body**: Scrollable content area with auto overflow handling
|
|
76
|
+
- **Main.Footer**: Status bar or secondary actions
|
|
77
|
+
|
|
78
|
+
**Benefits of This Structure:**
|
|
79
|
+
|
|
80
|
+
- **Clear Content Hierarchy**: Separates page header, content, and footer concerns
|
|
81
|
+
- **Automatic Scroll Management**: Body handles overflow while keeping header/footer fixed
|
|
82
|
+
- **Consistent Spacing**: Each section has optimized padding and layout
|
|
83
|
+
- **Accessibility**: Proper semantic HTML elements (`<header>`, `<main>`, `<footer>`)
|
|
84
|
+
|
|
68
85
|
## Automatic Layout Composition
|
|
69
86
|
|
|
70
87
|
**Key Concept**: Layout components automatically detect and organize their child components by `displayName`, even when components are distributed across different files or routing structures.
|
|
@@ -88,15 +105,15 @@ const AppLayout = () => (
|
|
|
88
105
|
|
|
89
106
|
// pages/Dashboard.tsx - Page-specific components
|
|
90
107
|
const Dashboard = () => (
|
|
91
|
-
|
|
108
|
+
<Layout.Main>
|
|
92
109
|
<Layout.Main.Header>
|
|
93
110
|
<h1>Dashboard</h1>
|
|
94
111
|
</Layout.Main.Header>
|
|
95
|
-
<Layout.Main>
|
|
112
|
+
<Layout.Main.Body>
|
|
96
113
|
<DashboardCharts />
|
|
97
|
-
</Layout.Main>
|
|
114
|
+
</Layout.Main.Body>
|
|
98
115
|
<Layout.Main.Footer>Last updated: {lastUpdate}</Layout.Main.Footer>
|
|
99
|
-
|
|
116
|
+
</Layout.Main>
|
|
100
117
|
);
|
|
101
118
|
```
|
|
102
119
|
|
|
@@ -106,12 +123,17 @@ The layout **automatically composes** itself by finding components with matching
|
|
|
106
123
|
|
|
107
124
|
```tsx
|
|
108
125
|
// These components can be anywhere in your component tree:
|
|
109
|
-
<Layout.Header />
|
|
110
|
-
<Layout.Sidebar />
|
|
111
|
-
<Layout.Main />
|
|
112
|
-
<Layout.Footer />
|
|
113
|
-
|
|
114
|
-
|
|
126
|
+
<Layout.Header /> // → Detected as "Header"
|
|
127
|
+
<Layout.Sidebar /> // → Detected as "Sidebar"
|
|
128
|
+
<Layout.Main /> // → Detected as "Main"
|
|
129
|
+
<Layout.Footer /> // → Detected as "Footer"
|
|
130
|
+
|
|
131
|
+
// Main sub-components are contained within Main:
|
|
132
|
+
<Layout.Main>
|
|
133
|
+
<Layout.Main.Header /> // → Detected as "MainHeader"
|
|
134
|
+
<Layout.Main.Body /> // → Detected as "MainBody"
|
|
135
|
+
<Layout.Main.Footer /> // → Detected as "MainFooter"
|
|
136
|
+
</Layout.Main>
|
|
115
137
|
```
|
|
116
138
|
|
|
117
139
|
## Component Properties
|
|
@@ -127,14 +149,17 @@ The layout **automatically composes** itself by finding components with matching
|
|
|
127
149
|
All components integrate seamlessly with `@ttoss/ui` theme system via `sx` prop:
|
|
128
150
|
|
|
129
151
|
```tsx
|
|
130
|
-
<Layout.
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
152
|
+
<Layout.Main>
|
|
153
|
+
<Layout.Main.Header
|
|
154
|
+
sx={{
|
|
155
|
+
backgroundColor: 'brand.primary',
|
|
156
|
+
borderBottom: '2px solid',
|
|
157
|
+
}}
|
|
158
|
+
>
|
|
159
|
+
Custom styled header
|
|
160
|
+
</Layout.Main.Header>
|
|
161
|
+
<Layout.Main.Body>Content</Layout.Main.Body>
|
|
162
|
+
</Layout.Main>
|
|
138
163
|
```
|
|
139
164
|
|
|
140
165
|
## Advanced Usage
|
package/dist/esm/index.js
CHANGED
|
@@ -2352,13 +2352,34 @@ var Header = ({
|
|
|
2352
2352
|
Header.displayName = "Header";
|
|
2353
2353
|
|
|
2354
2354
|
// src/components/Main.tsx
|
|
2355
|
-
import {
|
|
2355
|
+
import { Stack } from "@ttoss/ui";
|
|
2356
2356
|
|
|
2357
|
-
// src/components/
|
|
2357
|
+
// src/components/MainBody.tsx
|
|
2358
2358
|
import { Box as Box4 } from "@ttoss/ui";
|
|
2359
2359
|
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
2360
|
-
var
|
|
2360
|
+
var MainBody = props => {
|
|
2361
2361
|
return /* @__PURE__ */jsx6(Box4, {
|
|
2362
|
+
variant: "layout.main.body",
|
|
2363
|
+
...props,
|
|
2364
|
+
as: "main",
|
|
2365
|
+
sx: {
|
|
2366
|
+
paddingX: "10",
|
|
2367
|
+
paddingY: "6",
|
|
2368
|
+
overflowY: "auto",
|
|
2369
|
+
width: "full",
|
|
2370
|
+
height: "full",
|
|
2371
|
+
...props.sx
|
|
2372
|
+
},
|
|
2373
|
+
children: props.children
|
|
2374
|
+
});
|
|
2375
|
+
};
|
|
2376
|
+
MainBody.displayName = "MainBody";
|
|
2377
|
+
|
|
2378
|
+
// src/components/MainFooter.tsx
|
|
2379
|
+
import { Box as Box5 } from "@ttoss/ui";
|
|
2380
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
2381
|
+
var MainFooter = props => {
|
|
2382
|
+
return /* @__PURE__ */jsx7(Box5, {
|
|
2362
2383
|
variant: "layout.main.footer",
|
|
2363
2384
|
...props,
|
|
2364
2385
|
sx: {
|
|
@@ -2376,10 +2397,10 @@ var MainFooter = props => {
|
|
|
2376
2397
|
MainFooter.displayName = "MainFooter";
|
|
2377
2398
|
|
|
2378
2399
|
// src/components/MainHeader.tsx
|
|
2379
|
-
import { Box as
|
|
2380
|
-
import { jsx as
|
|
2400
|
+
import { Box as Box6 } from "@ttoss/ui";
|
|
2401
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
2381
2402
|
var MainHeader = props => {
|
|
2382
|
-
return /* @__PURE__ */
|
|
2403
|
+
return /* @__PURE__ */jsx8(Box6, {
|
|
2383
2404
|
variant: "layout.main.header",
|
|
2384
2405
|
...props,
|
|
2385
2406
|
as: "header",
|
|
@@ -2398,33 +2419,29 @@ var MainHeader = props => {
|
|
|
2398
2419
|
MainHeader.displayName = "MainHeader";
|
|
2399
2420
|
|
|
2400
2421
|
// src/components/Main.tsx
|
|
2401
|
-
import { jsx as
|
|
2422
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
2402
2423
|
var Main = props => {
|
|
2403
|
-
return /* @__PURE__ */
|
|
2424
|
+
return /* @__PURE__ */jsx9(Stack, {
|
|
2404
2425
|
variant: "layout.main",
|
|
2405
|
-
...props,
|
|
2406
|
-
as: "main",
|
|
2407
2426
|
sx: {
|
|
2408
|
-
|
|
2409
|
-
paddingY: "6",
|
|
2410
|
-
overflowY: "auto",
|
|
2411
|
-
width: "full",
|
|
2427
|
+
flex: 1,
|
|
2412
2428
|
height: "full",
|
|
2413
|
-
|
|
2429
|
+
overflow: "hidden"
|
|
2414
2430
|
},
|
|
2415
2431
|
children: props.children
|
|
2416
2432
|
});
|
|
2417
2433
|
};
|
|
2418
2434
|
Main.displayName = "Main";
|
|
2419
2435
|
Main.Header = MainHeader;
|
|
2436
|
+
Main.Body = MainBody;
|
|
2420
2437
|
Main.Footer = MainFooter;
|
|
2421
2438
|
|
|
2422
2439
|
// src/components/Layout.tsx
|
|
2423
|
-
import { jsx as
|
|
2440
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
2424
2441
|
var Layout = ({
|
|
2425
2442
|
children
|
|
2426
2443
|
}) => {
|
|
2427
|
-
return /* @__PURE__ */
|
|
2444
|
+
return /* @__PURE__ */jsx10(Box7, {
|
|
2428
2445
|
variant: "layout.layout",
|
|
2429
2446
|
children
|
|
2430
2447
|
});
|
|
@@ -2436,7 +2453,7 @@ Layout.Footer = Footer;
|
|
|
2436
2453
|
Layout.Container = Container;
|
|
2437
2454
|
|
|
2438
2455
|
// src/components/SidebarCollapseLayout.tsx
|
|
2439
|
-
import { Flex as Flex3, Stack } from "@ttoss/ui";
|
|
2456
|
+
import { Flex as Flex3, Stack as Stack2 } from "@ttoss/ui";
|
|
2440
2457
|
|
|
2441
2458
|
// src/getSemanticElements.ts
|
|
2442
2459
|
import * as React6 from "react";
|
|
@@ -2446,6 +2463,7 @@ var semanticComponents = {
|
|
|
2446
2463
|
Footer: "footer",
|
|
2447
2464
|
Main: "main",
|
|
2448
2465
|
MainHeader: "mainHeader",
|
|
2466
|
+
MainBody: "mainBody",
|
|
2449
2467
|
MainFooter: "mainFooter"
|
|
2450
2468
|
};
|
|
2451
2469
|
var getSematicElements = ({
|
|
@@ -2465,7 +2483,7 @@ var getSematicElements = ({
|
|
|
2465
2483
|
};
|
|
2466
2484
|
|
|
2467
2485
|
// src/components/SidebarCollapseLayout.tsx
|
|
2468
|
-
import { jsx as
|
|
2486
|
+
import { jsx as jsx11, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
2469
2487
|
var SidebarCollapseLayout = ({
|
|
2470
2488
|
children,
|
|
2471
2489
|
...props
|
|
@@ -2473,14 +2491,12 @@ var SidebarCollapseLayout = ({
|
|
|
2473
2491
|
const {
|
|
2474
2492
|
header,
|
|
2475
2493
|
main,
|
|
2476
|
-
sidebar
|
|
2477
|
-
mainFooter,
|
|
2478
|
-
mainHeader
|
|
2494
|
+
sidebar
|
|
2479
2495
|
} = getSematicElements({
|
|
2480
2496
|
children
|
|
2481
2497
|
});
|
|
2482
|
-
return /* @__PURE__ */
|
|
2483
|
-
children: /* @__PURE__ */jsxs3(
|
|
2498
|
+
return /* @__PURE__ */jsx11(LayoutProvider, {
|
|
2499
|
+
children: /* @__PURE__ */jsxs3(Stack2, {
|
|
2484
2500
|
...props,
|
|
2485
2501
|
sx: {
|
|
2486
2502
|
height: ["100vh"],
|
|
@@ -2495,22 +2511,15 @@ var SidebarCollapseLayout = ({
|
|
|
2495
2511
|
overflow: "hidden",
|
|
2496
2512
|
flexDirection: ["row"]
|
|
2497
2513
|
},
|
|
2498
|
-
children: [sidebar,
|
|
2499
|
-
sx: {
|
|
2500
|
-
flex: 1,
|
|
2501
|
-
height: "full",
|
|
2502
|
-
overflow: "hidden"
|
|
2503
|
-
},
|
|
2504
|
-
children: [mainHeader, main, mainFooter]
|
|
2505
|
-
})]
|
|
2514
|
+
children: [sidebar, main]
|
|
2506
2515
|
})]
|
|
2507
2516
|
})
|
|
2508
2517
|
});
|
|
2509
2518
|
};
|
|
2510
2519
|
|
|
2511
2520
|
// src/components/StackedLayout.tsx
|
|
2512
|
-
import { Stack as
|
|
2513
|
-
import { jsx as
|
|
2521
|
+
import { Stack as Stack3 } from "@ttoss/ui";
|
|
2522
|
+
import { jsx as jsx12, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
2514
2523
|
var StackedLayout = ({
|
|
2515
2524
|
children,
|
|
2516
2525
|
...props
|
|
@@ -2522,8 +2531,8 @@ var StackedLayout = ({
|
|
|
2522
2531
|
} = getSematicElements({
|
|
2523
2532
|
children
|
|
2524
2533
|
});
|
|
2525
|
-
return /* @__PURE__ */
|
|
2526
|
-
children: /* @__PURE__ */jsxs4(
|
|
2534
|
+
return /* @__PURE__ */jsx12(LayoutProvider, {
|
|
2535
|
+
children: /* @__PURE__ */jsxs4(Stack3, {
|
|
2527
2536
|
...props,
|
|
2528
2537
|
children: [header, main, footer]
|
|
2529
2538
|
})
|
package/dist/index.d.ts
CHANGED
|
@@ -25,6 +25,10 @@ declare const Layout: {
|
|
|
25
25
|
(props: BoxProps): react_jsx_runtime.JSX.Element;
|
|
26
26
|
displayName: string;
|
|
27
27
|
};
|
|
28
|
+
Body: {
|
|
29
|
+
(props: BoxProps): react_jsx_runtime.JSX.Element;
|
|
30
|
+
displayName: string;
|
|
31
|
+
};
|
|
28
32
|
Footer: {
|
|
29
33
|
(props: BoxProps): react_jsx_runtime.JSX.Element;
|
|
30
34
|
displayName: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ttoss/layouts",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"description": "Layout components for React",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "ttoss",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"sideEffects": false,
|
|
26
26
|
"peerDependencies": {
|
|
27
27
|
"react": ">=16.8.0",
|
|
28
|
-
"@ttoss/components": "^2.2.
|
|
28
|
+
"@ttoss/components": "^2.2.27",
|
|
29
29
|
"@ttoss/ui": "^5.9.2"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
"jest": "^30.0.4",
|
|
35
35
|
"react": "^19.1.0",
|
|
36
36
|
"tsup": "^8.5.0",
|
|
37
|
-
"@ttoss/components": "^2.2.
|
|
37
|
+
"@ttoss/components": "^2.2.27",
|
|
38
38
|
"@ttoss/config": "^1.35.6",
|
|
39
39
|
"@ttoss/react-icons": "^0.4.15",
|
|
40
|
-
"@ttoss/
|
|
41
|
-
"@ttoss/
|
|
40
|
+
"@ttoss/test-utils": "^2.1.26",
|
|
41
|
+
"@ttoss/ui": "^5.9.2"
|
|
42
42
|
},
|
|
43
43
|
"keywords": [
|
|
44
44
|
"React"
|