@choice-ui/react 1.9.0 → 1.9.1
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/dist/components/button/dist/index.js +7 -0
- package/dist/components/checkbox/dist/index.d.ts +10 -1
- package/dist/components/checkbox/dist/index.js +49 -5
- package/dist/components/colors/dist/index.d.ts +39 -6
- package/dist/components/colors/src/color-gradients-paint/color-gradient-combined.js +1 -4
- package/dist/components/colors/src/color-gradients-paint/color-gradient-slider.d.ts +4 -4
- package/dist/components/colors/src/color-gradients-paint/color-gradient-slider.js +9 -8
- package/dist/components/colors/src/color-image-paint/color-image-paint.js +2 -2
- package/dist/components/colors/src/color-slider/color-slider.d.ts +14 -6
- package/dist/components/colors/src/color-slider/color-slider.js +124 -46
- package/dist/components/colors/src/color-slider/components/index.d.ts +2 -0
- package/dist/components/colors/src/color-slider/components/thumb.d.ts +8 -0
- package/dist/components/colors/src/color-slider/components/thumb.js +49 -0
- package/dist/components/colors/src/color-slider/components/track.d.ts +18 -0
- package/dist/components/colors/src/color-slider/components/track.js +19 -0
- package/dist/components/colors/src/color-slider/context.d.ts +23 -0
- package/dist/components/colors/src/color-slider/context.js +13 -0
- package/dist/components/colors/src/color-slider/index.d.ts +2 -0
- package/dist/components/colors/src/color-slider/tv.d.ts +3 -0
- package/dist/components/colors/src/color-slider/tv.js +2 -1
- package/dist/components/colors/src/color-solid-paint/color-solid-paint.js +4 -7
- package/dist/components/colors/src/color-solid-paint/solid-paint-alpha-slider.js +2 -2
- package/dist/components/colors/src/color-solid-paint/solid-paint-hue-slider.js +2 -2
- package/dist/components/colors/src/simple-color-picker/simple-color-picker.js +4 -7
- package/dist/components/dropdown/dist/index.d.ts +6 -0
- package/dist/components/dropdown/dist/index.js +20 -10
- package/dist/components/emoji-picker/dist/index.d.ts +29 -1
- package/dist/components/emoji-picker/dist/index.js +144 -42
- package/dist/components/form/src/adapters/range-adapter.js +2 -2
- package/dist/components/icon-button/dist/index.d.ts +1 -1
- package/dist/components/icon-button/dist/index.js +39 -0
- package/dist/components/menus/dist/index.d.ts +5 -0
- package/dist/components/menus/dist/index.js +32 -3
- package/dist/components/radio/dist/index.d.ts +9 -1
- package/dist/components/radio/dist/index.js +50 -6
- package/dist/components/range/dist/index.d.ts +276 -20
- package/dist/components/range/dist/index.js +1030 -602
- package/dist/components/textarea/dist/index.js +3 -1
- package/dist/components/tooltip/dist/index.d.ts +2 -0
- package/dist/components/tooltip/dist/index.js +23 -5
- package/dist/components/virtual-select/dist/index.d.ts +48 -0
- package/package.json +20 -32
|
@@ -244,6 +244,13 @@ var buttonTv = tcv({
|
|
|
244
244
|
loading: false,
|
|
245
245
|
variant: "dark",
|
|
246
246
|
class: { button: "active:bg-gray-600" }
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
disabled: false,
|
|
250
|
+
loading: false,
|
|
251
|
+
variant: "secondary",
|
|
252
|
+
active: false,
|
|
253
|
+
class: { button: "hover:bg-secondary-background" }
|
|
247
254
|
}
|
|
248
255
|
],
|
|
249
256
|
defaultVariants: {
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { HTMLProps, ReactNode } from 'react';
|
|
2
2
|
import * as react from 'react';
|
|
3
3
|
|
|
4
|
+
interface CheckboxIconProps extends Omit<HTMLProps<HTMLDivElement>, "children"> {
|
|
5
|
+
children?: ReactNode | ((props: {
|
|
6
|
+
value?: boolean;
|
|
7
|
+
mixed?: boolean;
|
|
8
|
+
}) => ReactNode);
|
|
9
|
+
}
|
|
10
|
+
declare const CheckboxIcon: react.MemoExoticComponent<react.ForwardRefExoticComponent<Omit<CheckboxIconProps, "ref"> & react.RefAttributes<HTMLDivElement>>>;
|
|
11
|
+
|
|
4
12
|
interface CheckboxLabelProps extends Omit<HTMLProps<HTMLLabelElement>, "htmlFor" | "id" | "disabled"> {
|
|
5
13
|
children: ReactNode;
|
|
6
14
|
}
|
|
@@ -20,9 +28,10 @@ interface CheckboxType {
|
|
|
20
28
|
(props: CheckboxProps & {
|
|
21
29
|
ref?: React.Ref<HTMLInputElement>;
|
|
22
30
|
}): JSX.Element;
|
|
31
|
+
Icon: typeof CheckboxIcon;
|
|
23
32
|
Label: typeof CheckboxLabel;
|
|
24
33
|
displayName?: string;
|
|
25
34
|
}
|
|
26
35
|
declare const Checkbox: CheckboxType;
|
|
27
36
|
|
|
28
|
-
export { Checkbox, type CheckboxProps };
|
|
37
|
+
export { Checkbox, type CheckboxIconProps, type CheckboxLabelProps, type CheckboxProps };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Indeterminate, Check } from "@choiceform/icons-react";
|
|
2
|
-
import { memo, forwardRef, useId, createContext, useContext } from "react";
|
|
2
|
+
import { memo, forwardRef, useId, Children, isValidElement, createContext, useContext } from "react";
|
|
3
3
|
import { useEventCallback } from "usehooks-ts";
|
|
4
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
import { tcv, tcx } from "../../../shared/utils/tcx/tcx.js";
|
|
@@ -137,6 +137,38 @@ var checkboxTv = tcv({
|
|
|
137
137
|
focused: false
|
|
138
138
|
}
|
|
139
139
|
});
|
|
140
|
+
var CheckboxIcon = memo(
|
|
141
|
+
forwardRef(function CheckboxIcon2(props, ref) {
|
|
142
|
+
const { className, children, ...rest } = props;
|
|
143
|
+
const { value, mixed, disabled, variant } = useCheckboxContext();
|
|
144
|
+
const tv = checkboxTv({
|
|
145
|
+
type: "checkbox",
|
|
146
|
+
variant,
|
|
147
|
+
disabled,
|
|
148
|
+
checked: value || mixed
|
|
149
|
+
});
|
|
150
|
+
const renderIcon = () => {
|
|
151
|
+
if (typeof children === "function") {
|
|
152
|
+
return children({ value, mixed });
|
|
153
|
+
}
|
|
154
|
+
if (children !== void 0) {
|
|
155
|
+
return children;
|
|
156
|
+
}
|
|
157
|
+
return mixed ? /* @__PURE__ */ jsx(Indeterminate, {}) : value ? /* @__PURE__ */ jsx(Check, {}) : null;
|
|
158
|
+
};
|
|
159
|
+
return /* @__PURE__ */ jsx(
|
|
160
|
+
"div",
|
|
161
|
+
{
|
|
162
|
+
ref,
|
|
163
|
+
className: tcx(tv.box(), className),
|
|
164
|
+
"data-active": value,
|
|
165
|
+
...rest,
|
|
166
|
+
children: renderIcon()
|
|
167
|
+
}
|
|
168
|
+
);
|
|
169
|
+
})
|
|
170
|
+
);
|
|
171
|
+
CheckboxIcon.displayName = "Checkbox.Icon";
|
|
140
172
|
var CheckboxLabel = memo(
|
|
141
173
|
forwardRef(function CheckboxLabel2(props, ref) {
|
|
142
174
|
const { children, className, ...rest } = props;
|
|
@@ -195,12 +227,23 @@ var CheckboxBase = forwardRef(function Checkbox(props, ref) {
|
|
|
195
227
|
}
|
|
196
228
|
onKeyDown == null ? void 0 : onKeyDown(e);
|
|
197
229
|
});
|
|
230
|
+
const isIconElement = (child) => {
|
|
231
|
+
var _a;
|
|
232
|
+
return isValidElement(child) && (child.type === CheckboxIcon || ((_a = child.type) == null ? void 0 : _a.displayName) === "Checkbox.Icon");
|
|
233
|
+
};
|
|
234
|
+
const childArray = Children.toArray(children);
|
|
235
|
+
const iconChild = childArray.find(isIconElement);
|
|
236
|
+
const otherChildren = childArray.filter((child) => !isIconElement(child));
|
|
198
237
|
const renderChildren = () => {
|
|
199
|
-
if (
|
|
200
|
-
|
|
238
|
+
if (otherChildren.length === 1) {
|
|
239
|
+
const child = otherChildren[0];
|
|
240
|
+
if (typeof child === "string" || typeof child === "number") {
|
|
241
|
+
return /* @__PURE__ */ jsx(CheckboxLabel, { children: child });
|
|
242
|
+
}
|
|
201
243
|
}
|
|
202
|
-
return
|
|
244
|
+
return otherChildren;
|
|
203
245
|
};
|
|
246
|
+
const renderDefaultIcon = () => /* @__PURE__ */ jsx("div", { className: tv.box(), children: mixed ? /* @__PURE__ */ jsx(Indeterminate, {}) : value ? /* @__PURE__ */ jsx(Check, {}) : null });
|
|
204
247
|
return /* @__PURE__ */ jsx(
|
|
205
248
|
CheckboxContext.Provider,
|
|
206
249
|
{
|
|
@@ -234,7 +277,7 @@ var CheckboxBase = forwardRef(function Checkbox(props, ref) {
|
|
|
234
277
|
...rest
|
|
235
278
|
}
|
|
236
279
|
),
|
|
237
|
-
|
|
280
|
+
iconChild ?? renderDefaultIcon()
|
|
238
281
|
] }),
|
|
239
282
|
renderChildren()
|
|
240
283
|
] })
|
|
@@ -243,6 +286,7 @@ var CheckboxBase = forwardRef(function Checkbox(props, ref) {
|
|
|
243
286
|
});
|
|
244
287
|
var MemoizedCheckbox = memo(CheckboxBase);
|
|
245
288
|
var Checkbox2 = MemoizedCheckbox;
|
|
289
|
+
Checkbox2.Icon = CheckboxIcon;
|
|
246
290
|
Checkbox2.Label = CheckboxLabel;
|
|
247
291
|
Checkbox2.displayName = "Checkbox";
|
|
248
292
|
export {
|
|
@@ -452,8 +452,37 @@ interface ColorAreaProps {
|
|
|
452
452
|
}
|
|
453
453
|
declare const ColorArea: react.MemoExoticComponent<react.ForwardRefExoticComponent<ColorAreaProps & react.RefAttributes<HTMLDivElement>>>;
|
|
454
454
|
|
|
455
|
+
interface ColorSliderThumbProps {
|
|
456
|
+
className?: string;
|
|
457
|
+
size?: number;
|
|
458
|
+
}
|
|
459
|
+
declare function ColorSliderThumb(props: ColorSliderThumbProps): react_jsx_runtime.JSX.Element;
|
|
460
|
+
declare namespace ColorSliderThumb {
|
|
461
|
+
var displayName: string;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
interface ColorSliderTrackProps {
|
|
465
|
+
className?: string;
|
|
466
|
+
children?: React.ReactNode;
|
|
467
|
+
/**
|
|
468
|
+
* Height of the track in pixels.
|
|
469
|
+
* This prop is extracted by the parent ColorSlider and passed via context.
|
|
470
|
+
*/
|
|
471
|
+
height?: number;
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* ColorSliderTrack - The track background of the color slider.
|
|
475
|
+
* Renders the gradient background based on slider type (hue, alpha, etc.)
|
|
476
|
+
* Can contain custom children for additional visual elements.
|
|
477
|
+
*/
|
|
478
|
+
declare function ColorSliderTrack(props: ColorSliderTrackProps): react_jsx_runtime.JSX.Element;
|
|
479
|
+
declare namespace ColorSliderTrack {
|
|
480
|
+
var displayName: string;
|
|
481
|
+
}
|
|
482
|
+
|
|
455
483
|
interface ColorSliderProps {
|
|
456
484
|
backgroundStyle?: CSSProperties;
|
|
485
|
+
children?: React.ReactNode;
|
|
457
486
|
className?: string;
|
|
458
487
|
disabled?: boolean;
|
|
459
488
|
hue?: number;
|
|
@@ -461,14 +490,18 @@ interface ColorSliderProps {
|
|
|
461
490
|
onChangeEnd?: () => void;
|
|
462
491
|
onChangeStart?: () => void;
|
|
463
492
|
position: number;
|
|
464
|
-
thumbSize?: number;
|
|
465
|
-
trackSize?: {
|
|
466
|
-
height?: number;
|
|
467
|
-
width?: number;
|
|
468
|
-
};
|
|
469
493
|
type: PickerSliderType;
|
|
494
|
+
/**
|
|
495
|
+
* Width of the slider track in pixels.
|
|
496
|
+
* If not provided (undefined or false), the width will be auto-calculated from the container.
|
|
497
|
+
*/
|
|
498
|
+
width?: number | boolean;
|
|
499
|
+
}
|
|
500
|
+
interface ColorSliderComponent extends React.MemoExoticComponent<React.ForwardRefExoticComponent<ColorSliderProps & React.RefAttributes<HTMLDivElement>>> {
|
|
501
|
+
Thumb: typeof ColorSliderThumb;
|
|
502
|
+
Track: typeof ColorSliderTrack;
|
|
470
503
|
}
|
|
471
|
-
declare const ColorSlider:
|
|
504
|
+
declare const ColorSlider: ColorSliderComponent;
|
|
472
505
|
|
|
473
506
|
interface ColorSwatchProps extends Omit<HTMLProps<HTMLDivElement>, "color"> {
|
|
474
507
|
alpha?: number;
|
|
@@ -24,10 +24,7 @@ const ColorGradientCombined = (props) => {
|
|
|
24
24
|
onChangeEnd,
|
|
25
25
|
controlledSelectedStopId: selectedStopId,
|
|
26
26
|
onSelectedStopIdChange,
|
|
27
|
-
|
|
28
|
-
width: containerWidth - 32,
|
|
29
|
-
height: 16
|
|
30
|
-
},
|
|
27
|
+
width: containerWidth - 32,
|
|
31
28
|
className: "min-w-0 px-4 pb-4"
|
|
32
29
|
}
|
|
33
30
|
),
|
|
@@ -8,10 +8,10 @@ interface ColorGradientSliderProps {
|
|
|
8
8
|
onChangeStart?: () => void;
|
|
9
9
|
onSelectedStopIdChange?: (id: string) => void;
|
|
10
10
|
stopSize?: number;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Width of the gradient slider track in pixels.
|
|
13
|
+
*/
|
|
14
|
+
width?: number;
|
|
15
15
|
value?: GradientPaint["gradientStops"];
|
|
16
16
|
}
|
|
17
17
|
export declare const ColorGradientSlider: import('react').ForwardRefExoticComponent<ColorGradientSliderProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
@@ -18,10 +18,11 @@ const ColorGradientSlider = forwardRef(
|
|
|
18
18
|
controlledSelectedStopId,
|
|
19
19
|
onSelectedStopIdChange,
|
|
20
20
|
disabled = false,
|
|
21
|
-
|
|
21
|
+
width: trackWidth = 224,
|
|
22
22
|
stopSize = 18,
|
|
23
23
|
className
|
|
24
24
|
} = props;
|
|
25
|
+
const trackHeight = 16;
|
|
25
26
|
const { colorProfile } = useColors();
|
|
26
27
|
const sliderRef = useRef(null);
|
|
27
28
|
const stopsContainerRef = useRef(null);
|
|
@@ -182,15 +183,15 @@ const ColorGradientSlider = forwardRef(
|
|
|
182
183
|
});
|
|
183
184
|
const trackStyle = useMemo(() => {
|
|
184
185
|
return {
|
|
185
|
-
width:
|
|
186
|
-
height:
|
|
186
|
+
width: trackWidth,
|
|
187
|
+
height: trackHeight,
|
|
187
188
|
boxShadow: "inset 0 0 0 1px rgba(0,0,0,0.1)",
|
|
188
189
|
background: gradientBackground
|
|
189
190
|
};
|
|
190
|
-
}, [gradientBackground,
|
|
191
|
+
}, [gradientBackground, trackWidth, trackHeight]);
|
|
191
192
|
const stopStyle = useCallback(
|
|
192
193
|
(stop) => {
|
|
193
|
-
const position = stop.position *
|
|
194
|
+
const position = stop.position * trackWidth;
|
|
194
195
|
return {
|
|
195
196
|
width: stopSize,
|
|
196
197
|
height: stopSize,
|
|
@@ -198,12 +199,12 @@ const ColorGradientSlider = forwardRef(
|
|
|
198
199
|
willChange: isDragging.current ? "transform" : "auto"
|
|
199
200
|
};
|
|
200
201
|
},
|
|
201
|
-
[stopSize,
|
|
202
|
+
[stopSize, trackWidth]
|
|
202
203
|
);
|
|
203
204
|
const handleMouseMove = useEventCallback((e) => {
|
|
204
205
|
if (disabled || isDragging.current) return;
|
|
205
206
|
const position = calculatePosition(e.clientX);
|
|
206
|
-
setHoverPosition(position *
|
|
207
|
+
setHoverPosition(position * trackWidth);
|
|
207
208
|
});
|
|
208
209
|
const handleMouseLeave = useEventCallback(() => {
|
|
209
210
|
setHoverPosition(null);
|
|
@@ -221,7 +222,7 @@ const ColorGradientSlider = forwardRef(
|
|
|
221
222
|
className: "relative",
|
|
222
223
|
style: {
|
|
223
224
|
height: 24,
|
|
224
|
-
width:
|
|
225
|
+
width: trackWidth
|
|
225
226
|
},
|
|
226
227
|
children: stops.map((stop) => /* @__PURE__ */ jsx(
|
|
227
228
|
"div",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Button } from "../../../button/dist/index.js";
|
|
3
|
-
import { Range } from "../../../range/dist/index.js";
|
|
3
|
+
import { Range as Range2 } from "../../../range/dist/index.js";
|
|
4
4
|
import React__default, { memo, useState, useRef, useMemo, useEffect, useCallback } from "react";
|
|
5
5
|
import { useEventCallback } from "usehooks-ts";
|
|
6
6
|
import { ColorImageToolbar } from "./color-image-toolbar.js";
|
|
@@ -209,7 +209,7 @@ const ColorImagePaint = memo(function ColorImagePaint2(props) {
|
|
|
209
209
|
return /* @__PURE__ */ jsxs(React__default.Fragment, { children: [
|
|
210
210
|
/* @__PURE__ */ jsx("span", { className: styles.adjustLabel(), children: (_a2 = features == null ? void 0 : features.labels) == null ? void 0 : _a2[filterName] }),
|
|
211
211
|
/* @__PURE__ */ jsx(
|
|
212
|
-
|
|
212
|
+
Range2,
|
|
213
213
|
{
|
|
214
214
|
min: -100,
|
|
215
215
|
max: 100,
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { CSSProperties } from 'react';
|
|
2
2
|
import { PickerSliderType } from '../types/colors';
|
|
3
|
+
import { ColorSliderThumb, ColorSliderThumbProps } from './components/thumb';
|
|
4
|
+
import { ColorSliderTrack, ColorSliderTrackProps } from './components/track';
|
|
3
5
|
export interface ColorSliderProps {
|
|
4
6
|
backgroundStyle?: CSSProperties;
|
|
7
|
+
children?: React.ReactNode;
|
|
5
8
|
className?: string;
|
|
6
9
|
disabled?: boolean;
|
|
7
10
|
hue?: number;
|
|
@@ -9,11 +12,16 @@ export interface ColorSliderProps {
|
|
|
9
12
|
onChangeEnd?: () => void;
|
|
10
13
|
onChangeStart?: () => void;
|
|
11
14
|
position: number;
|
|
12
|
-
thumbSize?: number;
|
|
13
|
-
trackSize?: {
|
|
14
|
-
height?: number;
|
|
15
|
-
width?: number;
|
|
16
|
-
};
|
|
17
15
|
type: PickerSliderType;
|
|
16
|
+
/**
|
|
17
|
+
* Width of the slider track in pixels.
|
|
18
|
+
* If not provided (undefined or false), the width will be auto-calculated from the container.
|
|
19
|
+
*/
|
|
20
|
+
width?: number | boolean;
|
|
18
21
|
}
|
|
19
|
-
|
|
22
|
+
interface ColorSliderComponent extends React.MemoExoticComponent<React.ForwardRefExoticComponent<ColorSliderProps & React.RefAttributes<HTMLDivElement>>> {
|
|
23
|
+
Thumb: typeof ColorSliderThumb;
|
|
24
|
+
Track: typeof ColorSliderTrack;
|
|
25
|
+
}
|
|
26
|
+
export declare const ColorSlider: ColorSliderComponent;
|
|
27
|
+
export type { ColorSliderThumbProps, ColorSliderTrackProps };
|
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { clamp } from "es-toolkit";
|
|
3
|
-
import { memo, forwardRef, useRef, useCallback, useEffect
|
|
3
|
+
import { memo, forwardRef, useRef, useState, useMemo, Children, isValidElement, useCallback, useEffect } from "react";
|
|
4
4
|
import { useEventCallback } from "usehooks-ts";
|
|
5
5
|
import { useColors } from "../context/colots-context.js";
|
|
6
|
+
import { ColorSliderThumb } from "./components/thumb.js";
|
|
7
|
+
import { ColorSliderTrack } from "./components/track.js";
|
|
8
|
+
import { ColorSliderContext } from "./context.js";
|
|
6
9
|
import { ColorSliderTv } from "./tv.js";
|
|
7
10
|
import { positionToSliderValue } from "../utils/position.js";
|
|
8
11
|
import { getSliderBackground } from "../utils/background.js";
|
|
12
|
+
import { useIsomorphicLayoutEffect } from "../../../../shared/hooks/use-isomorphic-layout-effect/use-isomorphic-layout-effect.js";
|
|
9
13
|
import { tcx } from "../../../../shared/utils/tcx/tcx.js";
|
|
10
14
|
import { mergeRefs } from "../../../../shared/utils/merge-refs/merge-refs.js";
|
|
11
|
-
import { translation } from "../contents/translation.js";
|
|
12
15
|
const KEYBOARD_STEPS = {
|
|
13
16
|
NORMAL: 0.01,
|
|
14
17
|
SHIFT: 0.1
|
|
15
18
|
};
|
|
16
|
-
const
|
|
19
|
+
const ColorSliderRoot = memo(
|
|
17
20
|
forwardRef(function ColorSlider2(props, ref) {
|
|
18
21
|
const {
|
|
19
22
|
position,
|
|
@@ -24,18 +27,68 @@ const ColorSlider = memo(
|
|
|
24
27
|
hue = 0,
|
|
25
28
|
backgroundStyle,
|
|
26
29
|
disabled = false,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
},
|
|
31
|
-
thumbSize = 14,
|
|
32
|
-
className
|
|
30
|
+
width: propsWidth = 256,
|
|
31
|
+
className,
|
|
32
|
+
children
|
|
33
33
|
} = props;
|
|
34
34
|
const { colorProfile } = useColors();
|
|
35
35
|
const sliderRef = useRef(null);
|
|
36
36
|
const thumbRef = useRef(null);
|
|
37
37
|
const inputRef = useRef(null);
|
|
38
38
|
const isDragging = useRef(false);
|
|
39
|
+
const [actualTrackWidth, setActualTrackWidth] = useState();
|
|
40
|
+
const trackWidth = typeof propsWidth === "number" ? propsWidth : actualTrackWidth;
|
|
41
|
+
const { hasCustomChildren, extractedThumbSize, extractedTrackHeight } = useMemo(() => {
|
|
42
|
+
const childArray = Children.toArray(children);
|
|
43
|
+
let hasCustom = false;
|
|
44
|
+
let thumbSizeFromChild;
|
|
45
|
+
let trackHeightFromChild;
|
|
46
|
+
for (const child of childArray) {
|
|
47
|
+
if (isValidElement(child)) {
|
|
48
|
+
const childType = child.type;
|
|
49
|
+
if (child.type === ColorSliderThumb || (childType == null ? void 0 : childType.displayName) === "ColorSliderThumb") {
|
|
50
|
+
hasCustom = true;
|
|
51
|
+
const childProps = child.props;
|
|
52
|
+
if (childProps.size !== void 0) {
|
|
53
|
+
thumbSizeFromChild = childProps.size;
|
|
54
|
+
}
|
|
55
|
+
} else if (child.type === ColorSliderTrack || (childType == null ? void 0 : childType.displayName) === "ColorSliderTrack") {
|
|
56
|
+
hasCustom = true;
|
|
57
|
+
const childProps = child.props;
|
|
58
|
+
if (childProps.height !== void 0) {
|
|
59
|
+
trackHeightFromChild = childProps.height;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
hasCustomChildren: hasCustom,
|
|
66
|
+
extractedThumbSize: thumbSizeFromChild,
|
|
67
|
+
extractedTrackHeight: trackHeightFromChild
|
|
68
|
+
};
|
|
69
|
+
}, [children]);
|
|
70
|
+
const trackHeight = extractedTrackHeight ?? 16;
|
|
71
|
+
const thumbSize = extractedThumbSize ?? trackHeight;
|
|
72
|
+
useIsomorphicLayoutEffect(() => {
|
|
73
|
+
if (typeof propsWidth !== "number" && sliderRef.current) {
|
|
74
|
+
const updateWidth = () => {
|
|
75
|
+
if (sliderRef.current) {
|
|
76
|
+
const width = sliderRef.current.getBoundingClientRect().width;
|
|
77
|
+
if (width > 0) {
|
|
78
|
+
setActualTrackWidth(width);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
updateWidth();
|
|
83
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
84
|
+
updateWidth();
|
|
85
|
+
});
|
|
86
|
+
resizeObserver.observe(sliderRef.current);
|
|
87
|
+
return () => {
|
|
88
|
+
resizeObserver.disconnect();
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
}, [propsWidth]);
|
|
39
92
|
const updatePosition = useEventCallback((clientX, isEnd) => {
|
|
40
93
|
var _a;
|
|
41
94
|
const rect = (_a = sliderRef.current) == null ? void 0 : _a.getBoundingClientRect();
|
|
@@ -117,69 +170,94 @@ const ColorSlider = memo(
|
|
|
117
170
|
(_a = inputRef.current) == null ? void 0 : _a.blur();
|
|
118
171
|
}
|
|
119
172
|
}, [disabled]);
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
const
|
|
173
|
+
const computedTrackWidth = trackWidth ?? 256;
|
|
174
|
+
const thumbWrapperStyle = useMemo(() => {
|
|
175
|
+
const minTransform = 0;
|
|
176
|
+
const maxTransform = computedTrackWidth - thumbSize;
|
|
123
177
|
const transformX = minTransform + position * (maxTransform - minTransform);
|
|
124
178
|
return {
|
|
125
179
|
width: thumbSize,
|
|
126
180
|
height: thumbSize,
|
|
127
181
|
transform: `translate(${transformX}px, -50%)`,
|
|
182
|
+
willChange: isDragging.current ? "transform" : "auto"
|
|
183
|
+
};
|
|
184
|
+
}, [position, thumbSize, computedTrackWidth]);
|
|
185
|
+
const thumbStyle = useMemo(() => {
|
|
186
|
+
return {
|
|
187
|
+
"--thumb-size": `${thumbSize}px`,
|
|
128
188
|
backgroundColor: positionToSliderValue(position, type, hue),
|
|
129
|
-
willChange: isDragging.current ? "transform" : "auto",
|
|
130
189
|
boxShadow: `
|
|
131
190
|
inset 0 0 0 3px white,
|
|
132
191
|
inset 0 0 0 4px rgba(0,0,0,0.2),
|
|
133
192
|
0 0 0 1px rgba(0,0,0,0.2)
|
|
134
193
|
`
|
|
135
194
|
};
|
|
136
|
-
}, [position,
|
|
137
|
-
const
|
|
195
|
+
}, [position, type, hue]);
|
|
196
|
+
const trackStyle = useMemo(
|
|
138
197
|
() => ({
|
|
139
198
|
...getSliderBackground(type, hue, colorProfile),
|
|
140
|
-
...backgroundStyle
|
|
199
|
+
...backgroundStyle,
|
|
200
|
+
boxShadow: "inset 0 0 0 1px rgba(0,0,0,0.1)"
|
|
141
201
|
}),
|
|
142
202
|
[type, hue, colorProfile, backgroundStyle]
|
|
143
203
|
);
|
|
144
|
-
const
|
|
145
|
-
|
|
204
|
+
const tv = useMemo(() => ColorSliderTv({ disabled }), [disabled]);
|
|
205
|
+
const contextValue = useMemo(
|
|
206
|
+
() => ({
|
|
207
|
+
position,
|
|
208
|
+
disabled,
|
|
209
|
+
type,
|
|
210
|
+
hue,
|
|
211
|
+
thumbSize,
|
|
212
|
+
trackWidth: computedTrackWidth,
|
|
213
|
+
trackHeight,
|
|
214
|
+
thumbWrapperStyle,
|
|
215
|
+
thumbStyle,
|
|
216
|
+
trackStyle,
|
|
217
|
+
thumbRef,
|
|
218
|
+
inputRef,
|
|
219
|
+
isDragging,
|
|
220
|
+
handlePointerDown,
|
|
221
|
+
handleKeyDown,
|
|
222
|
+
tv
|
|
223
|
+
}),
|
|
224
|
+
[
|
|
225
|
+
position,
|
|
226
|
+
disabled,
|
|
227
|
+
type,
|
|
228
|
+
hue,
|
|
229
|
+
thumbSize,
|
|
230
|
+
computedTrackWidth,
|
|
231
|
+
trackHeight,
|
|
232
|
+
thumbWrapperStyle,
|
|
233
|
+
thumbStyle,
|
|
234
|
+
trackStyle,
|
|
235
|
+
handlePointerDown,
|
|
236
|
+
handleKeyDown,
|
|
237
|
+
tv
|
|
238
|
+
]
|
|
239
|
+
);
|
|
240
|
+
return /* @__PURE__ */ jsx(ColorSliderContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(
|
|
146
241
|
"div",
|
|
147
242
|
{
|
|
148
243
|
ref: mergeRefs(ref, sliderRef),
|
|
149
244
|
onPointerDown: handleSliderPointerDown,
|
|
150
245
|
style: {
|
|
151
|
-
...
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
width: trackSize == null ? void 0 : trackSize.width
|
|
246
|
+
...trackStyle,
|
|
247
|
+
height: trackHeight,
|
|
248
|
+
width: typeof propsWidth === "number" ? propsWidth : void 0
|
|
155
249
|
},
|
|
156
|
-
className: tcx(
|
|
157
|
-
children: /* @__PURE__ */ jsx(
|
|
158
|
-
"div",
|
|
159
|
-
{
|
|
160
|
-
ref: thumbRef,
|
|
161
|
-
onPointerDown: handlePointerDown,
|
|
162
|
-
className: styles.thumb(),
|
|
163
|
-
style: thumbStyle,
|
|
164
|
-
children: /* @__PURE__ */ jsx(
|
|
165
|
-
"input",
|
|
166
|
-
{
|
|
167
|
-
ref: inputRef,
|
|
168
|
-
type: "text",
|
|
169
|
-
onKeyDown: handleKeyDown,
|
|
170
|
-
className: styles.thumbInput(),
|
|
171
|
-
"aria-label": translation.slider.ARIA_LABEL,
|
|
172
|
-
tabIndex: disabled ? -1 : 0,
|
|
173
|
-
readOnly: true
|
|
174
|
-
}
|
|
175
|
-
)
|
|
176
|
-
}
|
|
177
|
-
)
|
|
250
|
+
className: tcx(tv.root(), className),
|
|
251
|
+
children: hasCustomChildren ? children : /* @__PURE__ */ jsx(ColorSliderThumb, {})
|
|
178
252
|
}
|
|
179
|
-
);
|
|
253
|
+
) });
|
|
180
254
|
})
|
|
181
255
|
);
|
|
182
|
-
|
|
256
|
+
ColorSliderRoot.displayName = "ColorSlider";
|
|
257
|
+
const ColorSlider = Object.assign(ColorSliderRoot, {
|
|
258
|
+
Thumb: ColorSliderThumb,
|
|
259
|
+
Track: ColorSliderTrack
|
|
260
|
+
});
|
|
183
261
|
export {
|
|
184
262
|
ColorSlider
|
|
185
263
|
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface ColorSliderThumbProps {
|
|
2
|
+
className?: string;
|
|
3
|
+
size?: number;
|
|
4
|
+
}
|
|
5
|
+
export declare function ColorSliderThumb(props: ColorSliderThumbProps): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export declare namespace ColorSliderThumb {
|
|
7
|
+
var displayName: string;
|
|
8
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useColorSlider } from "../context.js";
|
|
3
|
+
import { tcx } from "../../../../../shared/utils/tcx/tcx.js";
|
|
4
|
+
import { translation } from "../../contents/translation.js";
|
|
5
|
+
function ColorSliderThumb(props) {
|
|
6
|
+
const { className } = props;
|
|
7
|
+
const {
|
|
8
|
+
thumbRef,
|
|
9
|
+
inputRef,
|
|
10
|
+
thumbWrapperStyle,
|
|
11
|
+
thumbStyle,
|
|
12
|
+
disabled,
|
|
13
|
+
handlePointerDown,
|
|
14
|
+
handleKeyDown,
|
|
15
|
+
tv
|
|
16
|
+
} = useColorSlider();
|
|
17
|
+
return /* @__PURE__ */ jsx(
|
|
18
|
+
"div",
|
|
19
|
+
{
|
|
20
|
+
ref: thumbRef,
|
|
21
|
+
onPointerDown: handlePointerDown,
|
|
22
|
+
className: tv.thumbWrapper(),
|
|
23
|
+
style: thumbWrapperStyle,
|
|
24
|
+
children: /* @__PURE__ */ jsx(
|
|
25
|
+
"div",
|
|
26
|
+
{
|
|
27
|
+
className: tcx(tv.thumb(), className),
|
|
28
|
+
style: thumbStyle,
|
|
29
|
+
children: /* @__PURE__ */ jsx(
|
|
30
|
+
"input",
|
|
31
|
+
{
|
|
32
|
+
ref: inputRef,
|
|
33
|
+
type: "text",
|
|
34
|
+
onKeyDown: handleKeyDown,
|
|
35
|
+
className: tv.thumbInput(),
|
|
36
|
+
"aria-label": translation.slider.ARIA_LABEL,
|
|
37
|
+
tabIndex: disabled ? -1 : 0,
|
|
38
|
+
readOnly: true
|
|
39
|
+
}
|
|
40
|
+
)
|
|
41
|
+
}
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
ColorSliderThumb.displayName = "ColorSliderThumb";
|
|
47
|
+
export {
|
|
48
|
+
ColorSliderThumb
|
|
49
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface ColorSliderTrackProps {
|
|
2
|
+
className?: string;
|
|
3
|
+
children?: React.ReactNode;
|
|
4
|
+
/**
|
|
5
|
+
* Height of the track in pixels.
|
|
6
|
+
* This prop is extracted by the parent ColorSlider and passed via context.
|
|
7
|
+
*/
|
|
8
|
+
height?: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* ColorSliderTrack - The track background of the color slider.
|
|
12
|
+
* Renders the gradient background based on slider type (hue, alpha, etc.)
|
|
13
|
+
* Can contain custom children for additional visual elements.
|
|
14
|
+
*/
|
|
15
|
+
export declare function ColorSliderTrack(props: ColorSliderTrackProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export declare namespace ColorSliderTrack {
|
|
17
|
+
var displayName: string;
|
|
18
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useColorSlider } from "../context.js";
|
|
3
|
+
import { tcx } from "../../../../../shared/utils/tcx/tcx.js";
|
|
4
|
+
function ColorSliderTrack(props) {
|
|
5
|
+
const { className, children, height: _height } = props;
|
|
6
|
+
const { trackStyle } = useColorSlider();
|
|
7
|
+
return /* @__PURE__ */ jsx(
|
|
8
|
+
"div",
|
|
9
|
+
{
|
|
10
|
+
className: tcx("absolute inset-0 rounded-full", className),
|
|
11
|
+
style: trackStyle,
|
|
12
|
+
children
|
|
13
|
+
}
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
ColorSliderTrack.displayName = "ColorSliderTrack";
|
|
17
|
+
export {
|
|
18
|
+
ColorSliderTrack
|
|
19
|
+
};
|