@kobalte/core
Version:
Unstyled components and primitives for building accessible web apps and design systems with SolidJS.
114 lines (109 loc) • 3.63 kB
JavaScript
import { parseColor } from '../chunk/MQHWXXI2.js';
import { TextFieldInput, TextFieldRoot } from '../chunk/GWY7DBQ7.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 { composeEventHandlers, mergeDefaultProps } from '@kobalte/utils';
import { createContext, useContext, splitProps, createUniqueId, createMemo, createSignal, batch } from 'solid-js';
var ColorFieldContext = createContext();
function useColorFieldContext() {
const context = useContext(ColorFieldContext);
if (context === void 0) {
throw new Error("[kobalte]: `useColorFieldContext` must be used within a `ColorField` component");
}
return context;
}
// src/color-field/color-field-input.tsx
function ColorFieldInput(props) {
const context = useColorFieldContext();
const [local, others] = splitProps(props, ["onBlur"]);
return createComponent(TextFieldInput, mergeProps({
autoComplete: "off",
autoCorrect: "off",
spellCheck: "false",
get onBlur() {
return composeEventHandlers([local.onBlur, context.onBlur]);
}
}, others));
}
function ColorFieldRoot(props) {
const defaultId = `colorfield-${createUniqueId()}`;
const mergedProps = mergeDefaultProps({
id: defaultId
}, props);
const [local, others] = splitProps(mergedProps, ["value", "defaultValue", "onChange"]);
const defaultValue = createMemo(() => {
let defaultValue2 = local.defaultValue;
try {
defaultValue2 = parseColor(defaultValue2?.startsWith("#") ? defaultValue2 : `#${defaultValue2}`).toString("hex");
} catch {
defaultValue2 = "";
}
return defaultValue2;
});
const [value, setValue] = createControllableSignal({
value: () => local.value,
defaultValue,
onChange: (value2) => local.onChange?.(value2)
});
const [prevValue, setPrevValue] = createSignal(value());
const onChange = (value2) => {
if (isAllowedInput(value2)) {
setValue(value2);
}
};
const onBlur = (e) => {
if (!value().length) {
setPrevValue("");
return;
}
let newValue;
try {
newValue = parseColor(value().startsWith("#") ? value() : `#${value()}`).toString("hex");
} catch {
if (prevValue()) {
setValue(prevValue());
} else {
setValue("");
}
return;
}
batch(() => {
setValue(newValue);
setPrevValue(newValue);
});
};
const context = {
onBlur
};
return createComponent(ColorFieldContext.Provider, {
value: context,
get children() {
return createComponent(TextFieldRoot, mergeProps({
get value() {
return value();
},
get defaultValue() {
return defaultValue();
},
onChange
}, others));
}
});
}
function isAllowedInput(value) {
return value === "" || !!value.match(/^#?[0-9a-f]{0,6}$/i)?.[0];
}
// src/color-field/index.tsx
var ColorField = Object.assign(ColorFieldRoot, {
Description: FormControlDescription,
ErrorMessage: FormControlErrorMessage,
Input: ColorFieldInput,
Label: FormControlLabel
});
export { ColorField, ColorFieldInput as Input, ColorFieldRoot as Root, useColorFieldContext };