From 8677c6cd0f98c7bd78880c7699be156cc1088538 Mon Sep 17 00:00:00 2001 From: Kayla Firestack Date: Wed, 14 Feb 2024 12:42:16 -0500 Subject: [PATCH] feat(ts/components/navMenu): upgrade mobile nav to use bootstrap components (#2391) * feat(ts/components/navMenu): upgrade mobile nav to use bootstrap components * feat(sb/components/navMenu): add stories for mobile `navMenu` * cleanup(ts/components/navMenu): convert `className` to use `joinClasses` * fix:feat(ts/components/navMenu): update icons to use bootstrap icons --------- Co-authored-by: Eddie Maldonado --- assets/css/bootstrap.scss | 2 +- assets/src/components/nav/navMenu.tsx | 121 ++++++++---------- assets/src/helpers/bsIcons.tsx | 97 ++++++++++++++ .../skate-components/navMenu.stories.tsx | 27 ++++ assets/tests/components/nav/navMenu.test.tsx | 12 +- 5 files changed, 186 insertions(+), 73 deletions(-) create mode 100644 assets/src/helpers/bsIcons.tsx create mode 100644 assets/stories/skate-components/navMenu.stories.tsx diff --git a/assets/css/bootstrap.scss b/assets/css/bootstrap.scss index 08914a252..ca110faaa 100644 --- a/assets/css/bootstrap.scss +++ b/assets/css/bootstrap.scss @@ -40,7 +40,7 @@ // @import "../node_modules/bootstrap/scss/images"; @import "../node_modules/bootstrap/scss/list-group"; // @import "../node_modules/bootstrap/scss/modal"; -// @import "../node_modules/bootstrap/scss/nav"; +@import "../node_modules/bootstrap/scss/nav"; // @import "../node_modules/bootstrap/scss/navbar"; // @import "../node_modules/bootstrap/scss/offcanvas"; // @import "../node_modules/bootstrap/scss/pagination"; diff --git a/assets/src/components/nav/navMenu.tsx b/assets/src/components/nav/navMenu.tsx index a98c0a812..890d42098 100644 --- a/assets/src/components/nav/navMenu.tsx +++ b/assets/src/components/nav/navMenu.tsx @@ -1,15 +1,11 @@ import React from "react" -import { Link, NavLink } from "react-router-dom" +import { Link } from "react-router-dom" +import { Nav } from "react-bootstrap" import { displayHelp } from "../../helpers/appCue" import { openDrift } from "../../helpers/drift" -import { - OldCloseIcon, - LogoIcon, - QuestionMarkIcon, - RefreshIcon, - SettingsIcon, - SpeechBubbleIcon, -} from "../../helpers/icon" +import { OldCloseIcon, LogoIcon } from "../../helpers/icon" +import * as BsIcon from "../../helpers/bsIcons" +import { joinClasses } from "../../helpers/dom" import { reload } from "../../models/browser" interface Props { @@ -22,10 +18,12 @@ const NavMenu: React.FC = ({ mobileMenuIsOpen, toggleMobileMenu }) => { <>
= ({ mobileMenuIsOpen, toggleMobileMenu }) => {
-
    -
  • - -
  • -
  • - -
  • -
  • - -
  • - -
  • - - "c-nav-menu__link" + - (isActive ? " c-nav-menu__link--active" : "") - } - title="Settings" - to="/settings" - onClick={toggleMobileMenu} - > - - Settings - -
  • -
+
+ +
{mobileMenuIsOpen && (
`className` + * - Change `fill-rule` => `fillRule` + * 5. Add extra props to the React `` element + * - Add `{...props}` to the root `` tag so that properties _can_ be overridden + * - Set `aria-hidden` as default on by adding it _before_ the `{...props}` on the `` + * 6. Add a doc comment with a link to the icon + */ + +type SvgProps = ComponentPropsWithoutRef<"svg"> + +/** + * @returns https://icons.getbootstrap.com/icons/arrow-clockwise/ + */ +export const ArrowClockwise = (props: SvgProps) => ( + + + + +) + +/** + * @returns https://icons.getbootstrap.com/icons/chat-fill/ + */ +export const ChatFill = (props: SvgProps) => ( + + + +) + +/** + * @returns https://icons.getbootstrap.com/icons/gear-fill/ + */ +export const GearFill = (props: SvgProps) => ( + + + +) + +/** + * @returns https://icons.getbootstrap.com/icons/question-circle-fill/ + */ +export const QuestionFill = (props: SvgProps) => ( + + + +) diff --git a/assets/stories/skate-components/navMenu.stories.tsx b/assets/stories/skate-components/navMenu.stories.tsx new file mode 100644 index 000000000..48b80e242 --- /dev/null +++ b/assets/stories/skate-components/navMenu.stories.tsx @@ -0,0 +1,27 @@ +import type { Meta, StoryObj } from "@storybook/react" +import NavMenu from "../../src/components/nav/navMenu" +import { MemoryRouter } from "react-router-dom" +import React from "react" + +const meta = { + component: NavMenu, + title: "Mobile ", + args: { + mobileMenuIsOpen: true, + }, + decorators: [ + (StoryFn) => ( + + + + ), + ], + parameters: { + layout: "fullscreen", + }, +} satisfies Meta +export default meta + +type Story = StoryObj + +export const Story: Story = {} diff --git a/assets/tests/components/nav/navMenu.test.tsx b/assets/tests/components/nav/navMenu.test.tsx index 06695175a..a6d483155 100644 --- a/assets/tests/components/nav/navMenu.test.tsx +++ b/assets/tests/components/nav/navMenu.test.tsx @@ -85,7 +85,7 @@ describe("NavMenu", () => { ) - await user.click(result.getByTitle("Refresh")) + await user.click(result.getByRole("button", { name: "Refresh" })) expect(reloadSpy).toHaveBeenCalled() }) @@ -100,7 +100,7 @@ describe("NavMenu", () => { ) - await user.click(result.getByTitle("Support")) + await user.click(result.getByRole("button", { name: "Support" })) expect(openDrift).toHaveBeenCalled() }) @@ -115,7 +115,7 @@ describe("NavMenu", () => { ) - await user.click(result.getByTitle("Support")) + await user.click(result.getByRole("button", { name: "Support" })) expect(toggleMobileMenu).toHaveBeenCalled() }) @@ -130,7 +130,7 @@ describe("NavMenu", () => { ) - await user.click(result.getByTitle("Settings")) + await user.click(result.getByRole("link", { name: "Settings" })) expect(toggleMobileMenu).toHaveBeenCalled() }) @@ -145,7 +145,7 @@ describe("NavMenu", () => { ) - await user.click(result.getByTitle("About Skate")) + await user.click(result.getByRole("button", { name: "About Skate" })) expect(displayHelp).toHaveBeenCalled() }) @@ -160,7 +160,7 @@ describe("NavMenu", () => { ) - await user.click(result.getByTitle("About Skate")) + await user.click(result.getByRole("button", { name: "About Skate" })) expect(toggleMobileMenu).toHaveBeenCalled() })