Skip to content

Commit

Permalink
[Checkbox, Menu, Radio] Avoid applying hidden attr when `keepMounte…
Browse files Browse the repository at this point in the history
…d=true` for indicators (#1329)

Additionally, sets `keepMounted=false` for `Radio` by default to align with other indicators
  • Loading branch information
onehanddev authored Jan 22, 2025
1 parent 4803e59 commit 6fdba6b
Show file tree
Hide file tree
Showing 10 changed files with 34 additions and 58 deletions.
2 changes: 1 addition & 1 deletion docs/reference/generated/radio-indicator.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
},
"keepMounted": {
"type": "boolean",
"default": "true",
"default": "false",
"description": "Whether to keep the HTML element in the DOM when the radio button is inactive."
},
"render": {
Expand Down
16 changes: 5 additions & 11 deletions packages/react/src/checkbox/indicator/CheckboxIndicator.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ describe('<Checkbox.Indicator />', () => {
);
const indicator = container.querySelector('span');
expect(indicator).not.to.equal(null);
expect(indicator).to.have.attribute('hidden');
});

it('should keep indicator mounted when checked', async () => {
Expand All @@ -82,7 +81,6 @@ describe('<Checkbox.Indicator />', () => {
);
const indicator = container.querySelector('span');
expect(indicator).not.to.equal(null);
expect(indicator).not.to.have.attribute('hidden');
});

it('should keep indicator mounted when indeterminate', async () => {
Expand All @@ -93,7 +91,6 @@ describe('<Checkbox.Indicator />', () => {
);
const indicator = container.querySelector('span');
expect(indicator).not.to.equal(null);
expect(indicator).not.to.have.attribute('hidden');
});
});

Expand All @@ -108,22 +105,22 @@ describe('<Checkbox.Indicator />', () => {
<div>
<button onClick={() => setChecked(false)}>Close</button>
<Checkbox.Root checked={checked}>
<Checkbox.Indicator data-testid="indicator" keepMounted />
<Checkbox.Indicator data-testid="indicator" />
</Checkbox.Root>
</div>
);
}

const { user } = await render(<Test />);

expect(screen.getByTestId('indicator')).not.to.have.attribute('hidden');
expect(screen.getByTestId('indicator')).not.to.equal(null);

const closeButton = screen.getByText('Close');

await user.click(closeButton);

await waitFor(() => {
expect(screen.getByTestId('indicator')).to.have.attribute('hidden');
expect(screen.queryByTestId('indicator')).to.equal(null);
});
});

