mirror of
https://github.com/nextui-org/nextui.git
synced 2025-12-08 19:26:11 +00:00
fix: radio, checkbox, switch touch and selection behavior (#4311)
* fix: radio, checkbox, switch touch and selection behavior * Update .changeset/violet-tools-refuse.md * fix: switch toggle on tables
This commit is contained in:
parent
dfefdd6250
commit
03abf1daf4
8
.changeset/violet-tools-refuse.md
Normal file
8
.changeset/violet-tools-refuse.md
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
"@nextui-org/checkbox": patch
|
||||
"@nextui-org/switch": patch
|
||||
"@nextui-org/radio": patch
|
||||
"@nextui-org/theme": patch
|
||||
---
|
||||
|
||||
Fix #4252 #4260 interactive elements were not working properly
|
||||
@ -1,5 +1,4 @@
|
||||
import {forwardRef} from "@nextui-org/system";
|
||||
import {VisuallyHidden} from "@react-aria/visually-hidden";
|
||||
import {cloneElement, ReactElement} from "react";
|
||||
|
||||
import {UseCheckboxProps, useCheckbox} from "./use-checkbox";
|
||||
@ -26,9 +25,7 @@ const Checkbox = forwardRef<"input", CheckboxProps>((props, ref) => {
|
||||
|
||||
return (
|
||||
<Component {...getBaseProps()}>
|
||||
<VisuallyHidden elementType="span">
|
||||
<input {...getInputProps()} />
|
||||
</VisuallyHidden>
|
||||
<input {...getInputProps()} />
|
||||
<span {...getWrapperProps()}>{clonedIcon}</span>
|
||||
{children && <span {...getLabelProps()}>{children}</span>}
|
||||
</Component>
|
||||
|
||||
@ -310,9 +310,10 @@ export function useCheckbox(props: UseCheckboxProps = {}) {
|
||||
return {
|
||||
ref: mergeRefs(inputRef, ref),
|
||||
...mergeProps(inputProps, focusProps),
|
||||
className: slots.hiddenInput({class: classNames?.hiddenInput}),
|
||||
onChange: chain(inputProps.onChange, handleCheckboxChange),
|
||||
};
|
||||
}, [inputProps, focusProps, handleCheckboxChange]);
|
||||
}, [inputProps, focusProps, handleCheckboxChange, classNames?.hiddenInput]);
|
||||
|
||||
const getLabelProps: PropGetter = useCallback(
|
||||
() => ({
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import {forwardRef} from "@nextui-org/system";
|
||||
import {VisuallyHidden} from "@react-aria/visually-hidden";
|
||||
|
||||
import {UseRadioProps, useRadio} from "./use-radio";
|
||||
|
||||
@ -21,9 +20,7 @@ const Radio = forwardRef<"input", RadioProps>((props, ref) => {
|
||||
|
||||
return (
|
||||
<Component {...getBaseProps()}>
|
||||
<VisuallyHidden elementType="span">
|
||||
<input {...getInputProps()} />
|
||||
</VisuallyHidden>
|
||||
<input {...getInputProps()} />
|
||||
<span {...getWrapperProps()}>
|
||||
<span {...getControlProps()} />
|
||||
</span>
|
||||
|
||||
@ -202,6 +202,7 @@ export function useRadio(props: UseRadioProps) {
|
||||
return {
|
||||
ref: inputRef,
|
||||
...mergeProps(props, inputProps, focusProps),
|
||||
className: slots.hiddenInput({class: classNames?.hiddenInput}),
|
||||
onChange: chain(inputProps.onChange, onChange),
|
||||
};
|
||||
},
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import {VisuallyHidden} from "@react-aria/visually-hidden";
|
||||
import {cloneElement, ReactElement} from "react";
|
||||
import {forwardRef} from "@nextui-org/system";
|
||||
|
||||
@ -35,9 +34,7 @@ const Switch = forwardRef<"input", SwitchProps>((props, ref) => {
|
||||
|
||||
return (
|
||||
<Component {...getBaseProps()}>
|
||||
<VisuallyHidden elementType="span">
|
||||
<input {...getInputProps()} />
|
||||
</VisuallyHidden>
|
||||
<input {...getInputProps()} />
|
||||
<span {...getWrapperProps()}>
|
||||
{startContent && clonedStartContent}
|
||||
<span {...getThumbProps()}>{thumbIcon && clonedThumbIcon}</span>
|
||||
|
||||
@ -162,6 +162,7 @@ export function useSwitch(originalProps: UseSwitchProps = {}) {
|
||||
});
|
||||
|
||||
const isInteractionDisabled = ariaSwitchProps.isDisabled || isReadOnly;
|
||||
|
||||
const pressed = isInteractionDisabled ? false : isPressed;
|
||||
|
||||
const isSelected = inputProps.checked;
|
||||
@ -209,6 +210,7 @@ export function useSwitch(originalProps: UseSwitchProps = {}) {
|
||||
...mergeProps(inputProps, focusProps, props),
|
||||
ref: mergeRefs(inputRef, ref),
|
||||
id: inputProps.id,
|
||||
className: slots.hiddenInput({class: classNames?.hiddenInput}),
|
||||
onChange: chain(onChange, inputProps.onChange),
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import type {VariantProps} from "tailwind-variants";
|
||||
|
||||
import {tv} from "../utils/tv";
|
||||
import {groupDataFocusVisibleClasses} from "../utils";
|
||||
import {groupDataFocusVisibleClasses, hiddenInputClasses} from "../utils";
|
||||
|
||||
/**
|
||||
* Checkbox wrapper **Tailwind Variants** component
|
||||
@ -51,7 +51,8 @@ const checkbox = tv({
|
||||
// focus ring
|
||||
...groupDataFocusVisibleClasses,
|
||||
],
|
||||
icon: "z-10 w-4 h-3 opacity-0 group-data-[selected=true]:opacity-100",
|
||||
hiddenInput: hiddenInputClasses,
|
||||
icon: "z-10 w-4 h-3 opacity-0 group-data-[selected=true]:opacity-100 pointer-events-none",
|
||||
label: "relative text-foreground select-none",
|
||||
},
|
||||
variants: {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import type {VariantProps} from "tailwind-variants";
|
||||
|
||||
import {tv} from "../utils/tv";
|
||||
import {groupDataFocusVisibleClasses} from "../utils";
|
||||
import {groupDataFocusVisibleClasses, hiddenInputClasses} from "../utils";
|
||||
|
||||
/**
|
||||
* Radio wrapper **Tailwind Variants** component
|
||||
@ -44,6 +44,7 @@ const radio = tv({
|
||||
// focus ring
|
||||
...groupDataFocusVisibleClasses,
|
||||
],
|
||||
hiddenInput: hiddenInputClasses,
|
||||
labelWrapper: "flex flex-col ml-1",
|
||||
control: [
|
||||
"z-10",
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import type {VariantProps} from "tailwind-variants";
|
||||
|
||||
import {tv} from "../utils/tv";
|
||||
import {groupDataFocusVisibleClasses} from "../utils";
|
||||
import {groupDataFocusVisibleClasses, hiddenInputClasses} from "../utils";
|
||||
|
||||
/**
|
||||
* Toggle (Switch) wrapper **Tailwind Variants** component
|
||||
@ -53,7 +53,9 @@ const toggle = tv({
|
||||
"shadow-small",
|
||||
"rounded-full",
|
||||
"origin-right",
|
||||
"pointer-events-none",
|
||||
],
|
||||
hiddenInput: hiddenInputClasses,
|
||||
startContent: "z-0 absolute start-1.5 text-current",
|
||||
endContent: "z-0 absolute end-1.5 text-default-600",
|
||||
thumbIcon: "text-black",
|
||||
|
||||
@ -67,3 +67,38 @@ export const collapseAdjacentVariantBorders = {
|
||||
warning: ["[&+.border-medium.border-warning]:ms-[calc(theme(borderWidth.medium)*-1)]"],
|
||||
danger: ["[&+.border-medium.border-danger]:ms-[calc(theme(borderWidth.medium)*-1)]"],
|
||||
};
|
||||
|
||||
export const hiddenInputClasses = [
|
||||
// Variables
|
||||
"[--cursor-hit-x:8px]",
|
||||
|
||||
// Font styles
|
||||
"font-inherit",
|
||||
"text-[100%]",
|
||||
"leading-[1.15]",
|
||||
|
||||
// Reset margins and padding
|
||||
"m-0",
|
||||
"p-0",
|
||||
|
||||
// Overflow and box-sizing
|
||||
"overflow-visible",
|
||||
"box-border",
|
||||
|
||||
// Positioning & Hit area
|
||||
"absolute",
|
||||
"top-0",
|
||||
"start-[calc(var(--cursor-hit-x)*-1)]",
|
||||
"w-[calc(100%+var(--cursor-hit-x)*2)]",
|
||||
"h-full",
|
||||
|
||||
// Opacity and z-index
|
||||
"opacity-[0.0001]",
|
||||
"z-[1]",
|
||||
|
||||
// Cursor
|
||||
"cursor-pointer",
|
||||
|
||||
// Disabled state
|
||||
"disabled:cursor-default",
|
||||
];
|
||||
|
||||
@ -7,6 +7,7 @@ export {
|
||||
translateCenterClasses,
|
||||
absoluteFullClasses,
|
||||
collapseAdjacentVariantBorders,
|
||||
hiddenInputClasses,
|
||||
} from "./classes";
|
||||
export type {SlotsToClasses} from "./types";
|
||||
export {colorVariants} from "./variants";
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user