diff --git a/src/components/input/Checkbox.tsx b/src/components/input/Checkbox.tsx index 1d68ea3e..8c55990d 100644 --- a/src/components/input/Checkbox.tsx +++ b/src/components/input/Checkbox.tsx @@ -1,4 +1,4 @@ -import type { JSX } from 'preact'; +import type { JSX, Ref } from 'preact'; import { useState } from 'preact/hooks'; import type { CompositeProps, IconComponent } from '../../types'; @@ -20,6 +20,11 @@ type ComponentProps = { checkedIcon?: IconComponent; /** type is always `checkbox` */ type?: never; + + /** Optional extra CSS classes appended to the container's className */ + containerClasses?: string | string[]; + /** Ref associated with the components container */ + containerRef?: Ref; }; export type CheckboxProps = CompositeProps & diff --git a/src/components/input/RadioButton.tsx b/src/components/input/RadioButton.tsx index 091cdaca..5c738463 100644 --- a/src/components/input/RadioButton.tsx +++ b/src/components/input/RadioButton.tsx @@ -1,4 +1,4 @@ -import type { JSX } from 'preact'; +import type { JSX, Ref } from 'preact'; import type { CompositeProps, IconComponent } from '../../types'; import { RadioCheckedIcon, RadioIcon } from '../icons'; @@ -13,6 +13,11 @@ type ComponentProps = { checkedIcon?: IconComponent; /** type is always `radio` */ type?: never; + + /** Optional extra CSS classes appended to the container's className */ + containerClasses?: string | string[]; + /** Ref associated with the components container */ + containerRef?: Ref; }; export type RadioButtonProps = CompositeProps & diff --git a/src/components/input/Select.tsx b/src/components/input/Select.tsx index 43d8184a..850b50cd 100644 --- a/src/components/input/Select.tsx +++ b/src/components/input/Select.tsx @@ -72,6 +72,7 @@ function SelectOption({ elementRef, }: SelectOptionProps) { const checkboxRef = useRef(null); + const checkboxContainerRef = useRef(null); const optionRef = useSyncedRef(elementRef); const selectContext = useContext(SelectContext); @@ -150,9 +151,13 @@ function SelectOption({ classes, )} onClick={e => { - // Do not invoke callback if clicked element is the checkbox, as it has - // its own event handler. - if (!disabled && e.target !== checkboxRef.current) { + if ( + !disabled && + // Do not invoke callback if clicked element is the checkbox or its + // container, as it has its own event handler. + e.target !== checkboxRef.current && + e.target !== checkboxContainerRef.current + ) { selectOneValue(); } }} @@ -163,9 +168,10 @@ function SelectOption({ if ( ['Enter', ' '].includes(e.key) && - // Do not invoke callback if event triggers in checkbox, as it has its - // own event handler. - e.target !== checkboxRef.current + // Do not invoke callback if event triggers in the checkbox or its + // container, as it has its own event handler. + e.target !== checkboxRef.current && + e.target !== checkboxContainerRef.current ) { e.preventDefault(); selectOneValue(); @@ -203,25 +209,32 @@ function SelectOption({ /> )} {multiple && ( -
- { - if (e.key === 'ArrowLeft') { - e.preventDefault(); - optionRef.current?.focus(); - } - }} - /> -
+ { + if (e.key === 'ArrowLeft') { + e.preventDefault(); + optionRef.current?.focus(); + } + }} + /> )} diff --git a/src/components/input/ToggleInput.tsx b/src/components/input/ToggleInput.tsx index d4656bde..2b6f46d7 100644 --- a/src/components/input/ToggleInput.tsx +++ b/src/components/input/ToggleInput.tsx @@ -1,5 +1,5 @@ import classnames from 'classnames'; -import type { JSX } from 'preact'; +import type { JSX, Ref } from 'preact'; import type { CompositeProps, IconComponent } from '../../types'; import { downcastRef } from '../../util/typing'; @@ -13,6 +13,11 @@ type ComponentProps = { checkedIcon: IconComponent; type: 'checkbox' | 'radio'; + + /** Optional extra CSS classes appended to the container's className */ + containerClasses?: string | string[]; + /** Ref associated with the components container */ + containerRef?: Ref; }; export type ToggleInputProps = CompositeProps & @@ -27,6 +32,7 @@ export type ToggleInputProps = CompositeProps & export default function ToggleInput({ children, elementRef, + containerRef, checked, icon: UncheckedIcon, @@ -36,20 +42,26 @@ export default function ToggleInput({ onChange, id, type, + containerClasses, ...htmlAttributes }: ToggleInputProps) { const Icon = checked ? CheckedIcon : UncheckedIcon; return (