mirror of
https://github.com/nextui-org/nextui.git
synced 2025-12-08 19:26:11 +00:00
feat(switch): data management improved, animation improved
This commit is contained in:
parent
af7d07ab66
commit
da5aa53a6c
@ -3,9 +3,9 @@ import type {FocusableRef} from "@react-types/shared";
|
|||||||
import type {AriaSwitchProps} from "@react-aria/switch";
|
import type {AriaSwitchProps} from "@react-aria/switch";
|
||||||
import type {HTMLNextUIProps, PropGetter} from "@nextui-org/system";
|
import type {HTMLNextUIProps, PropGetter} from "@nextui-org/system";
|
||||||
|
|
||||||
import {ReactNode, Ref, useCallback, useId, useRef} from "react";
|
import {ReactNode, Ref, useCallback, useId, useRef, useState} from "react";
|
||||||
import {mapPropsVariants} from "@nextui-org/system";
|
import {mapPropsVariants} from "@nextui-org/system";
|
||||||
import {useHover} from "@react-aria/interactions";
|
import {useHover, usePress} from "@react-aria/interactions";
|
||||||
import {toggle} from "@nextui-org/theme";
|
import {toggle} from "@nextui-org/theme";
|
||||||
import {chain, mergeProps} from "@react-aria/utils";
|
import {chain, mergeProps} from "@react-aria/utils";
|
||||||
import {clsx, dataAttr} from "@nextui-org/shared-utils";
|
import {clsx, dataAttr} from "@nextui-org/shared-utils";
|
||||||
@ -82,7 +82,7 @@ export function useSwitch(originalProps: UseSwitchProps) {
|
|||||||
as,
|
as,
|
||||||
name,
|
name,
|
||||||
value = "",
|
value = "",
|
||||||
isReadOnly = false,
|
isReadOnly: isReadOnlyProp = false,
|
||||||
autoFocus = false,
|
autoFocus = false,
|
||||||
startIcon,
|
startIcon,
|
||||||
endIcon,
|
endIcon,
|
||||||
@ -116,7 +116,7 @@ export function useSwitch(originalProps: UseSwitchProps) {
|
|||||||
defaultSelected,
|
defaultSelected,
|
||||||
isSelected: isSelectedProp,
|
isSelected: isSelectedProp,
|
||||||
isDisabled: !!originalProps.isDisabled,
|
isDisabled: !!originalProps.isDisabled,
|
||||||
isReadOnly,
|
isReadOnly: isReadOnlyProp,
|
||||||
"aria-label": ariaLabel,
|
"aria-label": ariaLabel,
|
||||||
"aria-labelledby": otherProps["aria-labelledby"] || labelId,
|
"aria-labelledby": otherProps["aria-labelledby"] || labelId,
|
||||||
onChange: onValueChange,
|
onChange: onValueChange,
|
||||||
@ -127,6 +127,7 @@ export function useSwitch(originalProps: UseSwitchProps) {
|
|||||||
labelId,
|
labelId,
|
||||||
children,
|
children,
|
||||||
autoFocus,
|
autoFocus,
|
||||||
|
isReadOnlyProp,
|
||||||
isSelectedProp,
|
isSelectedProp,
|
||||||
defaultSelected,
|
defaultSelected,
|
||||||
originalProps.isDisabled,
|
originalProps.isDisabled,
|
||||||
@ -136,12 +137,38 @@ export function useSwitch(originalProps: UseSwitchProps) {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
const state = useToggleState(ariaSwitchProps);
|
const state = useToggleState(ariaSwitchProps);
|
||||||
const {inputProps} = useReactAriaSwitch(ariaSwitchProps, state, inputRef);
|
|
||||||
|
const {inputProps, isPressed: isPressedKeyboard, isReadOnly} = useReactAriaSwitch(
|
||||||
|
ariaSwitchProps,
|
||||||
|
state,
|
||||||
|
inputRef,
|
||||||
|
);
|
||||||
const {focusProps, isFocused, isFocusVisible} = useFocusRing({autoFocus: inputProps.autoFocus});
|
const {focusProps, isFocused, isFocusVisible} = useFocusRing({autoFocus: inputProps.autoFocus});
|
||||||
const {hoverProps, isHovered} = useHover({
|
const {hoverProps, isHovered} = useHover({
|
||||||
isDisabled: inputProps.disabled,
|
isDisabled: inputProps.disabled,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const isInteractionDisabled = ariaSwitchProps.isDisabled || isReadOnly;
|
||||||
|
|
||||||
|
// Handle press state for full label. Keyboard press state is returned by useSwitch
|
||||||
|
// since it is handled on the <input> element itself.
|
||||||
|
const [isPressed, setPressed] = useState(false);
|
||||||
|
const {pressProps} = usePress({
|
||||||
|
isDisabled: isInteractionDisabled,
|
||||||
|
onPressStart(e) {
|
||||||
|
if (e.pointerType !== "keyboard") {
|
||||||
|
setPressed(true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onPressEnd(e) {
|
||||||
|
if (e.pointerType !== "keyboard") {
|
||||||
|
setPressed(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const pressed = isInteractionDisabled ? false : isPressed || isPressedKeyboard;
|
||||||
|
|
||||||
const isSelected = inputProps.checked;
|
const isSelected = inputProps.checked;
|
||||||
const isDisabled = inputProps.disabled;
|
const isDisabled = inputProps.disabled;
|
||||||
|
|
||||||
@ -149,80 +176,64 @@ export function useSwitch(originalProps: UseSwitchProps) {
|
|||||||
() =>
|
() =>
|
||||||
toggle({
|
toggle({
|
||||||
...variantProps,
|
...variantProps,
|
||||||
isFocusVisible,
|
|
||||||
}),
|
}),
|
||||||
[...Object.values(variantProps), isFocusVisible],
|
[...Object.values(variantProps)],
|
||||||
);
|
);
|
||||||
|
|
||||||
const baseStyles = clsx(classNames?.base, className);
|
const baseStyles = clsx(classNames?.base, className);
|
||||||
|
|
||||||
const getBaseProps: PropGetter = () => {
|
const getBaseProps: PropGetter = (props) => {
|
||||||
return {
|
return {
|
||||||
|
...mergeProps(hoverProps, pressProps, otherProps, props),
|
||||||
ref: domRef,
|
ref: domRef,
|
||||||
className: slots.base({class: baseStyles}),
|
className: slots.base({class: clsx(baseStyles, props?.className)}),
|
||||||
"data-disabled": dataAttr(isDisabled),
|
"data-disabled": dataAttr(isDisabled),
|
||||||
"data-checked": dataAttr(isSelected),
|
"data-checked": dataAttr(isSelected),
|
||||||
...mergeProps(hoverProps, otherProps),
|
"data-readonly": dataAttr(isReadOnly),
|
||||||
|
"data-focus": dataAttr(isFocused),
|
||||||
|
"data-focus-visible": dataAttr(isFocusVisible),
|
||||||
|
"data-hover": dataAttr(isHovered),
|
||||||
|
"data-pressed": dataAttr(pressed),
|
||||||
|
style: {
|
||||||
|
...props?.style,
|
||||||
|
WebkitTapHighlightColor: "transparent",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const getWrapperProps: PropGetter = useCallback(() => {
|
const getWrapperProps: PropGetter = useCallback(
|
||||||
return {
|
(props = {}) => {
|
||||||
"data-hover": dataAttr(isHovered),
|
return {
|
||||||
"data-checked": dataAttr(isSelected),
|
...props,
|
||||||
"data-focus": dataAttr(isFocused),
|
"aria-hidden": true,
|
||||||
"data-focus-visible": dataAttr(isFocused && isFocusVisible),
|
className: clsx(slots.wrapper({class: clsx(classNames?.wrapper, props?.className)})),
|
||||||
"data-disabled": dataAttr(isDisabled),
|
};
|
||||||
"data-readonly": dataAttr(inputProps.readOnly),
|
},
|
||||||
"aria-hidden": true,
|
[slots, classNames?.wrapper],
|
||||||
className: clsx(slots.wrapper({class: classNames?.wrapper})),
|
);
|
||||||
};
|
|
||||||
}, [
|
|
||||||
slots,
|
|
||||||
classNames?.wrapper,
|
|
||||||
isHovered,
|
|
||||||
isSelected,
|
|
||||||
isFocused,
|
|
||||||
isFocusVisible,
|
|
||||||
isDisabled,
|
|
||||||
inputProps.readOnly,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const getInputProps: PropGetter = () => {
|
const getInputProps: PropGetter = (props = {}) => {
|
||||||
return {
|
return {
|
||||||
|
...mergeProps(inputProps, focusProps, props),
|
||||||
ref: inputRef,
|
ref: inputRef,
|
||||||
id: inputProps.id,
|
id: inputProps.id,
|
||||||
...mergeProps(inputProps, focusProps),
|
|
||||||
onChange: chain(onChange, inputProps.onChange),
|
onChange: chain(onChange, inputProps.onChange),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const getThumbProps: PropGetter = useCallback(
|
const getThumbProps: PropGetter = useCallback(
|
||||||
() => ({
|
(props = {}) => ({
|
||||||
"data-checked": dataAttr(isSelected),
|
...props,
|
||||||
"data-focus": dataAttr(isFocused),
|
className: slots.thumb({class: clsx(classNames?.thumb, props?.className)}),
|
||||||
"data-focus-visible": dataAttr(isFocused && isFocusVisible),
|
|
||||||
"data-disabled": dataAttr(isDisabled),
|
|
||||||
"data-readonly": dataAttr(inputProps.readOnly),
|
|
||||||
className: slots.thumb({class: classNames?.thumb}),
|
|
||||||
}),
|
}),
|
||||||
[
|
[slots, classNames?.thumb],
|
||||||
slots,
|
|
||||||
classNames?.thumb,
|
|
||||||
isSelected,
|
|
||||||
isFocused,
|
|
||||||
isFocusVisible,
|
|
||||||
isDisabled,
|
|
||||||
inputProps.readOnly,
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const getLabelProps: PropGetter = useCallback(
|
const getLabelProps: PropGetter = useCallback(
|
||||||
() => ({
|
(props = {}) => ({
|
||||||
|
...props,
|
||||||
id: labelId,
|
id: labelId,
|
||||||
"data-disabled": dataAttr(isDisabled),
|
className: slots.label({class: clsx(classNames?.label, props?.className)}),
|
||||||
"data-checked": dataAttr(isSelected),
|
|
||||||
className: slots.label({class: classNames?.label}),
|
|
||||||
}),
|
}),
|
||||||
[slots, classNames?.label, isDisabled, isSelected],
|
[slots, classNames?.label, isDisabled, isSelected],
|
||||||
);
|
);
|
||||||
@ -237,8 +248,7 @@ export function useSwitch(originalProps: UseSwitchProps) {
|
|||||||
{
|
{
|
||||||
width: "1em",
|
width: "1em",
|
||||||
height: "1em",
|
height: "1em",
|
||||||
"data-checked": dataAttr(isSelected),
|
className: slots.thumbIcon({class: clsx(classNames?.thumbIcon)}),
|
||||||
className: slots.thumbIcon({class: classNames?.thumbIcon}),
|
|
||||||
},
|
},
|
||||||
props.includeStateProps
|
props.includeStateProps
|
||||||
? {
|
? {
|
||||||
@ -246,25 +256,25 @@ export function useSwitch(originalProps: UseSwitchProps) {
|
|||||||
}
|
}
|
||||||
: {},
|
: {},
|
||||||
) as unknown) as SwitchThumbIconProps,
|
) as unknown) as SwitchThumbIconProps,
|
||||||
[slots, classNames?.thumbIcon, isSelected, originalProps.disableAnimation],
|
[slots, classNames?.thumbIcon, isSelected],
|
||||||
);
|
);
|
||||||
|
|
||||||
const getStartIconProps = useCallback(
|
const getStartIconProps = useCallback<PropGetter>(
|
||||||
() => ({
|
(props = {}) => ({
|
||||||
width: "1em",
|
width: "1em",
|
||||||
height: "1em",
|
height: "1em",
|
||||||
"data-checked": dataAttr(isSelected),
|
...props,
|
||||||
className: slots.startIcon({class: classNames?.startIcon}),
|
className: slots.startIcon({class: clsx(classNames?.startIcon, props?.className)}),
|
||||||
}),
|
}),
|
||||||
[slots, classNames?.startIcon, isSelected],
|
[slots, classNames?.startIcon, isSelected],
|
||||||
);
|
);
|
||||||
|
|
||||||
const getEndIconProps = useCallback(
|
const getEndIconProps = useCallback<PropGetter>(
|
||||||
() => ({
|
(props = {}) => ({
|
||||||
width: "1em",
|
width: "1em",
|
||||||
height: "1em",
|
height: "1em",
|
||||||
"data-checked": dataAttr(isSelected),
|
...props,
|
||||||
className: slots.endIcon({class: classNames?.endIcon}),
|
className: slots.endIcon({class: clsx(classNames?.endIcon, props?.className)}),
|
||||||
}),
|
}),
|
||||||
[slots, classNames?.endIcon, isSelected],
|
[slots, classNames?.endIcon, isSelected],
|
||||||
);
|
);
|
||||||
@ -280,6 +290,7 @@ export function useSwitch(originalProps: UseSwitchProps) {
|
|||||||
endIcon,
|
endIcon,
|
||||||
isHovered,
|
isHovered,
|
||||||
isSelected,
|
isSelected,
|
||||||
|
isPressed: pressed,
|
||||||
isFocused,
|
isFocused,
|
||||||
isFocusVisible,
|
isFocusVisible,
|
||||||
isDisabled,
|
isDisabled,
|
||||||
|
|||||||
@ -2,17 +2,22 @@ import type {VariantProps} from "tailwind-variants";
|
|||||||
|
|
||||||
import {tv} from "tailwind-variants";
|
import {tv} from "tailwind-variants";
|
||||||
|
|
||||||
import {ringClasses} from "../utils";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle (Switch) wrapper **Tailwind Variants** component
|
* Toggle (Switch) wrapper **Tailwind Variants** component
|
||||||
*
|
*
|
||||||
* const {base, wrapper, thumb, thumbIcon, label, startIcon, endIcon} = toggle({...})
|
* const {base, wrapper, thumb, thumbIcon, label, startIcon, endIcon} = toggle({...})
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* <label className={base())}>
|
* <label
|
||||||
* // hidden input
|
* className={base())}
|
||||||
* <span className={wrapper()} aria-hidden="true" data-checked={checked}>
|
* data-checked={checked}
|
||||||
|
* data-pressed={pressed}
|
||||||
|
* data-focus={focus}
|
||||||
|
* data-hover={hover}
|
||||||
|
* data-focus-visible={focusVisible}
|
||||||
|
* >
|
||||||
|
* <input/> // hidden input
|
||||||
|
* <span className={wrapper()} aria-hidden="true">
|
||||||
* <svg className={startIcon()}>...</svg>
|
* <svg className={startIcon()}>...</svg>
|
||||||
* <span className={thumb()}>
|
* <span className={thumb()}>
|
||||||
* <svg className={thumbIcon()}>...</svg>
|
* <svg className={thumbIcon()}>...</svg>
|
||||||
@ -24,9 +29,9 @@ import {ringClasses} from "../utils";
|
|||||||
*/
|
*/
|
||||||
const toggle = tv({
|
const toggle = tv({
|
||||||
slots: {
|
slots: {
|
||||||
base: "relative max-w-fit inline-flex items-center justify-start cursor-pointer",
|
base:
|
||||||
|
"group relative max-w-fit inline-flex items-center justify-start cursor-pointer touch-none",
|
||||||
wrapper: [
|
wrapper: [
|
||||||
"group",
|
|
||||||
"px-1",
|
"px-1",
|
||||||
"relative",
|
"relative",
|
||||||
"inline-flex",
|
"inline-flex",
|
||||||
@ -36,6 +41,13 @@ const toggle = tv({
|
|||||||
"overflow-hidden",
|
"overflow-hidden",
|
||||||
"bg-neutral-200",
|
"bg-neutral-200",
|
||||||
"rounded-full",
|
"rounded-full",
|
||||||
|
// focus ring
|
||||||
|
"group-data-[focus-visible]:outline-none",
|
||||||
|
"group-data-[focus-visible]:ring-2",
|
||||||
|
"group-data-[focus-visible]:!ring-primary",
|
||||||
|
"group-data-[focus-visible]:ring-offset-2",
|
||||||
|
"group-data-[focus-visible]:ring-offset-background",
|
||||||
|
"group-data-[focus-visible]:dark:ring-offset-background-dark",
|
||||||
],
|
],
|
||||||
thumb: [
|
thumb: [
|
||||||
"z-10",
|
"z-10",
|
||||||
@ -45,7 +57,7 @@ const toggle = tv({
|
|||||||
"bg-white",
|
"bg-white",
|
||||||
"shadow-sm",
|
"shadow-sm",
|
||||||
"rounded-full",
|
"rounded-full",
|
||||||
"data-[checked=true]:translate-x-full",
|
"origin-right",
|
||||||
],
|
],
|
||||||
startIcon: "z-0 absolute left-1.5 text-current",
|
startIcon: "z-0 absolute left-1.5 text-current",
|
||||||
endIcon: "z-0 absolute right-1.5 text-neutral-600",
|
endIcon: "z-0 absolute right-1.5 text-neutral-600",
|
||||||
@ -56,42 +68,52 @@ const toggle = tv({
|
|||||||
color: {
|
color: {
|
||||||
neutral: {
|
neutral: {
|
||||||
wrapper: [
|
wrapper: [
|
||||||
"data-[checked=true]:bg-neutral-400",
|
"group-data-[checked=true]:bg-neutral-400",
|
||||||
"data-[checked=true]:text-neutral-contrastText",
|
"group-data-[checked=true]:text-neutral-contrastText",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
primary: {
|
primary: {
|
||||||
wrapper: [
|
wrapper: [
|
||||||
"data-[checked=true]:bg-primary",
|
"group-data-[checked=true]:bg-primary",
|
||||||
"data-[checked=true]:text-primary-contrastText",
|
"group-data-[checked=true]:text-primary-contrastText",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
secondary: {
|
secondary: {
|
||||||
wrapper: [
|
wrapper: [
|
||||||
"data-[checked=true]:bg-secondary",
|
"group-data-[checked=true]:bg-secondary",
|
||||||
"data-[checked=true]:text-secondary-contrastText",
|
"group-data-[checked=true]:text-secondary-contrastText",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
success: {
|
success: {
|
||||||
wrapper: [
|
wrapper: [
|
||||||
"data-[checked=true]:bg-success",
|
"group-data-[checked=true]:bg-success",
|
||||||
"data-[checked=true]:text-success-contrastText",
|
"group-data-[checked=true]:text-success-contrastText",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
warning: {
|
warning: {
|
||||||
wrapper: [
|
wrapper: [
|
||||||
"data-[checked=true]:bg-warning",
|
"group-data-[checked=true]:bg-warning",
|
||||||
"data-[checked=true]:text-warning-contrastText",
|
"group-data-[checked=true]:text-warning-contrastText",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
danger: {
|
danger: {
|
||||||
wrapper: ["data-[checked=true]:bg-danger", "data-[checked=true]:text-danger-contrastText"],
|
wrapper: [
|
||||||
|
"group-data-[checked=true]:bg-danger",
|
||||||
|
"data-[checked=true]:text-danger-contrastText",
|
||||||
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
size: {
|
size: {
|
||||||
xs: {
|
xs: {
|
||||||
wrapper: "px-0.5 w-7 h-4 mr-1",
|
wrapper: "px-0.5 w-7 h-4 mr-1",
|
||||||
thumb: "w-3 h-3 text-[0.5rem]",
|
thumb: [
|
||||||
|
"w-3 h-3 text-[0.5rem]",
|
||||||
|
//checked
|
||||||
|
"group-data-[checked=true]:ml-3",
|
||||||
|
// pressed
|
||||||
|
"group-data-[pressed=true]:w-4",
|
||||||
|
"group-data-[checked]:group-data-[pressed]:ml-2",
|
||||||
|
],
|
||||||
startIcon: "text-[0.5rem] left-1",
|
startIcon: "text-[0.5rem] left-1",
|
||||||
endIcon: "text-[0.5rem] right-1",
|
endIcon: "text-[0.5rem] right-1",
|
||||||
right: "text-[0.5rem]",
|
right: "text-[0.5rem]",
|
||||||
@ -99,38 +121,61 @@ const toggle = tv({
|
|||||||
},
|
},
|
||||||
sm: {
|
sm: {
|
||||||
wrapper: "w-8 h-5 mr-1",
|
wrapper: "w-8 h-5 mr-1",
|
||||||
thumb: "w-3 h-3 text-[0.6rem]",
|
thumb: [
|
||||||
|
"w-3 h-3 text-[0.6rem]",
|
||||||
|
//checked
|
||||||
|
"group-data-[checked=true]:ml-3",
|
||||||
|
// pressed
|
||||||
|
"group-data-[pressed=true]:w-4",
|
||||||
|
"group-data-[checked]:group-data-[pressed]:ml-2",
|
||||||
|
],
|
||||||
startIcon: "text-[0.6rem] left-1",
|
startIcon: "text-[0.6rem] left-1",
|
||||||
endIcon: "text-[0.6rem] right-1",
|
endIcon: "text-[0.6rem] right-1",
|
||||||
label: "text-sm",
|
label: "text-sm",
|
||||||
},
|
},
|
||||||
md: {
|
md: {
|
||||||
wrapper: "w-10 h-6 mr-2",
|
wrapper: "w-10 h-6 mr-2",
|
||||||
thumb: "w-4 h-4 text-xs",
|
thumb: [
|
||||||
|
"w-4 h-4 text-xs",
|
||||||
|
//checked
|
||||||
|
"group-data-[checked=true]:ml-4",
|
||||||
|
// pressed
|
||||||
|
"group-data-[pressed=true]:w-5",
|
||||||
|
"group-data-[checked]:group-data-[pressed]:ml-4",
|
||||||
|
],
|
||||||
endIcon: "text-xs",
|
endIcon: "text-xs",
|
||||||
startIcon: "text-xs",
|
startIcon: "text-xs",
|
||||||
label: "text-base",
|
label: "text-base",
|
||||||
},
|
},
|
||||||
lg: {
|
lg: {
|
||||||
wrapper: "w-12 h-7 mr-2",
|
wrapper: "w-12 h-7 mr-2",
|
||||||
thumb: "w-5 h-5 text-sm",
|
thumb: [
|
||||||
|
"w-5 h-5 text-sm",
|
||||||
|
//checked
|
||||||
|
"group-data-[checked=true]:ml-5",
|
||||||
|
// pressed
|
||||||
|
"group-data-[pressed=true]:w-6",
|
||||||
|
"group-data-[checked]:group-data-[pressed]:ml-4",
|
||||||
|
],
|
||||||
endIcon: "text-sm",
|
endIcon: "text-sm",
|
||||||
startIcon: "text-sm",
|
startIcon: "text-sm",
|
||||||
label: "text-lg",
|
label: "text-lg",
|
||||||
},
|
},
|
||||||
xl: {
|
xl: {
|
||||||
wrapper: "w-14 h-8 mr-2",
|
wrapper: "w-14 h-8 mr-2",
|
||||||
thumb: "w-6 h-6 text-base",
|
thumb: [
|
||||||
|
"w-6 h-6 text-base",
|
||||||
|
//checked
|
||||||
|
"group-data-[checked=true]:ml-6",
|
||||||
|
// pressed
|
||||||
|
"group-data-[pressed=true]:w-7",
|
||||||
|
"group-data-[checked]:group-data-[pressed]:ml-5",
|
||||||
|
],
|
||||||
endIcon: "text-base",
|
endIcon: "text-base",
|
||||||
startIcon: "text-base",
|
startIcon: "text-base",
|
||||||
label: "text-xl",
|
label: "text-xl",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
isFocusVisible: {
|
|
||||||
true: {
|
|
||||||
wrapper: [...ringClasses],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
isDisabled: {
|
isDisabled: {
|
||||||
true: {
|
true: {
|
||||||
base: "opacity-50 pointer-events-none",
|
base: "opacity-50 pointer-events-none",
|
||||||
@ -142,20 +187,20 @@ const toggle = tv({
|
|||||||
thumb: "transition-none",
|
thumb: "transition-none",
|
||||||
},
|
},
|
||||||
false: {
|
false: {
|
||||||
wrapper: "transition-background",
|
wrapper: "transition-background !duration-500",
|
||||||
thumb: "transition-transform !ease-soft-spring !duration-500",
|
thumb: "transition-all !ease-soft-spring !duration-500",
|
||||||
startIcon: [
|
startIcon: [
|
||||||
"opacity-0",
|
"opacity-0",
|
||||||
"scale-50",
|
"scale-50",
|
||||||
"transition-transform-opacity",
|
"transition-transform-opacity",
|
||||||
"data-[checked=true]:scale-100",
|
"group-data-[checked=true]:scale-100",
|
||||||
"data-[checked=true]:opacity-100",
|
"group-data-[checked=true]:opacity-100",
|
||||||
],
|
],
|
||||||
endIcon: [
|
endIcon: [
|
||||||
"opacity-100",
|
"opacity-100",
|
||||||
"transition-transform-opacity",
|
"transition-transform-opacity",
|
||||||
"data-[checked=true]:translate-x-3",
|
"group-data-[checked=true]:translate-x-3",
|
||||||
"data-[checked=true]:opacity-0",
|
"group-data-[checked=true]:opacity-0",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user