Skip to content

Commit

Permalink
fix: ListItem disabled states
Browse files Browse the repository at this point in the history
The ListItem will now correctly apply the disabled states as needed and
also prevent the item from being clicked while disabled.
  • Loading branch information
mlaursen committed Jul 12, 2020
1 parent 0f67a4c commit 7b37292
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 3 deletions.
10 changes: 10 additions & 0 deletions packages/list/src/SimpleListItem.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable jsx-a11y/click-events-have-key-events, jsx-a11y/role-supports-aria-props */
import React, { forwardRef } from "react";
import cn from "classnames";
import { bem } from "@react-md/utils";
Expand Down Expand Up @@ -36,6 +37,8 @@ const SimpleListItem = forwardRef<HTMLLIElement, SimpleListItemProps>(
height: propHeight = "auto",
threeLines = false,
clickable = false,
onClick,
disabled = false,
...props
},
ref
Expand All @@ -48,19 +51,25 @@ const SimpleListItem = forwardRef<HTMLLIElement, SimpleListItemProps>(
rightAddonType,
secondaryText,
});
const { "aria-disabled": ariaDisabled } = props;
const isDisabled =
disabled || ariaDisabled === "true" || ariaDisabled === true;

return (
<li
{...props}
aria-disabled={isDisabled || undefined}
ref={ref}
className={cn(
block({
[height]: height !== "auto" && height !== "normal",
"three-lines": threeLines,
clickable,
disabled: isDisabled,
}),
className
)}
onClick={isDisabled ? undefined : onClick}
>
<ListItemChildren
textClassName={textClassName}
Expand Down Expand Up @@ -126,6 +135,7 @@ if (process.env.NODE_ENV !== "production") {
rightAddonPosition: PropTypes.oneOf(["top", "middle", "bottom"]),
forceAddonWrap: PropTypes.bool,
children: PropTypes.node,
onClick: PropTypes.func,
};
} catch (e) {}
}
Expand Down
20 changes: 19 additions & 1 deletion packages/list/src/__tests__/ListItem.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react";
import { render } from "@testing-library/react";
import { render, fireEvent } from "@testing-library/react";

import ListItem from "../ListItem";

Expand All @@ -11,4 +11,22 @@ describe("ListItem", () => {
rerender(<ListItem leftAddon={<span>Left Icon</span>}>Content</ListItem>);
expect(container).toMatchSnapshot();
});

it('should correctly "polyfill" the disabled behavior by preventing click events when disabled', () => {
const onClick = jest.fn();
const props = { children: "Content", onClick };
const { rerender, getByRole } = render(<ListItem {...props} disabled />);

const item = getByRole("button");
expect(item).toHaveAttribute("aria-disabled", "true");
expect(item.className).toContain("rmd-list-item--disabled");
fireEvent.click(item);
expect(onClick).not.toBeCalled();

rerender(<ListItem {...props} aria-disabled />);
expect(item).toHaveAttribute("aria-disabled", "true");
expect(item.className).toContain("rmd-list-item--disabled");
fireEvent.click(item);
expect(onClick).not.toBeCalled();
});
});
28 changes: 27 additions & 1 deletion packages/list/src/__tests__/SimpleListItem.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react";
import { render } from "@testing-library/react";
import { render, fireEvent } from "@testing-library/react";

import SimpleListItem from "../SimpleListItem";

Expand All @@ -13,4 +13,30 @@ describe("SimpleListItem", () => {
rerender(<SimpleListItem {...props} leftAddon={<span>Left</span>} />);
expect(container).toMatchSnapshot();
});

it('should correctly "polyfill" the disabled behavior by preventing click events when disabled', () => {
const onClick = jest.fn();
const props = { children: "Content", onClick, clickable: true };
const { rerender, getByText } = render(
<SimpleListItem {...props} disabled />
);

const item = getByText(props.children);
expect(item).toHaveAttribute("aria-disabled", "true");
expect(item.className).toContain("rmd-list-item--disabled");
fireEvent.click(item);
expect(onClick).not.toBeCalled();

rerender(<SimpleListItem {...props} aria-disabled />);
expect(item).toHaveAttribute("aria-disabled", "true");
expect(item.className).toContain("rmd-list-item--disabled");
fireEvent.click(item);
expect(onClick).not.toBeCalled();

rerender(<SimpleListItem {...props} aria-disabled={false} />);
expect(item).not.toHaveAttribute("aria-disabled");
expect(item.className).not.toContain("rmd-list-item--disabled");
fireEvent.click(item);
expect(onClick).toBeCalled();
});
});
4 changes: 3 additions & 1 deletion packages/list/src/_mixins.scss
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,10 @@
@include rmd-states-surface;
}

&[aria-disabled] {
&--disabled {
@include rmd-theme(color, text-disabled-on-background);

pointer-events: none;
}

&--link {
Expand Down

0 comments on commit 7b37292

Please sign in to comment.