jaci-ui 0.1.0 → 0.2.0
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 +23 -0
- package/README.md +168 -0
- package/dist/components/color-picker/color-picker.cjs +77 -22
- package/dist/components/color-picker/color-picker.cjs.map +1 -1
- package/dist/components/color-picker/color-picker.d.cts +3 -3
- package/dist/components/color-picker/color-picker.d.ts +3 -3
- package/dist/components/color-picker/color-picker.js +77 -22
- package/dist/components/color-picker/color-picker.js.map +1 -1
- package/dist/components/date-picker/date-picker.cjs +227 -30
- package/dist/components/date-picker/date-picker.cjs.map +1 -1
- package/dist/components/date-picker/date-picker.d.cts +23 -5
- package/dist/components/date-picker/date-picker.d.ts +23 -5
- package/dist/components/date-picker/date-picker.js +226 -32
- package/dist/components/date-picker/date-picker.js.map +1 -1
- package/dist/components/date-picker/date-utils.cjs +32 -2
- package/dist/components/date-picker/date-utils.cjs.map +1 -1
- package/dist/components/date-picker/date-utils.d.cts +5 -0
- package/dist/components/date-picker/date-utils.d.ts +5 -0
- package/dist/components/date-picker/date-utils.js +29 -3
- package/dist/components/date-picker/date-utils.js.map +1 -1
- package/dist/components/date-picker/index.d.cts +3 -2
- package/dist/components/date-picker/index.d.ts +3 -2
- package/dist/components/menu/menu.cjs +1 -2
- package/dist/components/menu/menu.cjs.map +1 -1
- package/dist/components/menu/menu.d.cts +1 -2
- package/dist/components/menu/menu.d.ts +1 -2
- package/dist/components/menu/menu.js +1 -2
- package/dist/components/menu/menu.js.map +1 -1
- package/dist/components/option-selector/option-selector.cjs.map +1 -1
- package/dist/components/option-selector/option-selector.d.cts +2 -2
- package/dist/components/option-selector/option-selector.d.ts +2 -2
- package/dist/components/option-selector/option-selector.js.map +1 -1
- package/dist/components/toast/toast.cjs +1 -1
- package/dist/components/toast/toast.cjs.map +1 -1
- package/dist/components/toast/toast.d.cts +1 -1
- package/dist/components/toast/toast.d.ts +1 -1
- package/dist/components/toast/toast.js +1 -1
- package/dist/components/toast/toast.js.map +1 -1
- package/dist/index.cjs +3 -0
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2 -2
- package/dist/styled-system/recipes/color-picker.cjs +1 -0
- package/dist/styled-system/recipes/color-picker.cjs.map +1 -1
- package/dist/styled-system/recipes/color-picker.js +1 -0
- package/dist/styled-system/recipes/color-picker.js.map +1 -1
- package/dist/styled-system/recipes/date-picker.cjs +6 -0
- package/dist/styled-system/recipes/date-picker.cjs.map +1 -1
- package/dist/styled-system/recipes/date-picker.js +6 -0
- package/dist/styled-system/recipes/date-picker.js.map +1 -1
- package/dist/styles.css +190 -4
- package/package.json +5 -2
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 3e3e82c: Add blurred input popups, draggable ColorPicker palette selection, and month/date-time DatePicker modes.
|
|
8
|
+
|
|
9
|
+
## 0.1.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- b8dce0e: Prepare the package for its next patch release with distributable documentation, reproducible consumer fixtures, expanded accessibility coverage, and release workflow improvements.
|
|
14
|
+
|
|
15
|
+
All notable changes to `jaci-ui` are documented in this file. Release entries are generated and
|
|
16
|
+
updated by Changesets.
|
|
17
|
+
|
|
18
|
+
## 0.1.0 — Initial public release
|
|
19
|
+
|
|
20
|
+
- Initial public Jaci UI component library.
|
|
21
|
+
- Static Panda CSS distribution at `jaci-ui/styles.css`.
|
|
22
|
+
- Optional Panda preset at `jaci-ui/panda-preset`.
|
|
23
|
+
- SSR-safe static and interactive React component families.
|
package/README.md
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# Jaci UI
|
|
2
|
+
|
|
3
|
+
Accessible, themeable React components for React 18.2 and React 19 applications.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
pnpm add jaci-ui
|
|
9
|
+
# or: npm install jaci-ui
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Import the static stylesheet once from the root of the application:
|
|
13
|
+
|
|
14
|
+
```tsx
|
|
15
|
+
import "jaci-ui/styles.css";
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The package declares `react` and `react-dom` as peer dependencies. `@base-ui/react` is installed
|
|
19
|
+
as a runtime dependency for accessible interactive primitives.
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
Components use named exports and compound APIs where several accessible parts work together:
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
import { Button, ColorPicker, Stack } from "jaci-ui";
|
|
27
|
+
|
|
28
|
+
export function Example() {
|
|
29
|
+
return (
|
|
30
|
+
<Stack gap="md">
|
|
31
|
+
<Button variant="solid">Continue</Button>
|
|
32
|
+
|
|
33
|
+
<ColorPicker.Root defaultValue="#2563eb" name="brand-color">
|
|
34
|
+
<ColorPicker.Label>Brand color</ColorPicker.Label>
|
|
35
|
+
<ColorPicker.Control>
|
|
36
|
+
<ColorPicker.Trigger aria-label="Choose brand color">
|
|
37
|
+
<ColorPicker.Preview />
|
|
38
|
+
<ColorPicker.Value />
|
|
39
|
+
</ColorPicker.Trigger>
|
|
40
|
+
</ColorPicker.Control>
|
|
41
|
+
<ColorPicker.Portal>
|
|
42
|
+
<ColorPicker.Positioner>
|
|
43
|
+
<ColorPicker.Popup>
|
|
44
|
+
<ColorPicker.Palette />
|
|
45
|
+
<ColorPicker.Hue />
|
|
46
|
+
<ColorPicker.Input />
|
|
47
|
+
<ColorPicker.NativeInput />
|
|
48
|
+
</ColorPicker.Popup>
|
|
49
|
+
</ColorPicker.Positioner>
|
|
50
|
+
</ColorPicker.Portal>
|
|
51
|
+
</ColorPicker.Root>
|
|
52
|
+
</Stack>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Interactive components support controlled and uncontrolled state where appropriate. For example,
|
|
58
|
+
`value`/`onValueChange` can be paired with `defaultValue` when the application does not need to
|
|
59
|
+
own the state. `ColorPicker.Palette` supports pointer dragging, keyboard arrows and a visible
|
|
60
|
+
selection indicator.
|
|
61
|
+
|
|
62
|
+
DatePicker supports day, month and date-time values while keeping the public value as a native
|
|
63
|
+
`Date`. Add the month and year selectors to the header for quick navigation, and use
|
|
64
|
+
`DatePicker.TimeField` for the date-time mode:
|
|
65
|
+
|
|
66
|
+
```tsx
|
|
67
|
+
<DatePicker.Root granularity="date-time" defaultValue={new Date()} name="meeting-at">
|
|
68
|
+
<DatePicker.Trigger><DatePicker.Value /></DatePicker.Trigger>
|
|
69
|
+
<DatePicker.Portal>
|
|
70
|
+
<DatePicker.Positioner>
|
|
71
|
+
<DatePicker.Popup>
|
|
72
|
+
<DatePicker.Header>
|
|
73
|
+
<DatePicker.Previous />
|
|
74
|
+
<DatePicker.MonthSelect />
|
|
75
|
+
<DatePicker.YearSelect />
|
|
76
|
+
<DatePicker.Next />
|
|
77
|
+
</DatePicker.Header>
|
|
78
|
+
<DatePicker.Calendar />
|
|
79
|
+
<DatePicker.TimeField />
|
|
80
|
+
<DatePicker.Close>Done</DatePicker.Close>
|
|
81
|
+
</DatePicker.Popup>
|
|
82
|
+
</DatePicker.Positioner>
|
|
83
|
+
</DatePicker.Portal>
|
|
84
|
+
</DatePicker.Root>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Use `granularity="month"` to select a month normalized to its first day. Date-time popups stay
|
|
88
|
+
open until `DatePicker.Close` is activated; day and month modes close after selection by default.
|
|
89
|
+
|
|
90
|
+
## Server rendering and frameworks
|
|
91
|
+
|
|
92
|
+
Static components are server-safe and interactive modules preserve their `"use client"` boundary.
|
|
93
|
+
In Next.js App Router, render interactive compositions inside a client component and import the
|
|
94
|
+
global stylesheet from `app/layout.tsx`:
|
|
95
|
+
|
|
96
|
+
```tsx
|
|
97
|
+
// app/layout.tsx
|
|
98
|
+
import "jaci-ui/styles.css";
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Vite, React Router, Remix and other client entry points can import the stylesheet from their
|
|
102
|
+
application root. Jaci UI does not access `window`, `document`, storage or media APIs during
|
|
103
|
+
module import or server rendering.
|
|
104
|
+
|
|
105
|
+
## Themes and customization
|
|
106
|
+
|
|
107
|
+
Set `data-jaci-theme` on the server-rendered HTML element or on a local scope:
|
|
108
|
+
|
|
109
|
+
```tsx
|
|
110
|
+
<html data-jaci-theme="light">
|
|
111
|
+
<body>{children}</body>
|
|
112
|
+
</html>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Use `data-jaci-theme="dark"` for the dark semantic palette. Brand colors can be changed with
|
|
116
|
+
the public CSS variables without a provider:
|
|
117
|
+
|
|
118
|
+
```css
|
|
119
|
+
:root {
|
|
120
|
+
--jaci-colors-accent-default: #7c3aed;
|
|
121
|
+
--jaci-colors-accent-hover: #6d28d9;
|
|
122
|
+
--jaci-colors-fg-on-accent: #ffffff;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
[data-jaci-theme="dark"] {
|
|
126
|
+
--jaci-colors-accent-default: #a78bfa;
|
|
127
|
+
--jaci-colors-accent-hover: #c4b5fd;
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
The package exposes semantic surface, foreground, border, status, spacing, radius, shadow and
|
|
132
|
+
transition tokens. See the Theming guide in Storybook for the complete token vocabulary.
|
|
133
|
+
|
|
134
|
+
## Optional Panda CSS preset
|
|
135
|
+
|
|
136
|
+
Applications that also use Panda CSS may import the optional preset:
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
import { defineConfig } from "@pandacss/dev";
|
|
140
|
+
import jaciPreset from "jaci-ui/panda-preset";
|
|
141
|
+
|
|
142
|
+
export default defineConfig({
|
|
143
|
+
presets: [jaciPreset],
|
|
144
|
+
});
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
The preset shares tokens and conditions; `jaci-ui/styles.css` remains the distribution stylesheet
|
|
148
|
+
for the component recipes.
|
|
149
|
+
|
|
150
|
+
## Public entry points
|
|
151
|
+
|
|
152
|
+
- `jaci-ui`: React components and named component types.
|
|
153
|
+
- `jaci-ui/styles.css`: generated static styles and semantic tokens.
|
|
154
|
+
- `jaci-ui/panda-preset`: optional Panda CSS preset.
|
|
155
|
+
|
|
156
|
+
## Development
|
|
157
|
+
|
|
158
|
+
This repository uses pnpm, Turborepo, Panda CSS and Storybook. From the repository root:
|
|
159
|
+
|
|
160
|
+
```sh
|
|
161
|
+
pnpm install
|
|
162
|
+
pnpm storybook
|
|
163
|
+
pnpm format:check
|
|
164
|
+
pnpm lint
|
|
165
|
+
pnpm typecheck
|
|
166
|
+
pnpm test
|
|
167
|
+
pnpm package:check
|
|
168
|
+
```
|
|
@@ -114,57 +114,112 @@ const ColorPickerPositioner = (0, react.forwardRef)(function ColorPickerPosition
|
|
|
114
114
|
const ColorPickerPopup = (0, react.forwardRef)(function ColorPickerPopup({ className, ...props }, ref) {
|
|
115
115
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_base_ui_react_popover.Popover.Popup, {
|
|
116
116
|
...props,
|
|
117
|
+
"aria-label": props["aria-label"] ?? "Color picker",
|
|
117
118
|
ref,
|
|
118
119
|
className: require_base_ui.withRecipeClassName(require_color_picker.colorPicker().popup, className),
|
|
119
120
|
"data-jaci-component": "color-picker",
|
|
120
121
|
"data-slot": "color-picker-popup"
|
|
121
122
|
});
|
|
122
123
|
});
|
|
124
|
+
function clamp(value, min, max) {
|
|
125
|
+
return Math.min(max, Math.max(min, value));
|
|
126
|
+
}
|
|
127
|
+
function formatPalettePercentage(value) {
|
|
128
|
+
return `${Number(value.toFixed(2))}%`;
|
|
129
|
+
}
|
|
130
|
+
function hslToPalettePosition(color) {
|
|
131
|
+
const lightness = clamp(color.lightness / 100, 0, 1);
|
|
132
|
+
const saturation = clamp(color.saturation / 100, 0, 1);
|
|
133
|
+
const chroma = (1 - Math.abs(2 * lightness - 1)) * saturation;
|
|
134
|
+
const value = lightness + chroma / 2;
|
|
135
|
+
return {
|
|
136
|
+
lightness: (1 - value) * 100,
|
|
137
|
+
saturation: value === 0 ? 0 : chroma / value * 100
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
function palettePositionToHsl(saturation, lightness, color) {
|
|
141
|
+
const hsvSaturation = clamp(saturation / 100, 0, 1);
|
|
142
|
+
const value = 1 - clamp(lightness / 100, 0, 1);
|
|
143
|
+
const hslLightness = value * (1 - hsvSaturation / 2);
|
|
144
|
+
const hslSaturation = hslLightness === 0 || hslLightness === 1 ? 0 : (value - hslLightness) / Math.min(hslLightness, 1 - hslLightness) * 100;
|
|
145
|
+
return {
|
|
146
|
+
...color,
|
|
147
|
+
lightness: hslLightness * 100,
|
|
148
|
+
saturation: clamp(hslSaturation, 0, 100)
|
|
149
|
+
};
|
|
150
|
+
}
|
|
123
151
|
function updateFromPoint(event, setColor, color) {
|
|
124
152
|
const rect = event.currentTarget.getBoundingClientRect();
|
|
125
|
-
|
|
126
|
-
const lightness = Math.round((1 - Math.min(1, Math.max(0, (event.clientY - rect.top) / rect.height))) * 100);
|
|
127
|
-
setColor({
|
|
128
|
-
...color,
|
|
129
|
-
lightness,
|
|
130
|
-
saturation
|
|
131
|
-
});
|
|
153
|
+
setColor(palettePositionToHsl(Math.round(clamp((event.clientX - rect.left) / rect.width, 0, 1) * 100), Math.round(clamp((event.clientY - rect.top) / rect.height, 0, 1) * 100), color));
|
|
132
154
|
}
|
|
133
|
-
const ColorPickerPalette = (0, react.forwardRef)(function ColorPickerPalette({ className, onKeyDown, onPointerDown, style, ...props }, ref) {
|
|
134
|
-
const { color, setColor, value } = useColorPicker();
|
|
155
|
+
const ColorPickerPalette = (0, react.forwardRef)(function ColorPickerPalette({ children, className, onKeyDown, onPointerCancel, onPointerDown, onPointerMove, onPointerUp, style, ...props }, ref) {
|
|
156
|
+
const { color, disabled, setColor, value } = useColorPicker();
|
|
157
|
+
const [isDragging, setIsDragging] = (0, react.useState)(false);
|
|
135
158
|
const background = `linear-gradient(to top, #000, transparent), linear-gradient(to right, #fff, hsl(${color.hue} 100% 50%))`;
|
|
136
|
-
|
|
159
|
+
const palettePosition = hslToPalettePosition(color);
|
|
160
|
+
const paletteStyle = {
|
|
161
|
+
"--jaci-color-palette-lightness": formatPalettePercentage(palettePosition.lightness),
|
|
162
|
+
"--jaci-color-palette-saturation": formatPalettePercentage(palettePosition.saturation),
|
|
163
|
+
background,
|
|
164
|
+
...style
|
|
165
|
+
};
|
|
166
|
+
const releasePointer = (event) => {
|
|
167
|
+
if (event.currentTarget.hasPointerCapture?.(event.pointerId)) event.currentTarget.releasePointerCapture(event.pointerId);
|
|
168
|
+
setIsDragging(false);
|
|
169
|
+
};
|
|
170
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
137
171
|
...props,
|
|
138
172
|
ref,
|
|
173
|
+
"aria-disabled": disabled || void 0,
|
|
139
174
|
"aria-label": props["aria-label"] ?? "Color saturation and lightness",
|
|
140
175
|
"aria-valuemax": 100,
|
|
141
176
|
"aria-valuemin": 0,
|
|
142
|
-
"aria-valuenow": Math.round(
|
|
177
|
+
"aria-valuenow": Math.round(palettePosition.saturation),
|
|
143
178
|
"aria-valuetext": value,
|
|
144
179
|
className: require_cx.cx(require_color_picker.colorPicker().palette, className),
|
|
180
|
+
"data-disabled": disabled || void 0,
|
|
181
|
+
"data-dragging": isDragging || void 0,
|
|
145
182
|
"data-slot": "color-picker-palette",
|
|
146
183
|
onKeyDown: (event) => {
|
|
147
184
|
const step = event.shiftKey ? 10 : 1;
|
|
148
185
|
if (event.key === "ArrowLeft" || event.key === "ArrowRight" || event.key === "ArrowUp" || event.key === "ArrowDown") {
|
|
149
186
|
event.preventDefault();
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
lightness: event.key === "ArrowDown" ? Math.max(0, color.lightness - step) : event.key === "ArrowUp" ? Math.min(100, color.lightness + step) : color.lightness
|
|
154
|
-
});
|
|
187
|
+
const saturation = event.key === "ArrowLeft" ? Math.max(0, palettePosition.saturation - step) : event.key === "ArrowRight" ? Math.min(100, palettePosition.saturation + step) : palettePosition.saturation;
|
|
188
|
+
const lightness = event.key === "ArrowDown" ? Math.min(100, palettePosition.lightness + step) : event.key === "ArrowUp" ? Math.max(0, palettePosition.lightness - step) : palettePosition.lightness;
|
|
189
|
+
setColor(palettePositionToHsl(saturation, lightness, color));
|
|
155
190
|
}
|
|
156
191
|
onKeyDown?.(event);
|
|
157
192
|
},
|
|
158
193
|
onPointerDown: (event) => {
|
|
159
|
-
|
|
194
|
+
if (!disabled) {
|
|
195
|
+
updateFromPoint(event, setColor, color);
|
|
196
|
+
setIsDragging(true);
|
|
197
|
+
try {
|
|
198
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
199
|
+
} catch {}
|
|
200
|
+
}
|
|
160
201
|
onPointerDown?.(event);
|
|
161
202
|
},
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
203
|
+
onPointerMove: (event) => {
|
|
204
|
+
if (!disabled && isDragging) updateFromPoint(event, setColor, color);
|
|
205
|
+
onPointerMove?.(event);
|
|
206
|
+
},
|
|
207
|
+
onPointerUp: (event) => {
|
|
208
|
+
releasePointer(event);
|
|
209
|
+
onPointerUp?.(event);
|
|
166
210
|
},
|
|
167
|
-
|
|
211
|
+
onPointerCancel: (event) => {
|
|
212
|
+
releasePointer(event);
|
|
213
|
+
onPointerCancel?.(event);
|
|
214
|
+
},
|
|
215
|
+
role: "slider",
|
|
216
|
+
style: paletteStyle,
|
|
217
|
+
tabIndex: props.tabIndex ?? (disabled ? -1 : 0),
|
|
218
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
219
|
+
"aria-hidden": "true",
|
|
220
|
+
className: require_color_picker.colorPicker().paletteIndicator,
|
|
221
|
+
"data-slot": "color-picker-palette-indicator"
|
|
222
|
+
}), children]
|
|
168
223
|
});
|
|
169
224
|
});
|
|
170
225
|
const ColorPickerHue = (0, react.forwardRef)(function ColorPickerHue({ className, onInput, ...props }, ref) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"color-picker.cjs","names":["defaultColor","parseColor","formatColor","BasePopover","cx","colorPicker","withRecipeClassName"],"sources":["../../../src/components/color-picker/color-picker.tsx"],"sourcesContent":["\"use client\";\n\nimport { Popover as BasePopover } from \"@base-ui/react/popover\";\nimport { createContext, forwardRef, useContext, useEffect, useId, useState } from \"react\";\nimport type { ComponentPropsWithoutRef, PointerEvent, ReactNode } from \"react\";\nimport type { PopoverRoot as BasePopoverRoot } from \"@base-ui/react/popover\";\n\nimport { cx } from \"../../styled-system/css\";\nimport { colorPicker } from \"../../styled-system/recipes\";\nimport { withRecipeClassName } from \"../base-ui\";\nimport { defaultColor, formatColor, parseColor } from \"./color-utils\";\nimport type { ColorFormat, ColorModel } from \"./color-utils\";\n\nexport type { ColorFormat, ColorModel } from \"./color-utils\";\nexport { defaultColor, formatColor, parseColor } from \"./color-utils\";\n\ninterface ColorPickerContextValue {\n color: ColorModel;\n disabled: boolean;\n format: ColorFormat;\n inputId: string;\n setColor: (color: ColorModel) => void;\n showAlpha: boolean;\n swatches: string[];\n value: string;\n}\n\nconst ColorPickerContext = createContext<ColorPickerContextValue | null>(null);\n\nfunction useColorPicker() {\n const context = useContext(ColorPickerContext);\n if (!context) throw new Error(\"ColorPicker parts must be rendered inside ColorPicker.Root.\");\n return context;\n}\n\nexport interface ColorPickerRootProps extends Omit<BasePopoverRoot.Props, \"children\"> {\n children?: ReactNode;\n defaultValue?: string;\n disabled?: boolean;\n format?: ColorFormat;\n id?: string;\n name?: string;\n onValueChange?: (value: string) => void;\n showAlpha?: boolean;\n swatches?: string[];\n value?: string;\n}\n\nexport function ColorPickerRoot({\n children,\n defaultValue = \"#000000\",\n disabled = false,\n format = \"hex\",\n id,\n name,\n onValueChange,\n showAlpha = false,\n swatches = [],\n value: controlledValue,\n ...popoverProps\n}: ColorPickerRootProps) {\n const generatedId = useId();\n const inputId = id ?? generatedId;\n const [uncontrolledColor, setUncontrolledColor] = useState<ColorModel>(() =>\n defaultColor(defaultValue),\n );\n const parsedControlled = parseColor(controlledValue);\n const color = parsedControlled ?? uncontrolledColor;\n const formattedValue = formatColor(color, format, showAlpha);\n const setColor = (nextColor: ColorModel) => {\n setUncontrolledColor(nextColor);\n onValueChange?.(formatColor(nextColor, format, showAlpha));\n };\n\n return (\n <ColorPickerContext.Provider\n value={{\n color,\n disabled,\n format,\n inputId,\n setColor,\n showAlpha,\n swatches,\n value: formattedValue,\n }}\n >\n <BasePopover.Root {...popoverProps}>\n {children}\n {name ? (\n <input\n aria-hidden=\"true\"\n id={`${inputId}-value`}\n name={name}\n type=\"hidden\"\n value={formattedValue}\n />\n ) : null}\n </BasePopover.Root>\n </ColorPickerContext.Provider>\n );\n}\n\nexport interface ColorPickerLabelProps extends ComponentPropsWithoutRef<\"label\"> {}\nexport const ColorPickerLabel = forwardRef<HTMLLabelElement, ColorPickerLabelProps>(\n function ColorPickerLabel({ children, className, htmlFor, ...props }, ref) {\n const { inputId } = useColorPicker();\n return (\n <label\n {...props}\n ref={ref}\n className={cx(colorPicker().label, className)}\n data-slot=\"color-picker-label\"\n htmlFor={htmlFor ?? inputId}\n >\n {children}\n </label>\n );\n },\n);\n\nexport type ColorPickerControlProps = ComponentPropsWithoutRef<\"div\">;\nexport const ColorPickerControl = forwardRef<HTMLDivElement, ColorPickerControlProps>(\n function ColorPickerControl({ className, ...props }, ref) {\n return (\n <div\n {...props}\n ref={ref}\n className={cx(colorPicker().control, className)}\n data-slot=\"color-picker-control\"\n />\n );\n },\n);\n\nexport type ColorPickerTriggerProps = ComponentPropsWithoutRef<typeof BasePopover.Trigger>;\nexport const ColorPickerTrigger = forwardRef<HTMLButtonElement, ColorPickerTriggerProps>(\n function ColorPickerTrigger({ className, disabled, ...props }, ref) {\n const context = useColorPicker();\n return (\n <BasePopover.Trigger\n {...props}\n ref={ref}\n className={withRecipeClassName(colorPicker().trigger, className)}\n data-jaci-component=\"color-picker\"\n data-slot=\"color-picker-trigger\"\n disabled={disabled ?? context.disabled}\n id={props.id ?? context.inputId}\n />\n );\n },\n);\n\nexport type ColorPickerPreviewProps = ComponentPropsWithoutRef<\"span\">;\nexport const ColorPickerPreview = forwardRef<HTMLSpanElement, ColorPickerPreviewProps>(\n function ColorPickerPreview({ className, style, ...props }, ref) {\n const { value } = useColorPicker();\n return (\n <span\n {...props}\n ref={ref}\n aria-label={props[\"aria-label\"] ?? value}\n className={cx(colorPicker().preview, className)}\n data-slot=\"color-picker-preview\"\n role=\"img\"\n style={{ backgroundColor: value, ...style }}\n />\n );\n },\n);\n\nexport type ColorPickerValueProps = ComponentPropsWithoutRef<\"span\">;\nexport const ColorPickerValue = forwardRef<HTMLSpanElement, ColorPickerValueProps>(\n function ColorPickerValue({ className, ...props }, ref) {\n const { value } = useColorPicker();\n return (\n <span\n {...props}\n ref={ref}\n className={cx(colorPicker().value, className)}\n data-slot=\"color-picker-value\"\n >\n {props.children ?? value}\n </span>\n );\n },\n);\n\nexport const ColorPickerPortal: typeof BasePopover.Portal = BasePopover.Portal;\nexport type ColorPickerPositionerProps = ComponentPropsWithoutRef<typeof BasePopover.Positioner>;\nexport const ColorPickerPositioner = forwardRef<HTMLDivElement, ColorPickerPositionerProps>(\n function ColorPickerPositioner({ className, ...props }, ref) {\n return (\n <BasePopover.Positioner\n {...props}\n ref={ref}\n className={withRecipeClassName(colorPicker().positioner, className)}\n data-slot=\"color-picker-positioner\"\n />\n );\n },\n);\n\nexport type ColorPickerPopupProps = ComponentPropsWithoutRef<typeof BasePopover.Popup>;\nexport const ColorPickerPopup = forwardRef<HTMLDivElement, ColorPickerPopupProps>(\n function ColorPickerPopup({ className, ...props }, ref) {\n return (\n <BasePopover.Popup\n {...props}\n ref={ref}\n className={withRecipeClassName(colorPicker().popup, className)}\n data-jaci-component=\"color-picker\"\n data-slot=\"color-picker-popup\"\n />\n );\n },\n);\n\nfunction updateFromPoint(\n event: PointerEvent<HTMLDivElement>,\n setColor: (color: ColorModel) => void,\n color: ColorModel,\n) {\n const rect = event.currentTarget.getBoundingClientRect();\n const saturation = Math.round(\n Math.min(1, Math.max(0, (event.clientX - rect.left) / rect.width)) * 100,\n );\n const lightness = Math.round(\n (1 - Math.min(1, Math.max(0, (event.clientY - rect.top) / rect.height))) * 100,\n );\n setColor({ ...color, lightness, saturation });\n}\n\nexport type ColorPickerPaletteProps = Omit<ComponentPropsWithoutRef<\"div\">, \"onChange\">;\nexport const ColorPickerPalette = forwardRef<HTMLDivElement, ColorPickerPaletteProps>(\n function ColorPickerPalette({ className, onKeyDown, onPointerDown, style, ...props }, ref) {\n const { color, setColor, value } = useColorPicker();\n const background = `linear-gradient(to top, #000, transparent), linear-gradient(to right, #fff, hsl(${color.hue} 100% 50%))`;\n return (\n <div\n {...props}\n ref={ref}\n aria-label={props[\"aria-label\"] ?? \"Color saturation and lightness\"}\n aria-valuemax={100}\n aria-valuemin={0}\n aria-valuenow={Math.round(color.saturation)}\n aria-valuetext={value}\n className={cx(colorPicker().palette, className)}\n data-slot=\"color-picker-palette\"\n onKeyDown={(event) => {\n const step = event.shiftKey ? 10 : 1;\n if (\n event.key === \"ArrowLeft\" ||\n event.key === \"ArrowRight\" ||\n event.key === \"ArrowUp\" ||\n event.key === \"ArrowDown\"\n ) {\n event.preventDefault();\n setColor({\n ...color,\n saturation:\n event.key === \"ArrowLeft\"\n ? Math.max(0, color.saturation - step)\n : event.key === \"ArrowRight\"\n ? Math.min(100, color.saturation + step)\n : color.saturation,\n lightness:\n event.key === \"ArrowDown\"\n ? Math.max(0, color.lightness - step)\n : event.key === \"ArrowUp\"\n ? Math.min(100, color.lightness + step)\n : color.lightness,\n });\n }\n onKeyDown?.(event);\n }}\n onPointerDown={(event) => {\n updateFromPoint(event, setColor, color);\n onPointerDown?.(event);\n }}\n role=\"slider\"\n style={{ background, ...style }}\n tabIndex={props.tabIndex ?? 0}\n />\n );\n },\n);\n\nexport type ColorPickerHueProps = Omit<\n ComponentPropsWithoutRef<\"input\">,\n \"max\" | \"min\" | \"onChange\" | \"step\" | \"type\" | \"value\"\n>;\nexport const ColorPickerHue = forwardRef<HTMLInputElement, ColorPickerHueProps>(\n function ColorPickerHue({ className, onInput, ...props }, ref) {\n const { color, setColor } = useColorPicker();\n return (\n <input\n {...props}\n ref={ref}\n aria-label={props[\"aria-label\"] ?? \"Hue\"}\n className={cx(colorPicker().hue, className)}\n data-slot=\"color-picker-hue\"\n max={360}\n min={0}\n onInput={(event) => {\n setColor({ ...color, hue: Number(event.currentTarget.value) });\n onInput?.(event);\n }}\n step={1}\n type=\"range\"\n value={color.hue}\n />\n );\n },\n);\n\nexport type ColorPickerAlphaProps = Omit<\n ComponentPropsWithoutRef<\"input\">,\n \"max\" | \"min\" | \"onChange\" | \"step\" | \"type\" | \"value\"\n>;\nexport const ColorPickerAlpha = forwardRef<HTMLInputElement, ColorPickerAlphaProps>(\n function ColorPickerAlpha({ className, onInput, style, ...props }, ref) {\n const { color, setColor, showAlpha } = useColorPicker();\n if (!showAlpha) return null;\n return (\n <input\n {...props}\n ref={ref}\n aria-label={props[\"aria-label\"] ?? \"Opacity\"}\n className={cx(colorPicker().alpha, className)}\n data-slot=\"color-picker-alpha\"\n max={1}\n min={0}\n onInput={(event) => {\n setColor({ ...color, alpha: Number(event.currentTarget.value) });\n onInput?.(event);\n }}\n step={0.01}\n style={{\n ...style,\n background: `linear-gradient(to right, transparent, ${formatColor({ ...color, alpha: 1 }, \"rgb\")})`,\n }}\n type=\"range\"\n value={color.alpha}\n />\n );\n },\n);\n\nexport type ColorPickerSwatchesProps = ComponentPropsWithoutRef<\"fieldset\">;\nexport const ColorPickerSwatches = forwardRef<HTMLFieldSetElement, ColorPickerSwatchesProps>(\n function ColorPickerSwatches({ children, className, ...props }, ref) {\n const { swatches } = useColorPicker();\n return (\n <fieldset\n {...props}\n ref={ref}\n className={cx(colorPicker().swatches, className)}\n data-slot=\"color-picker-swatches\"\n >\n {children ?? swatches.map((color) => <ColorPickerSwatch color={color} key={color} />)}\n </fieldset>\n );\n },\n);\n\nexport interface ColorPickerSwatchProps extends ComponentPropsWithoutRef<\"button\"> {\n color: string;\n}\nexport const ColorPickerSwatch = forwardRef<HTMLButtonElement, ColorPickerSwatchProps>(\n function ColorPickerSwatch({ children, className, color, style, ...props }, ref) {\n const context = useColorPicker();\n const parsed = parseColor(color);\n const selected =\n parsed && formatColor(parsed, context.format, context.showAlpha) === context.value;\n return (\n <button\n {...props}\n ref={ref}\n aria-label={props[\"aria-label\"] ?? color}\n aria-pressed={selected || undefined}\n className={cx(colorPicker().swatch, className)}\n data-selected={selected || undefined}\n data-slot=\"color-picker-swatch\"\n onClick={(event) => {\n if (parsed) context.setColor(parsed);\n props.onClick?.(event);\n }}\n style={{ backgroundColor: color, ...style }}\n type=\"button\"\n >\n {children}\n </button>\n );\n },\n);\n\nexport type ColorPickerInputProps = Omit<\n ComponentPropsWithoutRef<\"input\">,\n \"onChange\" | \"type\" | \"value\"\n>;\nexport const ColorPickerInput = forwardRef<HTMLInputElement, ColorPickerInputProps>(\n function ColorPickerInput({ className, onBlur, onKeyDown, ...props }, ref) {\n const { format, setColor, showAlpha, value } = useColorPicker();\n const [draft, setDraft] = useState(value);\n const [invalid, setInvalid] = useState(false);\n useEffect(() => setDraft(value), [value]);\n const commit = () => {\n const parsed = parseColor(draft);\n if (!parsed) {\n setInvalid(true);\n setDraft(value);\n return;\n }\n setInvalid(false);\n setColor(parsed);\n setDraft(formatColor(parsed, format, showAlpha));\n };\n return (\n <input\n {...props}\n ref={ref}\n aria-label={props[\"aria-label\"] ?? \"Color value\"}\n aria-invalid={invalid || undefined}\n className={cx(colorPicker().input, className)}\n data-slot=\"color-picker-input\"\n onBlur={(event) => {\n commit();\n onBlur?.(event);\n }}\n onChange={(event) => {\n setDraft(event.currentTarget.value);\n setInvalid(false);\n }}\n onKeyDown={(event) => {\n if (event.key === \"Enter\") {\n event.preventDefault();\n commit();\n }\n onKeyDown?.(event);\n }}\n type=\"text\"\n value={draft}\n />\n );\n },\n);\n\nexport type ColorPickerNativeInputProps = Omit<\n ComponentPropsWithoutRef<\"input\">,\n \"onChange\" | \"type\" | \"value\"\n>;\nexport const ColorPickerNativeInput = forwardRef<HTMLInputElement, ColorPickerNativeInputProps>(\n function ColorPickerNativeInput({ className, onInput, ...props }, ref) {\n const { color, setColor, showAlpha } = useColorPicker();\n const value = formatColor({ ...color, alpha: 1 }, \"hex\");\n return (\n <input\n {...props}\n ref={ref}\n aria-label={props[\"aria-label\"] ?? \"Choose a color\"}\n className={cx(colorPicker().nativeInput, className)}\n data-slot=\"color-picker-native-input\"\n onInput={(event) => {\n const parsed = parseColor(event.currentTarget.value);\n if (parsed) setColor({ ...parsed, alpha: showAlpha ? color.alpha : 1 });\n onInput?.(event);\n }}\n type=\"color\"\n value={value.slice(0, 7)}\n />\n );\n },\n);\n\nexport const ColorPicker = {\n Root: ColorPickerRoot,\n Label: ColorPickerLabel,\n Control: ColorPickerControl,\n Trigger: ColorPickerTrigger,\n Preview: ColorPickerPreview,\n Value: ColorPickerValue,\n Portal: ColorPickerPortal,\n Positioner: ColorPickerPositioner,\n Popup: ColorPickerPopup,\n Palette: ColorPickerPalette,\n Hue: ColorPickerHue,\n Alpha: ColorPickerAlpha,\n Swatches: ColorPickerSwatches,\n Swatch: ColorPickerSwatch,\n Input: ColorPickerInput,\n NativeInput: ColorPickerNativeInput,\n createHandle: BasePopover.createHandle,\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"color-picker.cjs","names":["defaultColor","parseColor","formatColor","BasePopover","cx","colorPicker","withRecipeClassName"],"sources":["../../../src/components/color-picker/color-picker.tsx"],"sourcesContent":["\"use client\";\n\nimport { Popover as BasePopover } from \"@base-ui/react/popover\";\nimport { createContext, forwardRef, useContext, useEffect, useId, useState } from \"react\";\nimport type { ComponentPropsWithoutRef, CSSProperties, PointerEvent, ReactNode } from \"react\";\nimport type { PopoverRoot as BasePopoverRoot } from \"@base-ui/react/popover\";\n\nimport { cx } from \"../../styled-system/css\";\nimport { colorPicker } from \"../../styled-system/recipes\";\nimport { withRecipeClassName } from \"../base-ui\";\nimport { defaultColor, formatColor, parseColor } from \"./color-utils\";\nimport type { ColorFormat, ColorModel } from \"./color-utils\";\n\nexport type { ColorFormat, ColorModel } from \"./color-utils\";\nexport { defaultColor, formatColor, parseColor } from \"./color-utils\";\n\ninterface ColorPickerContextValue {\n color: ColorModel;\n disabled: boolean;\n format: ColorFormat;\n inputId: string;\n setColor: (color: ColorModel) => void;\n showAlpha: boolean;\n swatches: string[];\n value: string;\n}\n\nconst ColorPickerContext = createContext<ColorPickerContextValue | null>(null);\n\nfunction useColorPicker() {\n const context = useContext(ColorPickerContext);\n if (!context) throw new Error(\"ColorPicker parts must be rendered inside ColorPicker.Root.\");\n return context;\n}\n\nexport interface ColorPickerRootProps extends Omit<BasePopoverRoot.Props, \"children\"> {\n children?: ReactNode;\n defaultValue?: string;\n disabled?: boolean;\n format?: ColorFormat;\n id?: string;\n name?: string;\n onValueChange?: (value: string) => void;\n showAlpha?: boolean;\n swatches?: string[];\n value?: string;\n}\n\nexport function ColorPickerRoot({\n children,\n defaultValue = \"#000000\",\n disabled = false,\n format = \"hex\",\n id,\n name,\n onValueChange,\n showAlpha = false,\n swatches = [],\n value: controlledValue,\n ...popoverProps\n}: ColorPickerRootProps) {\n const generatedId = useId();\n const inputId = id ?? generatedId;\n const [uncontrolledColor, setUncontrolledColor] = useState<ColorModel>(() =>\n defaultColor(defaultValue),\n );\n const parsedControlled = parseColor(controlledValue);\n const color = parsedControlled ?? uncontrolledColor;\n const formattedValue = formatColor(color, format, showAlpha);\n const setColor = (nextColor: ColorModel) => {\n setUncontrolledColor(nextColor);\n onValueChange?.(formatColor(nextColor, format, showAlpha));\n };\n\n return (\n <ColorPickerContext.Provider\n value={{\n color,\n disabled,\n format,\n inputId,\n setColor,\n showAlpha,\n swatches,\n value: formattedValue,\n }}\n >\n <BasePopover.Root {...popoverProps}>\n {children}\n {name ? (\n <input\n aria-hidden=\"true\"\n id={`${inputId}-value`}\n name={name}\n type=\"hidden\"\n value={formattedValue}\n />\n ) : null}\n </BasePopover.Root>\n </ColorPickerContext.Provider>\n );\n}\n\nexport interface ColorPickerLabelProps extends ComponentPropsWithoutRef<\"label\"> {}\nexport const ColorPickerLabel = forwardRef<HTMLLabelElement, ColorPickerLabelProps>(\n function ColorPickerLabel({ children, className, htmlFor, ...props }, ref) {\n const { inputId } = useColorPicker();\n return (\n <label\n {...props}\n ref={ref}\n className={cx(colorPicker().label, className)}\n data-slot=\"color-picker-label\"\n htmlFor={htmlFor ?? inputId}\n >\n {children}\n </label>\n );\n },\n);\n\nexport type ColorPickerControlProps = ComponentPropsWithoutRef<\"div\">;\nexport const ColorPickerControl = forwardRef<HTMLDivElement, ColorPickerControlProps>(\n function ColorPickerControl({ className, ...props }, ref) {\n return (\n <div\n {...props}\n ref={ref}\n className={cx(colorPicker().control, className)}\n data-slot=\"color-picker-control\"\n />\n );\n },\n);\n\nexport type ColorPickerTriggerProps = ComponentPropsWithoutRef<typeof BasePopover.Trigger>;\nexport const ColorPickerTrigger = forwardRef<HTMLButtonElement, ColorPickerTriggerProps>(\n function ColorPickerTrigger({ className, disabled, ...props }, ref) {\n const context = useColorPicker();\n return (\n <BasePopover.Trigger\n {...props}\n ref={ref}\n className={withRecipeClassName(colorPicker().trigger, className)}\n data-jaci-component=\"color-picker\"\n data-slot=\"color-picker-trigger\"\n disabled={disabled ?? context.disabled}\n id={props.id ?? context.inputId}\n />\n );\n },\n);\n\nexport type ColorPickerPreviewProps = ComponentPropsWithoutRef<\"span\">;\nexport const ColorPickerPreview = forwardRef<HTMLSpanElement, ColorPickerPreviewProps>(\n function ColorPickerPreview({ className, style, ...props }, ref) {\n const { value } = useColorPicker();\n return (\n <span\n {...props}\n ref={ref}\n aria-label={props[\"aria-label\"] ?? value}\n className={cx(colorPicker().preview, className)}\n data-slot=\"color-picker-preview\"\n role=\"img\"\n style={{ backgroundColor: value, ...style }}\n />\n );\n },\n);\n\nexport type ColorPickerValueProps = ComponentPropsWithoutRef<\"span\">;\nexport const ColorPickerValue = forwardRef<HTMLSpanElement, ColorPickerValueProps>(\n function ColorPickerValue({ className, ...props }, ref) {\n const { value } = useColorPicker();\n return (\n <span\n {...props}\n ref={ref}\n className={cx(colorPicker().value, className)}\n data-slot=\"color-picker-value\"\n >\n {props.children ?? value}\n </span>\n );\n },\n);\n\nexport const ColorPickerPortal: typeof BasePopover.Portal = BasePopover.Portal;\nexport type ColorPickerPositionerProps = ComponentPropsWithoutRef<typeof BasePopover.Positioner>;\nexport const ColorPickerPositioner = forwardRef<HTMLDivElement, ColorPickerPositionerProps>(\n function ColorPickerPositioner({ className, ...props }, ref) {\n return (\n <BasePopover.Positioner\n {...props}\n ref={ref}\n className={withRecipeClassName(colorPicker().positioner, className)}\n data-slot=\"color-picker-positioner\"\n />\n );\n },\n);\n\nexport type ColorPickerPopupProps = ComponentPropsWithoutRef<typeof BasePopover.Popup>;\nexport const ColorPickerPopup = forwardRef<HTMLDivElement, ColorPickerPopupProps>(\n function ColorPickerPopup({ className, ...props }, ref) {\n return (\n <BasePopover.Popup\n {...props}\n aria-label={props[\"aria-label\"] ?? \"Color picker\"}\n ref={ref}\n className={withRecipeClassName(colorPicker().popup, className)}\n data-jaci-component=\"color-picker\"\n data-slot=\"color-picker-popup\"\n />\n );\n },\n);\n\nfunction clamp(value: number, min: number, max: number) {\n return Math.min(max, Math.max(min, value));\n}\n\nfunction formatPalettePercentage(value: number) {\n return `${Number(value.toFixed(2))}%`;\n}\n\nfunction hslToPalettePosition(color: ColorModel) {\n const lightness = clamp(color.lightness / 100, 0, 1);\n const saturation = clamp(color.saturation / 100, 0, 1);\n const chroma = (1 - Math.abs(2 * lightness - 1)) * saturation;\n const value = lightness + chroma / 2;\n\n return {\n lightness: (1 - value) * 100,\n saturation: value === 0 ? 0 : (chroma / value) * 100,\n };\n}\n\nfunction palettePositionToHsl(\n saturation: number,\n lightness: number,\n color: ColorModel,\n): ColorModel {\n const hsvSaturation = clamp(saturation / 100, 0, 1);\n const value = 1 - clamp(lightness / 100, 0, 1);\n const hslLightness = value * (1 - hsvSaturation / 2);\n const hslSaturation =\n hslLightness === 0 || hslLightness === 1\n ? 0\n : ((value - hslLightness) / Math.min(hslLightness, 1 - hslLightness)) * 100;\n\n return {\n ...color,\n lightness: hslLightness * 100,\n saturation: clamp(hslSaturation, 0, 100),\n };\n}\n\nfunction updateFromPoint(\n event: PointerEvent<HTMLDivElement>,\n setColor: (color: ColorModel) => void,\n color: ColorModel,\n) {\n const rect = event.currentTarget.getBoundingClientRect();\n const saturation = Math.round(clamp((event.clientX - rect.left) / rect.width, 0, 1) * 100);\n const lightness = Math.round(clamp((event.clientY - rect.top) / rect.height, 0, 1) * 100);\n setColor(palettePositionToHsl(saturation, lightness, color));\n}\n\nexport type ColorPickerPaletteProps = Omit<ComponentPropsWithoutRef<\"div\">, \"onChange\">;\nexport const ColorPickerPalette = forwardRef<HTMLDivElement, ColorPickerPaletteProps>(\n function ColorPickerPalette(\n {\n children,\n className,\n onKeyDown,\n onPointerCancel,\n onPointerDown,\n onPointerMove,\n onPointerUp,\n style,\n ...props\n },\n ref,\n ) {\n const { color, disabled, setColor, value } = useColorPicker();\n const [isDragging, setIsDragging] = useState(false);\n const background = `linear-gradient(to top, #000, transparent), linear-gradient(to right, #fff, hsl(${color.hue} 100% 50%))`;\n const palettePosition = hslToPalettePosition(color);\n const paletteStyle = {\n \"--jaci-color-palette-lightness\": formatPalettePercentage(palettePosition.lightness),\n \"--jaci-color-palette-saturation\": formatPalettePercentage(palettePosition.saturation),\n background,\n ...style,\n } as CSSProperties;\n\n const releasePointer = (event: PointerEvent<HTMLDivElement>) => {\n if (event.currentTarget.hasPointerCapture?.(event.pointerId)) {\n event.currentTarget.releasePointerCapture(event.pointerId);\n }\n setIsDragging(false);\n };\n\n return (\n <div\n {...props}\n ref={ref}\n aria-disabled={disabled || undefined}\n aria-label={props[\"aria-label\"] ?? \"Color saturation and lightness\"}\n aria-valuemax={100}\n aria-valuemin={0}\n aria-valuenow={Math.round(palettePosition.saturation)}\n aria-valuetext={value}\n className={cx(colorPicker().palette, className)}\n data-disabled={disabled || undefined}\n data-dragging={isDragging || undefined}\n data-slot=\"color-picker-palette\"\n onKeyDown={(event) => {\n const step = event.shiftKey ? 10 : 1;\n if (\n event.key === \"ArrowLeft\" ||\n event.key === \"ArrowRight\" ||\n event.key === \"ArrowUp\" ||\n event.key === \"ArrowDown\"\n ) {\n event.preventDefault();\n const saturation =\n event.key === \"ArrowLeft\"\n ? Math.max(0, palettePosition.saturation - step)\n : event.key === \"ArrowRight\"\n ? Math.min(100, palettePosition.saturation + step)\n : palettePosition.saturation;\n const lightness =\n event.key === \"ArrowDown\"\n ? Math.min(100, palettePosition.lightness + step)\n : event.key === \"ArrowUp\"\n ? Math.max(0, palettePosition.lightness - step)\n : palettePosition.lightness;\n setColor(palettePositionToHsl(saturation, lightness, color));\n }\n onKeyDown?.(event);\n }}\n onPointerDown={(event) => {\n if (!disabled) {\n updateFromPoint(event, setColor, color);\n setIsDragging(true);\n try {\n event.currentTarget.setPointerCapture(event.pointerId);\n } catch {\n // Pointer capture is not available in every test environment.\n }\n }\n onPointerDown?.(event);\n }}\n onPointerMove={(event) => {\n if (!disabled && isDragging) updateFromPoint(event, setColor, color);\n onPointerMove?.(event);\n }}\n onPointerUp={(event) => {\n releasePointer(event);\n onPointerUp?.(event);\n }}\n onPointerCancel={(event) => {\n releasePointer(event);\n onPointerCancel?.(event);\n }}\n role=\"slider\"\n style={paletteStyle}\n tabIndex={props.tabIndex ?? (disabled ? -1 : 0)}\n >\n <span\n aria-hidden=\"true\"\n className={colorPicker().paletteIndicator}\n data-slot=\"color-picker-palette-indicator\"\n />\n {children}\n </div>\n );\n },\n);\n\nexport type ColorPickerHueProps = Omit<\n ComponentPropsWithoutRef<\"input\">,\n \"max\" | \"min\" | \"onChange\" | \"step\" | \"type\" | \"value\"\n>;\nexport const ColorPickerHue = forwardRef<HTMLInputElement, ColorPickerHueProps>(\n function ColorPickerHue({ className, onInput, ...props }, ref) {\n const { color, setColor } = useColorPicker();\n return (\n <input\n {...props}\n ref={ref}\n aria-label={props[\"aria-label\"] ?? \"Hue\"}\n className={cx(colorPicker().hue, className)}\n data-slot=\"color-picker-hue\"\n max={360}\n min={0}\n onInput={(event) => {\n setColor({ ...color, hue: Number(event.currentTarget.value) });\n onInput?.(event);\n }}\n step={1}\n type=\"range\"\n value={color.hue}\n />\n );\n },\n);\n\nexport type ColorPickerAlphaProps = Omit<\n ComponentPropsWithoutRef<\"input\">,\n \"max\" | \"min\" | \"onChange\" | \"step\" | \"type\" | \"value\"\n>;\nexport const ColorPickerAlpha = forwardRef<HTMLInputElement, ColorPickerAlphaProps>(\n function ColorPickerAlpha({ className, onInput, style, ...props }, ref) {\n const { color, setColor, showAlpha } = useColorPicker();\n if (!showAlpha) return null;\n return (\n <input\n {...props}\n ref={ref}\n aria-label={props[\"aria-label\"] ?? \"Opacity\"}\n className={cx(colorPicker().alpha, className)}\n data-slot=\"color-picker-alpha\"\n max={1}\n min={0}\n onInput={(event) => {\n setColor({ ...color, alpha: Number(event.currentTarget.value) });\n onInput?.(event);\n }}\n step={0.01}\n style={{\n ...style,\n background: `linear-gradient(to right, transparent, ${formatColor({ ...color, alpha: 1 }, \"rgb\")})`,\n }}\n type=\"range\"\n value={color.alpha}\n />\n );\n },\n);\n\nexport type ColorPickerSwatchesProps = ComponentPropsWithoutRef<\"fieldset\">;\nexport const ColorPickerSwatches = forwardRef<HTMLFieldSetElement, ColorPickerSwatchesProps>(\n function ColorPickerSwatches({ children, className, ...props }, ref) {\n const { swatches } = useColorPicker();\n return (\n <fieldset\n {...props}\n ref={ref}\n className={cx(colorPicker().swatches, className)}\n data-slot=\"color-picker-swatches\"\n >\n {children ?? swatches.map((color) => <ColorPickerSwatch color={color} key={color} />)}\n </fieldset>\n );\n },\n);\n\nexport interface ColorPickerSwatchProps extends ComponentPropsWithoutRef<\"button\"> {\n color: string;\n}\nexport const ColorPickerSwatch = forwardRef<HTMLButtonElement, ColorPickerSwatchProps>(\n function ColorPickerSwatch({ children, className, color, style, ...props }, ref) {\n const context = useColorPicker();\n const parsed = parseColor(color);\n const selected =\n parsed && formatColor(parsed, context.format, context.showAlpha) === context.value;\n return (\n <button\n {...props}\n ref={ref}\n aria-label={props[\"aria-label\"] ?? color}\n aria-pressed={selected || undefined}\n className={cx(colorPicker().swatch, className)}\n data-selected={selected || undefined}\n data-slot=\"color-picker-swatch\"\n onClick={(event) => {\n if (parsed) context.setColor(parsed);\n props.onClick?.(event);\n }}\n style={{ backgroundColor: color, ...style }}\n type=\"button\"\n >\n {children}\n </button>\n );\n },\n);\n\nexport type ColorPickerInputProps = Omit<\n ComponentPropsWithoutRef<\"input\">,\n \"onChange\" | \"type\" | \"value\"\n>;\nexport const ColorPickerInput = forwardRef<HTMLInputElement, ColorPickerInputProps>(\n function ColorPickerInput({ className, onBlur, onKeyDown, ...props }, ref) {\n const { format, setColor, showAlpha, value } = useColorPicker();\n const [draft, setDraft] = useState(value);\n const [invalid, setInvalid] = useState(false);\n useEffect(() => setDraft(value), [value]);\n const commit = () => {\n const parsed = parseColor(draft);\n if (!parsed) {\n setInvalid(true);\n setDraft(value);\n return;\n }\n setInvalid(false);\n setColor(parsed);\n setDraft(formatColor(parsed, format, showAlpha));\n };\n return (\n <input\n {...props}\n ref={ref}\n aria-label={props[\"aria-label\"] ?? \"Color value\"}\n aria-invalid={invalid || undefined}\n className={cx(colorPicker().input, className)}\n data-slot=\"color-picker-input\"\n onBlur={(event) => {\n commit();\n onBlur?.(event);\n }}\n onChange={(event) => {\n setDraft(event.currentTarget.value);\n setInvalid(false);\n }}\n onKeyDown={(event) => {\n if (event.key === \"Enter\") {\n event.preventDefault();\n commit();\n }\n onKeyDown?.(event);\n }}\n type=\"text\"\n value={draft}\n />\n );\n },\n);\n\nexport type ColorPickerNativeInputProps = Omit<\n ComponentPropsWithoutRef<\"input\">,\n \"onChange\" | \"type\" | \"value\"\n>;\nexport const ColorPickerNativeInput = forwardRef<HTMLInputElement, ColorPickerNativeInputProps>(\n function ColorPickerNativeInput({ className, onInput, ...props }, ref) {\n const { color, setColor, showAlpha } = useColorPicker();\n const value = formatColor({ ...color, alpha: 1 }, \"hex\");\n return (\n <input\n {...props}\n ref={ref}\n aria-label={props[\"aria-label\"] ?? \"Choose a color\"}\n className={cx(colorPicker().nativeInput, className)}\n data-slot=\"color-picker-native-input\"\n onInput={(event) => {\n const parsed = parseColor(event.currentTarget.value);\n if (parsed) setColor({ ...parsed, alpha: showAlpha ? color.alpha : 1 });\n onInput?.(event);\n }}\n type=\"color\"\n value={value.slice(0, 7)}\n />\n );\n },\n);\n\nexport const ColorPicker = {\n Root: ColorPickerRoot,\n Label: ColorPickerLabel,\n Control: ColorPickerControl,\n Trigger: ColorPickerTrigger,\n Preview: ColorPickerPreview,\n Value: ColorPickerValue,\n Portal: ColorPickerPortal,\n Positioner: ColorPickerPositioner,\n Popup: ColorPickerPopup,\n Palette: ColorPickerPalette,\n Hue: ColorPickerHue,\n Alpha: ColorPickerAlpha,\n Swatches: ColorPickerSwatches,\n Swatch: ColorPickerSwatch,\n Input: ColorPickerInput,\n NativeInput: ColorPickerNativeInput,\n createHandle: BasePopover.createHandle,\n};\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ColorFormat, ColorModel, defaultColor, formatColor, parseColor } from "./color-utils.cjs";
|
|
2
|
-
import { ComponentPropsWithoutRef, ReactNode } from "react";
|
|
2
|
+
import { CSSProperties, ComponentPropsWithoutRef, ReactNode } from "react";
|
|
3
3
|
import { Popover, PopoverRoot } from "@base-ui/react/popover";
|
|
4
4
|
//#region src/components/color-picker/color-picker.d.ts
|
|
5
5
|
interface ColorPickerRootProps extends Omit<PopoverRoot.Props, "children"> {
|
|
@@ -23,7 +23,7 @@ type ColorPickerTriggerProps = ComponentPropsWithoutRef<typeof Popover.Trigger>;
|
|
|
23
23
|
declare const ColorPickerTrigger: import("react").ForwardRefExoticComponent<Omit<import("@base-ui/react/internals/types").NativeButtonProps & Omit<import("@base-ui/react/internals/types").WithBaseUIEvent<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>>, "style" | "defaultChecked" | "defaultValue" | "className" | "color"> & {
|
|
24
24
|
className?: string | ((state: import("@base-ui/react").PopoverTriggerState) => string | undefined) | undefined;
|
|
25
25
|
render?: import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | import("@base-ui/react").ComponentRenderFn<import("@base-ui/react").HTMLProps, import("@base-ui/react").PopoverTriggerState> | undefined;
|
|
26
|
-
style?:
|
|
26
|
+
style?: CSSProperties | ((state: import("@base-ui/react").PopoverTriggerState) => React.CSSProperties | undefined) | undefined;
|
|
27
27
|
} & {
|
|
28
28
|
nativeButton?: boolean | undefined;
|
|
29
29
|
handle?: Popover.Handle<unknown> | undefined;
|
|
@@ -65,7 +65,7 @@ declare const ColorPicker: {
|
|
|
65
65
|
Trigger: import("react").ForwardRefExoticComponent<Omit<import("@base-ui/react/internals/types").NativeButtonProps & Omit<import("@base-ui/react/internals/types").WithBaseUIEvent<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>>, "style" | "defaultChecked" | "defaultValue" | "className" | "color"> & {
|
|
66
66
|
className?: string | ((state: import("@base-ui/react").PopoverTriggerState) => string | undefined) | undefined;
|
|
67
67
|
render?: import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | import("@base-ui/react").ComponentRenderFn<import("@base-ui/react").HTMLProps, import("@base-ui/react").PopoverTriggerState> | undefined;
|
|
68
|
-
style?:
|
|
68
|
+
style?: CSSProperties | ((state: import("@base-ui/react").PopoverTriggerState) => React.CSSProperties | undefined) | undefined;
|
|
69
69
|
} & {
|
|
70
70
|
nativeButton?: boolean | undefined;
|
|
71
71
|
handle?: Popover.Handle<unknown> | undefined;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ColorFormat, ColorModel, defaultColor, formatColor, parseColor } from "./color-utils.js";
|
|
2
|
-
import { ComponentPropsWithoutRef, ReactNode } from "react";
|
|
2
|
+
import { CSSProperties, ComponentPropsWithoutRef, ReactNode } from "react";
|
|
3
3
|
import { Popover, PopoverRoot } from "@base-ui/react/popover";
|
|
4
4
|
//#region src/components/color-picker/color-picker.d.ts
|
|
5
5
|
interface ColorPickerRootProps extends Omit<PopoverRoot.Props, "children"> {
|
|
@@ -23,7 +23,7 @@ type ColorPickerTriggerProps = ComponentPropsWithoutRef<typeof Popover.Trigger>;
|
|
|
23
23
|
declare const ColorPickerTrigger: import("react").ForwardRefExoticComponent<Omit<import("@base-ui/react/internals/types").NativeButtonProps & Omit<import("@base-ui/react/internals/types").WithBaseUIEvent<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>>, "style" | "defaultChecked" | "defaultValue" | "className" | "color"> & {
|
|
24
24
|
className?: string | ((state: import("@base-ui/react").PopoverTriggerState) => string | undefined) | undefined;
|
|
25
25
|
render?: import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | import("@base-ui/react").ComponentRenderFn<import("@base-ui/react").HTMLProps, import("@base-ui/react").PopoverTriggerState> | undefined;
|
|
26
|
-
style?:
|
|
26
|
+
style?: CSSProperties | ((state: import("@base-ui/react").PopoverTriggerState) => React.CSSProperties | undefined) | undefined;
|
|
27
27
|
} & {
|
|
28
28
|
nativeButton?: boolean | undefined;
|
|
29
29
|
handle?: Popover.Handle<unknown> | undefined;
|
|
@@ -65,7 +65,7 @@ declare const ColorPicker: {
|
|
|
65
65
|
Trigger: import("react").ForwardRefExoticComponent<Omit<import("@base-ui/react/internals/types").NativeButtonProps & Omit<import("@base-ui/react/internals/types").WithBaseUIEvent<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>>, "style" | "defaultChecked" | "defaultValue" | "className" | "color"> & {
|
|
66
66
|
className?: string | ((state: import("@base-ui/react").PopoverTriggerState) => string | undefined) | undefined;
|
|
67
67
|
render?: import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | import("@base-ui/react").ComponentRenderFn<import("@base-ui/react").HTMLProps, import("@base-ui/react").PopoverTriggerState> | undefined;
|
|
68
|
-
style?:
|
|
68
|
+
style?: CSSProperties | ((state: import("@base-ui/react").PopoverTriggerState) => React.CSSProperties | undefined) | undefined;
|
|
69
69
|
} & {
|
|
70
70
|
nativeButton?: boolean | undefined;
|
|
71
71
|
handle?: Popover.Handle<unknown> | undefined;
|
|
@@ -114,57 +114,112 @@ const ColorPickerPositioner = forwardRef(function ColorPickerPositioner({ classN
|
|
|
114
114
|
const ColorPickerPopup = forwardRef(function ColorPickerPopup({ className, ...props }, ref) {
|
|
115
115
|
return /* @__PURE__ */ jsx(Popover.Popup, {
|
|
116
116
|
...props,
|
|
117
|
+
"aria-label": props["aria-label"] ?? "Color picker",
|
|
117
118
|
ref,
|
|
118
119
|
className: withRecipeClassName(colorPicker().popup, className),
|
|
119
120
|
"data-jaci-component": "color-picker",
|
|
120
121
|
"data-slot": "color-picker-popup"
|
|
121
122
|
});
|
|
122
123
|
});
|
|
124
|
+
function clamp(value, min, max) {
|
|
125
|
+
return Math.min(max, Math.max(min, value));
|
|
126
|
+
}
|
|
127
|
+
function formatPalettePercentage(value) {
|
|
128
|
+
return `${Number(value.toFixed(2))}%`;
|
|
129
|
+
}
|
|
130
|
+
function hslToPalettePosition(color) {
|
|
131
|
+
const lightness = clamp(color.lightness / 100, 0, 1);
|
|
132
|
+
const saturation = clamp(color.saturation / 100, 0, 1);
|
|
133
|
+
const chroma = (1 - Math.abs(2 * lightness - 1)) * saturation;
|
|
134
|
+
const value = lightness + chroma / 2;
|
|
135
|
+
return {
|
|
136
|
+
lightness: (1 - value) * 100,
|
|
137
|
+
saturation: value === 0 ? 0 : chroma / value * 100
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
function palettePositionToHsl(saturation, lightness, color) {
|
|
141
|
+
const hsvSaturation = clamp(saturation / 100, 0, 1);
|
|
142
|
+
const value = 1 - clamp(lightness / 100, 0, 1);
|
|
143
|
+
const hslLightness = value * (1 - hsvSaturation / 2);
|
|
144
|
+
const hslSaturation = hslLightness === 0 || hslLightness === 1 ? 0 : (value - hslLightness) / Math.min(hslLightness, 1 - hslLightness) * 100;
|
|
145
|
+
return {
|
|
146
|
+
...color,
|
|
147
|
+
lightness: hslLightness * 100,
|
|
148
|
+
saturation: clamp(hslSaturation, 0, 100)
|
|
149
|
+
};
|
|
150
|
+
}
|
|
123
151
|
function updateFromPoint(event, setColor, color) {
|
|
124
152
|
const rect = event.currentTarget.getBoundingClientRect();
|
|
125
|
-
|
|
126
|
-
const lightness = Math.round((1 - Math.min(1, Math.max(0, (event.clientY - rect.top) / rect.height))) * 100);
|
|
127
|
-
setColor({
|
|
128
|
-
...color,
|
|
129
|
-
lightness,
|
|
130
|
-
saturation
|
|
131
|
-
});
|
|
153
|
+
setColor(palettePositionToHsl(Math.round(clamp((event.clientX - rect.left) / rect.width, 0, 1) * 100), Math.round(clamp((event.clientY - rect.top) / rect.height, 0, 1) * 100), color));
|
|
132
154
|
}
|
|
133
|
-
const ColorPickerPalette = forwardRef(function ColorPickerPalette({ className, onKeyDown, onPointerDown, style, ...props }, ref) {
|
|
134
|
-
const { color, setColor, value } = useColorPicker();
|
|
155
|
+
const ColorPickerPalette = forwardRef(function ColorPickerPalette({ children, className, onKeyDown, onPointerCancel, onPointerDown, onPointerMove, onPointerUp, style, ...props }, ref) {
|
|
156
|
+
const { color, disabled, setColor, value } = useColorPicker();
|
|
157
|
+
const [isDragging, setIsDragging] = useState(false);
|
|
135
158
|
const background = `linear-gradient(to top, #000, transparent), linear-gradient(to right, #fff, hsl(${color.hue} 100% 50%))`;
|
|
136
|
-
|
|
159
|
+
const palettePosition = hslToPalettePosition(color);
|
|
160
|
+
const paletteStyle = {
|
|
161
|
+
"--jaci-color-palette-lightness": formatPalettePercentage(palettePosition.lightness),
|
|
162
|
+
"--jaci-color-palette-saturation": formatPalettePercentage(palettePosition.saturation),
|
|
163
|
+
background,
|
|
164
|
+
...style
|
|
165
|
+
};
|
|
166
|
+
const releasePointer = (event) => {
|
|
167
|
+
if (event.currentTarget.hasPointerCapture?.(event.pointerId)) event.currentTarget.releasePointerCapture(event.pointerId);
|
|
168
|
+
setIsDragging(false);
|
|
169
|
+
};
|
|
170
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
137
171
|
...props,
|
|
138
172
|
ref,
|
|
173
|
+
"aria-disabled": disabled || void 0,
|
|
139
174
|
"aria-label": props["aria-label"] ?? "Color saturation and lightness",
|
|
140
175
|
"aria-valuemax": 100,
|
|
141
176
|
"aria-valuemin": 0,
|
|
142
|
-
"aria-valuenow": Math.round(
|
|
177
|
+
"aria-valuenow": Math.round(palettePosition.saturation),
|
|
143
178
|
"aria-valuetext": value,
|
|
144
179
|
className: cx(colorPicker().palette, className),
|
|
180
|
+
"data-disabled": disabled || void 0,
|
|
181
|
+
"data-dragging": isDragging || void 0,
|
|
145
182
|
"data-slot": "color-picker-palette",
|
|
146
183
|
onKeyDown: (event) => {
|
|
147
184
|
const step = event.shiftKey ? 10 : 1;
|
|
148
185
|
if (event.key === "ArrowLeft" || event.key === "ArrowRight" || event.key === "ArrowUp" || event.key === "ArrowDown") {
|
|
149
186
|
event.preventDefault();
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
lightness: event.key === "ArrowDown" ? Math.max(0, color.lightness - step) : event.key === "ArrowUp" ? Math.min(100, color.lightness + step) : color.lightness
|
|
154
|
-
});
|
|
187
|
+
const saturation = event.key === "ArrowLeft" ? Math.max(0, palettePosition.saturation - step) : event.key === "ArrowRight" ? Math.min(100, palettePosition.saturation + step) : palettePosition.saturation;
|
|
188
|
+
const lightness = event.key === "ArrowDown" ? Math.min(100, palettePosition.lightness + step) : event.key === "ArrowUp" ? Math.max(0, palettePosition.lightness - step) : palettePosition.lightness;
|
|
189
|
+
setColor(palettePositionToHsl(saturation, lightness, color));
|
|
155
190
|
}
|
|
156
191
|
onKeyDown?.(event);
|
|
157
192
|
},
|
|
158
193
|
onPointerDown: (event) => {
|
|
159
|
-
|
|
194
|
+
if (!disabled) {
|
|
195
|
+
updateFromPoint(event, setColor, color);
|
|
196
|
+
setIsDragging(true);
|
|
197
|
+
try {
|
|
198
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
199
|
+
} catch {}
|
|
200
|
+
}
|
|
160
201
|
onPointerDown?.(event);
|
|
161
202
|
},
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
203
|
+
onPointerMove: (event) => {
|
|
204
|
+
if (!disabled && isDragging) updateFromPoint(event, setColor, color);
|
|
205
|
+
onPointerMove?.(event);
|
|
206
|
+
},
|
|
207
|
+
onPointerUp: (event) => {
|
|
208
|
+
releasePointer(event);
|
|
209
|
+
onPointerUp?.(event);
|
|
166
210
|
},
|
|
167
|
-
|
|
211
|
+
onPointerCancel: (event) => {
|
|
212
|
+
releasePointer(event);
|
|
213
|
+
onPointerCancel?.(event);
|
|
214
|
+
},
|
|
215
|
+
role: "slider",
|
|
216
|
+
style: paletteStyle,
|
|
217
|
+
tabIndex: props.tabIndex ?? (disabled ? -1 : 0),
|
|
218
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
219
|
+
"aria-hidden": "true",
|
|
220
|
+
className: colorPicker().paletteIndicator,
|
|
221
|
+
"data-slot": "color-picker-palette-indicator"
|
|
222
|
+
}), children]
|
|
168
223
|
});
|
|
169
224
|
});
|
|
170
225
|
const ColorPickerHue = forwardRef(function ColorPickerHue({ className, onInput, ...props }, ref) {
|