@synerise/ds-card-tabs 1.5.46 → 1.5.48

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 +172 -0
  3. package/package.json +13 -12
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.5.48](https://github.com/Synerise/synerise-design/compare/@synerise/ds-card-tabs@1.5.47...@synerise/ds-card-tabs@1.5.48) (2026-07-23)
7
+
8
+ **Note:** Version bump only for package @synerise/ds-card-tabs
9
+
10
+ ## [1.5.47](https://github.com/Synerise/synerise-design/compare/@synerise/ds-card-tabs@1.5.46...@synerise/ds-card-tabs@1.5.47) (2026-07-16)
11
+
12
+ **Note:** Version bump only for package @synerise/ds-card-tabs
13
+
6
14
  ## [1.5.46](https://github.com/Synerise/synerise-design/compare/@synerise/ds-card-tabs@1.5.45...@synerise/ds-card-tabs@1.5.46) (2026-07-09)
7
15
 
8
16
  **Note:** Version bump only for package @synerise/ds-card-tabs
package/CLAUDE.md ADDED
@@ -0,0 +1,172 @@
1
+ # CardTabs (`@synerise/ds-card-tabs`)
2
+
3
+ > Horizontally scrolling row of fixed-size tab cards with colour coding, drag-to-reorder, inline rename, and an "add tab" button — each card rendered as a generic `CardTab<IdType>`.
4
+
5
+ ## Package structure
6
+
7
+ ```
8
+ src/
9
+ CardTabs.tsx — main container component
10
+ CardTabs.types.ts — CardTabsProps, CardTabsPropsBase, CardTabsItem (deprecated)
11
+ CardTabs.styles.ts — CardTabsContainer, CardTabsAddButton
12
+ CardTab/
13
+ CardTab.tsx — individual tab card (generic IdType)
14
+ CardTab.types.ts — CardTabProps, prefixType enum, PrefixProps union, CardTabTexts
15
+ CardTab.styles.ts — all styled components for the card
16
+ CardTabActions/ — inline CRUD icon buttons (edit/duplicate/remove/preview)
17
+ CardTabDropdown/ — 3-dot dropdown menu for the same actions
18
+ CardTabPrefix/ — left-side prefix (tag, dot, icon, or drag handle)
19
+ utils.ts — getColor, getLighterColor helpers
20
+ index.ts — public exports
21
+ ```
22
+
23
+ ## Public exports
24
+
25
+ ### `CardTabs` (default)
26
+
27
+ Container component. Generic: `CardTabs<IdType extends string | number>`. Accepts all `HTMLDivElement` attributes in addition to its own props.
28
+
29
+ | Prop | Type | Default | Description |
30
+ |------|------|---------|-------------|
31
+ | `children` | `Array<ReactElement<CardTabProps<IdType>>>` | `[]` | Array of `CardTab` elements. |
32
+ | `onChangeOrder` | `(newOrder: CardTabProps<IdType>[]) => void` | `undefined` | Enables drag-to-reorder when provided (and >1 child). Called with the new props array. |
33
+ | `onAddTab` | `() => void` | `undefined` | When provided, renders a `Creator` button after the tabs. |
34
+ | `addTabLabel` | `string` | `undefined` | Label text shown inside the add-tab Creator button (hidden at narrow widths via CSS). |
35
+ | `maxTabsCount` | `number` | `undefined` | Disables the add-tab button when `children.length >= maxTabsCount`. |
36
+ | `className` | `string` | `undefined` | Extra class on the container div (always includes `ds-card-tabs`). |
37
+
38
+ ### `CardTab`
39
+
40
+ Individual tab card. Generic: `CardTab<IdType extends string | number>`. Not usually used standalone — rendered as children of `CardTabs`.
41
+
42
+ #### Required props
43
+
44
+ | Prop | Type | Description |
45
+ |------|------|-------------|
46
+ | `id` | `IdType` | Unique identifier passed back in all callbacks. |
47
+ | `name` | `string` | Tab label displayed with ellipsis overflow. |
48
+ | `prefix` | `prefixType` | Discriminated union key. Determines which prefix variant is rendered. |
49
+
50
+ #### Optional props
51
+
52
+ | Prop | Type | Default | Description |
53
+ |------|------|---------|-------------|
54
+ | `color` | `Color \| DefaultColor \| string` | `'yellow'` | Background colour of the active state. Auto-assigned by `CardTabs` from `defaultColorsOrder` if not set. |
55
+ | `active` | `boolean` | `undefined` | Shows the card in its active/selected state (coloured background). |
56
+ | `draggable` | `boolean` | `undefined` | Shows a drag handle. Also auto-set by `CardTabs` when >1 children and `onChangeOrder` is provided. |
57
+ | `disabled` | `boolean` | `undefined` | Sets `pointer-events: none` and reduces opacity. Does NOT disable child actions individually. |
58
+ | `invalid` | `boolean` | `undefined` | Red border. Combined with `active`, turns the card red-600. |
59
+ | `invalidName` | `boolean` | `undefined` | Same visual effect as `invalid` (both flags are OR'd). |
60
+ | `greyBackground` | `boolean` | `undefined` | White card with drop shadow instead of the default grey-050 bordered card. |
61
+ | `suffixIcon` | `ReactNode` | `undefined` | Renders a static icon on the right. **Suppresses** `CardTabActions`/`CardTabDropdown` entirely. |
62
+ | `renderSuffix` | `(props: CardTabSuffixProps) => ReactNode` | `undefined` | Custom suffix renderer. Takes precedence over action icons. |
63
+ | `actionsAsDropdown` | `boolean` | `undefined` | Renders action callbacks in a 3-dot `CardTabDropdown` instead of inline `CardTabActions` icons. |
64
+ | `texts` | `CardTabTexts` | `undefined` | Override i18n strings for tooltips and dropdown menu labels. |
65
+ | `itemData` | `unknown` | `undefined` | Arbitrary data forwarded to `CardTabContainer` styled component (available to `Sortable`). |
66
+ | `dragHandleProps` | `DragHandlePropType` | `undefined` | Drag handle props injected by `@synerise/ds-sortable` when draggable. |
67
+ | `onSelectTab` | `(id: IdType) => void` | `undefined` | Called on click (only when not in edit mode). |
68
+ | `onChangeName` | `(id: IdType, name: string) => void` | `undefined` | Called on inline edit blur. Also enables the rename action in CRUD/dropdown. |
69
+ | `onDuplicateTab` | `(id: IdType) => void` | `undefined` | Called when the duplicate action is triggered. |
70
+ | `onRemoveTab` | `(id: IdType) => void` | `undefined` | Called when the remove action is triggered. |
71
+ | `onPreviewTab` | `(id: IdType) => void` | `undefined` | Called when the preview action is triggered. |
72
+ | `keyId` | `string` | `undefined` | **Deprecated.** Used as React `key` when set. |
73
+ | `intl` | `IntlShape` | `undefined` | **Deprecated.** Previously used to override internal i18n. Now unused. |
74
+
75
+ #### `PrefixProps` discriminated union
76
+
77
+ `prefix` selects which additional props are available:
78
+
79
+ | `prefix` value | Additional props | Renders |
80
+ |----------------|------------------|---------|
81
+ | `prefixType.TAG` | `tag: string` | Coloured square badge with a text label |
82
+ | `prefixType.DOT` | `colorDot?: ReactNode` | Small coloured circle; defaults to `CardDot` |
83
+ | `prefixType.ICON` | `prefixIcon: ReactNode` | An icon element |
84
+ | `prefixType.HANDLE` | _(none)_ | Persistent drag handle (always visible, not only on hover) |
85
+
86
+ ### `prefixType` (enum)
87
+
88
+ ```ts
89
+ enum prefixType { TAG, ICON, DOT, HANDLE }
90
+ ```
91
+
92
+ ### `CardDot`
93
+
94
+ Exported styled component (`div`, 8×8px, 50% border-radius). Use as the `colorDot` value when you want to render the DS dot style at a custom colour.
95
+
96
+ ### `CardTabsStyles`
97
+
98
+ Object of styled-component exports for styled-extension use:
99
+ ```ts
100
+ { CardTabs: MainCardTabsStyles, CardTab: CardTabStyles }
101
+ ```
102
+
103
+ ### Types
104
+
105
+ | Export | Description |
106
+ |--------|-------------|
107
+ | `CardTabProps<IdType>` | Full props interface for `CardTab` |
108
+ | `CardTabsProps<IdType>` | Full props interface for `CardTabs` (includes HTMLDiv attributes) |
109
+ | `CardTabsPropsBase<IdType>` | Props without HTMLDiv attributes |
110
+ | `CardTabsItem` | **Deprecated.** `Partial<CardTabProps>` alias |
111
+
112
+ ## Usage patterns
113
+
114
+ ```tsx
115
+ import CardTabs, { CardTab, prefixType } from '@synerise/ds-card-tabs';
116
+
117
+ // Basic usage
118
+ <CardTabs onAddTab={handleAdd} addTabLabel="Add tab" maxTabsCount={6}>
119
+ <CardTab id={1} name="Variant A" prefix={prefixType.TAG} tag="A" active />
120
+ <CardTab id={2} name="Variant B" prefix={prefixType.TAG} tag="B" onSelectTab={handleSelect} />
121
+ </CardTabs>
122
+
123
+ // With reorder and CRUD actions
124
+ <CardTabs onChangeOrder={handleReorder}>
125
+ <CardTab
126
+ id={1}
127
+ name="Tab 1"
128
+ prefix={prefixType.DOT}
129
+ onSelectTab={handleSelect}
130
+ onChangeName={handleRename}
131
+ onDuplicateTab={handleDuplicate}
132
+ onRemoveTab={handleRemove}
133
+ />
134
+ </CardTabs>
135
+
136
+ // Actions in dropdown menu
137
+ <CardTab
138
+ id={1}
139
+ name="Tab 1"
140
+ prefix={prefixType.ICON}
141
+ prefixIcon={<FileM />}
142
+ actionsAsDropdown
143
+ onChangeName={handleRename}
144
+ onRemoveTab={handleRemove}
145
+ />
146
+ ```
147
+
148
+ ## Styling
149
+
150
+ - `CardTabs.styles.ts` — container is full-width flex row with `gap: 16px 12px`, wraps at 588px breakpoint; at ≤588px, the Creator add button collapses to icon-only (label hidden via CSS).
151
+ - `CardTab.styles.ts` — `CardTabContainer` is a styled div 168×48px, 3px border-radius. Background, border, and text colours all derive from the `color` prop and the `active`/`invalid`/`greyBackground` flags via inline theme palette lookups.
152
+ - Uses `@synerise/ds-core` theme palette tokens throughout; `getLighterColor` utility steps colour levels down by 100 on hover.
153
+
154
+ ## Key dependencies
155
+
156
+ - `@synerise/ds-sortable` — drag-to-reorder when `onChangeOrder` is provided (uses `Sortable` with `CardTab` as `ItemComponent` and injects `dragHandleProps`)
157
+ - `@synerise/ds-inline-edit` — inline name editing triggered by double-click or rename action
158
+ - `@synerise/ds-cruds` — inline CRUD icon buttons in `CardTabActions`
159
+ - `@synerise/ds-dropdown` `DropdownMenu` — 3-dot contextual menu in `CardTabDropdown`
160
+ - `react-intl` `useIntl` — default tooltip/label strings (requires `IntlProvider` in the tree)
161
+ - `@synerise/ds-core` `defaultColorsOrder` — auto-assigns colours to tabs by index
162
+
163
+ ## Implementation notes
164
+
165
+ - **`useIntl()` is called unconditionally** in `CardTab.tsx`. An `IntlProvider` must be present in the React tree or the component will throw. The `texts` prop can override individual strings but does not remove this requirement.
166
+ - **Colour auto-assignment** — `CardTabs` uses `cloneElement` to inject `color` from `defaultColorsOrder[i % length]` for any tab that doesn't have an explicit `color` prop.
167
+ - **Sortable mode is activated automatically** — when `onChangeOrder` is provided AND `childrenCount > 1`, `CardTabs` switches from `renderChildren` (cloneElement loop) to a `<Sortable>` component that manages drag state. Individual tab's `draggable` prop is also OR'd with parent's `onChangeOrder` presence.
168
+ - **Suffix rendering priority** — `actionsAsDropdown` > `renderSuffix` > `suffixIcon` (suppresses actions) > `CardTabActions` (if any action callback present).
169
+ - **Double-click to rename** — `CardTabLabel` has an `onDoubleClick` handler that triggers `handleEditName` (same as clicking the rename action). While `edited=true`, the prefix is hidden and the suffix is replaced by `InlineEdit`.
170
+ - **`disabled` is visual only** — applies `pointer-events: none` on the container div, but does not disable action icons individually; individual buttons inside the card are not disabled.
171
+ - **`invalid` + `active` combination** — when both are true, the background becomes `red-600` and hover/active states use `getLighterColor('red-600')` (i.e., `red-500`).
172
+ - **`index` prop does not exist** — the README incorrectly documents an `index` prop; no such prop is in `CardTabProps`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synerise/ds-card-tabs",
3
- "version": "1.5.46",
3
+ "version": "1.5.48",
4
4
  "description": "CardTabs 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,16 +42,16 @@
41
42
  ],
42
43
  "types": "dist/index.d.ts",
43
44
  "dependencies": {
44
- "@synerise/ds-button": "^1.5.33",
45
- "@synerise/ds-cruds": "^1.1.15",
46
- "@synerise/ds-dropdown": "^1.3.18",
47
- "@synerise/ds-icon": "^1.18.4",
48
- "@synerise/ds-inline-edit": "^1.1.46",
49
- "@synerise/ds-menu": "^1.4.30",
50
- "@synerise/ds-sortable": "^1.3.20",
51
- "@synerise/ds-tooltip": "^1.5.3",
52
- "@synerise/ds-typography": "^1.1.26",
53
- "@synerise/ds-utils": "^1.10.1"
45
+ "@synerise/ds-button": "^1.5.35",
46
+ "@synerise/ds-cruds": "^1.1.16",
47
+ "@synerise/ds-dropdown": "^1.3.20",
48
+ "@synerise/ds-icon": "^1.18.5",
49
+ "@synerise/ds-inline-edit": "^1.1.48",
50
+ "@synerise/ds-menu": "^1.4.32",
51
+ "@synerise/ds-sortable": "^1.3.21",
52
+ "@synerise/ds-tooltip": "^1.5.4",
53
+ "@synerise/ds-typography": "^1.1.27",
54
+ "@synerise/ds-utils": "^1.10.2"
54
55
  },
55
56
  "peerDependencies": {
56
57
  "@synerise/ds-core": "*",
@@ -60,5 +61,5 @@
60
61
  "styled-components": "^5.3.3",
61
62
  "vitest": "4"
62
63
  },
63
- "gitHead": "5c90008871be36fb52553a2ed3a633acf5db5b3b"
64
+ "gitHead": "d0a43cc43d8528a36f105aceea52ab470edb71d9"
64
65
  }