@kobalte/core
Version:
Unstyled components and primitives for building accessible web apps and design systems with SolidJS.
264 lines (259 loc) • 8.71 kB
JavaScript
import { createToggleState } from './YGDQXQ2B.js';
import { FORM_CONTROL_FIELD_PROP_NAMES, createFormControlField } from './HYP2U57X.js';
import { FormControlLabel } from './7ZHN3PYD.js';
import { createFormResetListener } from './ANN3A2QM.js';
import { FormControlErrorMessage } from './ICNSTULC.js';
import { useFormControlContext, FormControlDescription, FORM_CONTROL_PROP_NAMES, createFormControl, FormControlContext } from './YKGT7A57.js';
import { Polymorphic } from './6Y7B2NEO.js';
import { __export } from './5ZKAE4VZ.js';
import { createComponent, mergeProps, memo } from 'solid-js/web';
import { mergeDefaultProps, mergeRefs, visuallyHiddenStyles, createGenerateId, access, isFunction, callHandler, EventKey } from '@kobalte/utils';
import { createContext, useContext, splitProps, createUniqueId, createSignal, createMemo, children } from 'solid-js';
import { combineStyle } from '@solid-primitives/props';
// src/switch/index.tsx
var switch_exports = {};
__export(switch_exports, {
Control: () => SwitchControl,
Description: () => SwitchDescription,
ErrorMessage: () => SwitchErrorMessage,
Input: () => SwitchInput,
Label: () => SwitchLabel,
Root: () => SwitchRoot,
Switch: () => Switch,
Thumb: () => SwitchThumb,
useSwitchContext: () => useSwitchContext
});
var SwitchContext = createContext();
function useSwitchContext() {
const context = useContext(SwitchContext);
if (context === void 0) {
throw new Error("[kobalte]: `useSwitchContext` must be used within a `Switch` component");
}
return context;
}
// src/switch/switch-control.tsx
function SwitchControl(props) {
const formControlContext = useFormControlContext();
const context = useSwitchContext();
const mergedProps = mergeDefaultProps({
id: context.generateId("control")
}, props);
const [local, others] = splitProps(mergedProps, ["onClick", "onKeyDown"]);
const onClick = (e) => {
callHandler(e, local.onClick);
context.toggle();
context.inputRef()?.focus();
};
const onKeyDown = (e) => {
callHandler(e, local.onKeyDown);
if (e.key === EventKey.Space) {
context.toggle();
context.inputRef()?.focus();
}
};
return createComponent(Polymorphic, mergeProps({
as: "div",
onClick,
onKeyDown
}, () => formControlContext.dataset(), () => context.dataset(), others));
}
function SwitchDescription(props) {
const context = useSwitchContext();
return createComponent(FormControlDescription, mergeProps(() => context.dataset(), props));
}
function SwitchErrorMessage(props) {
const context = useSwitchContext();
return createComponent(FormControlErrorMessage, mergeProps(() => context.dataset(), props));
}
function SwitchInput(props) {
const formControlContext = useFormControlContext();
const context = useSwitchContext();
const mergedProps = mergeDefaultProps({
id: context.generateId("input")
}, props);
const [local, formControlFieldProps, others] = splitProps(mergedProps, ["ref", "style", "onChange", "onFocus", "onBlur"], FORM_CONTROL_FIELD_PROP_NAMES);
const {
fieldProps
} = createFormControlField(formControlFieldProps);
const onChange = (e) => {
callHandler(e, local.onChange);
e.stopPropagation();
const target = e.target;
context.setIsChecked(target.checked);
target.checked = context.checked();
};
const onFocus = (e) => {
callHandler(e, local.onFocus);
context.setIsFocused(true);
};
const onBlur = (e) => {
callHandler(e, local.onBlur);
context.setIsFocused(false);
};
return createComponent(Polymorphic, mergeProps({
as: "input",
ref(r$) {
const _ref$ = mergeRefs(context.setInputRef, local.ref);
typeof _ref$ === "function" && _ref$(r$);
},
type: "checkbox",
role: "switch",
get id() {
return fieldProps.id();
},
get name() {
return formControlContext.name();
},
get value() {
return context.value();
},
get checked() {
return context.checked();
},
get required() {
return formControlContext.isRequired();
},
get disabled() {
return formControlContext.isDisabled();
},
get readonly() {
return formControlContext.isReadOnly();
},
get style() {
return combineStyle({
...visuallyHiddenStyles
}, local.style);
},
get ["aria-checked"]() {
return context.checked();
},
get ["aria-label"]() {
return fieldProps.ariaLabel();
},
get ["aria-labelledby"]() {
return fieldProps.ariaLabelledBy();
},
get ["aria-describedby"]() {
return fieldProps.ariaDescribedBy();
},
get ["aria-invalid"]() {
return formControlContext.validationState() === "invalid" || void 0;
},
get ["aria-required"]() {
return formControlContext.isRequired() || void 0;
},
get ["aria-disabled"]() {
return formControlContext.isDisabled() || void 0;
},
get ["aria-readonly"]() {
return formControlContext.isReadOnly() || void 0;
},
onChange,
onFocus,
onBlur
}, () => formControlContext.dataset(), () => context.dataset(), others));
}
function SwitchLabel(props) {
const context = useSwitchContext();
return createComponent(FormControlLabel, mergeProps(() => context.dataset(), props));
}
function SwitchRoot(props) {
let ref;
const defaultId = `switch-${createUniqueId()}`;
const mergedProps = mergeDefaultProps({
value: "on",
id: defaultId
}, props);
const [local, formControlProps, others] = splitProps(mergedProps, ["ref", "children", "value", "checked", "defaultChecked", "onChange", "onPointerDown"], FORM_CONTROL_PROP_NAMES);
const [inputRef, setInputRef] = createSignal();
const [isFocused, setIsFocused] = createSignal(false);
const {
formControlContext
} = createFormControl(formControlProps);
const state = createToggleState({
isSelected: () => local.checked,
defaultIsSelected: () => local.defaultChecked,
onSelectedChange: (selected) => local.onChange?.(selected),
isDisabled: () => formControlContext.isDisabled(),
isReadOnly: () => formControlContext.isReadOnly()
});
createFormResetListener(() => ref, () => state.setIsSelected(local.defaultChecked ?? false));
const onPointerDown = (e) => {
callHandler(e, local.onPointerDown);
if (isFocused()) {
e.preventDefault();
}
};
const dataset = createMemo(() => ({
"data-checked": state.isSelected() ? "" : void 0
}));
const context = {
value: () => local.value,
dataset,
checked: () => state.isSelected(),
inputRef,
generateId: createGenerateId(() => access(formControlProps.id)),
toggle: () => state.toggle(),
setIsChecked: (isChecked) => state.setIsSelected(isChecked),
setIsFocused,
setInputRef
};
return createComponent(FormControlContext.Provider, {
value: formControlContext,
get children() {
return createComponent(SwitchContext.Provider, {
value: context,
get children() {
return createComponent(Polymorphic, mergeProps({
as: "div",
ref(r$) {
const _ref$ = mergeRefs((el) => ref = el, local.ref);
typeof _ref$ === "function" && _ref$(r$);
},
role: "group",
get id() {
return access(formControlProps.id);
},
onPointerDown
}, () => formControlContext.dataset(), dataset, others, {
get children() {
return createComponent(SwitchRootChild, {
state: context,
get children() {
return local.children;
}
});
}
}));
}
});
}
});
}
function SwitchRootChild(props) {
const resolvedChildren = children(() => {
const body = props.children;
return isFunction(body) ? body(props.state) : body;
});
return memo(resolvedChildren);
}
function SwitchThumb(props) {
const formControlContext = useFormControlContext();
const context = useSwitchContext();
const mergedProps = mergeDefaultProps({
id: context.generateId("thumb")
}, props);
return createComponent(Polymorphic, mergeProps({
as: "div"
}, () => formControlContext.dataset(), () => context.dataset(), mergedProps));
}
// src/switch/index.tsx
var Switch = Object.assign(SwitchRoot, {
Control: SwitchControl,
Description: SwitchDescription,
ErrorMessage: SwitchErrorMessage,
Input: SwitchInput,
Label: SwitchLabel,
Thumb: SwitchThumb
});
export { Switch, SwitchControl, SwitchDescription, SwitchErrorMessage, SwitchInput, SwitchLabel, SwitchRoot, SwitchThumb, switch_exports, useSwitchContext };