@veracity/vui
Version:
Veracity UI is a React component library crafted for use within Veracity applications and pages. Based on Styled Components and @xstyled.
149 lines (144 loc) • 4.4 kB
JavaScript
import { filterUndefined } from "../utils/object.js";
import { cs } from "../utils/styles.js";
import { switchColors } from "./consts.js";
import { omitThemingProps, useStyleConfig } from "../core/theme.js";
import styled from "../core/styled.js";
import vui from "../core/vui.js";
import { useSwitchContext } from "./context.js";
import { useEffect, useRef, useState } from "react";
import { jsx, jsxs } from "react/jsx-runtime";
//#region src/switch/switchButton.tsx
const SwitchInput = styled.inputBox`
cursor: inherit;
height: calc(100% + 10px);
left: -5px;
margin: 0;
opacity: 0;
padding: 0;
position: absolute;
top: -5px;
width: calc(100% + 10px);
z-index: 1;
`;
const SwitchFoundation = styled.spanBox`
border-radius: 100px;
display: inline-flex;
flex-shrink: 0;
transition-duration: fast;
position: relative;
`;
/** Circular element that moves along the track when toggled. */
const SwitchThumb = styled(SwitchFoundation)`
position: absolute;
`;
/** Track element along which the thumb moves when toggled. */
const SwitchTrack = styled(SwitchFoundation)`
align-items: center;
flex: 1;
`;
const SwitchButtonBase = styled(SwitchFoundation)`
color: white;
cursor: pointer;
--x-ring-color: green;
&[aria-disabled='true'] {
cursor: not-allowed;
.vui-switchThumb {
background-color: ${switchColors.disabled};
}
.vui-switchTrack {
--x-ring-color: ${switchColors.disabled};
background-color: ${switchColors.disabledBg};
color: ${switchColors.disabled};
}
}
`;
/**
* Controls the logic and visuals of multiple inner parts, such as input, track or thumb elements.
* Handles controlled and uncontrolled modes.
*/
const SwitchButton = vui((props, ref) => {
const mergedProps = {
...useSwitchContext(),
...props
};
const { checked, className, defaultChecked, disabled, id, innerLabelOff, innerLabelOn, inputProps, inputRef, name, onBlur, onChange, onFocus, required, value, ...rest } = omitThemingProps(mergedProps);
const { current: isControlled } = useRef(checked !== void 0);
const [isChecked, setIsChecked] = useState(checked ?? defaultChecked);
const [isFocused, setIsFocused] = useState(false);
const { thumb: thumbStyles, track: trackStyles, ...buttonStyles } = useStyleConfig("Switch", useSwitchContext()).button;
useEffect(() => {
if (isControlled) setIsChecked(checked);
}, [checked, isControlled]);
function handleOnBlur(e) {
setIsFocused(false);
onBlur?.(e);
}
function handleOnChange(e) {
if (!isControlled) setIsChecked(e.target.checked);
onChange?.(e);
}
function handleOnFocus(e) {
setIsFocused(true);
onFocus?.(e);
}
const hDiff = (thumbStyles.h - trackStyles.h) / 2;
const thumbOffset = `calc(100% - ${Math.abs(hDiff - thumbStyles.h)}px)`;
const labelOffset = `${thumbStyles.h - hDiff + 4}px`;
const aliasedProps = filterUndefined({
"aria-disabled": disabled,
"data-focused": isFocused ? true : false
});
const thumbAliasedProps = filterUndefined({
left: isChecked ? thumbOffset : -hDiff,
ring: isFocused ? thumbStyles.ring : 0
});
const trackAliasedProps = filterUndefined({
bg: isChecked ? trackStyles.bg : innerLabelOff ? switchColors.offBgContrast : switchColors.offBg,
pl: isChecked ? 1 : labelOffset,
pr: isChecked ? labelOffset : 1,
ring: !disabled ? isFocused ? trackStyles.ring : 0 : 3
});
return /* @__PURE__ */ jsxs(SwitchButtonBase, {
className: cs("vui-switchButton", className),
ref,
...buttonStyles,
...aliasedProps,
...rest,
children: [/* @__PURE__ */ jsx(SwitchInput, {
className: "vui-switchInput",
onBlur: handleOnBlur,
onChange: handleOnChange,
onFocus: handleOnFocus,
ref: inputRef,
tabIndex: -1,
type: "checkbox",
checked,
defaultChecked,
disabled,
id,
name,
required,
value,
...inputProps
}), /* @__PURE__ */ jsxs(SwitchTrack, {
className: "vui-switchTrack",
tabIndex: 0,
...trackStyles,
...trackAliasedProps,
children: [
!isChecked && innerLabelOff,
/* @__PURE__ */ jsx(SwitchThumb, {
className: "vui-switchThumb",
...thumbStyles,
...thumbAliasedProps
}),
isChecked && innerLabelOn
]
})]
});
});
SwitchButton.displayName = "SwitchButton";
//#endregion
export { SwitchButton, SwitchButton as default, SwitchButtonBase };
globalThis.__vuiVersion__ = "5.3.1"
//# sourceMappingURL=switchButton.js.map