@ttoss/layouts 0.4.36 → 0.5.0
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 +138 -23
- package/dist/esm/index.js +90 -222
- package/dist/index.d.ts +8 -0
- package/package.json +8 -8
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @ttoss/layouts
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
##
|
|
11
|
+
## Available Layouts
|
|
12
12
|
|
|
13
|
-
|
|
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>
|
|
21
|
-
<Layout.Main>
|
|
22
|
-
<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
|
-
|
|
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
|
-
|
|
47
|
+
## Core Components
|
|
30
48
|
|
|
31
|
-
|
|
49
|
+
### Layout.Main Sub-Components
|
|
32
50
|
|
|
33
|
-
|
|
51
|
+
Enhanced main content area with optional header and footer sections.
|
|
34
52
|
|
|
35
53
|
```tsx
|
|
36
|
-
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
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
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
-
|
|
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
|
|
4
|
+
import { Box as Box7, Container } from "@ttoss/ui";
|
|
5
5
|
|
|
6
6
|
// src/components/Footer.tsx
|
|
7
7
|
import { Box } from "@ttoss/ui";
|
|
@@ -16,10 +16,10 @@ var Footer = props => {
|
|
|
16
16
|
};
|
|
17
17
|
Footer.displayName = "Footer";
|
|
18
18
|
|
|
19
|
-
// ../../node_modules/.pnpm/@iconify-icon+react@2.
|
|
19
|
+
// ../../node_modules/.pnpm/@iconify-icon+react@2.3.0_react@19.1.1/node_modules/@iconify-icon/react/dist/iconify.mjs
|
|
20
20
|
import React from "react";
|
|
21
21
|
|
|
22
|
-
// ../../node_modules/.pnpm/iconify-icon@2.
|
|
22
|
+
// ../../node_modules/.pnpm/iconify-icon@2.3.0/node_modules/iconify-icon/dist/iconify-icon.mjs
|
|
23
23
|
var defaultIconDimensions = Object.freeze({
|
|
24
24
|
left: 0,
|
|
25
25
|
top: 0,
|
|
@@ -869,181 +869,6 @@ function sendAPIQuery(target, query, callback) {
|
|
|
869
869
|
}
|
|
870
870
|
return redundancy.query(query, send2, callback)().abort;
|
|
871
871
|
}
|
|
872
|
-
var browserCacheVersion = "iconify2";
|
|
873
|
-
var browserCachePrefix = "iconify";
|
|
874
|
-
var browserCacheCountKey = browserCachePrefix + "-count";
|
|
875
|
-
var browserCacheVersionKey = browserCachePrefix + "-version";
|
|
876
|
-
var browserStorageHour = 36e5;
|
|
877
|
-
var browserStorageCacheExpiration = 168;
|
|
878
|
-
var browserStorageLimit = 50;
|
|
879
|
-
function getStoredItem(func, key) {
|
|
880
|
-
try {
|
|
881
|
-
return func.getItem(key);
|
|
882
|
-
} catch (err) {}
|
|
883
|
-
}
|
|
884
|
-
function setStoredItem(func, key, value) {
|
|
885
|
-
try {
|
|
886
|
-
func.setItem(key, value);
|
|
887
|
-
return true;
|
|
888
|
-
} catch (err) {}
|
|
889
|
-
}
|
|
890
|
-
function removeStoredItem(func, key) {
|
|
891
|
-
try {
|
|
892
|
-
func.removeItem(key);
|
|
893
|
-
} catch (err) {}
|
|
894
|
-
}
|
|
895
|
-
function setBrowserStorageItemsCount(storage2, value) {
|
|
896
|
-
return setStoredItem(storage2, browserCacheCountKey, value.toString());
|
|
897
|
-
}
|
|
898
|
-
function getBrowserStorageItemsCount(storage2) {
|
|
899
|
-
return parseInt(getStoredItem(storage2, browserCacheCountKey)) || 0;
|
|
900
|
-
}
|
|
901
|
-
var browserStorageConfig = {
|
|
902
|
-
local: true,
|
|
903
|
-
session: true
|
|
904
|
-
};
|
|
905
|
-
var browserStorageEmptyItems = {
|
|
906
|
-
local: /* @__PURE__ */new Set(),
|
|
907
|
-
session: /* @__PURE__ */new Set()
|
|
908
|
-
};
|
|
909
|
-
var browserStorageStatus = false;
|
|
910
|
-
function setBrowserStorageStatus(status) {
|
|
911
|
-
browserStorageStatus = status;
|
|
912
|
-
}
|
|
913
|
-
var _window = typeof window === "undefined" ? {} : window;
|
|
914
|
-
function getBrowserStorage(key) {
|
|
915
|
-
const attr = key + "Storage";
|
|
916
|
-
try {
|
|
917
|
-
if (_window && _window[attr] && typeof _window[attr].length === "number") {
|
|
918
|
-
return _window[attr];
|
|
919
|
-
}
|
|
920
|
-
} catch (err) {}
|
|
921
|
-
browserStorageConfig[key] = false;
|
|
922
|
-
}
|
|
923
|
-
function iterateBrowserStorage(key, callback) {
|
|
924
|
-
const func = getBrowserStorage(key);
|
|
925
|
-
if (!func) {
|
|
926
|
-
return;
|
|
927
|
-
}
|
|
928
|
-
const version = getStoredItem(func, browserCacheVersionKey);
|
|
929
|
-
if (version !== browserCacheVersion) {
|
|
930
|
-
if (version) {
|
|
931
|
-
const total2 = getBrowserStorageItemsCount(func);
|
|
932
|
-
for (let i = 0; i < total2; i++) {
|
|
933
|
-
removeStoredItem(func, browserCachePrefix + i.toString());
|
|
934
|
-
}
|
|
935
|
-
}
|
|
936
|
-
setStoredItem(func, browserCacheVersionKey, browserCacheVersion);
|
|
937
|
-
setBrowserStorageItemsCount(func, 0);
|
|
938
|
-
return;
|
|
939
|
-
}
|
|
940
|
-
const minTime = Math.floor(Date.now() / browserStorageHour) - browserStorageCacheExpiration;
|
|
941
|
-
const parseItem = index => {
|
|
942
|
-
const name = browserCachePrefix + index.toString();
|
|
943
|
-
const item = getStoredItem(func, name);
|
|
944
|
-
if (typeof item !== "string") {
|
|
945
|
-
return;
|
|
946
|
-
}
|
|
947
|
-
try {
|
|
948
|
-
const data = JSON.parse(item);
|
|
949
|
-
if (typeof data === "object" && typeof data.cached === "number" && data.cached > minTime && typeof data.provider === "string" && typeof data.data === "object" && typeof data.data.prefix === "string" &&
|
|
950
|
-
// Valid item: run callback
|
|
951
|
-
callback(data, index)) {
|
|
952
|
-
return true;
|
|
953
|
-
}
|
|
954
|
-
} catch (err) {}
|
|
955
|
-
removeStoredItem(func, name);
|
|
956
|
-
};
|
|
957
|
-
let total = getBrowserStorageItemsCount(func);
|
|
958
|
-
for (let i = total - 1; i >= 0; i--) {
|
|
959
|
-
if (!parseItem(i)) {
|
|
960
|
-
if (i === total - 1) {
|
|
961
|
-
total--;
|
|
962
|
-
setBrowserStorageItemsCount(func, total);
|
|
963
|
-
} else {
|
|
964
|
-
browserStorageEmptyItems[key].add(i);
|
|
965
|
-
}
|
|
966
|
-
}
|
|
967
|
-
}
|
|
968
|
-
}
|
|
969
|
-
function initBrowserStorage() {
|
|
970
|
-
if (browserStorageStatus) {
|
|
971
|
-
return;
|
|
972
|
-
}
|
|
973
|
-
setBrowserStorageStatus(true);
|
|
974
|
-
for (const key in browserStorageConfig) {
|
|
975
|
-
iterateBrowserStorage(key, item => {
|
|
976
|
-
const iconSet = item.data;
|
|
977
|
-
const provider = item.provider;
|
|
978
|
-
const prefix = iconSet.prefix;
|
|
979
|
-
const storage2 = getStorage(provider, prefix);
|
|
980
|
-
if (!addIconSet(storage2, iconSet).length) {
|
|
981
|
-
return false;
|
|
982
|
-
}
|
|
983
|
-
const lastModified = iconSet.lastModified || -1;
|
|
984
|
-
storage2.lastModifiedCached = storage2.lastModifiedCached ? Math.min(storage2.lastModifiedCached, lastModified) : lastModified;
|
|
985
|
-
return true;
|
|
986
|
-
});
|
|
987
|
-
}
|
|
988
|
-
}
|
|
989
|
-
function updateLastModified(storage2, lastModified) {
|
|
990
|
-
const lastValue = storage2.lastModifiedCached;
|
|
991
|
-
if (
|
|
992
|
-
// Matches or newer
|
|
993
|
-
lastValue && lastValue >= lastModified) {
|
|
994
|
-
return lastValue === lastModified;
|
|
995
|
-
}
|
|
996
|
-
storage2.lastModifiedCached = lastModified;
|
|
997
|
-
if (lastValue) {
|
|
998
|
-
for (const key in browserStorageConfig) {
|
|
999
|
-
iterateBrowserStorage(key, item => {
|
|
1000
|
-
const iconSet = item.data;
|
|
1001
|
-
return item.provider !== storage2.provider || iconSet.prefix !== storage2.prefix || iconSet.lastModified === lastModified;
|
|
1002
|
-
});
|
|
1003
|
-
}
|
|
1004
|
-
}
|
|
1005
|
-
return true;
|
|
1006
|
-
}
|
|
1007
|
-
function storeInBrowserStorage(storage2, data) {
|
|
1008
|
-
if (!browserStorageStatus) {
|
|
1009
|
-
initBrowserStorage();
|
|
1010
|
-
}
|
|
1011
|
-
function store(key) {
|
|
1012
|
-
let func;
|
|
1013
|
-
if (!browserStorageConfig[key] || !(func = getBrowserStorage(key))) {
|
|
1014
|
-
return;
|
|
1015
|
-
}
|
|
1016
|
-
const set = browserStorageEmptyItems[key];
|
|
1017
|
-
let index;
|
|
1018
|
-
if (set.size) {
|
|
1019
|
-
set.delete(index = Array.from(set).shift());
|
|
1020
|
-
} else {
|
|
1021
|
-
index = getBrowserStorageItemsCount(func);
|
|
1022
|
-
if (index >= browserStorageLimit || !setBrowserStorageItemsCount(func, index + 1)) {
|
|
1023
|
-
return;
|
|
1024
|
-
}
|
|
1025
|
-
}
|
|
1026
|
-
const item = {
|
|
1027
|
-
cached: Math.floor(Date.now() / browserStorageHour),
|
|
1028
|
-
provider: storage2.provider,
|
|
1029
|
-
data
|
|
1030
|
-
};
|
|
1031
|
-
return setStoredItem(func, browserCachePrefix + index.toString(), JSON.stringify(item));
|
|
1032
|
-
}
|
|
1033
|
-
if (data.lastModified && !updateLastModified(storage2, data.lastModified)) {
|
|
1034
|
-
return;
|
|
1035
|
-
}
|
|
1036
|
-
if (!Object.keys(data.icons).length) {
|
|
1037
|
-
return;
|
|
1038
|
-
}
|
|
1039
|
-
if (data.not_found) {
|
|
1040
|
-
data = Object.assign({}, data);
|
|
1041
|
-
delete data.not_found;
|
|
1042
|
-
}
|
|
1043
|
-
if (!store("local")) {
|
|
1044
|
-
store("session");
|
|
1045
|
-
}
|
|
1046
|
-
}
|
|
1047
872
|
function emptyCallback() {}
|
|
1048
873
|
function loadedNewIcons(storage2) {
|
|
1049
874
|
if (!storage2.iconsLoaderFlag) {
|
|
@@ -1065,7 +890,7 @@ function checkIconNamesForAPI(icons) {
|
|
|
1065
890
|
invalid
|
|
1066
891
|
};
|
|
1067
892
|
}
|
|
1068
|
-
function parseLoaderResponse(storage2, icons, data
|
|
893
|
+
function parseLoaderResponse(storage2, icons, data) {
|
|
1069
894
|
function checkMissing() {
|
|
1070
895
|
const pending = storage2.pendingIcons;
|
|
1071
896
|
icons.forEach(name => {
|
|
@@ -1084,9 +909,6 @@ function parseLoaderResponse(storage2, icons, data, isAPIResponse) {
|
|
|
1084
909
|
checkMissing();
|
|
1085
910
|
return;
|
|
1086
911
|
}
|
|
1087
|
-
if (isAPIResponse) {
|
|
1088
|
-
storeInBrowserStorage(storage2, data);
|
|
1089
|
-
}
|
|
1090
912
|
} catch (err) {
|
|
1091
913
|
console.error(err);
|
|
1092
914
|
}
|
|
@@ -1127,7 +949,7 @@ function loadNewIcons(storage2, icons) {
|
|
|
1127
949
|
const customIconLoader = storage2.loadIcon;
|
|
1128
950
|
if (storage2.loadIcons && (icons2.length > 1 || !customIconLoader)) {
|
|
1129
951
|
parsePossiblyAsyncResponse(storage2.loadIcons(icons2, prefix, provider), data => {
|
|
1130
|
-
parseLoaderResponse(storage2, icons2, data
|
|
952
|
+
parseLoaderResponse(storage2, icons2, data);
|
|
1131
953
|
});
|
|
1132
954
|
return;
|
|
1133
955
|
}
|
|
@@ -1141,7 +963,7 @@ function loadNewIcons(storage2, icons) {
|
|
|
1141
963
|
[name]: data
|
|
1142
964
|
}
|
|
1143
965
|
} : null;
|
|
1144
|
-
parseLoaderResponse(storage2, [name], iconSet
|
|
966
|
+
parseLoaderResponse(storage2, [name], iconSet);
|
|
1145
967
|
});
|
|
1146
968
|
});
|
|
1147
969
|
return;
|
|
@@ -1151,20 +973,20 @@ function loadNewIcons(storage2, icons) {
|
|
|
1151
973
|
invalid
|
|
1152
974
|
} = checkIconNamesForAPI(icons2);
|
|
1153
975
|
if (invalid.length) {
|
|
1154
|
-
parseLoaderResponse(storage2, invalid, null
|
|
976
|
+
parseLoaderResponse(storage2, invalid, null);
|
|
1155
977
|
}
|
|
1156
978
|
if (!valid.length) {
|
|
1157
979
|
return;
|
|
1158
980
|
}
|
|
1159
981
|
const api = prefix.match(matchIconName) ? getAPIModule(provider) : null;
|
|
1160
982
|
if (!api) {
|
|
1161
|
-
parseLoaderResponse(storage2, valid, null
|
|
983
|
+
parseLoaderResponse(storage2, valid, null);
|
|
1162
984
|
return;
|
|
1163
985
|
}
|
|
1164
986
|
const params = api.prepare(provider, prefix, valid);
|
|
1165
987
|
params.forEach(item => {
|
|
1166
988
|
sendAPIQuery(provider, item, data => {
|
|
1167
|
-
parseLoaderResponse(storage2, item.icons, data
|
|
989
|
+
parseLoaderResponse(storage2, item.icons, data);
|
|
1168
990
|
});
|
|
1169
991
|
});
|
|
1170
992
|
});
|
|
@@ -1641,19 +1463,6 @@ function setCustomIconsLoader$1(loader, prefix, provider) {
|
|
|
1641
1463
|
function setCustomIconLoader$1(loader, prefix, provider) {
|
|
1642
1464
|
getStorage(provider || "", prefix).loadIcon = loader;
|
|
1643
1465
|
}
|
|
1644
|
-
function toggleBrowserCache(storage2, value) {
|
|
1645
|
-
switch (storage2) {
|
|
1646
|
-
case "local":
|
|
1647
|
-
case "session":
|
|
1648
|
-
browserStorageConfig[storage2] = value;
|
|
1649
|
-
break;
|
|
1650
|
-
case "all":
|
|
1651
|
-
for (const key in browserStorageConfig) {
|
|
1652
|
-
browserStorageConfig[key] = value;
|
|
1653
|
-
}
|
|
1654
|
-
break;
|
|
1655
|
-
}
|
|
1656
|
-
}
|
|
1657
1466
|
var nodeAttr = "data-style";
|
|
1658
1467
|
var customStyle = "";
|
|
1659
1468
|
function appendCustomStyle(style) {
|
|
@@ -1671,14 +1480,13 @@ function updateStyle(parent, inline) {
|
|
|
1671
1480
|
function exportFunctions() {
|
|
1672
1481
|
setAPIModule("", fetchAPIModule);
|
|
1673
1482
|
allowSimpleNames(true);
|
|
1674
|
-
let
|
|
1483
|
+
let _window;
|
|
1675
1484
|
try {
|
|
1676
|
-
|
|
1485
|
+
_window = window;
|
|
1677
1486
|
} catch (err) {}
|
|
1678
|
-
if (
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
const preload = _window2.IconifyPreload;
|
|
1487
|
+
if (_window) {
|
|
1488
|
+
if (_window.IconifyPreload !== void 0) {
|
|
1489
|
+
const preload = _window.IconifyPreload;
|
|
1682
1490
|
const err = "Invalid IconifyPreload syntax.";
|
|
1683
1491
|
if (typeof preload === "object" && preload !== null) {
|
|
1684
1492
|
(preload instanceof Array ? preload : [preload]).forEach(item => {
|
|
@@ -1698,8 +1506,8 @@ function exportFunctions() {
|
|
|
1698
1506
|
});
|
|
1699
1507
|
}
|
|
1700
1508
|
}
|
|
1701
|
-
if (
|
|
1702
|
-
const providers =
|
|
1509
|
+
if (_window.IconifyProviders !== void 0) {
|
|
1510
|
+
const providers = _window.IconifyProviders;
|
|
1703
1511
|
if (typeof providers === "object" && providers !== null) {
|
|
1704
1512
|
for (const key in providers) {
|
|
1705
1513
|
const err = "IconifyProviders[" + key + "] is invalid.";
|
|
@@ -1727,8 +1535,10 @@ function exportFunctions() {
|
|
|
1727
1535
|
listAPIProviders
|
|
1728
1536
|
};
|
|
1729
1537
|
return {
|
|
1730
|
-
|
|
1731
|
-
|
|
1538
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1539
|
+
enableCache: storage2 => {},
|
|
1540
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1541
|
+
disableCache: storage2 => {},
|
|
1732
1542
|
iconLoaded: iconLoaded$1,
|
|
1733
1543
|
iconExists: iconLoaded$1,
|
|
1734
1544
|
// deprecated, kept to avoid breaking changes
|
|
@@ -2242,7 +2052,7 @@ var {
|
|
|
2242
2052
|
_api
|
|
2243
2053
|
} = IconifyIconComponent;
|
|
2244
2054
|
|
|
2245
|
-
// ../../node_modules/.pnpm/@iconify-icon+react@2.
|
|
2055
|
+
// ../../node_modules/.pnpm/@iconify-icon+react@2.3.0_react@19.1.1/node_modules/@iconify-icon/react/dist/iconify.mjs
|
|
2246
2056
|
var Icon = React.forwardRef((props, ref) => {
|
|
2247
2057
|
const newProps = {
|
|
2248
2058
|
...props,
|
|
@@ -2542,10 +2352,55 @@ var Header = ({
|
|
|
2542
2352
|
Header.displayName = "Header";
|
|
2543
2353
|
|
|
2544
2354
|
// src/components/Main.tsx
|
|
2355
|
+
import { Box as Box6 } from "@ttoss/ui";
|
|
2356
|
+
|
|
2357
|
+
// src/components/MainFooter.tsx
|
|
2545
2358
|
import { Box as Box4 } from "@ttoss/ui";
|
|
2546
2359
|
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
2547
|
-
var
|
|
2360
|
+
var MainFooter = props => {
|
|
2548
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, {
|
|
2549
2404
|
variant: "layout.main",
|
|
2550
2405
|
...props,
|
|
2551
2406
|
as: "main",
|
|
@@ -2561,13 +2416,15 @@ var Main = props => {
|
|
|
2561
2416
|
});
|
|
2562
2417
|
};
|
|
2563
2418
|
Main.displayName = "Main";
|
|
2419
|
+
Main.Header = MainHeader;
|
|
2420
|
+
Main.Footer = MainFooter;
|
|
2564
2421
|
|
|
2565
2422
|
// src/components/Layout.tsx
|
|
2566
|
-
import { jsx as
|
|
2423
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
2567
2424
|
var Layout = ({
|
|
2568
2425
|
children
|
|
2569
2426
|
}) => {
|
|
2570
|
-
return /* @__PURE__ */
|
|
2427
|
+
return /* @__PURE__ */jsx9(Box7, {
|
|
2571
2428
|
variant: "layout.layout",
|
|
2572
2429
|
children
|
|
2573
2430
|
});
|
|
@@ -2587,7 +2444,9 @@ var semanticComponents = {
|
|
|
2587
2444
|
Header: "header",
|
|
2588
2445
|
Sidebar: "sidebar",
|
|
2589
2446
|
Footer: "footer",
|
|
2590
|
-
Main: "main"
|
|
2447
|
+
Main: "main",
|
|
2448
|
+
MainHeader: "mainHeader",
|
|
2449
|
+
MainFooter: "mainFooter"
|
|
2591
2450
|
};
|
|
2592
2451
|
var getSematicElements = ({
|
|
2593
2452
|
children
|
|
@@ -2606,7 +2465,7 @@ var getSematicElements = ({
|
|
|
2606
2465
|
};
|
|
2607
2466
|
|
|
2608
2467
|
// src/components/SidebarCollapseLayout.tsx
|
|
2609
|
-
import { jsx as
|
|
2468
|
+
import { jsx as jsx10, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
2610
2469
|
var SidebarCollapseLayout = ({
|
|
2611
2470
|
children,
|
|
2612
2471
|
...props
|
|
@@ -2614,11 +2473,13 @@ var SidebarCollapseLayout = ({
|
|
|
2614
2473
|
const {
|
|
2615
2474
|
header,
|
|
2616
2475
|
main,
|
|
2617
|
-
sidebar
|
|
2476
|
+
sidebar,
|
|
2477
|
+
mainFooter,
|
|
2478
|
+
mainHeader
|
|
2618
2479
|
} = getSematicElements({
|
|
2619
2480
|
children
|
|
2620
2481
|
});
|
|
2621
|
-
return /* @__PURE__ */
|
|
2482
|
+
return /* @__PURE__ */jsx10(LayoutProvider, {
|
|
2622
2483
|
children: /* @__PURE__ */jsxs3(Stack, {
|
|
2623
2484
|
...props,
|
|
2624
2485
|
sx: {
|
|
@@ -2634,7 +2495,14 @@ var SidebarCollapseLayout = ({
|
|
|
2634
2495
|
overflow: "hidden",
|
|
2635
2496
|
flexDirection: ["row"]
|
|
2636
2497
|
},
|
|
2637
|
-
children: [sidebar,
|
|
2498
|
+
children: [sidebar, /* @__PURE__ */jsxs3(Stack, {
|
|
2499
|
+
sx: {
|
|
2500
|
+
flex: 1,
|
|
2501
|
+
height: "full",
|
|
2502
|
+
overflow: "hidden"
|
|
2503
|
+
},
|
|
2504
|
+
children: [mainHeader, main, mainFooter]
|
|
2505
|
+
})]
|
|
2638
2506
|
})]
|
|
2639
2507
|
})
|
|
2640
2508
|
});
|
|
@@ -2642,7 +2510,7 @@ var SidebarCollapseLayout = ({
|
|
|
2642
2510
|
|
|
2643
2511
|
// src/components/StackedLayout.tsx
|
|
2644
2512
|
import { Stack as Stack2 } from "@ttoss/ui";
|
|
2645
|
-
import { jsx as
|
|
2513
|
+
import { jsx as jsx11, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
2646
2514
|
var StackedLayout = ({
|
|
2647
2515
|
children,
|
|
2648
2516
|
...props
|
|
@@ -2654,7 +2522,7 @@ var StackedLayout = ({
|
|
|
2654
2522
|
} = getSematicElements({
|
|
2655
2523
|
children
|
|
2656
2524
|
});
|
|
2657
|
-
return /* @__PURE__ */
|
|
2525
|
+
return /* @__PURE__ */jsx11(LayoutProvider, {
|
|
2658
2526
|
children: /* @__PURE__ */jsxs4(Stack2, {
|
|
2659
2527
|
...props,
|
|
2660
2528
|
children: [header, main, footer]
|
|
@@ -2674,6 +2542,6 @@ iconify-icon/dist/iconify-icon.mjs:
|
|
|
2674
2542
|
* Licensed under MIT.
|
|
2675
2543
|
*
|
|
2676
2544
|
* @license MIT
|
|
2677
|
-
* @version 2.
|
|
2545
|
+
* @version 2.3.0
|
|
2678
2546
|
*)
|
|
2679
2547
|
*/
|
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.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Layout components for React",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "ttoss",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"sideEffects": false,
|
|
26
26
|
"peerDependencies": {
|
|
27
27
|
"react": ">=16.8.0",
|
|
28
|
-
"@ttoss/components": "^2.2.
|
|
29
|
-
"@ttoss/ui": "^5.9.
|
|
28
|
+
"@ttoss/components": "^2.2.26",
|
|
29
|
+
"@ttoss/ui": "^5.9.2"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@types/jest": "^30.0.0",
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
"jest": "^30.0.4",
|
|
35
35
|
"react": "^19.1.0",
|
|
36
36
|
"tsup": "^8.5.0",
|
|
37
|
-
"@ttoss/
|
|
38
|
-
"@ttoss/
|
|
39
|
-
"@ttoss/
|
|
40
|
-
"@ttoss/
|
|
41
|
-
"@ttoss/
|
|
37
|
+
"@ttoss/components": "^2.2.26",
|
|
38
|
+
"@ttoss/config": "^1.35.6",
|
|
39
|
+
"@ttoss/react-icons": "^0.4.15",
|
|
40
|
+
"@ttoss/ui": "^5.9.2",
|
|
41
|
+
"@ttoss/test-utils": "^2.1.26"
|
|
42
42
|
},
|
|
43
43
|
"keywords": [
|
|
44
44
|
"React"
|