@synerise/ds-tray 1.1.44 → 1.1.46

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 +157 -0
  3. package/package.json +8 -7
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
+ ## [1.1.46](https://github.com/Synerise/synerise-design/compare/@synerise/ds-tray@1.1.45...@synerise/ds-tray@1.1.46) (2026-08-11)
7
+
8
+ **Note:** Version bump only for package @synerise/ds-tray
9
+
10
+ ## [1.1.45](https://github.com/Synerise/synerise-design/compare/@synerise/ds-tray@1.1.44...@synerise/ds-tray@1.1.45) (2026-07-23)
11
+
12
+ **Note:** Version bump only for package @synerise/ds-tray
13
+
6
14
  ## [1.1.44](https://github.com/Synerise/synerise-design/compare/@synerise/ds-tray@1.1.43...@synerise/ds-tray@1.1.44) (2026-07-16)
7
15
 
8
16
  **Note:** Version bump only for package @synerise/ds-tray
package/CLAUDE.md ADDED
@@ -0,0 +1,157 @@
1
+ # Tray (`@synerise/ds-tray`)
2
+
3
+ > A fixed-position slide-over panel (400 px wide, anchored top-right by default) whose content and visibility are controlled via React context — the `Tray` instance only renders when its `id` is opened by a `TrayProvider`.
4
+
5
+ ## Package structure
6
+
7
+ ```
8
+ src/
9
+ Tray.tsx — main component; reads state from context, renders null when closed
10
+ Tray.types.ts — TrayProps interface
11
+ Tray.styles.ts — all styled-components (wrapper, header, footer, scrollbar, title)
12
+ Tray.const.ts — fixed dimensions (WRAPPER_HEIGHT, HEADER_HEIGHT, FOOTER_HEIGHT)
13
+ index.ts — public exports
14
+ components/
15
+ TrayProvider.tsx — context provider + TrayData / TrayState types
16
+ contexts/
17
+ TrayContext.ts — TrayContext + TrayContextType
18
+ hooks/
19
+ useTray.ts — public hook: { open, close }
20
+ useTrayContext.ts — internal hook; throws if used outside TrayProvider
21
+ __specs__/
22
+ Tray.spec.tsx — Vitest tests (show, hide, multi-tray isolation)
23
+ ```
24
+
25
+ ## Public exports
26
+
27
+ ### `Tray` (default export)
28
+
29
+ Mounts a tray instance bound to an `id`. Returns `null` when the tray for that id is not open.
30
+
31
+ `TrayProps = WithHTMLAttributes<HTMLDivElement, { id: string }>`
32
+
33
+ | Prop | Type | Required | Description |
34
+ |------|------|----------|-------------|
35
+ | `id` | `string` | yes | Binds this instance to provider state |
36
+ | `className`, `style`, `data-*`, … | `HTMLDivElement` attrs | no | Forwarded to the outer wrapper — use these to override default `position: fixed; top: 0; right: 0` |
37
+
38
+ No `forwardRef`.
39
+
40
+ ### `TrayProps`
41
+
42
+ Type re-export for consumers that need to type the component's props.
43
+
44
+ ### `TrayProvider`
45
+
46
+ Context provider that must wrap any `Tray` instances and any code calling `useTray`.
47
+
48
+ | Prop | Type | Description |
49
+ |------|------|-------------|
50
+ | `children` | `ReactNode` | App tree |
51
+
52
+ ### `useTray`
53
+
54
+ Returns `{ open, close }`.
55
+
56
+ | Method | Signature | Description |
57
+ |--------|-----------|-------------|
58
+ | `open` | `(id: string, data: TrayData) => void` | Opens the tray with the given id, setting its content |
59
+ | `close` | `(id: string) => void` | Closes the tray with the given id |
60
+
61
+ `TrayData` shape (passed as the second argument to `open`):
62
+
63
+ | Field | Type | Required | Description |
64
+ |-------|------|----------|-------------|
65
+ | `content` | `ReactNode` | yes | Main scrollable body |
66
+ | `title` | `ReactNode` | yes | Rendered in the header as a level-4 `Title` |
67
+ | `headerRightSide` | `ReactNode` | no | Rendered to the right of the title (before the built-in close button) |
68
+ | `footer` | `ReactNode` | no | Rendered in the footer bar; bar is hidden when `footer` is `undefined` |
69
+ | `onClose` | `(id: string) => void` | no | Called after the built-in close button triggers `closeTray(id)` |
70
+
71
+ ## Usage patterns
72
+
73
+ ```tsx
74
+ import React from 'react';
75
+ import Tray, { TrayProvider, useTray } from '@synerise/ds-tray';
76
+
77
+ // 1. Wrap once with provider and mount Tray instances
78
+ const App = () => (
79
+ <TrayProvider>
80
+ <Tray id="details" />
81
+ <PageContent />
82
+ </TrayProvider>
83
+ );
84
+
85
+ // 2. Open/close from anywhere inside the provider
86
+ const PageContent = () => {
87
+ const { open, close } = useTray();
88
+
89
+ return (
90
+ <button
91
+ onClick={() =>
92
+ open('details', {
93
+ title: 'Details',
94
+ content: <div>Body content</div>,
95
+ footer: <button onClick={() => close('details')}>Close</button>,
96
+ onClose: (id) => console.log('closed', id),
97
+ })
98
+ }
99
+ >
100
+ Open details
101
+ </button>
102
+ );
103
+ };
104
+ ```
105
+
106
+ ```tsx
107
+ // Repositioning via className / style
108
+ import styled from 'styled-components';
109
+ import Tray from '@synerise/ds-tray';
110
+
111
+ const TopLeftTray = styled(Tray)`
112
+ top: 20px;
113
+ left: 50px;
114
+ `;
115
+
116
+ <TopLeftTray id="sidebar" />
117
+ ```
118
+
119
+ ## Context / Provider
120
+
121
+ `TrayContext` (in `contexts/TrayContext.ts`) is created with `undefined` as the default value. `TrayProvider` supplies `{ openTray, closeTray, getTrayState }`. `useTrayContext` throws with a descriptive error when called outside the provider. The `Tray` component calls `useTrayContext` internally — mounting `<Tray>` outside `<TrayProvider>` will throw at render time.
122
+
123
+ ## Styling
124
+
125
+ All styles are in `Tray.styles.ts`. Key layout:
126
+ - `TrayWrapper`: `position: fixed; top: 0; right: 0; width: 400px; max-height: 562px; z-index: zindex-tooltip`. Override via `className`/`style`.
127
+ - `TrayHeader`: fixed height `56px`, `padding-left: 18px`, flex row with space-between.
128
+ - `TrayContent`: flex `1 1 auto`, wraps a `@synerise/ds-scrollbar` in `absolute` mode.
129
+ - `TrayFooter`: fixed height `48px`, `grey-050` background, only rendered when `footer` is provided.
130
+
131
+ All colours and shadow come from `@synerise/ds-core` theme tokens (`grey-050`, `grey-100`, `grey-200`, `white`, `box-shadow-2`, `zindex-tooltip`).
132
+
133
+ ## Custom hooks
134
+
135
+ ### `useTray`
136
+
137
+ Public hook. Thin alias over `useTrayContext` — exposes `open` (`openTray`) and `close` (`closeTray`) with friendlier names. No side effects.
138
+
139
+ ### `useTrayContext` _(internal)_
140
+
141
+ Reads `TrayContext` and throws `'useTrayContext must be used within a TrayProvider'` if the context is `undefined`. Used internally by `Tray.tsx` and `useTray`.
142
+
143
+ ## Key dependencies
144
+
145
+ - `@synerise/ds-button` — ghost single-icon close button in the header
146
+ - `@synerise/ds-icon` + `CloseM` — close icon
147
+ - `@synerise/ds-scrollbar` — scrollable content area inside `TrayContent`
148
+ - `@synerise/ds-typography` — `Title` level 4 for the header title
149
+
150
+ ## Implementation notes
151
+
152
+ - **No open/close animation** — `Tray` returns `null` directly when `isOpen` is `false`. There is no CSS transition or mount/unmount animation.
153
+ - **`id` is `string` only** — despite some documentation saying `string | number`, the actual types (`TrayProps`, `TrayContext`, `TrayData.onClose`) all use `string`.
154
+ - **`TrayData` is not exported from `index.ts`** — consumers who need to type the data object must import it directly from the internal path `@synerise/ds-tray/dist/components/TrayProvider` or use `Parameters<ReturnType<typeof useTray>['open']>[1]`.
155
+ - **`content` and `title` are required** in `TrayData` — omitting them will cause a TypeScript error but no runtime guard.
156
+ - **Closing sets `isOpen: false`** but keeps the `data` object in state. Re-opening with the same id and new data replaces the previous data.
157
+ - **Uses Vitest** — `"test": "jest"` in package.json, uses `jest.config.js`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synerise/ds-tray",
3
- "version": "1.1.44",
3
+ "version": "1.1.46",
4
4
  "description": "Tray 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"
@@ -40,11 +41,11 @@
40
41
  ],
41
42
  "types": "dist/index.d.ts",
42
43
  "dependencies": {
43
- "@synerise/ds-button": "^1.5.34",
44
- "@synerise/ds-icon": "^1.18.4",
45
- "@synerise/ds-scrollbar": "^1.5.1",
46
- "@synerise/ds-typography": "^1.1.26",
47
- "@synerise/ds-utils": "^1.10.1"
44
+ "@synerise/ds-button": "^1.5.36",
45
+ "@synerise/ds-icon": "^1.18.5",
46
+ "@synerise/ds-scrollbar": "^1.5.2",
47
+ "@synerise/ds-typography": "^1.1.28",
48
+ "@synerise/ds-utils": "^1.10.2"
48
49
  },
49
50
  "peerDependencies": {
50
51
  "@synerise/ds-core": "*",
@@ -52,5 +53,5 @@
52
53
  "styled-components": "^5.3.3",
53
54
  "vitest": "4"
54
55
  },
55
- "gitHead": "a81ab6519d49a3dea9c0cfebcdc9104cbb4f4226"
56
+ "gitHead": "6df24ed12cd5f276d8eccde730591807982e3385"
56
57
  }