Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Add TypeScript types to inlinecheckbox #17729

Merged
merged 10 commits into from
Nov 13, 2024
49 changes: 39 additions & 10 deletions packages/react/src/components/DataTable/TableSelectRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,29 +87,58 @@
}: TableSelectRowProps) => {
const prefix = usePrefix();
const uniqueNameId = useId();

const handleRadioChange = onChange
? (
value: string | number | undefined,
name: string | undefined,
event: React.ChangeEvent<HTMLInputElement>
) => {

Check warning on line 96 in packages/react/src/components/DataTable/TableSelectRow.tsx

View check run for this annotation

Codecov / codecov/patch

packages/react/src/components/DataTable/TableSelectRow.tsx#L96

Added line #L96 was not covered by tests
// Convert the radio value to boolean for consistency
onChange(!!value, name || '', event);
}
: undefined;

const handleCheckboxChange = onChange
? (
checked: boolean,
name: string,
event: React.ChangeEvent<HTMLInputElement>
) => {
onChange(checked, name, event);
}
: undefined;

const selectionInputProps = {
id,
name: name ? name : uniqueNameId,
onClick: onSelect,
onChange,
checked,
disabled,
};
const InlineInputComponent = radio ? RadioButton : InlineCheckbox;
// const InlineInputComponent = radio ? RadioButton : InlineCheckbox;
2nikhiltom marked this conversation as resolved.
Show resolved Hide resolved

const labelValue = ariaLabel || deprecatedAriaLabel || '';
const tableSelectRowClasses = classNames(`${prefix}--table-column-checkbox`, {
...(className && { [className]: true }),
[`${prefix}--table-column-radio`]: radio,
});
return (
<td className={tableSelectRowClasses} aria-live="off">
<InlineInputComponent
{...selectionInputProps}
{...(radio && {
labelText: ariaLabel || deprecatedAriaLabel,
hideLabel: true,
})}
{...(!radio && { 'aria-label': ariaLabel || deprecatedAriaLabel })}
/>
{radio ? (
<RadioButton
{...selectionInputProps}
labelText={labelValue}
onChange={handleRadioChange}
hideLabel={true}
/>
) : (
<InlineCheckbox
{...selectionInputProps}
aria-label={labelValue}
onChange={handleCheckboxChange}
/>
)}
</td>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<HTMLInputElement>
) => void;

/**
* Provide a handler that is invoked when a user clicks on the control
*/
onClick?: (event: React.MouseEvent<HTMLInputElement>) => void;

/**
* Provide a handler that is invoked on the key down event for the control
*/
onKeyDown?: (event: React.KeyboardEvent<HTMLInputElement>) => void;

/**
* Provide an optional tooltip for the InlineCheckbox
*/
title?: string;
}

const InlineCheckbox = React.forwardRef<HTMLInputElement, InlineCheckboxProps>(
function InlineCheckbox(props, forwardRef) {
const {
['aria-label']: ariaLabel,
Expand All @@ -28,16 +91,19 @@
title,
} = props;
const prefix = usePrefix();
const inputRef = useRef(null);
const inputRef = useRef<HTMLInputElement>(null);
const ref = useMergedRefs([inputRef, forwardRef]);
const inputProps = {

const inputProps: React.InputHTMLAttributes<HTMLInputElement> & {
ref: React.Ref<HTMLInputElement>;
} = {
checked,
className: `${prefix}--checkbox`,
disabled,
id,
name,
onClick: onClick ? onClickCheckBoxInput : onClick,
onChange: (evt) => {
onChange: (evt: React.ChangeEvent<HTMLInputElement>) => {
onChange(evt.target.checked, id, evt);
},
onKeyDown,
Expand All @@ -51,16 +117,15 @@

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<HTMLInputElement>) {
if (indeterminate) {
evt.target.checked = false;
(evt.target as HTMLInputElement).checked = false;
}
onClick(evt);
onClick?.(evt);
}

return (
Expand All @@ -72,7 +137,7 @@
htmlFor={id}
className={`${prefix}--checkbox-label`}
title={title}
onClick={(evt) => {
onClick={(evt: React.MouseEvent) => {

Check warning on line 140 in packages/react/src/components/InlineCheckbox/InlineCheckbox.tsx

View check run for this annotation

Codecov / codecov/patch

packages/react/src/components/InlineCheckbox/InlineCheckbox.tsx#L140

Added line #L140 was not covered by tests
evt.stopPropagation();
}}>
<span className={`${prefix}--visually-hidden`}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
Loading