@synerise/ds-manageable-list 1.8.10 → 1.8.12
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 +182 -0
- package/package.json +20 -19
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.8.12](https://github.com/Synerise/synerise-design/compare/@synerise/ds-manageable-list@1.8.11...@synerise/ds-manageable-list@1.8.12) (2026-07-24)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @synerise/ds-manageable-list
|
|
9
|
+
|
|
10
|
+
## [1.8.11](https://github.com/Synerise/synerise-design/compare/@synerise/ds-manageable-list@1.8.10...@synerise/ds-manageable-list@1.8.11) (2026-07-23)
|
|
11
|
+
|
|
12
|
+
**Note:** Version bump only for package @synerise/ds-manageable-list
|
|
13
|
+
|
|
6
14
|
## [1.8.10](https://github.com/Synerise/synerise-design/compare/@synerise/ds-manageable-list@1.8.9...@synerise/ds-manageable-list@1.8.10) (2026-07-16)
|
|
7
15
|
|
|
8
16
|
**Note:** Version bump only for package @synerise/ds-manageable-list
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# ManageableList (`@synerise/ds-manageable-list`)
|
|
2
|
+
|
|
3
|
+
> A feature-rich list management component supporting 5 item types (default, blank, content, content-large, filter), drag-and-drop reordering, expandable content, inline rename/delete/duplicate, show-more pagination, and full i18n.
|
|
4
|
+
|
|
5
|
+
## Package structure
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
src/
|
|
9
|
+
ManageableList.tsx — main component; renders item list + add button + drag wrapper
|
|
10
|
+
ManageableList.types.ts — ManageableListProps, ItemProps, Texts, ListType, ExpansionBehaviour, AdditionalAction
|
|
11
|
+
ManageableList.styles.ts — ManageableListContainer, ShowMoreButton
|
|
12
|
+
index.ts — public exports
|
|
13
|
+
Item/
|
|
14
|
+
Item.tsx — router: delegates to SimpleItem / ContentItem / FilterItem / BlankItem
|
|
15
|
+
DraggableItem.tsx — wraps Item in @synerise/ds-sortable DraggableItem
|
|
16
|
+
SimpleItem/ — DEFAULT list type: name + optional icon/tag + actions
|
|
17
|
+
ContentItem/ — CONTENT / CONTENT_LARGE type: expandable header + body
|
|
18
|
+
ContentItem/ContentItemHeader.tsx — header with expand toggle, drag handle, meta, actions
|
|
19
|
+
FilterItem/ — FILTER type: checkbox select + dropdown menu
|
|
20
|
+
BlankItem/ — BLANK type: custom render function; full layout control
|
|
21
|
+
ItemName/ — name display with search-query highlighting
|
|
22
|
+
ItemNameLarge/ — name + unique key + tags (content-large only)
|
|
23
|
+
ItemMeta/ — creation date + user avatar
|
|
24
|
+
ItemActions/ — edit / duplicate / delete icon buttons with tooltips
|
|
25
|
+
AddItem/ — add button for CONTENT / CONTENT_LARGE types (Creator button)
|
|
26
|
+
AddBlankItem/ — add button for BLANK type (divider + button)
|
|
27
|
+
AddItemWithName/ — inline name-input add for DEFAULT type
|
|
28
|
+
hooks/
|
|
29
|
+
useTexts.tsx — i18n defaults via react-intl
|
|
30
|
+
__specs__/
|
|
31
|
+
ManageableList.spec.tsx — default list type tests
|
|
32
|
+
ManageableListWithContentItems.spec.tsx
|
|
33
|
+
ManageableListWithFilterItems.spec.tsx
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Public exports
|
|
37
|
+
|
|
38
|
+
### `ManageableList` (default export)
|
|
39
|
+
|
|
40
|
+
Generic component: `ManageableList<T extends object>`. Has static properties:
|
|
41
|
+
- `ManageableList.ManageableListContainer` — styled wrapper (for external overrides)
|
|
42
|
+
- `ManageableList.ShowMoreButton` — styled button (for external overrides)
|
|
43
|
+
|
|
44
|
+
**Mutually exclusive props:** pass either `visibleItemsLimit` OR the deprecated `maxToShowItems` — not both (enforced via `ExactlyOne` utility type).
|
|
45
|
+
|
|
46
|
+
| Prop | Type | Default | Description |
|
|
47
|
+
|------|------|---------|-------------|
|
|
48
|
+
| `items` | `ItemProps<T>[]` | — (required) | Items to render |
|
|
49
|
+
| `loading` | `boolean` | — (required) | Shows `@synerise/ds-list` loading skeleton when true |
|
|
50
|
+
| `type` | `ManageableListType` | `'default'` | One of `'default' \| 'blank' \| 'content' \| 'content-large' \| 'filter'` |
|
|
51
|
+
| `visibleItemsLimit` | `number` | — | Show N items, rest behind a toggle button |
|
|
52
|
+
| `maxToShowItems` | `number` | — | **`@deprecated`** — use `visibleItemsLimit` |
|
|
53
|
+
| `onItemAdd` | `(params?: { name: string }) => void` | — | Called when user adds an item; renders the add button when provided |
|
|
54
|
+
| `onItemRemove` | `({ id: ReactText }) => void` | — | Enables delete action |
|
|
55
|
+
| `onItemEdit` | `({ id: ReactText; name: string }) => void` | — | Enables inline rename |
|
|
56
|
+
| `onItemSelect` | `({ id: ReactText }) => void` | — | Called on item click |
|
|
57
|
+
| `onItemDuplicate` | `({ id: ReactText }) => void` | — | Enables duplicate action |
|
|
58
|
+
| `onChangeOrder` | `(newOrder: ItemProps<T>[]) => void` | — | Enables drag-and-drop reorder (and button-based reorder) |
|
|
59
|
+
| `changeOrderByButtons` | `boolean` | `false` | Adds move-to-top / move-to-bottom buttons instead of drag handles |
|
|
60
|
+
| `changeOrderDisabled` | `boolean` | `false` | Hides all reorder affordances |
|
|
61
|
+
| `addButtonDisabled` | `boolean` | `false` | Disables the add button |
|
|
62
|
+
| `greyBackground` | `boolean` | `false` | Grey background on list and items |
|
|
63
|
+
| `selectedItemId` | `string` | — | Highlights the matching item |
|
|
64
|
+
| `searchQuery` | `string` | — | Highlights matching text inside item names |
|
|
65
|
+
| `expanderDisabled` | `boolean` | — | Hides the expand toggle on content items |
|
|
66
|
+
| `onExpand` | `(id: ReactText, isExpanded: boolean) => void` | — | Called when a content item is expanded/collapsed |
|
|
67
|
+
| `expansionBehaviour` | `string` | — | `'default' \| 'accordion' \| 'custom'` (see `ExpansionBehaviour` enum) |
|
|
68
|
+
| `expandedIds` | `ReactText[]` | — | **`@deprecated`** — use `item.expanded` on each item instead |
|
|
69
|
+
| `texts` | `Partial<Texts>` | see defaults | i18n overrides |
|
|
70
|
+
| `additionalActions` | `AdditionalAction[]` | — | Extra icon actions appended to each item's action row |
|
|
71
|
+
| `placeholder` | `string` | — | Input placeholder for the DEFAULT-type add-item field |
|
|
72
|
+
| `style` | `CSSProperties` | — | Inline styles on the root container |
|
|
73
|
+
| `renderCustomToggleButton` | `(props: { onClick, total, limit, allItemsVisible }) => ReactNode` | — | Replaces the default show-more/less button |
|
|
74
|
+
| `renderItem` | `(item: ItemProps) => ReactNode` | `() => <></>` | Custom item renderer (used by BLANK type) |
|
|
75
|
+
| `className` | `string` | — | Appended after `ds-manageable-list` |
|
|
76
|
+
|
|
77
|
+
### `ItemProps<T extends object>`
|
|
78
|
+
|
|
79
|
+
Extends `T` with:
|
|
80
|
+
|
|
81
|
+
| Field | Type | Description |
|
|
82
|
+
|-------|------|-------------|
|
|
83
|
+
| `id` | `ReactText` | Required unique identifier |
|
|
84
|
+
| `name` | `string` | Required display name |
|
|
85
|
+
| `canUpdate` | `boolean` | Shows rename action |
|
|
86
|
+
| `canDelete` | `boolean` | Shows delete action |
|
|
87
|
+
| `canDuplicate` | `boolean` | Shows duplicate action |
|
|
88
|
+
| `icon` | `ReactNode` | Item icon (DEFAULT type) |
|
|
89
|
+
| `tag` | `ReactElement` | Tag prefix (CONTENT types) |
|
|
90
|
+
| `tags` | `ReactNode` | Tag list in header (CONTENT_LARGE only) |
|
|
91
|
+
| `headerPrefix` | `ReactNode` | Rendered before the item name in the header (CONTENT_LARGE only) |
|
|
92
|
+
| `content` | `ReactNode` | Expandable body (CONTENT types) |
|
|
93
|
+
| `uniqueKey` | `ReactNode` | Unique key display (CONTENT_LARGE only) |
|
|
94
|
+
| `user` | `{ avatar_url?, firstname?, lastname?, email? }` | Shown in `ItemMeta` (CONTENT types) |
|
|
95
|
+
| `created` | `string` | Creation date shown in `ItemMeta` (CONTENT types) |
|
|
96
|
+
| `dropdown` | `ReactElement` | Custom dropdown menu for FILTER type |
|
|
97
|
+
| `expanded` | `boolean` | Initial expanded state (replaces deprecated `expandedIds`) |
|
|
98
|
+
| `selected` | `boolean` | Checked state for FILTER type |
|
|
99
|
+
| `disabled` | `boolean` | Disables the item |
|
|
100
|
+
| `changeOrderDisabled` | `boolean` | Disables drag for this specific item |
|
|
101
|
+
| `disableExpanding` | `boolean` | Always shows full content without expand toggle |
|
|
102
|
+
| `disableHeaderClick` | `boolean` | Prevents header click from toggling expand |
|
|
103
|
+
| `headerSuffix` | `ReactNode` | Rendered at the start of the item suffix area |
|
|
104
|
+
| `hideHeaderSuffixOnHover` | `boolean` | Hides `headerSuffix` on hover |
|
|
105
|
+
| `additionalSuffix` | `ReactNode` | Rendered at the end of the item suffix area |
|
|
106
|
+
| `nameWrapperClassNames` | `string[]` | Extra classes on the name wrapper |
|
|
107
|
+
| `description` | `string` | Sub-text (available in some item types) |
|
|
108
|
+
|
|
109
|
+
### `AdditionalAction`
|
|
110
|
+
|
|
111
|
+
`{ icon: ReactNode; tooltip: string; onClick: (item: ItemProps) => void; color?: string }`
|
|
112
|
+
|
|
113
|
+
### `ManageableListProps`, `ManageableListItemProps`, `AddItemProps`, `StyledContentItem`
|
|
114
|
+
|
|
115
|
+
Type re-exports.
|
|
116
|
+
|
|
117
|
+
### `ContentItem`, `FilterItem`, `SimpleItem`, `AddItem`
|
|
118
|
+
|
|
119
|
+
Sub-component re-exports for consumers who need to render items standalone.
|
|
120
|
+
|
|
121
|
+
### `ListType` (enum)
|
|
122
|
+
|
|
123
|
+
`DEFAULT = 'default'` | `BLANK = 'blank'` | `CONTENT = 'content'` | `CONTENT_LARGE = 'content-large'` | `FILTER = 'filter'`
|
|
124
|
+
|
|
125
|
+
### `ExpansionBehaviour` (enum)
|
|
126
|
+
|
|
127
|
+
`DEFAULT = 'default'` | `ACCORDION = 'accordion'` | `CUSTOM = 'custom'`
|
|
128
|
+
|
|
129
|
+
## Usage patterns
|
|
130
|
+
|
|
131
|
+
```tsx
|
|
132
|
+
import ManageableList from '@synerise/ds-manageable-list';
|
|
133
|
+
import { ListType } from '@synerise/ds-manageable-list';
|
|
134
|
+
|
|
135
|
+
// Default list (with inline add)
|
|
136
|
+
<ManageableList
|
|
137
|
+
type={ListType.DEFAULT}
|
|
138
|
+
items={items}
|
|
139
|
+
loading={false}
|
|
140
|
+
visibleItemsLimit={5}
|
|
141
|
+
onItemAdd={({ name }) => addItem(name)}
|
|
142
|
+
onItemRemove={({ id }) => removeItem(id)}
|
|
143
|
+
onItemEdit={({ id, name }) => editItem(id, name)}
|
|
144
|
+
onItemSelect={({ id }) => selectItem(id)}
|
|
145
|
+
onChangeOrder={(newOrder) => setItems(newOrder)}
|
|
146
|
+
selectedItemId={activeId}
|
|
147
|
+
/>
|
|
148
|
+
|
|
149
|
+
// Content list (expandable)
|
|
150
|
+
<ManageableList
|
|
151
|
+
type={ListType.CONTENT}
|
|
152
|
+
items={contentItems}
|
|
153
|
+
loading={false}
|
|
154
|
+
onExpand={(id, isExpanded) => handleExpand(id, isExpanded)}
|
|
155
|
+
/>
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Custom hooks
|
|
159
|
+
|
|
160
|
+
### `useTexts`
|
|
161
|
+
|
|
162
|
+
Merges `react-intl` `FormattedMessage` defaults with `texts` prop overrides. Returns a complete `Texts` object. **Note:** the `useMemo` dependency array is `[defaultTexts]` — if the `texts` object is recreated on every render, texts will be rememoized each time.
|
|
163
|
+
|
|
164
|
+
## Styling
|
|
165
|
+
|
|
166
|
+
`ManageableList.styles.ts` is minimal — only the root container and show-more button. All per-item styles live in `Item.styles.ts` and each item type's own styles file. Uses `@synerise/ds-list` for the loading skeleton.
|
|
167
|
+
|
|
168
|
+
## Key dependencies
|
|
169
|
+
|
|
170
|
+
- `@synerise/ds-sortable` — `SortableContainer` + `DragOverlay` for drag-and-drop reorder
|
|
171
|
+
- `@synerise/ds-list` — loading skeleton and base list wrapper when drag is disabled
|
|
172
|
+
- `react-intl` — i18n for all text labels; requires `IntlProvider`
|
|
173
|
+
|
|
174
|
+
## Implementation notes
|
|
175
|
+
|
|
176
|
+
- **Add button placement differs by type** — `DEFAULT` renders `AddItemWithName` at the **top**; `CONTENT`/`CONTENT_LARGE` render `AddItem` at the **bottom**; `BLANK` renders `AddBlankItem` at the **bottom**.
|
|
177
|
+
- **Drag-and-drop is conditional** — `SortableContainer` is used only when `onChangeOrder` is provided and `changeOrderDisabled` is false; otherwise items render via `@synerise/ds-list`.
|
|
178
|
+
- **`expandedIds` vs `item.expanded`** — `expandedIds` prop is deprecated; prefer setting `expanded: true` on individual `ItemProps`. Both are supported; `expandedIds` takes priority when defined.
|
|
179
|
+
- **`ExactlyOne` constraint** — passing both `maxToShowItems` and `visibleItemsLimit` causes a TypeScript error. Only one should be used.
|
|
180
|
+
- **`Item.types.ts` re-exports `Props`** — `Props` is re-exported as `@deprecated` alias for `ManageableListItemProps`; do not use.
|
|
181
|
+
- **README inaccuracies** — README documents `listType` (should be `type`), `styles` (should be `style`), `activateItem` text key (should be `activateItemTitle`); many `ItemProps` fields and `visibleItemsLimit` are missing; `maxToShowItems` is documented without the deprecation warning.
|
|
182
|
+
- **Uses Vitest**.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@synerise/ds-manageable-list",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.12",
|
|
4
4
|
"description": "ManageableList 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,23 +42,23 @@
|
|
|
41
42
|
],
|
|
42
43
|
"types": "dist/index.d.ts",
|
|
43
44
|
"dependencies": {
|
|
44
|
-
"@synerise/ds-avatar": "^1.3.
|
|
45
|
-
"@synerise/ds-button": "^1.5.
|
|
46
|
-
"@synerise/ds-divider": "^1.3.
|
|
47
|
-
"@synerise/ds-dropdown": "^1.3.
|
|
48
|
-
"@synerise/ds-icon": "^1.18.
|
|
49
|
-
"@synerise/ds-inline-edit": "^1.1.
|
|
50
|
-
"@synerise/ds-input": "^1.7.
|
|
51
|
-
"@synerise/ds-list": "^1.1.
|
|
52
|
-
"@synerise/ds-menu": "^1.4.
|
|
53
|
-
"@synerise/ds-modal": "^1.6.
|
|
54
|
-
"@synerise/ds-popconfirm": "^1.4.
|
|
55
|
-
"@synerise/ds-result": "^1.0.
|
|
56
|
-
"@synerise/ds-sortable": "^1.3.
|
|
57
|
-
"@synerise/ds-tag": "^1.4.
|
|
58
|
-
"@synerise/ds-tooltip": "^1.5.
|
|
59
|
-
"@synerise/ds-typography": "^1.1.
|
|
60
|
-
"@synerise/ds-utils": "^1.10.
|
|
45
|
+
"@synerise/ds-avatar": "^1.3.19",
|
|
46
|
+
"@synerise/ds-button": "^1.5.35",
|
|
47
|
+
"@synerise/ds-divider": "^1.3.16",
|
|
48
|
+
"@synerise/ds-dropdown": "^1.3.21",
|
|
49
|
+
"@synerise/ds-icon": "^1.18.5",
|
|
50
|
+
"@synerise/ds-inline-edit": "^1.1.49",
|
|
51
|
+
"@synerise/ds-input": "^1.7.14",
|
|
52
|
+
"@synerise/ds-list": "^1.1.43",
|
|
53
|
+
"@synerise/ds-menu": "^1.4.32",
|
|
54
|
+
"@synerise/ds-modal": "^1.6.7",
|
|
55
|
+
"@synerise/ds-popconfirm": "^1.4.2",
|
|
56
|
+
"@synerise/ds-result": "^1.0.66",
|
|
57
|
+
"@synerise/ds-sortable": "^1.3.21",
|
|
58
|
+
"@synerise/ds-tag": "^1.4.32",
|
|
59
|
+
"@synerise/ds-tooltip": "^1.5.4",
|
|
60
|
+
"@synerise/ds-typography": "^1.1.27",
|
|
61
|
+
"@synerise/ds-utils": "^1.10.2",
|
|
61
62
|
"moment": "^2.30.1",
|
|
62
63
|
"react-animate-height": "^2.0.23"
|
|
63
64
|
},
|
|
@@ -69,5 +70,5 @@
|
|
|
69
70
|
"styled-components": "^5.3.3",
|
|
70
71
|
"vitest": "4"
|
|
71
72
|
},
|
|
72
|
-
"gitHead": "
|
|
73
|
+
"gitHead": "018414e0d7ffd102a07f8aa35fa2e2d3d4ed19e2"
|
|
73
74
|
}
|