@synerise/ds-layout 1.2.15 → 2.0.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/CHANGELOG.md +8 -0
- package/CLAUDE.md +129 -0
- package/package.json +6 -5
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [2.0.0](https://github.com/synerise/synerise-design/compare/@synerise/ds-layout@1.2.16...@synerise/ds-layout@2.0.0) (2026-08-26)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @synerise/ds-layout
|
|
9
|
+
|
|
10
|
+
## [1.2.16](https://github.com/synerise/synerise-design/compare/@synerise/ds-layout@1.2.15...@synerise/ds-layout@1.2.16) (2026-07-23)
|
|
11
|
+
|
|
12
|
+
**Note:** Version bump only for package @synerise/ds-layout
|
|
13
|
+
|
|
6
14
|
## [1.2.15](https://github.com/synerise/synerise-design/compare/@synerise/ds-layout@1.2.14...@synerise/ds-layout@1.2.15) (2026-06-17)
|
|
7
15
|
|
|
8
16
|
**Note:** Version bump only for package @synerise/ds-layout
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Layout (`@synerise/ds-layout`)
|
|
2
|
+
|
|
3
|
+
> Shell components for building full-page application layouts with optional left/right sidebars, a header zone, a subheader zone, and a scrollable main content area.
|
|
4
|
+
|
|
5
|
+
## Package structure
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
src/
|
|
9
|
+
Layout.tsx — main layout component (header + sidebars + main content)
|
|
10
|
+
Layout.types.ts — exported types: LayoutProps, SidebarProps, ColumnProps
|
|
11
|
+
Layout.styles.ts — all styled-components (LayoutContainer, LayoutSidebar, SidebarButton, etc.)
|
|
12
|
+
index.ts — public exports
|
|
13
|
+
Page/
|
|
14
|
+
Page.tsx — top-level page shell (navbar + app menu + layout slot)
|
|
15
|
+
Page.styles.tsx — styled-components for Page
|
|
16
|
+
Sidebar/
|
|
17
|
+
Sidebar.tsx — internal sidebar component (not exported)
|
|
18
|
+
__specs__/
|
|
19
|
+
Layout.spec.tsx — Vitest tests
|
|
20
|
+
modules.d.ts — *.less module declaration
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Public exports
|
|
24
|
+
|
|
25
|
+
### `Layout` (default export)
|
|
26
|
+
|
|
27
|
+
| Prop | Type | Default | Description |
|
|
28
|
+
|------|------|---------|-------------|
|
|
29
|
+
| `children` | `ReactNode` | — | Main content area |
|
|
30
|
+
| `header` | `ReactNode` | — | Rendered above the sidebar/main row |
|
|
31
|
+
| `subheader` | `ReactNode` | — | Rendered inside main column, above `children`, with a drop shadow |
|
|
32
|
+
| `left` | `SidebarProps` | — | Left sidebar config; omit to hide sidebar entirely |
|
|
33
|
+
| `right` | `SidebarProps` | — | Right sidebar config; omit to hide sidebar entirely |
|
|
34
|
+
| `className` | `string` | — | Added alongside `ds-layout` class |
|
|
35
|
+
| `styles` | `ColumnProps<CSSProperties>` | — | Inline style overrides per region |
|
|
36
|
+
| `fullPage` | `boolean` | `false` | Removes 24 px padding from main content inner wrapper |
|
|
37
|
+
| `nativeScroll` | `boolean` | — | Use native browser scroll in main column instead of `@synerise/ds-scrollbar` |
|
|
38
|
+
| `nativeScrollRef` | `Ref<HTMLDivElement>` | — | Ref forwarded to the native-scroll inner `<div>` |
|
|
39
|
+
| `fillViewport` | `boolean` | — | Positions container absolutely; height = `calc(100vh - viewportTopOffset)` |
|
|
40
|
+
| `viewportTopOffset` | `number` | `55` | Top offset used when `fillViewport` is true |
|
|
41
|
+
| `sidebarAnimationDisabled` | `boolean` | — | Disables CSS transitions on sidebar width |
|
|
42
|
+
| `renderLeftSidebarControls` | `boolean \| (() => ReactNode)` | `false` | `true` = built-in show/hide button; function = custom toggle UI |
|
|
43
|
+
| `renderRightSidebarControls` | `boolean \| (() => ReactNode)` | `false` | Same as above for right sidebar |
|
|
44
|
+
| `leftSidebarWithDnd` | `boolean` | `false` | Passes `withDnd` to left sidebar scrollbar |
|
|
45
|
+
| `rightSidebarWithDnd` | `boolean` | `false` | Passes `withDnd` to right sidebar scrollbar |
|
|
46
|
+
| `leftSidebarWithScrollbar` | `boolean` | `true` | Wraps left sidebar content in `@synerise/ds-scrollbar` |
|
|
47
|
+
| `rightSidebarWithScrollbar` | `boolean` | `true` | Wraps right sidebar content in `@synerise/ds-scrollbar` |
|
|
48
|
+
| `mainSidebarWithDnd` | `boolean` | `false` | Passes `withDnd` to main content scrollbar |
|
|
49
|
+
|
|
50
|
+
### `SidebarProps` (type export)
|
|
51
|
+
|
|
52
|
+
| Field | Type | Default | Description |
|
|
53
|
+
|-------|------|---------|-------------|
|
|
54
|
+
| `content` | `ReactNode` | — | Rendered inside sidebar |
|
|
55
|
+
| `opened` | `boolean` | — | Controlled open state |
|
|
56
|
+
| `onChange` | `(isOpened: boolean) => void` | — | Called when built-in toggle is clicked |
|
|
57
|
+
| `width` | `number` | `320` | Width in px when sidebar is open |
|
|
58
|
+
|
|
59
|
+
### `ColumnProps<T>` (type export)
|
|
60
|
+
|
|
61
|
+
Generic type used for `styles` prop. Keys: `left`, `leftInner`, `main`, `mainInner`, `right`, `rightInner`.
|
|
62
|
+
|
|
63
|
+
### `Page` (named export)
|
|
64
|
+
|
|
65
|
+
Outer page shell wrapping a top navbar and an app menu alongside the main content.
|
|
66
|
+
|
|
67
|
+
| Prop | Type | Default | Description |
|
|
68
|
+
|------|------|---------|-------------|
|
|
69
|
+
| `children` | `ReactNode` | — | Typically a `<Layout>` instance |
|
|
70
|
+
| `navBar` | `ReactNode` | — | Top navigation bar (56 px tall; shifts content below it) |
|
|
71
|
+
| `appMenu` | `ReactElement` | — | Side application menu; rendered in a 64 px wide fixed slot; receives `top` prop via `cloneElement` |
|
|
72
|
+
| `className` | `string` | — | Applied to outer `PageContainer` |
|
|
73
|
+
|
|
74
|
+
## Usage patterns
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
import Layout, { Page } from '@synerise/ds-layout';
|
|
78
|
+
import type { SidebarProps } from '@synerise/ds-layout';
|
|
79
|
+
|
|
80
|
+
// Full-page shell with both sidebars
|
|
81
|
+
const [leftOpen, setLeftOpen] = useState(false);
|
|
82
|
+
const [rightOpen, setRightOpen] = useState(false);
|
|
83
|
+
|
|
84
|
+
<Page navBar={<Navbar />} appMenu={<AppMenu />}>
|
|
85
|
+
<Layout
|
|
86
|
+
header={<PageHeader title="My Page" />}
|
|
87
|
+
left={{ content: <LeftPanel />, opened: leftOpen, onChange: setLeftOpen }}
|
|
88
|
+
right={{ content: <RightPanel />, opened: rightOpen, onChange: setRightOpen }}
|
|
89
|
+
renderLeftSidebarControls
|
|
90
|
+
renderRightSidebarControls
|
|
91
|
+
>
|
|
92
|
+
<Content />
|
|
93
|
+
</Layout>
|
|
94
|
+
</Page>
|
|
95
|
+
|
|
96
|
+
// Full-page mode (no padding, native scroll)
|
|
97
|
+
<Page>
|
|
98
|
+
<Layout fullPage nativeScroll header={<Header />}>
|
|
99
|
+
<LargeContent />
|
|
100
|
+
</Layout>
|
|
101
|
+
</Page>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Styling
|
|
105
|
+
|
|
106
|
+
- `LayoutContainer` is `display: flex; flex-direction: column; height: 100%; overflow: hidden`.
|
|
107
|
+
- `fillViewport` switches container to `position: absolute; height: calc(100vh - N px)`.
|
|
108
|
+
- Default top offset for `fillViewport` is **55 px** (matches a typical navbar height).
|
|
109
|
+
- Main content inner wrapper has **24 px padding** on all sides except on `medium` breakpoint and below (handled by `@synerise/ds-core` `mediaQuery` helpers). `fullPage=true` overrides this to `0`.
|
|
110
|
+
- Sidebar slide animation uses CSS `max-width` transitions (0.3 s ease); disabled entirely when `sidebarAnimationDisabled` is true.
|
|
111
|
+
- `SidebarButton` (toggle handle) is absolutely positioned outside the sidebar; repositions at `top: 48px` normally, or `top: 170px` when `subheader` is present.
|
|
112
|
+
- `LayoutSidebar` has a hardcoded `background-color: #fff` — not a theme token.
|
|
113
|
+
- `Page.PageContainer` has a hardcoded `background-color: rgb(243, 245, 246)` — not a theme token.
|
|
114
|
+
|
|
115
|
+
## Key dependencies
|
|
116
|
+
|
|
117
|
+
- `@synerise/ds-scrollbar` — scrollbar used in main content and sidebars
|
|
118
|
+
- `@synerise/ds-icon` — arrow and close icons on sidebar toggle button
|
|
119
|
+
- `@synerise/ds-core` — `useTheme`, `mediaQuery` breakpoint helpers
|
|
120
|
+
- `styled-components ^5` (peer)
|
|
121
|
+
|
|
122
|
+
## Implementation notes
|
|
123
|
+
|
|
124
|
+
- `Sidebar` is an internal component not exported from `index.ts`.
|
|
125
|
+
- Sidebar `opened` / `onChange` are fully **controlled** — the component never manages its own open state.
|
|
126
|
+
- When `renderLeftSidebarControls` / `renderRightSidebarControls` is `false` (default), the sidebar visibility is derived purely from `left?.opened` / `right?.opened`. When the flag is truthy, a toggle button is rendered and `LayoutBody` allows `overflow: visible` on the relevant side.
|
|
127
|
+
- `Page` uses `React.cloneElement` to inject a `top` prop into `appMenu` equal to `56` (when `navBar` is present) or `0`. The `appMenu` element must accept a `top` prop.
|
|
128
|
+
- The test file has three `it.todo` stubs for sidebar control behaviour — this logic is untested.
|
|
129
|
+
- `Layout.styles.ts` contains a stray `}` character at line 235 (inside `LayoutSidebar`) which is a syntax artefact but compiles due to template-literal context.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@synerise/ds-layout",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Layout UI Component for the Synerise Design System",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"repository": "synerise/synerise-design",
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"files": [
|
|
18
18
|
"/dist",
|
|
19
19
|
"CHANGELOG.md",
|
|
20
|
+
"CLAUDE.md",
|
|
20
21
|
"README.md",
|
|
21
22
|
"package.json",
|
|
22
23
|
"LICENSE.md"
|
|
@@ -41,9 +42,9 @@
|
|
|
41
42
|
],
|
|
42
43
|
"types": "dist/index.d.ts",
|
|
43
44
|
"dependencies": {
|
|
44
|
-
"@synerise/ds-icon": "^
|
|
45
|
-
"@synerise/ds-scrollbar": "^
|
|
46
|
-
"@synerise/ds-utils": "^
|
|
45
|
+
"@synerise/ds-icon": "^2.0.0",
|
|
46
|
+
"@synerise/ds-scrollbar": "^2.0.0",
|
|
47
|
+
"@synerise/ds-utils": "^2.0.0"
|
|
47
48
|
},
|
|
48
49
|
"peerDependencies": {
|
|
49
50
|
"@synerise/ds-core": "*",
|
|
@@ -51,5 +52,5 @@
|
|
|
51
52
|
"styled-components": "^5.3.3",
|
|
52
53
|
"vitest": "4"
|
|
53
54
|
},
|
|
54
|
-
"gitHead": "
|
|
55
|
+
"gitHead": "033854a18f038079e9a16b0ff250f8401a2287c2"
|
|
55
56
|
}
|