@synerise/ds-color-picker 1.3.49 → 1.3.51
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 +116 -0
- package/package.json +12 -11
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.51](https://github.com/Synerise/synerise-design/compare/@synerise/ds-color-picker@1.3.50...@synerise/ds-color-picker@1.3.51) (2026-07-23)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @synerise/ds-color-picker
|
|
9
|
+
|
|
10
|
+
## [1.3.50](https://github.com/Synerise/synerise-design/compare/@synerise/ds-color-picker@1.3.49...@synerise/ds-color-picker@1.3.50) (2026-07-16)
|
|
11
|
+
|
|
12
|
+
**Note:** Version bump only for package @synerise/ds-color-picker
|
|
13
|
+
|
|
6
14
|
## [1.3.49](https://github.com/Synerise/synerise-design/compare/@synerise/ds-color-picker@1.3.48...@synerise/ds-color-picker@1.3.49) (2026-07-09)
|
|
7
15
|
|
|
8
16
|
**Note:** Version bump only for package @synerise/ds-color-picker
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# ColorPicker (`@synerise/ds-color-picker`)
|
|
2
|
+
|
|
3
|
+
> An input-triggered dropdown color picker built on `react-colorful`, with hex input, copy-to-clipboard, and optional saved color swatches.
|
|
4
|
+
|
|
5
|
+
## Package structure
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
src/
|
|
9
|
+
ColorPicker.tsx — main component; all state, dropdown, and trigger logic
|
|
10
|
+
ColorPicker.types.ts — ColorPickerProps, ColorPickerSize enum, ColorHookType
|
|
11
|
+
ColorPicker.styles.ts — all styled-components + createGlobalStyle for maxWidth
|
|
12
|
+
utils.ts — color validation and conversion utilities
|
|
13
|
+
index.tsx — default export + ColorPickerProps type export
|
|
14
|
+
__specs__/
|
|
15
|
+
ColorPicker.spec.tsx — component + utility unit tests (Vitest)
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Public exports
|
|
19
|
+
|
|
20
|
+
### `ColorPicker` (default)
|
|
21
|
+
|
|
22
|
+
| Prop | Type | Default | Description |
|
|
23
|
+
|------|------|---------|-------------|
|
|
24
|
+
| `value` | `string` | `undefined` | Controlled color value. Accepts hex (`#fff`, `#ffffff`) or CSS named colors (`red`). |
|
|
25
|
+
| `onChange` | `(color: string) => void` | `undefined` | Called with a normalised 6-digit hex string on every valid change. |
|
|
26
|
+
| `colors` | `string[]` | `[]` | Initial saved color swatches. Local copy is maintained in component state. |
|
|
27
|
+
| `onSaveColors` | `(colors: string[]) => void` | `undefined` | Called when the user saves a new swatch. Receives the full updated array. |
|
|
28
|
+
| `maxSavedColors` | `number` | `9` | Maximum number of swatches. Older entries are dropped from the front. |
|
|
29
|
+
| `isShownSavedColors` | `boolean` | `undefined` | Shows the divider + swatch section below the hex input. |
|
|
30
|
+
| `infix` | `(colorHooks?: Partial<ColorHookType>) => JSX.Element` | `() => <></>` | Render slot between the save button and the swatches (e.g. color-format converter). Receives `{ color, setColor }`. |
|
|
31
|
+
| `size` | `'S' \| 'M' \| 'L'` | `'M'` | Height of the `react-colorful` picker: S=136px, M=168px, L=200px. |
|
|
32
|
+
| `maxWidth` | `number` | `undefined` | When `>= 228`, injects a `createGlobalStyle` to constrain `.color-picker-overlay` to this width. |
|
|
33
|
+
| `placeholder` | `string` | `undefined` | Input placeholder text. |
|
|
34
|
+
| `tooltip` | `{ copy: string; copied: string }` | `undefined` | Tooltips for the copy-to-clipboard icon inside the dropdown hex input. |
|
|
35
|
+
| `error` | `boolean` | `undefined` | Error state on the trigger input. |
|
|
36
|
+
| `errorText` | `string` | `undefined` | Error message below the trigger (from `FormFieldCommonProps`). |
|
|
37
|
+
| `description` | `string` | `undefined` | Description text below the trigger (from `FormFieldCommonProps`). |
|
|
38
|
+
| `disabled` | `boolean` | `undefined` | Disables the input. **Dropdown is not rendered at all** when `true`. |
|
|
39
|
+
| `readOnly` | `boolean` | `undefined` | Makes the input read-only. **Dropdown is not rendered at all** when `true`. |
|
|
40
|
+
| `inputProps` | `Omit<InputProps, 'value'\|'onChange'\|'defaultValue'\|'placeholder'\|'disabled'\|'readOnly'\|'prefix'\|keyof FormFieldCommonProps>` | `undefined` | Extra props forwarded to the trigger `Input`. |
|
|
41
|
+
| `getPopupContainer` | `(triggerNode: HTMLElement) => HTMLElement` | `defaultGetPopupContainer` from `@synerise/ds-utils` | Portal target for the dropdown. |
|
|
42
|
+
|
|
43
|
+
### `ColorPickerProps`
|
|
44
|
+
|
|
45
|
+
Type exported from `index.tsx`.
|
|
46
|
+
|
|
47
|
+
### `ColorHookType` _(not in index.tsx)_
|
|
48
|
+
|
|
49
|
+
Type used for the `infix` render prop: `{ color: string; setColor: (color: string) => void }`. Not exported from `index.tsx` — import from `@synerise/ds-color-picker/dist/ColorPicker.types` if needed, or declare inline.
|
|
50
|
+
|
|
51
|
+
## Usage patterns
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
import ColorPicker from '@synerise/ds-color-picker';
|
|
55
|
+
|
|
56
|
+
// Controlled basic usage
|
|
57
|
+
const [color, setColor] = useState('#00ffff');
|
|
58
|
+
<ColorPicker value={color} onChange={setColor} />
|
|
59
|
+
|
|
60
|
+
// With saved swatches and copy tooltip
|
|
61
|
+
const [color, setColor] = useState('#00ffff');
|
|
62
|
+
const [savedColors, setSavedColors] = useState<string[]>([]);
|
|
63
|
+
<ColorPicker
|
|
64
|
+
value={color}
|
|
65
|
+
onChange={setColor}
|
|
66
|
+
colors={savedColors}
|
|
67
|
+
onSaveColors={setSavedColors}
|
|
68
|
+
isShownSavedColors
|
|
69
|
+
maxSavedColors={9}
|
|
70
|
+
tooltip={{ copy: 'Copy', copied: 'Copied!' }}
|
|
71
|
+
size="S"
|
|
72
|
+
description="Brand colour"
|
|
73
|
+
/>
|
|
74
|
+
|
|
75
|
+
// With infix slot (e.g. format converter between save button and swatches)
|
|
76
|
+
<ColorPicker
|
|
77
|
+
value={color}
|
|
78
|
+
onChange={setColor}
|
|
79
|
+
isShownSavedColors
|
|
80
|
+
infix={({ color, setColor }) => (
|
|
81
|
+
<Select ... onChange={setColor} />
|
|
82
|
+
)}
|
|
83
|
+
/>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Styling
|
|
87
|
+
|
|
88
|
+
All styles are in `ColorPicker.styles.ts`. Uses `theme.palette` tokens for borders, backgrounds, and text. `react-colorful` internal class names (`.react-colorful__*`) are overridden directly inside the `Container` styled-component.
|
|
89
|
+
|
|
90
|
+
`ColorPickerModalStyle` is a `createGlobalStyle` that targets `.color-picker-overlay` — it is only injected into the DOM when `maxWidth >= 228`. This is a **global CSS side-effect**.
|
|
91
|
+
|
|
92
|
+
The saved-colour **swatch section** is built from plain styled elements matching the Figma spec (16×16, `border-radius: 3px`): `SwatchCreatorButton` (the "+" button, `<button>` — hover shows a `grey-200` background), `Swatch` (a filled `<button>` whose `background-color` is the saved colour; the selected one renders a centred `SwatchDot`), and `SwatchPlaceholder` (an empty `<div>` slot with a `grey-300` border, `grey-400` on hover). It does **not** use `ds-tags`/`ds-button` for swatches. Filled swatches carry `.ds-color-swatch`; empty slots carry `.ds-color-swatch-placeholder`.
|
|
93
|
+
|
|
94
|
+
## Key dependencies
|
|
95
|
+
|
|
96
|
+
- `react-colorful` (`HexColorPicker`) — the core colour-gradient picker UI
|
|
97
|
+
- `@synerise/ds-dropdown` — popover/overlay shell for the picker panel
|
|
98
|
+
- `@synerise/ds-input` — trigger text input and the hex input inside the dropdown
|
|
99
|
+
- `@synerise/ds-tags` — `Tag` for the colour preview swatch (trigger `innerPrefix` + the dropdown preview square); **not** used for saved-colour swatches
|
|
100
|
+
- `@synerise/ds-copy-icon` — copy-to-clipboard button in the dropdown hex input
|
|
101
|
+
- `@synerise/ds-icon` — the `FormulaPlusM` plus glyph inside the swatch creator button
|
|
102
|
+
- `@synerise/ds-form-field` — `FormFieldCommonProps` for `description`/`errorText`
|
|
103
|
+
- `@synerise/ds-utils` (`useOnClickOutside`, `getPopupContainer`) — click-outside close, default portal target
|
|
104
|
+
|
|
105
|
+
## Implementation notes
|
|
106
|
+
|
|
107
|
+
- **`disabled`/`readOnly` bypass the Dropdown entirely** — when either is set, the component returns just the trigger `Input` directly (no `Dropdown` wrapper). Opening the picker is impossible.
|
|
108
|
+
- **Dual color state** — `colorTextInput` (what the user typed / named color) and `colorHexInput` (the normalised hex shown in the dropdown) are kept in sync. `lastValidHexColor` drives the `react-colorful` picker and the preview tag — it only updates on valid input.
|
|
109
|
+
- **`onBlur` resets to last valid** — if the user types an invalid color in the trigger input and blurs, both inputs revert to `lastValidHexColor`.
|
|
110
|
+
- **Initial sync is one-time** — `useEffect` with empty deps `[]` runs only on mount to initialise local state from `value`. After that, `value` changes are **not** automatically reflected (the component is semi-controlled). Pass `value` and handle `onChange` consistently.
|
|
111
|
+
- **`standardizeColor` uses `document.createElement('canvas')`** — browser-only. Will throw in SSR/Node environments.
|
|
112
|
+
- **`isValidTextColor` uses `new Option().style`** — also browser-only.
|
|
113
|
+
- **`maxWidth` threshold** — the prop only takes effect when `>= 228` (the default picker width). Values below 228 are silently ignored.
|
|
114
|
+
- **Swatch grid renders `maxSavedColors` slots** — saved colours fill the leading slots (`Swatch`); the remainder render as empty `SwatchPlaceholder` slots (Figma shows the full grid). The grid wraps (`flex-wrap`) if `maxSavedColors` exceeds what fits the 196px content width.
|
|
115
|
+
- **Selected swatch** — `pressed` holds the index of the last-clicked swatch (its `SwatchDot` shows); it resets to `-1` on any text/hex input change, so typing a colour clears the selection highlight.
|
|
116
|
+
- **`savedColors` is local state** — `colors` prop initialises the local `savedColors` state on mount only. Subsequent `colors` prop changes are not reflected unless the component remounts.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@synerise/ds-color-picker",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.51",
|
|
4
4
|
"description": "Color-Picker 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,15 +42,15 @@
|
|
|
41
42
|
],
|
|
42
43
|
"types": "dist/index.d.ts",
|
|
43
44
|
"dependencies": {
|
|
44
|
-
"@synerise/ds-copy-icon": "^1.2.
|
|
45
|
-
"@synerise/ds-divider": "^1.3.
|
|
46
|
-
"@synerise/ds-dropdown": "^1.3.
|
|
47
|
-
"@synerise/ds-form-field": "^1.3.
|
|
48
|
-
"@synerise/ds-icon": "^1.18.
|
|
49
|
-
"@synerise/ds-input": "^1.7.
|
|
50
|
-
"@synerise/ds-tags": "^1.5.
|
|
51
|
-
"@synerise/ds-tooltip": "^1.5.
|
|
52
|
-
"@synerise/ds-utils": "^1.10.
|
|
45
|
+
"@synerise/ds-copy-icon": "^1.2.16",
|
|
46
|
+
"@synerise/ds-divider": "^1.3.16",
|
|
47
|
+
"@synerise/ds-dropdown": "^1.3.20",
|
|
48
|
+
"@synerise/ds-form-field": "^1.3.24",
|
|
49
|
+
"@synerise/ds-icon": "^1.18.5",
|
|
50
|
+
"@synerise/ds-input": "^1.7.13",
|
|
51
|
+
"@synerise/ds-tags": "^1.5.51",
|
|
52
|
+
"@synerise/ds-tooltip": "^1.5.4",
|
|
53
|
+
"@synerise/ds-utils": "^1.10.2",
|
|
53
54
|
"react-colorful": "^5.2.0"
|
|
54
55
|
},
|
|
55
56
|
"devDependencies": {
|
|
@@ -61,5 +62,5 @@
|
|
|
61
62
|
"react": ">=16.9.0 <= 18.3.1",
|
|
62
63
|
"styled-components": "^5.3.3"
|
|
63
64
|
},
|
|
64
|
-
"gitHead": "
|
|
65
|
+
"gitHead": "d0a43cc43d8528a36f105aceea52ab470edb71d9"
|
|
65
66
|
}
|