@ttoss/layouts 0.4.37 → 0.5.1

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # @ttoss/layouts
2
2
 
3
- **@ttoss/layouts** is a collection of React components that implement the layouts to use in your application.
3
+ Professional layout components for React applications with responsive design and accessibility built-in.
4
4
 
5
5
  ## Installation
6
6
 
@@ -8,51 +8,166 @@
8
8
  pnpm add @ttoss/layouts @ttoss/ui @emotion/react
9
9
  ```
10
10
 
11
- ## Quickstart
11
+ ## Available Layouts
12
12
 
13
- Use a layout as `StackedLayout` to add specific layout to your application:
13
+ ### StackedLayout - Simple Vertical Layout
14
+
15
+ Perfect for traditional websites with header, main content, and footer.
14
16
 
15
17
  ```tsx
16
18
  import { Layout, StackedLayout } from '@ttoss/layouts';
17
19
 
18
20
  const App = () => (
19
21
  <StackedLayout>
20
- <Layout.Header>Header</Layout.Header>
21
- <Layout.Main>Main</Layout.Main>
22
- <Layout.Footer>Footer</Layout.Footer>
22
+ <Layout.Header>Navigation & Branding</Layout.Header>
23
+ <Layout.Main>Page Content</Layout.Main>
24
+ <Layout.Footer>Copyright & Links</Layout.Footer>
23
25
  </StackedLayout>
24
26
  );
25
27
  ```
26
28
 
27
- ## Layouts
29
+ ### SidebarCollapseLayout - Dashboard & Admin Interfaces
30
+
31
+ Responsive sidebar that collapses on mobile, perfect for dashboards and admin panels.
32
+
33
+ ```tsx
34
+ import { Layout, SidebarCollapseLayout } from '@ttoss/layouts';
35
+
36
+ const Dashboard = () => (
37
+ <SidebarCollapseLayout>
38
+ <Layout.Header showSidebarButton>App Header with Menu Toggle</Layout.Header>
39
+ <Layout.Sidebar>Navigation Menu</Layout.Sidebar>
40
+ <Layout.Main.Header>Page Title & Actions</Layout.Main.Header>
41
+ <Layout.Main>Dashboard Content</Layout.Main>
42
+ <Layout.Main.Footer>Status Bar</Layout.Main.Footer>
43
+ </SidebarCollapseLayout>
44
+ );
45
+ ```
28
46
 
29
- Check the [Layouts Stories](http://localhost:6006/?path=/story/layouts-layout) to see the available layouts.
47
+ ## Core Components
30
48
 
31
- ## Custom Layout Components
49
+ ### Layout.Main Sub-Components
32
50
 
33
- You can create your own layout components by using the `Layout` sub-components:
51
+ Enhanced main content area with optional header and footer sections.
34
52
 
35
53
  ```tsx
36
- import { Layout, StackedLayout } from '@ttoss/layouts';
54
+ <Layout.Main.Header>
55
+ <h1>Page Title</h1>
56
+ <button>Action Button</button>
57
+ </Layout.Main.Header>
58
+
59
+ <Layout.Main>
60
+ Main content with consistent padding and overflow handling
61
+ </Layout.Main>
62
+
63
+ <Layout.Main.Footer>
64
+ <span>Last updated: Today</span>
65
+ </Layout.Main.Footer>
66
+ ```
37
67
 
38
- const CustomHeader = (props) => (
39
- <Layout.Header {...props} style={{ backgroundColor: 'red' }}>
40
- Header
41
- </Layout.Header>
68
+ ## Automatic Layout Composition
69
+
70
+ **Key Concept**: Layout components automatically detect and organize their child components by `displayName`, even when components are distributed across different files or routing structures.
71
+
72
+ ### React Router Integration
73
+
74
+ Perfect for apps where layout components come from different routes:
75
+
76
+ ```tsx
77
+ // App.tsx - Layout wrapper
78
+ import { Layout, SidebarCollapseLayout } from '@ttoss/layouts';
79
+ import { Outlet } from 'react-router-dom';
80
+
81
+ const AppLayout = () => (
82
+ <SidebarCollapseLayout>
83
+ <AppHeader />
84
+ <AppSidebar />
85
+ <Outlet /> {/* Routes render here */}
86
+ </SidebarCollapseLayout>
42
87
  );
