UNPKG

@kobalte/core

Version:

Unstyled components and primitives for building accessible web apps and design systems with SolidJS.

183 lines (178 loc) 6.96 kB
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 };