@kobalte/core
Version:
Unstyled components and primitives for building accessible web apps and design systems with SolidJS.
183 lines (178 loc) • 6.96 kB
JavaScript
import { COLOR_INTL_TRANSLATIONS, parseColor } from '../chunk/MQHWXXI2.js';
import { SliderInput, SliderValueLabel, SliderRoot, SliderThumb, useSliderContext, SliderTrack } from '../chunk/UQ2TD6AR.js';
export { SliderInput as Input, SliderValueLabel as ValueLabel } from '../chunk/UQ2TD6AR.js';
import { useLocale } from '../chunk/XHJPQEZP.js';
import { FormControlLabel } from '../chunk/7ZHN3PYD.js';
export { FormControlLabel as Label } from '../chunk/7ZHN3PYD.js';
import { FormControlErrorMessage } from '../chunk/ICNSTULC.js';
export { FormControlErrorMessage as ErrorMessage } from '../chunk/ICNSTULC.js';
import { FormControlDescription } from '../chunk/YKGT7A57.js';
export { FormControlDescription as Description } from '../chunk/YKGT7A57.js';
import { createControllableSignal } from '../chunk/BLN63FDC.js';
import { createComponent, mergeProps } from 'solid-js/web';
import { mergeDefaultProps } from '@kobalte/utils';
import { createContext, useContext, createUniqueId, splitProps, createMemo } from 'solid-js';
import { combineStyle } from '@solid-primitives/props';
var ColorSliderContext = createContext();
function useColorSliderContext() {
const context = useContext(ColorSliderContext);
if (context === void 0) {
throw new Error("[kobalte]: `useColorSliderContext` must be used within a `ColorSlider.Root` component");
}
return context;
}
// src/color-slider/color-slider-root.tsx
function ColorSliderRoot(props) {
const defaultId = `colorslider-${createUniqueId()}`;
const mergedProps = mergeDefaultProps({
id: defaultId,
translations: COLOR_INTL_TRANSLATIONS,
defaultValue: parseColor("hsl(0, 100%, 50%)")
}, props);
const [local, others] = splitProps(mergedProps, ["value", "defaultValue", "onChange", "onChangeEnd", "channel", "colorSpace", "getValueLabel", "translations"]);
const [value, setValue] = createControllableSignal({
value: () => local.value,
defaultValue: () => local.defaultValue,
onChange: (value2) => local.onChange?.(value2)
});
const color = createMemo(() => {
return local.colorSpace ? value().toFormat(local.colorSpace) : value();
});
const onChange = (value2) => {
setValue(color().withChannelValue(local.channel, value2[0]));
};
const onChangeEnd = (value2) => {
local.onChangeEnd?.(color().withChannelValue(local.channel, value2[0]));
};
const getValueLabel = createMemo(() => {
if (local.getValueLabel) {
return local.getValueLabel(color());
}
return color().formatChannelValue(local.channel);
});
const getDisplayColor = createMemo(() => {
switch (local.channel) {
case "hue":
return parseColor(`hsl(${color().getChannelValue("hue")}, 100%, 50%)`);
case "lightness":
case "brightness":
case "saturation":
case "red":
case "green":
case "blue":
return color().withChannelValue("alpha", 1);
case "alpha": {
return color();
}
default:
throw new Error(`Unknown color channel: ${local.channel}`);
}
});
const context = {
value: color,
channel: () => local.channel,
getDisplayColor,
translations: () => local.translations
};
return createComponent(ColorSliderContext.Provider, {
value: context,
get children() {
return createComponent(SliderRoot, mergeProps({
get value() {
return [color().getChannelValue(local.channel)];
},
onChange,
onChangeEnd,
getValueLabel
}, () => color().getChannelRange(local.channel), others));
}
});
}
function ColorSliderThumb(props) {
const context = useColorSliderContext();
const [local, others] = splitProps(props, ["style"]);
const valueText = createMemo(() => {
const formattedValue = context.value()?.formatChannelValue(context.channel());
if (context.channel() === "hue") {
return `${formattedValue}, ${context.getDisplayColor().getHueName(context.translations())}`;
}
if (context.channel() !== "alpha") {
return `${formattedValue}, ${context.getDisplayColor().getColorName(context.translations())}`;
}
return formattedValue;
});
return createComponent(SliderThumb, mergeProps({
get style() {
return combineStyle({
"forced-color-adjust": "none",
"--kb-color-current": context.value().toString()
}, local.style);
},
get ["aria-valuetext"]() {
return valueText();
}
}, others));
}
function ColorSliderTrack(props) {
const sliderContext = useSliderContext();
const context = useColorSliderContext();
const [local, others] = splitProps(props, ["style"]);
const {
direction
} = useLocale();
const backgroundStyles = createMemo(() => {
let to;
if (sliderContext.state.orientation() === "vertical") {
to = "top";
} else if (direction() === "ltr") {
to = "right";
} else {
to = "left";
}
switch (context.channel()) {
case "hue": {
const stops = [0, 60, 120, 180, 240, 300, 360].map((hue) => context.getDisplayColor().withChannelValue("hue", hue).toString("css")).join(", ");
return `linear-gradient(to ${to}, ${stops})`;
}
case "lightness": {
const min = sliderContext.state.getThumbMinValue(0);
const max = sliderContext.state.getThumbMaxValue(0);
const start = context.getDisplayColor().withChannelValue(context.channel(), min).toString("css");
const middle = context.getDisplayColor().withChannelValue(context.channel(), (max - min) / 2).toString("css");
const end = context.getDisplayColor().withChannelValue(context.channel(), max).toString("css");
return `linear-gradient(to ${to}, ${start}, ${middle}, ${end})`;
}
case "saturation":
case "brightness":
case "red":
case "green":
case "blue":
case "alpha": {
const start = context.getDisplayColor().withChannelValue(context.channel(), sliderContext.state.getThumbMinValue(0)).toString("css");
const end = context.getDisplayColor().withChannelValue(context.channel(), sliderContext.state.getThumbMaxValue(0)).toString("css");
return `linear-gradient(to ${to}, ${start}, ${end})`;
}
default:
throw new Error(`Unknown color channel: ${context.channel()}`);
}
});
return createComponent(SliderTrack, mergeProps({
get style() {
return combineStyle({
"forced-color-adjust": "none",
background: backgroundStyles()
}, local.style);
}
}, others));
}
// src/color-slider/index.tsx
var ColorSlider = Object.assign(ColorSliderRoot, {
Description: FormControlDescription,
ErrorMessage: FormControlErrorMessage,
Input: SliderInput,
Label: FormControlLabel,
Thumb: ColorSliderThumb,
Track: ColorSliderTrack,
ValueLabel: SliderValueLabel
});
export { ColorSlider, ColorSliderRoot as Root, ColorSliderThumb as Thumb, ColorSliderTrack as Track, useColorSliderContext };