43
88
 
44
- CustomHeader.displayName = Layout.Header.displayName;
89
+ // pages/Dashboard.tsx - Page-specific components
90
+ const Dashboard = () => (
91
+ <>
92
+ <Layout.Main.Header>
93
+ <h1>Dashboard</h1>
94
+ </Layout.Main.Header>
95
+ <Layout.Main>
96
+ <DashboardCharts />
97
+ </Layout.Main>
98
+ <Layout.Main.Footer>Last updated: {lastUpdate}</Layout.Main.Footer>
99
+ </>
100
+ );
101
+ ```
45
102
 
46
- const App = () => (
47
- <StackedLayout>
48
- <CustomHeader />
49
- <Layout.Main>Main</Layout.Main>
50
- <Layout.Footer>Footer</Layout.Footer>
51
- </StackedLayout>
103
+ The layout **automatically composes** itself by finding components with matching `displayName` properties, regardless of component hierarchy or file structure.
104
+
105
+ ### Component Detection System
106
+
107
+ ```tsx
108
+ // These components can be anywhere in your component tree:
109
+ <Layout.Header /> // → Detected as "Header"
110
+ <Layout.Sidebar /> // → Detected as "Sidebar"
111
+ <Layout.Main /> // → Detected as "Main"
112
+ <Layout.Footer /> // → Detected as "Footer"
113
+ <Layout.Main.Header /> // → Detected as "MainHeader"
114
+ <Layout.Main.Footer /> // → Detected as "MainFooter"
115
+ ```
116
+
117
+ ## Component Properties
118
+
119
+ ### Responsive Behavior
120
+
121
+ - **Desktop**: Sidebar remains visible, toggleable via button
122
+ - **Mobile**: Sidebar becomes slide-out drawer, auto-closes on navigation
123
+ - **Accessible**: Full keyboard navigation and screen reader support
124
+
125
+ ### Styling Integration
126
+
127
+ All components integrate seamlessly with `@ttoss/ui` theme system via `sx` prop:
128
+
129
+ ```tsx
130
+ <Layout.Header
131
+ sx={{
132
+ backgroundColor: 'brand.primary',
133
+ borderBottom: '2px solid',
134
+ }}
135
+ >
136
+ Custom styled header
137
+ </Layout.Header>
138
+ ```
139
+
140
+ ## Advanced Usage
141
+
142
+ ### Custom Components with displayName
143
+
144
+ Create reusable layout components by preserving the required `displayName`:
145
+
146
+ ```tsx
147
+ const AppHeader = ({ children, ...props }) => (
148
+ <Layout.Header {...props}>
149
+ <Logo />
150
+ {children}
151
+ <UserMenu />
152
+ </Layout.Header>
52
153
  );
