@statsbygg/layout 0.0.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/.turbo/turbo-build.log +89 -0
- package/README.md +206 -0
- package/dist/index.css +154 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.mts +40 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.js +395 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +357 -0
- package/dist/index.mjs.map +1 -0
- package/dist/logo-X7RC63NT.svg +9 -0
- package/package.json +44 -0
- package/src/components/Breadcrumbs/Breadcrumbs.module.css +22 -0
- package/src/components/Breadcrumbs/Breadcrumbs.tsx +49 -0
- package/src/components/Breadcrumbs/Breadcrumbs.types.ts +4 -0
- package/src/components/Breadcrumbs/index.ts +2 -0
- package/src/components/GlobalFooter/GlobalFooter.module.css +28 -0
- package/src/components/GlobalFooter/GlobalFooter.tsx +23 -0
- package/src/components/GlobalFooter/GlobalFooter.types.ts +3 -0
- package/src/components/GlobalFooter/index.ts +2 -0
- package/src/components/GlobalHeader/GlobalHeader.module.css +70 -0
- package/src/components/GlobalHeader/GlobalHeader.tsx +38 -0
- package/src/components/GlobalHeader/GlobalHeader.types.ts +4 -0
- package/src/components/GlobalHeader/index.ts +2 -0
- package/src/components/MenuButton/MenuButton.module.css +41 -0
- package/src/components/MenuButton/MenuButton.tsx +57 -0
- package/src/components/MenuButton/MenuButton.types.ts +3 -0
- package/src/components/MenuButton/index.ts +2 -0
- package/src/components/RootLayout/RootLayout.module.css +9 -0
- package/src/components/RootLayout/RootLayout.tsx +39 -0
- package/src/components/RootLayout/RootLayout.types.ts +5 -0
- package/src/components/RootLayout/index.ts +2 -0
- package/src/index.ts +6 -0
- package/src/logo.svg +9 -0
- package/src/routes.ts +211 -0
- package/src/store/globalState.ts +40 -0
- package/src/types/css.d.ts +8 -0
- package/src/utils/routeRegistry.ts +92 -0
- package/tsconfig.json +20 -0
- package/tsup.config.ts +15 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
|
|
2
|
+
> @statsbygg/layout@0.0.1 build
|
|
3
|
+
> tsup
|
|
4
|
+
|
|
5
|
+
[1G[0K[33m▲ [43;33m[[43;30mWARNING[43;33m][0m [1mThe condition "types" here will never be used as it comes after both "import" and "require"[0m [package.json]
|
|
6
|
+
|
|
7
|
+
package.json:13:6:
|
|
8
|
+
[37m 13 │ [32m"types"[37m: "./dist/index.d.ts"
|
|
9
|
+
╵ [32m~~~~~~~[0m
|
|
10
|
+
|
|
11
|
+
The "import" condition comes earlier and will be used for all "import" statements:
|
|
12
|
+
|
|
13
|
+
package.json:11:6:
|
|
14
|
+
[37m 11 │ [32m"import"[37m: "./dist/index.mjs",
|
|
15
|
+
╵ [32m~~~~~~~~[0m
|
|
16
|
+
|
|
17
|
+
The "require" condition comes earlier and will be used for all "require" calls:
|
|
18
|
+
|
|
19
|
+
package.json:12:6:
|
|
20
|
+
[37m 12 │ [32m"require"[37m: "./dist/index.js",
|
|
21
|
+
╵ [32m~~~~~~~~~[0m
|
|
22
|
+
|
|
23
|
+
[34mCLI[39m Building entry: src/index.ts
|
|
24
|
+
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
25
|
+
[34mCLI[39m tsup v8.5.0
|
|
26
|
+
[34mCLI[39m Using tsup config: /home/jimmy/dev/work/statsbygg-components/packages/layout/tsup.config.ts
|
|
27
|
+
[34mCLI[39m Target: es2018
|
|
28
|
+
[34mCLI[39m Cleaning output folder
|
|
29
|
+
[34mCJS[39m Build start
|
|
30
|
+
[34mESM[39m Build start
|
|
31
|
+
|
|
32
|
+
[90m[[90m9:21:10 AM[90m][39m [43m[30m WARN [39m[49m [33m▲ [43;33m[[43;30mWARNING[43;33m][0m [1mThe condition "types" here will never be used as it comes after both "import" and "require"[0m [package.json]
|
|
33
|
+
|
|
34
|
+
package.json:13:6:
|
|
35
|
+
[37m 13 │ [32m"types"[37m: "./dist/index.d.ts"
|
|
36
|
+
╵ [32m~~~~~~~[0m
|
|
37
|
+
|
|
38
|
+
The "import" condition comes earlier and will be used for all "import" statements:
|
|
39
|
+
|
|
40
|
+
package.json:11:6:
|
|
41
|
+
[37m 11 │ [32m"import"[37m: "./dist/index.mjs",
|
|
42
|
+
╵ [32m~~~~~~~~[0m
|
|
43
|
+
|
|
44
|
+
The "require" condition comes earlier and will be used for all "require" calls:
|
|
45
|
+
|
|
46
|
+
package.json:12:6:
|
|
47
|
+
[37m 12 │ [32m"require"[37m: "./dist/index.js",
|
|
48
|
+
╵ [32m~~~~~~~~~[0m
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
[90m[[90m9:21:10 AM[90m][39m [43m[30m WARN [39m[49m [33m▲ [43;33m[[43;30mWARNING[43;33m][0m [1mThe condition "types" here will never be used as it comes after both "import" and "require"[0m [package.json]
|
|
54
|
+
|
|
55
|
+
package.json:13:6:
|
|
56
|
+
[37m 13 │ [32m"types"[37m: "./dist/index.d.ts"
|
|
57
|
+
╵ [32m~~~~~~~[0m
|
|
58
|
+
|
|
59
|
+
The "import" condition comes earlier and will be used for all "import" statements:
|
|
60
|
+
|
|
61
|
+
package.json:11:6:
|
|
62
|
+
[37m 11 │ [32m"import"[37m: "./dist/index.mjs",
|
|
63
|
+
╵ [32m~~~~~~~~[0m
|
|
64
|
+
|
|
65
|
+
The "require" condition comes earlier and will be used for all "require" calls:
|
|
66
|
+
|
|
67
|
+
package.json:12:6:
|
|
68
|
+
[37m 12 │ [32m"require"[37m: "./dist/index.js",
|
|
69
|
+
╵ [32m~~~~~~~~~[0m
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
[32mCJS[39m [1mdist/index.css [22m[32m3.55 KB[39m
|
|
74
|
+
[32mCJS[39m [1mdist/index.js [22m[32m16.49 KB[39m
|
|
75
|
+
[32mCJS[39m [1mdist/logo-X7RC63NT.svg [22m[32m72.76 KB[39m
|
|
76
|
+
[32mCJS[39m [1mdist/index.js.map [22m[32m26.88 KB[39m
|
|
77
|
+
[32mCJS[39m [1mdist/index.css.map [22m[32m5.38 KB[39m
|
|
78
|
+
[32mCJS[39m ⚡️ Build success in 66ms
|
|
79
|
+
[32mESM[39m [1mdist/index.mjs [22m[32m13.22 KB[39m
|
|
80
|
+
[32mESM[39m [1mdist/index.css [22m[32m3.55 KB[39m
|
|
81
|
+
[32mESM[39m [1mdist/logo-X7RC63NT.svg [22m[32m72.76 KB[39m
|
|
82
|
+
[32mESM[39m [1mdist/index.css.map [22m[32m5.38 KB[39m
|
|
83
|
+
[32mESM[39m [1mdist/index.mjs.map [22m[32m26.56 KB[39m
|
|
84
|
+
[32mESM[39m ⚡️ Build success in 66ms
|
|
85
|
+
DTS Build start
|
|
86
|
+
DTS ⚡️ Build success in 1201ms
|
|
87
|
+
DTS dist/index.d.ts 1.63 KB
|
|
88
|
+
DTS dist/index.d.mts 1.63 KB
|
|
89
|
+
[1G[0K⠙[1G[0K
|
package/README.md
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# @statsbygg/layout
|
|
2
|
+
|
|
3
|
+
Self-contained shared layout package for Statsbygg's Next.js microfrontend architecture using DigDir Designsystemet.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This package provides a consistent layout and state management across multiple independent Next.js applications (zones) in a microfrontend architecture.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **DigDir Designsystemet Integration**: Uses official Norwegian design system components
|
|
12
|
+
- **Self-Contained State Management**: Built-in zustand store for global state (user, theme, locale)
|
|
13
|
+
- **Dynamic Breadcrumbs**: Automatic breadcrumb generation with responsive behavior
|
|
14
|
+
- **Cross-Zone Synchronization**: State persists across browser tabs and zone navigation
|
|
15
|
+
- **CSS Modules with Colocation**: Each component follows ComponentName/ComponentName.tsx pattern
|
|
16
|
+
- **TypeScript**: Full type safety with separate .types.ts files
|
|
17
|
+
- **Function Declarations**: All functions use function declaration syntax
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install @statsbygg/layout
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Peer Dependencies
|
|
26
|
+
|
|
27
|
+
This package requires:
|
|
28
|
+
- `next` >= 14.0.0
|
|
29
|
+
- `react` >= 18.0.0
|
|
30
|
+
- `react-dom` >= 18.0.0
|
|
31
|
+
|
|
32
|
+
## Package Structure
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
src/
|
|
36
|
+
├── components/
|
|
37
|
+
│ ├── Breadcrumbs/
|
|
38
|
+
│ │ ├── Breadcrumbs.tsx
|
|
39
|
+
│ │ ├── Breadcrumbs.types.ts
|
|
40
|
+
│ │ ├── Breadcrumbs.module.css
|
|
41
|
+
│ │ └── index.ts
|
|
42
|
+
│ ├── GlobalHeader/
|
|
43
|
+
│ │ ├── GlobalHeader.tsx
|
|
44
|
+
│ │ ├── GlobalHeader.types.ts
|
|
45
|
+
│ │ ├── GlobalHeader.module.css
|
|
46
|
+
│ │ └── index.ts
|
|
47
|
+
│ ├── GlobalFooter/
|
|
48
|
+
│ │ ├── GlobalFooter.tsx
|
|
49
|
+
│ │ ├── GlobalFooter.types.ts
|
|
50
|
+
│ │ ├── GlobalFooter.module.css
|
|
51
|
+
│ │ └── index.ts
|
|
52
|
+
│ └── RootLayout/
|
|
53
|
+
│ ├── RootLayout.tsx
|
|
54
|
+
│ ├── RootLayout.types.ts
|
|
55
|
+
│ ├── RootLayout.module.css
|
|
56
|
+
│ └── index.ts
|
|
57
|
+
├── store/
|
|
58
|
+
│ └── globalState.ts
|
|
59
|
+
├── utils/
|
|
60
|
+
│ └── routeRegistry.ts
|
|
61
|
+
└── index.ts
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Usage
|
|
65
|
+
|
|
66
|
+
### Basic Setup
|
|
67
|
+
|
|
68
|
+
In your Next.js zone's root layout file (`app/layout.tsx`):
|
|
69
|
+
|
|
70
|
+
```tsx
|
|
71
|
+
import { RootLayout } from '@statsbygg/layout';
|
|
72
|
+
import '@digdir/designsystemet-theme';
|
|
73
|
+
import '@digdir/designsystemet-css';
|
|
74
|
+
|
|
75
|
+
export default function Layout({ children }: { children: React.ReactNode }) {
|
|
76
|
+
return (
|
|
77
|
+
<html lang="no">
|
|
78
|
+
<body>
|
|
79
|
+
<RootLayout zoneName="your-app-zone">
|
|
80
|
+
{children}
|
|
81
|
+
</RootLayout>
|
|
82
|
+
</body>
|
|
83
|
+
</html>
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Using the Global Store
|
|
89
|
+
|
|
90
|
+
The package exports a zustand store for managing global state:
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
import { useGlobalStore } from '@statsbygg/layout';
|
|
94
|
+
|
|
95
|
+
function MyComponent() {
|
|
96
|
+
const { user, theme, setUser, setTheme } = useGlobalStore();
|
|
97
|
+
|
|
98
|
+
function handleLogin() {
|
|
99
|
+
setUser({ name: 'John Doe', email: 'john@statsbygg.no' });
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function toggleTheme() {
|
|
103
|
+
setTheme(theme === 'light' ? 'dark' : 'light');
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return (
|
|
107
|
+
<div>
|
|
108
|
+
<p>Current theme: {theme}</p>
|
|
109
|
+
{user && <p>Logged in as {user.name}</p>}
|
|
110
|
+
<button onClick={toggleTheme}>Toggle theme</button>
|
|
111
|
+
</div>
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
## API Reference
|
|
116
|
+
|
|
117
|
+
### RootLayout
|
|
118
|
+
|
|
119
|
+
Main layout component that orchestrates the entire layout structure.
|
|
120
|
+
|
|
121
|
+
```tsx
|
|
122
|
+
interface RootLayoutProps {
|
|
123
|
+
children: React.ReactNode;
|
|
124
|
+
zoneName: string;
|
|
125
|
+
className?: string;
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### useGlobalStore
|
|
130
|
+
|
|
131
|
+
Zustand store hook for global state management.
|
|
132
|
+
|
|
133
|
+
```tsx
|
|
134
|
+
interface GlobalState {
|
|
135
|
+
user: { name: string; email: string } | null;
|
|
136
|
+
theme: 'light' | 'dark';
|
|
137
|
+
locale: 'no' | 'en';
|
|
138
|
+
setUser: (user: { name: string; email: string } | null) => void;
|
|
139
|
+
setTheme: (theme: 'light' | 'dark') => void;
|
|
140
|
+
setLocale: (locale: 'no' | 'en') => void;
|
|
141
|
+
initialize: () => Promise<void>;
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
## Breadcrumbs Behavior
|
|
147
|
+
|
|
148
|
+
The Breadcrumbs component uses Designsystemet's responsive behavior:
|
|
149
|
+
|
|
150
|
+
- **On narrow screens (<650px)**: Shows a back button to parent level
|
|
151
|
+
- **On wide screens (≥650px)**: Shows full breadcrumb path
|
|
152
|
+
- **Last item**: Automatically marked with `aria-current="page"`
|
|
153
|
+
|
|
154
|
+
## State Persistence
|
|
155
|
+
|
|
156
|
+
Global state is automatically persisted to localStorage using zustand's persist middleware. This enables:
|
|
157
|
+
|
|
158
|
+
- **Cross-tab synchronization**: Changes in one tab reflect in others
|
|
159
|
+
- **Cross-zone persistence**: State is maintained when navigating between zones
|
|
160
|
+
- **Session persistence**: State survives page refreshes
|
|
161
|
+
|
|
162
|
+
## Design System Integration
|
|
163
|
+
|
|
164
|
+
This package uses [DigDir Designsystemet](https://designsystemet.no) components:
|
|
165
|
+
|
|
166
|
+
- `Breadcrumbs` (with List, Item, Link)
|
|
167
|
+
- `Button`
|
|
168
|
+
- `Heading`
|
|
169
|
+
- `Link`
|
|
170
|
+
- `Paragraph`
|
|
171
|
+
|
|
172
|
+
All styling uses Designsystemet design tokens:
|
|
173
|
+
- `--ds-spacing-*` for spacing
|
|
174
|
+
- `--ds-color-*` for colors
|
|
175
|
+
- `--ds-font-size-*` for typography
|
|
176
|
+
|
|
177
|
+
## Development
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
# Install dependencies
|
|
181
|
+
npm install
|
|
182
|
+
|
|
183
|
+
# Build the package
|
|
184
|
+
npm run build
|
|
185
|
+
|
|
186
|
+
# Watch mode for development
|
|
187
|
+
npm run dev
|
|
188
|
+
|
|
189
|
+
# Type checking
|
|
190
|
+
npm run type-check
|
|
191
|
+
|
|
192
|
+
# Linting
|
|
193
|
+
npm run lint
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Dependencies
|
|
197
|
+
|
|
198
|
+
This package includes:
|
|
199
|
+
- `@digdir/designsystemet-react` ^1.5.1
|
|
200
|
+
- `@statsbygg/design-tokens` ^0.2.0
|
|
201
|
+
- `clsx` ^2.0.0
|
|
202
|
+
- `zustand` ^5.0.4
|
|
203
|
+
|
|
204
|
+
## License
|
|
205
|
+
|
|
206
|
+
Internal use only - Statsbygg
|
package/dist/index.css
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/* src/components/Breadcrumbs/Breadcrumbs.module.css */
|
|
2
|
+
.Breadcrumbs_breadcrumbs {
|
|
3
|
+
--dsc-breadcrumbs-color: var(--ds-color-text-default);
|
|
4
|
+
padding: 2.5rem 0 0 0;
|
|
5
|
+
}
|
|
6
|
+
.Breadcrumbs_link {
|
|
7
|
+
text-decoration: underline;
|
|
8
|
+
text-underline-offset: 2px;
|
|
9
|
+
color: var(--ds-color-text-default);
|
|
10
|
+
}
|
|
11
|
+
.Breadcrumbs_link:hover .Breadcrumbs_link:visited {
|
|
12
|
+
color: var(--ds-color-text-default);
|
|
13
|
+
}
|
|
14
|
+
.Breadcrumbs_currentLink {
|
|
15
|
+
text-decoration: none;
|
|
16
|
+
font-weight: 500;
|
|
17
|
+
pointer-events: none;
|
|
18
|
+
color: var(--ds-color-text-default);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/* src/components/MenuButton/MenuButton.module.css */
|
|
22
|
+
.MenuButton_userInfo {
|
|
23
|
+
display: flex;
|
|
24
|
+
flex-direction: column;
|
|
25
|
+
gap: var(--ds-spacing-1);
|
|
26
|
+
padding: var(--ds-spacing-2) var(--ds-spacing-3);
|
|
27
|
+
}
|
|
28
|
+
.MenuButton_userName {
|
|
29
|
+
font-size: var(--ds-font-size-sm);
|
|
30
|
+
font-weight: var(--ds-font-weight-medium);
|
|
31
|
+
color: var(--ds-color-neutral-text-default);
|
|
32
|
+
}
|
|
33
|
+
.MenuButton_userEmail {
|
|
34
|
+
font-size: var(--ds-font-size-xs);
|
|
35
|
+
color: var(--ds-color-neutral-text-subtle);
|
|
36
|
+
}
|
|
37
|
+
.MenuButton_menuButton {
|
|
38
|
+
background-color: var(--ds-color-neutral-base-default);
|
|
39
|
+
}
|
|
40
|
+
.MenuButton_devContainer {
|
|
41
|
+
display: flex;
|
|
42
|
+
gap: var(--ds-spacing-4);
|
|
43
|
+
padding: var(--ds-spacing-2);
|
|
44
|
+
}
|
|
45
|
+
.MenuButton_zoneSection {
|
|
46
|
+
flex: 1;
|
|
47
|
+
min-width: 12rem;
|
|
48
|
+
}
|
|
49
|
+
.MenuButton_zoneTitle {
|
|
50
|
+
font-weight: 600;
|
|
51
|
+
padding: var(--ds-spacing-2);
|
|
52
|
+
color: var(--ds-color-neutral-text-default);
|
|
53
|
+
border-bottom: 1px solid var(--ds-color-neutral-border-subtle);
|
|
54
|
+
margin-bottom: var(--ds-spacing-2);
|
|
55
|
+
text-transform: capitalize;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/* src/components/GlobalHeader/GlobalHeader.module.css */
|
|
59
|
+
.GlobalHeader_header {
|
|
60
|
+
background-color: var(--ds-color-accent-surface-tinted);
|
|
61
|
+
border-bottom: 1px solid var(--ds-color-neutral-border-subtle);
|
|
62
|
+
position: sticky;
|
|
63
|
+
top: 0;
|
|
64
|
+
z-index: 100;
|
|
65
|
+
}
|
|
66
|
+
.GlobalHeader_headerContainer {
|
|
67
|
+
max-width: 90rem;
|
|
68
|
+
margin: 0 auto;
|
|
69
|
+
padding: 0 var(--ds-size-30);
|
|
70
|
+
}
|
|
71
|
+
.GlobalHeader_topBarContainer {
|
|
72
|
+
display: flex;
|
|
73
|
+
justify-content: space-between;
|
|
74
|
+
align-items: center;
|
|
75
|
+
padding: 1.25rem 0;
|
|
76
|
+
}
|
|
77
|
+
.GlobalHeader_logo {
|
|
78
|
+
margin: 0;
|
|
79
|
+
color: var(--ds-color-neutral-text-default);
|
|
80
|
+
white-space: nowrap;
|
|
81
|
+
display: flex;
|
|
82
|
+
align-items: center;
|
|
83
|
+
min-height: inherit;
|
|
84
|
+
}
|
|
85
|
+
.GlobalHeader_actionsContainer {
|
|
86
|
+
display: flex;
|
|
87
|
+
align-items: stretch;
|
|
88
|
+
gap: var(--ds-size-9);
|
|
89
|
+
min-height: inherit;
|
|
90
|
+
}
|
|
91
|
+
.GlobalHeader_searchInput {
|
|
92
|
+
min-width: 12.5rem;
|
|
93
|
+
display: flex;
|
|
94
|
+
align-items: center;
|
|
95
|
+
}
|
|
96
|
+
@media (max-width: 768px) {
|
|
97
|
+
.GlobalHeader_container {
|
|
98
|
+
padding: 0 var(--ds-spacing-4);
|
|
99
|
+
}
|
|
100
|
+
.GlobalHeader_topBar {
|
|
101
|
+
flex-wrap: wrap;
|
|
102
|
+
padding: var(--ds-spacing-4) 0;
|
|
103
|
+
}
|
|
104
|
+
.GlobalHeader_actions {
|
|
105
|
+
order: 3;
|
|
106
|
+
width: 100%;
|
|
107
|
+
flex-direction: column;
|
|
108
|
+
gap: var(--ds-spacing-3);
|
|
109
|
+
}
|
|
110
|
+
.GlobalHeader_searchInput {
|
|
111
|
+
width: 100%;
|
|
112
|
+
min-width: auto;
|
|
113
|
+
}
|
|
114
|
+
.GlobalHeader_menuButton {
|
|
115
|
+
width: 100%;
|
|
116
|
+
justify-content: center;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/* src/components/GlobalFooter/GlobalFooter.module.css */
|
|
121
|
+
.GlobalFooter_footer {
|
|
122
|
+
background-color: var(--ds-color-neutral-surface-subtle);
|
|
123
|
+
border-top: 1px solid var(--ds-color-neutral-border-subtle);
|
|
124
|
+
margin-top: auto;
|
|
125
|
+
}
|
|
126
|
+
.GlobalFooter_container {
|
|
127
|
+
max-width: 1440px;
|
|
128
|
+
margin: 0 auto;
|
|
129
|
+
padding: var(--ds-spacing-6) var(--ds-spacing-4);
|
|
130
|
+
}
|
|
131
|
+
.GlobalFooter_content {
|
|
132
|
+
display: flex;
|
|
133
|
+
justify-content: space-between;
|
|
134
|
+
align-items: center;
|
|
135
|
+
gap: var(--ds-spacing-4);
|
|
136
|
+
flex-wrap: wrap;
|
|
137
|
+
}
|
|
138
|
+
@media (max-width: 768px) {
|
|
139
|
+
.GlobalFooter_content {
|
|
140
|
+
flex-direction: column;
|
|
141
|
+
align-items: flex-start;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/* src/components/RootLayout/RootLayout.module.css */
|
|
146
|
+
.RootLayout_root {
|
|
147
|
+
display: flex;
|
|
148
|
+
flex-direction: column;
|
|
149
|
+
min-height: 100vh;
|
|
150
|
+
}
|
|
151
|
+
.RootLayout_main {
|
|
152
|
+
flex: 1;
|
|
153
|
+
}
|
|
154
|
+
/*# sourceMappingURL=index.css.map */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/Breadcrumbs/Breadcrumbs.module.css","../src/components/MenuButton/MenuButton.module.css","../src/components/GlobalHeader/GlobalHeader.module.css","../src/components/GlobalFooter/GlobalFooter.module.css","../src/components/RootLayout/RootLayout.module.css"],"sourcesContent":[".breadcrumbs {\n --dsc-breadcrumbs-color: var(--ds-color-text-default);\n padding: 2.5rem 0 0 0;\n}\n\n.link {\n text-decoration: underline;\n text-underline-offset: 2px;\n color: var(--ds-color-text-default);\n}\n\n.link:hover \n.link:visited{\n color: var(--ds-color-text-default);\n}\n\n.currentLink {\n text-decoration: none;\n font-weight: 500;\n pointer-events: none;\n color: var(--ds-color-text-default);\n}\n",".userInfo {\n display: flex;\n flex-direction: column;\n gap: var(--ds-spacing-1);\n padding: var(--ds-spacing-2) var(--ds-spacing-3);\n}\n\n.userName {\n font-size: var(--ds-font-size-sm);\n font-weight: var(--ds-font-weight-medium);\n color: var(--ds-color-neutral-text-default);\n}\n\n.userEmail {\n font-size: var(--ds-font-size-xs);\n color: var(--ds-color-neutral-text-subtle);\n}\n\n.menuButton {\n background-color: var(--ds-color-neutral-base-default);\n}\n\n.devContainer {\n display: flex;\n gap: var(--ds-spacing-4);\n padding: var(--ds-spacing-2);\n}\n\n.zoneSection {\n flex: 1;\n min-width: 12rem;\n}\n\n.zoneTitle {\n font-weight: 600;\n padding: var(--ds-spacing-2);\n color: var(--ds-color-neutral-text-default);\n border-bottom: 1px solid var(--ds-color-neutral-border-subtle);\n margin-bottom: var(--ds-spacing-2);\n text-transform: capitalize;\n}\n",".header {\n background-color: var(--ds-color-accent-surface-tinted);\n border-bottom: 1px solid var(--ds-color-neutral-border-subtle);\n position: sticky;\n top: 0;\n z-index: 100;\n}\n\n.headerContainer {\n max-width: 90rem;\n margin: 0 auto;\n padding: 0 var(--ds-size-30);\n}\n\n.topBarContainer {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.25rem 0;\n}\n\n.logo {\n margin: 0;\n color: var(--ds-color-neutral-text-default);\n white-space: nowrap;\n display: flex;\n align-items: center;\n min-height: inherit;\n}\n\n.actionsContainer {\n display: flex;\n align-items: stretch;\n gap: var(--ds-size-9);\n min-height: inherit;\n}\n\n.searchInput {\n min-width: 12.5rem;\n display: flex;\n align-items: center;\n}\n\n@media (max-width: 768px) {\n .container {\n padding: 0 var(--ds-spacing-4);\n }\n\n .topBar {\n flex-wrap: wrap;\n padding: var(--ds-spacing-4) 0;\n }\n\n .actions {\n order: 3;\n width: 100%;\n flex-direction: column;\n gap: var(--ds-spacing-3);\n }\n\n .searchInput {\n width: 100%;\n min-width: auto;\n }\n\n .menuButton {\n width: 100%;\n justify-content: center;\n }\n}",".footer {\n background-color: var(--ds-color-neutral-surface-subtle);\n border-top: 1px solid var(--ds-color-neutral-border-subtle);\n margin-top: auto;\n}\n\n.container {\n max-width: 1440px;\n margin: 0 auto;\n padding: var(--ds-spacing-6) var(--ds-spacing-4);\n}\n\n.content {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: var(--ds-spacing-4);\n flex-wrap: wrap;\n}\n\n@media (max-width: 768px) {\n .content {\n flex-direction: column;\n align-items: flex-start;\n }\n\n\n}",".root {\n display: flex;\n flex-direction: column;\n min-height: 100vh;\n}\n\n.main {\n flex: 1;\n}"],"mappings":";AAAA,CAACA;AACC,2BAAyB,IAAI;AAC7B,WAAS,OAAO,EAAE,EAAE;AACtB;AAEA,CAACC;AACC,mBAAiB;AACjB,yBAAuB;AACvB,SAAO,IAAI;AACb;AAEA,CANCA,gBAMI,OACL,CAPCA,gBAOI;AACH,SAAO,IAAI;AACb;AAEA,CAACC;AACC,mBAAiB;AACjB,eAAa;AACb,kBAAgB;AAChB,SAAO,IAAI;AACb;;;ACrBA,CAACC;AACC,WAAS;AACT,kBAAgB;AAChB,OAAK,IAAI;AACT,WAAS,IAAI,gBAAgB,IAAI;AACnC;AAEA,CAACC;AACC,aAAW,IAAI;AACf,eAAa,IAAI;AACjB,SAAO,IAAI;AACb;AAEA,CAACC;AACC,aAAW,IAAI;AACf,SAAO,IAAI;AACb;AAEA,CAACC;AACC,oBAAkB,IAAI;AACxB;AAEA,CAACC;AACC,WAAS;AACT,OAAK,IAAI;AACT,WAAS,IAAI;AACf;AAEA,CAACC;AACC,QAAM;AACN,aAAW;AACb;AAEA,CAACC;AACC,eAAa;AACb,WAAS,IAAI;AACb,SAAO,IAAI;AACX,iBAAe,IAAI,MAAM,IAAI;AAC7B,iBAAe,IAAI;AACnB,kBAAgB;AAClB;;;ACxCA,CAACC;AACC,oBAAkB,IAAI;AACtB,iBAAe,IAAI,MAAM,IAAI;AAC7B,YAAU;AACV,OAAK;AACL,WAAS;AACX;AAEA,CAACC;AACC,aAAW;AACX,UAAQ,EAAE;AACV,WAAS,EAAE,IAAI;AACjB;AAEA,CAACC;AACC,WAAS;AACT,mBAAiB;AACjB,eAAa;AACb,WAAS,QAAQ;AACnB;AAEA,CAACC;AACC,UAAQ;AACR,SAAO,IAAI;AACX,eAAa;AACb,WAAS;AACT,eAAa;AACb,cAAY;AACd;AAEA,CAACC;AACC,WAAS;AACT,eAAa;AACb,OAAK,IAAI;AACT,cAAY;AACd;AAEA,CAACC;AACC,aAAW;AACX,WAAS;AACT,eAAa;AACf;AAEA,OAAO,CAAC,SAAS,EAAE;AACjB,GAACC;AACC,aAAS,EAAE,IAAI;AACjB;AAEA,GAACC;AACC,eAAW;AACX,aAAS,IAAI,gBAAgB;AAC/B;AAEA,GAACC;AACC,WAAO;AACP,WAAO;AACP,oBAAgB;AAChB,SAAK,IAAI;AACX;AAEA,GAvBDH;AAwBG,WAAO;AACP,eAAW;AACb;AAEA,GAACI;AACC,WAAO;AACP,qBAAiB;AACnB;AACF;;;ACrEA,CAACC;AACC,oBAAkB,IAAI;AACtB,cAAY,IAAI,MAAM,IAAI;AAC1B,cAAY;AACd;AAEA,CAACC;AACC,aAAW;AACX,UAAQ,EAAE;AACV,WAAS,IAAI,gBAAgB,IAAI;AACnC;AAEA,CAACC;AACC,WAAS;AACT,mBAAiB;AACjB,eAAa;AACb,OAAK,IAAI;AACT,aAAW;AACb;AAEA,OAAO,CAAC,SAAS,EAAE;AACjB,GATDA;AAUG,oBAAgB;AAChB,iBAAa;AACf;AAGF;;;AC3BA,CAACC;AACC,WAAS;AACT,kBAAgB;AAChB,cAAY;AACd;AAEA,CAACC;AACC,QAAM;AACR;","names":["breadcrumbs","link","currentLink","userInfo","userName","userEmail","menuButton","devContainer","zoneSection","zoneTitle","header","headerContainer","topBarContainer","logo","actionsContainer","searchInput","container","topBar","actions","menuButton","footer","container","content","root","main"]}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as zustand_middleware from 'zustand/middleware';
|
|
3
|
+
import * as zustand from 'zustand';
|
|
4
|
+
|
|
5
|
+
interface RootLayoutProps {
|
|
6
|
+
children: React.ReactNode;
|
|
7
|
+
zone: string;
|
|
8
|
+
className?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
declare function RootLayout({ children, zone, className, }: RootLayoutProps): react_jsx_runtime.JSX.Element;
|
|
12
|
+
|
|
13
|
+
type Theme = 'light' | 'dark' | 'system';
|
|
14
|
+
type GlobalState = {
|
|
15
|
+
user?: {
|
|
16
|
+
id: string;
|
|
17
|
+
name?: string;
|
|
18
|
+
} | null;
|
|
19
|
+
theme: Theme;
|
|
20
|
+
locale: string;
|
|
21
|
+
setUser: (user: GlobalState['user']) => void;
|
|
22
|
+
setTheme: (theme: Theme) => void;
|
|
23
|
+
setLocale: (locale: string) => void;
|
|
24
|
+
initialize: () => void | Promise<void>;
|
|
25
|
+
};
|
|
26
|
+
declare const useGlobalStore: zustand.UseBoundStore<Omit<zustand.StoreApi<GlobalState>, "setState" | "persist"> & {
|
|
27
|
+
setState(partial: GlobalState | Partial<GlobalState> | ((state: GlobalState) => GlobalState | Partial<GlobalState>), replace?: false | undefined): unknown;
|
|
28
|
+
setState(state: GlobalState | ((state: GlobalState) => GlobalState), replace: true): unknown;
|
|
29
|
+
persist: {
|
|
30
|
+
setOptions: (options: Partial<zustand_middleware.PersistOptions<GlobalState, unknown, unknown>>) => void;
|
|
31
|
+
clearStorage: () => void;
|
|
32
|
+
rehydrate: () => Promise<void> | void;
|
|
33
|
+
hasHydrated: () => boolean;
|
|
34
|
+
onHydrate: (fn: (state: GlobalState) => void) => () => void;
|
|
35
|
+
onFinishHydration: (fn: (state: GlobalState) => void) => () => void;
|
|
36
|
+
getOptions: () => Partial<zustand_middleware.PersistOptions<GlobalState, unknown, unknown>>;
|
|
37
|
+
};
|
|
38
|
+
}>;
|
|
39
|
+
|
|
40
|
+
export { type GlobalState, RootLayout, type RootLayoutProps, useGlobalStore };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as zustand_middleware from 'zustand/middleware';
|
|
3
|
+
import * as zustand from 'zustand';
|
|
4
|
+
|
|
5
|
+
interface RootLayoutProps {
|
|
6
|
+
children: React.ReactNode;
|
|
7
|
+
zone: string;
|
|
8
|
+
className?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
declare function RootLayout({ children, zone, className, }: RootLayoutProps): react_jsx_runtime.JSX.Element;
|
|
12
|
+
|
|
13
|
+
type Theme = 'light' | 'dark' | 'system';
|
|
14
|
+
type GlobalState = {
|
|
15
|
+
user?: {
|
|
16
|
+
id: string;
|
|
17
|
+
name?: string;
|
|
18
|
+
} | null;
|
|
19
|
+
theme: Theme;
|
|
20
|
+
locale: string;
|
|
21
|
+
setUser: (user: GlobalState['user']) => void;
|
|
22
|
+
setTheme: (theme: Theme) => void;
|
|
23
|
+
setLocale: (locale: string) => void;
|
|
24
|
+
initialize: () => void | Promise<void>;
|
|
25
|
+
};
|
|
26
|
+
declare const useGlobalStore: zustand.UseBoundStore<Omit<zustand.StoreApi<GlobalState>, "setState" | "persist"> & {
|
|
27
|
+
setState(partial: GlobalState | Partial<GlobalState> | ((state: GlobalState) => GlobalState | Partial<GlobalState>), replace?: false | undefined): unknown;
|
|
28
|
+
setState(state: GlobalState | ((state: GlobalState) => GlobalState), replace: true): unknown;
|
|
29
|
+
persist: {
|
|
30
|
+
setOptions: (options: Partial<zustand_middleware.PersistOptions<GlobalState, unknown, unknown>>) => void;
|
|
31
|
+
clearStorage: () => void;
|
|
32
|
+
rehydrate: () => Promise<void> | void;
|
|
33
|
+
hasHydrated: () => boolean;
|
|
34
|
+
onHydrate: (fn: (state: GlobalState) => void) => () => void;
|
|
35
|
+
onFinishHydration: (fn: (state: GlobalState) => void) => () => void;
|
|
36
|
+
getOptions: () => Partial<zustand_middleware.PersistOptions<GlobalState, unknown, unknown>>;
|
|
37
|
+
};
|
|
38
|
+
}>;
|
|
39
|
+
|
|
40
|
+
export { type GlobalState, RootLayout, type RootLayoutProps, useGlobalStore };
|