Expand Down Expand Up @@ -172,16 +169,13 @@ describe('<Checkbox.Indicator />', () => {
}

const { user } = await render(<Test />);

expect(screen.getByTestId('indicator')).not.to.have.attribute('hidden');
expect(screen.getByTestId('indicator')).not.to.equal(null);

const closeButton = screen.getByText('Close');
await user.click(closeButton);

await waitFor(() => {
expect(screen.getByTestId('indicator')).to.have.attribute('hidden');
expect(animationFinished).to.equal(true);
});

expect(animationFinished).to.equal(true);
});
});
7 changes: 2 additions & 5 deletions packages/react/src/checkbox/indicator/CheckboxIndicator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const CheckboxIndicator = React.forwardRef(function CheckboxIndicator(

const rendered = rootState.checked || rootState.indeterminate;

const { mounted, transitionStatus, setMounted } = useTransitionStatus(rendered);
const { transitionStatus, setMounted } = useTransitionStatus(rendered);

const indicatorRef = React.useRef<HTMLSpanElement | null>(null);
const mergedRef = useForkRef(forwardedRef, indicatorRef);
Expand Down Expand Up @@ -65,10 +65,7 @@ const CheckboxIndicator = React.forwardRef(function CheckboxIndicator(
state,
className,
customStyleHookMapping,
extraProps: {
hidden: !mounted,
...otherProps,
},
extraProps: otherProps,
});

const shouldRender = keepMounted || rendered;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ describe('<Menu.CheckboxItemIndicator />', () => {
<Menu.Positioner>
<Menu.Popup>
<Menu.CheckboxItem checked={checked}>
<Menu.CheckboxItemIndicator data-testid="indicator" keepMounted />
<Menu.CheckboxItemIndicator data-testid="indicator" />
</Menu.CheckboxItem>
</Menu.Popup>
</Menu.Positioner>
Expand All @@ -55,14 +55,14 @@ describe('<Menu.CheckboxItemIndicator />', () => {

const { user } = await render(<Test />);

expect(screen.getByTestId('indicator')).not.to.have.attribute('hidden');
expect(screen.queryByTestId('indicator')).not.to.equal(null);

const closeButton = screen.getByText('Close');

await user.click(closeButton);

await waitFor(() => {
expect(screen.getByTestId('indicator')).to.have.attribute('hidden');
expect(screen.queryByTestId('indicator')).to.equal(null);
});
});

Expand Down Expand Up @@ -125,9 +125,7 @@ describe('<Menu.CheckboxItemIndicator />', () => {
await user.click(closeButton);

await waitFor(() => {
expect(screen.getByTestId('indicator')).to.have.attribute('hidden');
expect(animationFinished).to.equal(true);
});

expect(animationFinished).to.equal(true);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,14 @@ const MenuCheckboxItemIndicator = React.forwardRef(function MenuCheckboxItemIndi
const indicatorRef = React.useRef<HTMLSpanElement | null>(null);
const mergedRef = useForkRef(forwardedRef, indicatorRef);

const { mounted, transitionStatus, setMounted } = useTransitionStatus(item.checked);
const { transitionStatus, setMounted } = useTransitionStatus(item.checked);

const getItemProps = React.useCallback(
(externalProps = {}) =>
mergeReactProps(externalProps, {
'aria-hidden': true,
hidden: !mounted,
}),
[mounted],
[],
);

useAfterExitAnimation({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ describe('<Menu.RadioItemIndicator />', () => {
<Menu.Popup>
<Menu.RadioGroup value={value}>
<Menu.RadioItem value="a">
<Menu.RadioItemIndicator data-testid="indicator" keepMounted />
<Menu.RadioItemIndicator data-testid="indicator" />
</Menu.RadioItem>
<Menu.RadioItem value="b">
<Menu.RadioItemIndicator keepMounted />
Expand All @@ -60,14 +60,14 @@ describe('<Menu.RadioItemIndicator />', () => {

const { user } = await render(<Test />);

expect(screen.getByTestId('indicator')).not.to.have.attribute('hidden');
expect(screen.queryByTestId('indicator')).not.to.equal(null);

const closeButton = screen.getByText('Close');

await user.click(closeButton);

await waitFor(() => {
expect(screen.getByTestId('indicator')).to.have.attribute('hidden');
expect(screen.queryByTestId('indicator')).to.equal(null);
});
});

Expand Down Expand Up @@ -129,15 +129,13 @@ describe('<Menu.RadioItemIndicator />', () => {

const { user } = await render(<Test />);

expect(screen.getByTestId('indicator')).not.to.have.attribute('hidden');
expect(screen.getByTestId('indicator')).not.to.equal(null);

const closeButton = screen.getByText('Close');
await user.click(closeButton);

await waitFor(() => {
expect(screen.getByTestId('indicator')).to.have.attribute('hidden');
expect(animationFinished).to.equal(true);
});

expect(animationFinished).to.equal(true);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,14 @@ const MenuRadioItemIndicator = React.forwardRef(function MenuRadioItemIndicator(
const indicatorRef = React.useRef<HTMLSpanElement | null>(null);
const mergedRef = useForkRef(forwardedRef, indicatorRef);

const { mounted, transitionStatus, setMounted } = useTransitionStatus(item.checked);
const { transitionStatus, setMounted } = useTransitionStatus(item.checked);

const getItemProps = React.useCallback(
(externalProps = {}) =>
mergeReactProps(externalProps, {
'aria-hidden': true,
hidden: !mounted,
}),
[mounted],
[],
);

useAfterExitAnimation({
Expand Down
4 changes: 2 additions & 2 deletions packages/react/src/radio-group/RadioGroup.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -314,10 +314,10 @@ describe('<RadioGroup />', () => {
render(
<RadioGroup>
<Radio.Root value="a" data-testid="a">
<Radio.Indicator data-testid="indicator-a" />
<Radio.Indicator keepMounted data-testid="indicator-a" />
</Radio.Root>
<Radio.Root value="b" data-testid="b">
<Radio.Indicator data-testid="indicator-b" />
<Radio.Indicator keepMounted data-testid="indicator-b" />
</Radio.Root>
</RadioGroup>,
);
Expand Down
18 changes: 6 additions & 12 deletions packages/react/src/radio/indicator/RadioIndicator.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,10 @@ describe('<Radio.Indicator />', () => {
<button onClick={() => setValue('b')}>Close</button>
<RadioGroup value={value}>
<Radio.Root value="a">
<Radio.Indicator
className="animation-test-indicator"
keepMounted
data-testid="indicator-a"
/>
<Radio.Indicator className="animation-test-indicator" data-testid="indicator-a" />
</Radio.Root>
<Radio.Root value="a">
<Radio.Indicator className="animation-test-indicator" keepMounted />
<Radio.Indicator className="animation-test-indicator" />
</Radio.Root>
</RadioGroup>
</div>
Expand All @@ -47,14 +43,14 @@ describe('<Radio.Indicator />', () => {

const { user } = await render(<Test />);

expect(screen.getByTestId('indicator-a')).not.to.have.attribute('hidden');
expect(screen.getByTestId('indicator-a')).not.to.equal(null);

const closeButton = screen.getByText('Close');

await user.click(closeButton);

await waitFor(() => {
expect(screen.getByTestId('indicator-a')).to.have.attribute('hidden');
expect(screen.queryByTestId('indicator-a')).to.equal(null);
});
});

Expand Down Expand Up @@ -109,15 +105,13 @@ describe('<Radio.Indicator />', () => {

const { user } = await render(<Test />);

expect(screen.getByTestId('indicator-a')).not.to.have.attribute('hidden');
expect(screen.getByTestId('indicator-a')).not.to.equal(null);

const closeButton = screen.getByText('Close');
await user.click(closeButton);

await waitFor(() => {
expect(screen.getByTestId('indicator-a')).to.have.attribute('hidden');
expect(animationFinished).to.equal(true);
});

expect(animationFinished).to.equal(true);
});
});
13 changes: 5 additions & 8 deletions packages/react/src/radio/indicator/RadioIndicator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ const RadioIndicator = React.forwardRef(function RadioIndicator(
props: RadioIndicator.Props,
forwardedRef: React.ForwardedRef<HTMLSpanElement>,
) {
const { render, className, keepMounted = true, ...otherProps } = props;
const { render, className, keepMounted = false, ...otherProps } = props;

const rootState = useRadioRootContext();

const rendered = rootState.checked;

const { mounted, transitionStatus, setMounted } = useTransitionStatus(rendered);
const { transitionStatus, setMounted } = useTransitionStatus(rendered);

const state: RadioIndicator.State = React.useMemo(
() => ({
Expand All @@ -43,10 +43,7 @@ const RadioIndicator = React.forwardRef(function RadioIndicator(
ref: mergedRef,
className,
state,
extraProps: {
hidden: !mounted,
...otherProps,
},
extraProps: otherProps,
customStyleHookMapping,
});

Expand All @@ -70,7 +67,7 @@ namespace RadioIndicator {
export interface Props extends BaseUIComponentProps<'span', State> {
/**
* Whether to keep the HTML element in the DOM when the radio button is inactive.
* @default true
* @default false
*/
keepMounted?: boolean;
}
Expand Down Expand Up @@ -100,7 +97,7 @@ RadioIndicator.propTypes /* remove-proptypes */ = {
className: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
/**
* Whether to keep the HTML element in the DOM when the radio button is inactive.
* @default true
* @default false
*/
keepMounted: PropTypes.bool,
/**
Expand Down

0 comments on commit 6fdba6b

Please sign in to comment.