154
+
155
+ AppHeader.displayName = Layout.Header.displayName; // Required for layout detection
53
156
  ```
54
157
 
55
- For the layout to work correctly, you must use the `displayName` property of the `Layout` sub-components, because the layout components use the `displayName` to identify the layout sub-components.
158
+ ### Sidebar with Logo Slot
159
+
160
+ Add branding or controls to the sidebar area:
161
+
162
+ ```tsx
163
+ <Layout.Header sidebarSlot={<CompanyLogo />} showSidebarButton>
164
+ Main header content
165
+ </Layout.Header>
166
+ ```
167
+
168
+ ## Examples
169
+
170
+ View complete examples in [Storybook](https://storybook.ttoss.dev/?path=/story/layouts-layout).
56
171
 
57
172
  ## License
58
173
 
package/dist/esm/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
2
2
 
3
3
  // src/components/Layout.tsx
4
- import { Box as Box5, Container } from "@ttoss/ui";
4
+ import { Box as Box7, Container } from "@ttoss/ui";
5
5
 
6
6
  // src/components/Footer.tsx
7
7
  import { Box } from "@ttoss/ui";
@@ -2352,10 +2352,55 @@ var Header = ({
2352
2352
  Header.displayName = "Header";
2353
2353
 
2354
2354
  // src/components/Main.tsx
2355
+ import { Box as Box6 } from "@ttoss/ui";
2356
+
2357
+ // src/components/MainFooter.tsx
2355
2358
  import { Box as Box4 } from "@ttoss/ui";
2356
2359
  import { jsx as jsx6 } from "react/jsx-runtime";
2357
- var Main = props => {
2360
+ var MainFooter = props => {
2358
2361
  return /* @__PURE__ */jsx6(Box4, {
2362
+ variant: "layout.main.footer",
2363
+ ...props,
2364
+ sx: {
2365
+ paddingX: "10",
2366
+ paddingY: "3",
2367
+ borderTop: "sm",
2368
+ borderColor: "display.border.muted.default",
2369
+ backgroundColor: "navigation.background.primary.default",
2370
+ width: "full",
2371
+ ...props.sx
2372
+ },
2373
+ children: props.children
2374
+ });
2375
+ };
2376
+ MainFooter.displayName = "MainFooter";
2377
+
2378
+ // src/components/MainHeader.tsx
2379
+ import { Box as Box5 } from "@ttoss/ui";
2380
+ import { jsx as jsx7 } from "react/jsx-runtime";
2381
+ var MainHeader = props => {
2382
+ return /* @__PURE__ */jsx7(Box5, {
2383
+ variant: "layout.main.header",
2384
+ ...props,
2385
+ as: "header",
2386
+ sx: {
2387
+ paddingX: "4",
2388
+ paddingY: "3",
2389
+ borderBottom: "sm",
2390
+ borderColor: "display.border.muted.default",
2391
+ backgroundColor: "navigation.background.primary.default",
2392
+ width: "full",
2393
+ ...props.sx
2394
+ },
2395
+ children: props.children
2396
+ });
2397
+ };
2398
+ MainHeader.displayName = "MainHeader";
2399
+
2400
+ // src/components/Main.tsx
2401
+ import { jsx as jsx8 } from "react/jsx-runtime";
2402
+ var Main = props => {
2403
+ return /* @__PURE__ */jsx8(Box6, {
2359
2404
  variant: "layout.main",
2360
2405
  ...props,
2361
2406
  as: "main",
@@ -2371,13 +2416,15 @@ var Main = props => {
2371
2416
  });
2372
2417
  };
2373
2418
  Main.displayName = "Main";
2419
+ Main.Header = MainHeader;
2420
+ Main.Footer = MainFooter;
2374
2421
 
2375
2422
  // src/components/Layout.tsx
2376
- import { jsx as jsx7 } from "react/jsx-runtime";
2423
+ import { jsx as jsx9 } from "react/jsx-runtime";
2377
2424
  var Layout = ({
2378
2425
  children
2379
2426
  }) => {
2380
- return /* @__PURE__ */jsx7(Box5, {
2427
+ return /* @__PURE__ */jsx9(Box7, {
2381
2428
  variant: "layout.layout",
2382
2429
  children
2383
2430
  });
@@ -2397,7 +2444,9 @@ var semanticComponents = {
2397
2444
  Header: "header",
2398
2445
  Sidebar: "sidebar",
2399
2446
  Footer: "footer",
2400
- Main: "main"
2447
+ Main: "main",
2448
+ MainHeader: "mainHeader",
2449
+ MainFooter: "mainFooter"
2401
2450
  };
2402
2451
  var getSematicElements = ({
2403
2452
  children
@@ -2416,7 +2465,7 @@ var getSematicElements = ({
2416
2465
  };
2417
2466
 
2418
2467
  // src/components/SidebarCollapseLayout.tsx
2419
- import { jsx as jsx8, jsxs as jsxs3 } from "react/jsx-runtime";
2468
+ import { jsx as jsx10, jsxs as jsxs3 } from "react/jsx-runtime";
2420
2469
  var SidebarCollapseLayout = ({
2421
2470
  children,
2422
2471
  ...props
@@ -2424,11 +2473,13 @@ var SidebarCollapseLayout = ({
2424
2473
  const {
2425
2474
  header,
2426
2475
  main,
2427
- sidebar
2476
+ sidebar,
2477
+ mainFooter,
2478
+ mainHeader
2428
2479
  } = getSematicElements({
2429
2480
  children
2430
2481
  });
2431
- return /* @__PURE__ */jsx8(LayoutProvider, {
2482
+ return /* @__PURE__ */jsx10(LayoutProvider, {
2432
2483
  children: /* @__PURE__ */jsxs3(Stack, {
2433
2484
  ...props,
2434
2485
  sx: {
@@ -2444,7 +2495,14 @@ var SidebarCollapseLayout = ({
2444
2495
  overflow: "hidden",
2445
2496
  flexDirection: ["row"]
2446
2497
  },
2447
- children: [sidebar, main]
2498
+ children: [sidebar, /* @__PURE__ */jsxs3(Stack, {
2499
+ sx: {
2500
+ flex: 1,
2501
+ height: "full",
2502
+ overflow: "hidden"
2503
+ },
2504
+ children: [mainHeader, main, mainFooter]
2505
+ })]
2448
2506
  })]
2449
2507
  })
2450
2508
  });
@@ -2452,7 +2510,7 @@ var SidebarCollapseLayout = ({
2452
2510
 
2453
2511
  // src/components/StackedLayout.tsx
2454
2512
  import { Stack as Stack2 } from "@ttoss/ui";
2455
- import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
2513
+ import { jsx as jsx11, jsxs as jsxs4 } from "react/jsx-runtime";
2456
2514
  var StackedLayout = ({
2457
2515
  children,
2458
2516
  ...props
@@ -2464,7 +2522,7 @@ var StackedLayout = ({
2464
2522
  } = getSematicElements({
2465
2523
  children
2466
2524
  });
2467
- return /* @__PURE__ */jsx9(LayoutProvider, {
2525
+ return /* @__PURE__ */jsx11(LayoutProvider, {
2468
2526
  children: /* @__PURE__ */jsxs4(Stack2, {
2469
2527
  ...props,
2470
2528
  children: [header, main, footer]
package/dist/index.d.ts CHANGED
@@ -21,6 +21,14 @@ declare const Layout: {
21
21
  Main: {
22
22
  (props: BoxProps): react_jsx_runtime.JSX.Element;
23
23
  displayName: string;
24
+ Header: {
25
+ (props: BoxProps): react_jsx_runtime.JSX.Element;
26
+ displayName: string;
27
+ };
28
+ Footer: {
29
+ (props: BoxProps): react_jsx_runtime.JSX.Element;
30
+ displayName: string;
31
+ };
24
32
  };
25
33
  Footer: {
26
34
  (props: BoxProps): react_jsx_runtime.JSX.Element;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttoss/layouts",
3
- "version": "0.4.37",
3
+ "version": "0.5.1",
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.26",
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/config": "^1.35.6",
38
- "@ttoss/ui": "^5.9.2",
39
- "@ttoss/components": "^2.2.26",
37
+ "@ttoss/components": "^2.2.27",
40
38
  "@ttoss/test-utils": "^2.1.26",
41
- "@ttoss/react-icons": "^0.4.15"
39
+ "@ttoss/react-icons": "^0.4.15",
40
+ "@ttoss/config": "^1.35.6",
41
+ "@ttoss/ui": "^5.9.2"
42
42
  },
43
43
  "keywords": [
44
44
  "React"