@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.
Files changed (3) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/CLAUDE.md +129 -0
  3. 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": "1.2.15",
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": "^1.18.4",
45
- "@synerise/ds-scrollbar": "^1.5.1",
46
- "@synerise/ds-utils": "^1.10.1"
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": "d8c64070f58f14e3fb1bfbcbf00d1e3b8fd51eb8"
55
+ "gitHead": "033854a18f038079e9a16b0ff250f8401a2287c2"
55
56
  }