Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/violet-tools-refuse.md
Original file line number Diff line number Diff line change
@@ -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
5 changes: 1 addition & 4 deletions packages/components/checkbox/src/checkbox.tsx
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -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>
Expand Down
3 changes: 2 additions & 1 deletion packages/components/checkbox/src/use-checkbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(
() => ({
Expand Down
5 changes: 1 addition & 4 deletions packages/components/radio/src/radio.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {forwardRef} from "@nextui-org/system";
import {VisuallyHidden} from "@react-aria/visually-hidden";

import {UseRadioProps, useRadio} from "./use-radio";

Expand All @@ -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>
Expand Down
1 change: 1 addition & 0 deletions packages/components/radio/src/use-radio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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),
};
},
Expand Down
5 changes: 1 addition & 4 deletions packages/components/switch/src/switch.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import {VisuallyHidden} from "@react-aria/visually-hidden";
import {cloneElement, ReactElement} from "react";
import {forwardRef} from "@nextui-org/system";

Expand Down Expand Up @@ -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>
Expand Down
2 changes: 2 additions & 0 deletions packages/components/switch/src/use-switch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ export function useSwitch(originalProps: UseSwitchProps = {}) {
});

const isInteractionDisabled = ariaSwitchProps.isDisabled || isReadOnly;

const pressed = isInteractionDisabled ? false : isPressed;

const isSelected = inputProps.checked;
Expand Down Expand Up @@ -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),
};
};
Expand Down
5 changes: 3 additions & 2 deletions packages/core/theme/src/components/checkbox.ts
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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: {
Expand Down
3 changes: 2 additions & 1 deletion packages/core/theme/src/components/radio.ts
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -44,6 +44,7 @@ const radio = tv({
// focus ring
...groupDataFocusVisibleClasses,
],
hiddenInput: hiddenInputClasses,
labelWrapper: "flex flex-col ml-1",
control: [
"z-10",
Expand Down
4 changes: 3 additions & 1 deletion packages/core/theme/src/components/toggle.ts
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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",
Expand Down
35 changes: 35 additions & 0 deletions packages/core/theme/src/utils/classes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",
];
1 change: 1 addition & 0 deletions packages/core/theme/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export {
translateCenterClasses,
absoluteFullClasses,
collapseAdjacentVariantBorders,
hiddenInputClasses,
} from "./classes";
export type {SlotsToClasses} from "./types";
export {colorVariants} from "./variants";
Expand Down