diff --git a/packages/react/src/components/DataTable/TableSelectRow.tsx b/packages/react/src/components/DataTable/TableSelectRow.tsx index bfe38b550e37..8a209dacf62e 100644 --- a/packages/react/src/components/DataTable/TableSelectRow.tsx +++ b/packages/react/src/components/DataTable/TableSelectRow.tsx @@ -87,29 +87,57 @@ const TableSelectRow = ({ }: TableSelectRowProps) => { const prefix = usePrefix(); const uniqueNameId = useId(); + + const handleRadioChange = onChange + ? ( + value: string | number | undefined, + name: string | undefined, + event: React.ChangeEvent + ) => { + // Convert the radio value to boolean for consistency + onChange(!!value, name || '', event); + } + : undefined; + + const handleCheckboxChange = onChange + ? ( + checked: boolean, + name: string, + event: React.ChangeEvent + ) => { + onChange(checked, name, event); + } + : undefined; + const selectionInputProps = { id, name: name ? name : uniqueNameId, onClick: onSelect, - onChange, checked, disabled, }; - const InlineInputComponent = radio ? RadioButton : InlineCheckbox; + + const labelValue = ariaLabel || deprecatedAriaLabel || ''; const tableSelectRowClasses = classNames(`${prefix}--table-column-checkbox`, { ...(className && { [className]: true }), [`${prefix}--table-column-radio`]: radio, }); return ( - + {radio ? ( + + ) : ( + + )} ); }; diff --git a/packages/react/src/components/InlineCheckbox/InlineCheckbox.js b/packages/react/src/components/InlineCheckbox/InlineCheckbox.tsx similarity index 63% rename from packages/react/src/components/InlineCheckbox/InlineCheckbox.js rename to packages/react/src/components/InlineCheckbox/InlineCheckbox.tsx index ae1b45d26325..1c8c455412ae 100644 --- a/packages/react/src/components/InlineCheckbox/InlineCheckbox.js +++ b/packages/react/src/components/InlineCheckbox/InlineCheckbox.tsx @@ -4,15 +4,78 @@ * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ - import PropTypes from 'prop-types'; import React, { useEffect, useRef } from 'react'; import deprecate from '../../prop-types/deprecate'; import { usePrefix } from '../../internal/usePrefix'; import { useMergedRefs } from '../../internal/useMergedRefs'; -/** @type any */ -const InlineCheckbox = React.forwardRef( +export interface InlineCheckboxProps { + /* + * Specify the label for the control + */ + 'aria-label': string; + + /** + * Deprecated, please use `aria-label` instead. + * Specify the label for the control + */ + ariaLabel?: string; + + /** + * Specify whether the underlying control is checked, + * or not + * @default false + * */ + checked?: boolean; + + /** + * Specify whether the underlying input control should be disabled + * @default false + */ + disabled?: boolean; + + /** + * Provide an `id` for the underlying input control + */ + id: string; + + /** + * Specify whether the control is in an indeterminate state + */ + indeterminate?: boolean; + + /** + * Provide a `name` for the underlying input control + */ + name: string; + + /** + * Provide an optional hook that is called each time the input is updated + */ + onChange?: ( + checked: boolean, + id: string, + event: React.ChangeEvent + ) => void; + + /** + * Provide a handler that is invoked when a user clicks on the control + */ + onClick?: (event: React.MouseEvent) => void; + + /** + * Provide a handler that is invoked on the key down event for the control + */ + onKeyDown?: (event: React.KeyboardEvent) => void; + + /** + * Provide an optional tooltip for the InlineCheckbox + */ + title?: string; +} + +const InlineCheckbox = React.forwardRef( function InlineCheckbox(props, forwardRef) { const { ['aria-label']: ariaLabel, @@ -28,16 +91,19 @@ const InlineCheckbox = React.forwardRef( title, } = props; const prefix = usePrefix(); - const inputRef = useRef(null); + const inputRef = useRef(null); const ref = useMergedRefs([inputRef, forwardRef]); - const inputProps = { + + const inputProps: React.InputHTMLAttributes & { + ref: React.Ref; + } = { checked, className: `${prefix}--checkbox`, disabled, id, name, onClick: onClick ? onClickCheckBoxInput : onClick, - onChange: (evt) => { + onChange: (evt: React.ChangeEvent) => { onChange(evt.target.checked, id, evt); }, onKeyDown, @@ -51,16 +117,15 @@ const InlineCheckbox = React.forwardRef( useEffect(() => { if (inputRef?.current) { - inputRef.current.indeterminate = indeterminate; + inputRef.current.indeterminate = indeterminate || false; } }, [indeterminate]); - function onClickCheckBoxInput(evt) { - // If the previous "indeterminate" is true, change "checked" to false. If it is not undefined, we're working on `TableSelectAll` + function onClickCheckBoxInput(evt: React.MouseEvent) { if (indeterminate) { - evt.target.checked = false; + (evt.target as HTMLInputElement).checked = false; } - onClick(evt); + onClick?.(evt); } return ( @@ -72,7 +137,7 @@ const InlineCheckbox = React.forwardRef( htmlFor={id} className={`${prefix}--checkbox-label`} title={title} - onClick={(evt) => { + onClick={(evt: React.MouseEvent) => { evt.stopPropagation(); }}> diff --git a/packages/react/src/components/InlineCheckbox/index.js b/packages/react/src/components/InlineCheckbox/index.tsx similarity index 61% rename from packages/react/src/components/InlineCheckbox/index.js rename to packages/react/src/components/InlineCheckbox/index.tsx index 4711c79865e8..c159d312a87a 100644 --- a/packages/react/src/components/InlineCheckbox/index.js +++ b/packages/react/src/components/InlineCheckbox/index.tsx @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -import InlineCheckbox from './InlineCheckbox'; - +import InlineCheckbox, { type InlineCheckboxProps } from './InlineCheckbox'; export default InlineCheckbox; -export { InlineCheckbox }; +export { InlineCheckbox, type InlineCheckboxProps };