diff --git a/src/molecules/accessible-list/accessible-list.test.tsx b/src/molecules/accessible-list/accessible-list.test.tsx
index 136639e..10a2f2f 100644
--- a/src/molecules/accessible-list/accessible-list.test.tsx
+++ b/src/molecules/accessible-list/accessible-list.test.tsx
@@ -1,7 +1,80 @@
-// import React from "react";
-// import { render } from "@testing-library/react";
-// import { AccessibleList } from "./accessible-list";
+import React, { Component } from "react";
+import faker from "faker";
+import { render, fireEvent, screen } from "@testing-library/react";
+import { AccessibleList } from "./accessible-list";
+import { KeyboardKeys } from "../../constants/keyboard-keys";
describe("AccessibleList", () => {
- test.skip("TODO - https://github.com/AndcultureCode/AndcultureCode.JavaScript.React.Components/issues/19", () => {});
+ test("when default props, renders items", () => {
+ // Arrange
+ const expected = faker.random.word();
+
+ // Act
+ const { getByText } = render(
+
+
+
+ );
+
+ // Assert
+ expect(getByText(expected)).not.toBeNil();
+ });
+
+ test("when onEsc set, calls handler upon escape pressed", () => {
+ // Arrange
+ let isChecked = false;
+ const buttonText = faker.random.word();
+ const onEscHandler = () => {
+ isChecked = true;
+ };
+
+ // Act
+ const { getByText } = render(
+
+
+
+ );
+ fireEvent.keyDown(getByText(buttonText), { key: KeyboardKeys.Escape });
+
+ // Assert
+ expect(isChecked).toBeTrue();
+ });
+
+ test("when invalid react element, does not render in list", () => {
+ // Arrange
+ const buttonText = [faker.random.word(), faker.random.word()];
+
+ // Act
+ const { container } = render(
+
+
+ {null}
+ {undefined}
+
+
+ );
+
+ // Assert
+ expect(container.childNodes).toHaveLength(2);
+ });
+
+ it("when onClick set, calls handler upon click", async () => {
+ // Arrange
+ let isChecked = false;
+ const handleClick = () => {
+ isChecked = true;
+ };
+ const buttonText = faker.random.word();
+
+ // Act
+ const { getByText } = render(
+
+
+
+ );
+ fireEvent.click(getByText(buttonText));
+
+ // Assert
+ expect(isChecked).toBeTrue();
+ });
});
diff --git a/src/molecules/accessible-list/accessible-list.tsx b/src/molecules/accessible-list/accessible-list.tsx
index ab90c91..e61f524 100644
--- a/src/molecules/accessible-list/accessible-list.tsx
+++ b/src/molecules/accessible-list/accessible-list.tsx
@@ -37,47 +37,46 @@ const AccessibleList: React.FunctionComponent = (
}, [refArray, current, props.focusFirstItem]);
const handleKeyDown = (e: KeyboardEvent) => {
- if (
- e.key === KeyboardKeys.DownArrow &&
- current === refArray.length - 1
- ) {
- e.preventDefault();
- setCurrent(0);
- return;
+ switch (e.key) {
+ case KeyboardKeys.UpArrow: {
+ handleUpArrowPress(e);
+ break;
+ }
+ case KeyboardKeys.DownArrow: {
+ handleDownArrowPress(e);
+ break;
+ }
+ case KeyboardKeys.Escape: {
+ handleEscapePress(e);
+ break;
+ }
+ default: {
+ return;
+ }
}
+ };
- if (e.key === KeyboardKeys.UpArrow && current === 0) {
- e.preventDefault();
- setCurrent(refArray.length - 1);
- return;
- }
+ const handleDownArrowPress = (e: KeyboardEvent) => {
+ const isLastElementFocused = current === refArray.length - 1;
+ const indexToFocus = isLastElementFocused ? 0 : current + 1;
- if (
- e.key === KeyboardKeys.DownArrow &&
- current !== refArray.length - 1
- ) {
- e.preventDefault();
+ setCurrentAndPreventDefault(e, indexToFocus);
+ };
- setCurrent(current + 1);
- return;
- }
-
- if (e.key === KeyboardKeys.UpArrow && current !== 0) {
- e.preventDefault();
-
- setCurrent(current - 1);
- return;
+ const handleEscapePress = (e: KeyboardEvent) => {
+ setCurrentAndPreventDefault(e, 0);
+ if (props.onEsc != null) {
+ props.onEsc();
}
+ };
- if (e.key === KeyboardKeys.Escape) {
- e.preventDefault();
- setCurrent(0);
+ const handleUpArrowPress = (e: KeyboardEvent) => {
+ const isFirstElementFocused = current === 0;
+ const indexToFocus = isFirstElementFocused
+ ? refArray.length - 1
+ : current - 1;
- if (props.onEsc != null) {
- props.onEsc();
- }
- return;
- }
+ setCurrentAndPreventDefault(e, indexToFocus);
};
const renderChildren = () => {
@@ -87,19 +86,36 @@ const AccessibleList: React.FunctionComponent = (
return child;
}
- return React.cloneElement(child, {
- ...child.props,
- onClick: () => {
- if (child.props.onClick != null) {
- child.props.onClick();
- }
- },
- onKeyDown: handleKeyDown,
- ref: (el: HTMLElement) => (refArray[validElementIndex++] = el),
- });
+ const renderedChild = renderChild(child, validElementIndex);
+ validElementIndex++;
+ return renderedChild;
+ });
+ };
+
+ const renderChild = (child: React.ReactElement, index: number) => {
+ return React.cloneElement(child, {
+ ...child.props,
+ onClick: () => {
+ if (child.props.onClick != null) {
+ child.props.onClick();
+ }
+ },
+ onKeyDown: handleKeyDown,
+ ref: (el: HTMLElement) => (refArray[index] = el),
});
};
+ const setCurrentAndPreventDefault = (
+ e: KeyboardEvent,
+ indexToFocus: number
+ ) => {
+ if (indexToFocus < 0) {
+ return;
+ }
+ e.preventDefault();
+ setCurrent(indexToFocus);
+ };
+
return {renderChildren()};
};