@synerise/ds-column-manager 1.3.4 → 1.3.6

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 +152 -0
  3. package/package.json +16 -15
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.3.6](https://github.com/Synerise/synerise-design/compare/@synerise/ds-column-manager@1.3.5...@synerise/ds-column-manager@1.3.6) (2026-07-23)
7
+
8
+ **Note:** Version bump only for package @synerise/ds-column-manager
9
+
10
+ ## [1.3.5](https://github.com/Synerise/synerise-design/compare/@synerise/ds-column-manager@1.3.4...@synerise/ds-column-manager@1.3.5) (2026-07-16)
11
+
12
+ **Note:** Version bump only for package @synerise/ds-column-manager
13
+
6
14
  ## [1.3.4](https://github.com/Synerise/synerise-design/compare/@synerise/ds-column-manager@1.3.3...@synerise/ds-column-manager@1.3.4) (2026-07-09)
7
15
 
8
16
  **Note:** Version bump only for package @synerise/ds-column-manager
package/CLAUDE.md ADDED
@@ -0,0 +1,152 @@
1
+ # ColumnManager (`@synerise/ds-column-manager`)
2
+
3
+ > A drawer-based panel for managing table column visibility and order — supports search filtering, drag-to-reorder, per-column type icons, read-only columns, and full i18n.
4
+
5
+ ## Package structure
6
+
7
+ ```
8
+ src/
9
+ ColumnManager.tsx — main component (Drawer + SearchBar + list + actions)
10
+ ColumnManager.types.ts — Column, ColumnIconType, ColumnManagerTexts, ColumnManagerProps
11
+ ColumnManager.styles.ts — styled Drawer, SearchBar, list wrapper
12
+ index.ts — public exports (default + all types via export *)
13
+ ColumnManagerActions/
14
+ ColumnManagerActions.tsx — footer with Cancel / Apply buttons
15
+ ColumnManagerActions.types.ts
16
+ ColumnManagerActions.styles.ts
17
+ ColumnManagerItem/
18
+ ColumnManagerItem.tsx — single row: drag handle + type icon + name + switch
19
+ ColumManagerItem.types.ts — (typo in filename: Colum not Column)
20
+ ColumnManagerItem.styles.ts
21
+ ColumnManagerItem.const.tsx — ICON_MAP, TYPES_WITH_ICONS, DEFAULT_ITEM_TYPE
22
+ ColumnManagerList/
23
+ ColumnManagerList.tsx — virtualised list (react-window) + sortable container
24
+ ColumnManagerList.types.ts
25
+ ColumnManager.style.ts — (inconsistent filename: no 's', no List prefix)
26
+ ColumnManagerSortableItem/
27
+ ColumnManagerSortableItem.tsx — useSortable wrapper that injects drag props into ColumnManagerItem
28
+ ColumnManagerSortableItem.types.ts
29
+ hooks/
30
+ useTranslations.ts — merges custom texts with react-intl defaults
31
+ utils/
32
+ matchesSearchQuery.ts — case-insensitive substring filter
33
+ __specs__/
34
+ ColumnManager.spec.tsx — Vitest tests
35
+ ```
36
+
37
+ ## Public exports
38
+
39
+ `index.ts` does `export * from './ColumnManager.types'` — all types are public.
40
+
41
+ ### `ColumnManager` (default export)
42
+
43
+ Generic component: `ColumnManager<ColumnType extends Column>`.
44
+
45
+ | Prop | Type | Default | Description |
46
+ |------|------|---------|-------------|
47
+ | `visible` | `boolean` | — (required) | Controls drawer open/closed state |
48
+ | `hide` | `() => void` | — (required) | Called on close button, mask click, or Cancel |
49
+ | `onApply` | `(columns: ColumnType[]) => void` | — (required) | Called when user clicks Apply; receives the full (reordered/toggled) column list |
50
+ | `columns` | `ColumnType[]` | — (required) | Current column configuration |
51
+ | `texts` | `Partial<ColumnManagerTexts>` | see defaults below | Override any subset of UI strings |
52
+ | `draggable` | `boolean` | `true` | Enable drag-to-reorder; when `false` drag handles are hidden |
53
+
54
+ ### `Column`
55
+
56
+ Shape every column object must satisfy:
57
+
58
+ | Field | Type | Required | Description |
59
+ |-------|------|----------|-------------|
60
+ | `id` | `string` | yes | Unique identifier |
61
+ | `name` | `string` | yes | Display name (also searched) |
62
+ | `visible` | `boolean` | yes | Whether the column is shown in the table |
63
+ | `readOnly` | `boolean` | no | Disables the visibility toggle switch |
64
+ | `type` | `ColumnIconType` | no | Renders a type icon; see `ICON_MAP` for supported values |
65
+
66
+ ### `ColumnIconType`
67
+
68
+ `'text' | 'number' | 'date' | 'boolean' | 'list' | string`
69
+
70
+ Only the five named values have icons (`VarTypeStringM`, `VarTypeNumberM`, `VarTypeDateM`, `VarTypeBooleanM`, `VarTypeListM`). Any other string falls back to `DEFAULT_ITEM_TYPE = 'text'` for the icon.
71
+
72
+ ### `ColumnManagerTexts`
73
+
74
+ All fields are `ReactNode` except `searchPlaceholder` which is `string`. Defaults (from `useTranslations`):
75
+
76
+ | Key | Default |
77
+ |-----|---------|
78
+ | `title` | `'Manage columns'` |
79
+ | `searchPlaceholder` | `'Search columns'` |
80
+ | `searchClearTooltip` | `'Clear'` |
81
+ | `noResults` | `'No results'` |
82
+ | `cancel` | `'Cancel'` |
83
+ | `apply` | `'Apply'` |
84
+ | `clear` | `'Clear'` |
85
+ | `switchOn` | `'Hide column'` |
86
+ | `switchOff` | `'Show column'` |
87
+
88
+ ### `ColumnManagerProps<ColumnType extends Column>`
89
+
90
+ Type export for consumers that need to type the props.
91
+
92
+ ## Usage patterns
93
+
94
+ ```tsx
95
+ import ColumnManager, { type Column } from '@synerise/ds-column-manager';
96
+ import { useState } from 'react';
97
+
98
+ type MyColumn = Column & { key: string };
99
+
100
+ const [visible, setVisible] = useState(false);
101
+ const [columns, setColumns] = useState<MyColumn[]>([
102
+ { id: 'name', key: 'name', name: 'Name', visible: true },
103
+ { id: 'status', key: 'status', name: 'Status', visible: false, readOnly: true },
104
+ { id: 'date', key: 'date', name: 'Date', visible: true, type: 'date' },
105
+ ]);
106
+
107
+ <ColumnManager
108
+ visible={visible}
109
+ hide={() => setVisible(false)}
110
+ columns={columns}
111
+ onApply={(updated) => {
112
+ setColumns(updated);
113
+ setVisible(false);
114
+ }}
115
+ draggable
116
+ texts={{ title: 'Manage columns' }}
117
+ />
118
+ ```
119
+
120
+ ## Styling
121
+
122
+ - `ColumnManager.styles.ts` — styled `@synerise/ds-drawer` wrapper (fixed width `338px`), styled `@synerise/ds-search-bar` (height `52px`), flex list wrapper.
123
+ - `ColumnManagerItem.styles.ts` — hover reveals drag handle (opacity transition), adds `grey-050` background and a `blue-600` left border on hover.
124
+ - `ColumnManager.style.ts` (list) — `FixedSizeList` gets `blue-050` background and `blue-600` inset box-shadow; `user-select: none` when `isDragging`.
125
+ - All colours via `theme.palette` tokens; no hardcoded hex values.
126
+
127
+ ## Custom hooks
128
+
129
+ ### `useTranslations`
130
+
131
+ Calls `useIntl()` to produce fully resolved text defaults, then shallow-merges `texts` override on top. Returns a complete `ColumnManagerTexts` object. Requires a `react-intl` `IntlProvider` somewhere in the tree (supplied by `@synerise/ds-core`'s `DSProvider`).
132
+
133
+ ## Key dependencies
134
+
135
+ - `@synerise/ds-drawer` — outer panel shell (header, content, `DrawerHeader`, `DrawerHeaderBar`, `DrawerContent`)
136
+ - `@synerise/ds-search-bar` — search input in the header area
137
+ - `@synerise/ds-sortable` — `SortableContainer` + `useSortable` for drag-and-drop reordering
138
+ - `react-window` (`FixedSizeList`) — virtualisation for large column lists
139
+ - `@synerise/ds-scrollbar` — scrollbar with `withDnd` prop (required for correct drag behaviour inside virtualised list)
140
+ - `@synerise/ds-result` — empty state rendered when search yields no columns
141
+ - `@synerise/ds-switch` — `RawSwitch` for column visibility toggle
142
+ - `react-intl` — i18n (via `useTranslations`)
143
+
144
+ ## Implementation notes
145
+
146
+ - **State is local until Apply** — toggling visibility or reordering columns updates internal `currentColumns` state only. The parent's `columns` prop is not mutated until `onApply` fires. Clicking Cancel (or closing) resets `currentColumns` back to the incoming `columns` prop.
147
+ - **`columns` prop sync** — two `useEffect`s keep internal state in sync: one when `columns` changes, one when `visible` becomes `false` (resets to latest `columns`). The second prevents stale state after Cancel.
148
+ - **Search only filters display** — `filteredColumns` (passed to the list) is derived from `currentColumns` via `useMemo`. Reordering while a search is active operates on IDs only and re-sorts the full `currentColumns` array, so hidden items are not lost.
149
+ - **Drag + virtualisation** — `ColumnManagerList` passes `Scrollbar` as the `outerElementType` of `FixedSizeList` with `withDnd` so the drag library can interact with the scroll container.
150
+ - **Filename typo** — `ColumnManagerItem/ColumManagerItem.types.ts` is missing an `n` (Col**um** vs Col**umn**). Do not rename without updating all imports.
151
+ - **Style file inconsistency** — the list style file is `ColumnManagerList/ColumnManager.style.ts` (no `List` suffix, no trailing `s`). All other packages use `<ComponentName>.styles.ts`.
152
+ - **Test runner is Vitest** — `__specs__/ColumnManager.spec.tsx` uses `vi.mock` and `import { describe, it, expect } from 'vitest'`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synerise/ds-column-manager",
3
- "version": "1.3.4",
3
+ "version": "1.3.6",
4
4
  "description": "ColumnManager 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"
@@ -38,22 +39,22 @@
38
39
  "sideEffects": false,
39
40
  "types": "dist/index.d.ts",
40
41
  "dependencies": {
41
- "@synerise/ds-button": "^1.5.33",
42
- "@synerise/ds-drawer": "^1.1.5",
43
- "@synerise/ds-icon": "^1.18.4",
44
- "@synerise/ds-menu": "^1.4.30",
45
- "@synerise/ds-result": "^1.0.64",
46
- "@synerise/ds-scrollbar": "^1.5.1",
47
- "@synerise/ds-search-bar": "^1.4.34",
48
- "@synerise/ds-sortable": "^1.3.20",
49
- "@synerise/ds-switch": "^1.2.33",
50
- "@synerise/ds-tooltip": "^1.5.3",
51
- "@synerise/ds-typography": "^1.1.26",
52
- "@synerise/ds-utils": "^1.10.1",
42
+ "@synerise/ds-button": "^1.5.35",
43
+ "@synerise/ds-drawer": "^1.1.6",
44
+ "@synerise/ds-icon": "^1.18.5",
45
+ "@synerise/ds-menu": "^1.4.32",
46
+ "@synerise/ds-result": "^1.0.66",
47
+ "@synerise/ds-scrollbar": "^1.5.2",
48
+ "@synerise/ds-search-bar": "^1.4.35",
49
+ "@synerise/ds-sortable": "^1.3.21",
50
+ "@synerise/ds-switch": "^1.2.34",
51
+ "@synerise/ds-tooltip": "^1.5.4",
52
+ "@synerise/ds-typography": "^1.1.27",
53
+ "@synerise/ds-utils": "^1.10.2",
53
54
  "react-window": "1.8.11"
54
55
  },
55
56
  "devDependencies": {
56
- "@synerise/ds-input": "^1.7.12",
57
+ "@synerise/ds-input": "^1.7.13",
57
58
  "vitest": "4"
58
59
  },
59
60
  "peerDependencies": {
@@ -63,5 +64,5 @@
63
64
  "react-intl": ">=3.12.0 <= 6.8",
64
65
  "styled-components": "^5.3.3"
65
66
  },
66
- "gitHead": "5c90008871be36fb52553a2ed3a633acf5db5b3b"
67
+ "gitHead": "d0a43cc43d8528a36f105aceea52ab470edb71d9"
67
68
  }