From ec02ae7a9b1273e7e7d2a3af65c347c799103573 Mon Sep 17 00:00:00 2001 From: Huw Wilkins Date: Fri, 17 May 2024 15:13:12 +1000 Subject: [PATCH 1/4] feat: add application layout components --- package.json | 5 +- .../AppAside/AppAside.stories.tsx | 145 +++++++++ .../AppAside/AppAside.test.tsx | 24 ++ .../ApplicationLayout/AppAside/AppAside.tsx | 63 ++++ .../ApplicationLayout/AppAside/index.ts | 2 + .../AppMain/AppMain.stories.tsx | 65 +++++ .../AppMain/AppMain.test.tsx | 10 + .../ApplicationLayout/AppMain/AppMain.tsx | 24 ++ .../ApplicationLayout/AppMain/index.ts | 2 + .../AppNavigation/AppNavigation.stories.tsx | 129 ++++++++ .../AppNavigation/AppNavigation.test.tsx | 20 ++ .../AppNavigation/AppNavigation.tsx | 51 ++++ .../ApplicationLayout/AppNavigation/index.ts | 2 + .../AppNavigationBar.stories.tsx | 68 +++++ .../AppNavigationBar.test.tsx | 10 + .../AppNavigationBar/AppNavigationBar.tsx | 31 ++ .../AppNavigationBar/index.ts | 2 + .../AppStatus/AppStatus.stories.tsx | 62 ++++ .../AppStatus/AppStatus.test.tsx | 10 + .../ApplicationLayout/AppStatus/AppStatus.tsx | 24 ++ .../ApplicationLayout/AppStatus/index.ts | 2 + .../Application/Application.stories.tsx | 16 + .../Application/Application.test.tsx | 10 + .../Application/Application.tsx | 32 ++ .../ApplicationLayout/Application/index.ts | 2 + .../ApplicationLayout.stories.tsx | 276 ++++++++++++++++++ .../ApplicationLayout.test.tsx | 113 +++++++ .../ApplicationLayout/ApplicationLayout.tsx | 227 ++++++++++++++ src/components/ApplicationLayout/index.ts | 16 + src/index.ts | 14 + src/types/index.ts | 8 + 31 files changed, 1464 insertions(+), 1 deletion(-) create mode 100644 src/components/ApplicationLayout/AppAside/AppAside.stories.tsx create mode 100644 src/components/ApplicationLayout/AppAside/AppAside.test.tsx create mode 100644 src/components/ApplicationLayout/AppAside/AppAside.tsx create mode 100644 src/components/ApplicationLayout/AppAside/index.ts create mode 100644 src/components/ApplicationLayout/AppMain/AppMain.stories.tsx create mode 100644 src/components/ApplicationLayout/AppMain/AppMain.test.tsx create mode 100644 src/components/ApplicationLayout/AppMain/AppMain.tsx create mode 100644 src/components/ApplicationLayout/AppMain/index.ts create mode 100644 src/components/ApplicationLayout/AppNavigation/AppNavigation.stories.tsx create mode 100644 src/components/ApplicationLayout/AppNavigation/AppNavigation.test.tsx create mode 100644 src/components/ApplicationLayout/AppNavigation/AppNavigation.tsx create mode 100644 src/components/ApplicationLayout/AppNavigation/index.ts create mode 100644 src/components/ApplicationLayout/AppNavigationBar/AppNavigationBar.stories.tsx create mode 100644 src/components/ApplicationLayout/AppNavigationBar/AppNavigationBar.test.tsx create mode 100644 src/components/ApplicationLayout/AppNavigationBar/AppNavigationBar.tsx create mode 100644 src/components/ApplicationLayout/AppNavigationBar/index.ts create mode 100644 src/components/ApplicationLayout/AppStatus/AppStatus.stories.tsx create mode 100644 src/components/ApplicationLayout/AppStatus/AppStatus.test.tsx create mode 100644 src/components/ApplicationLayout/AppStatus/AppStatus.tsx create mode 100644 src/components/ApplicationLayout/AppStatus/index.ts create mode 100644 src/components/ApplicationLayout/Application/Application.stories.tsx create mode 100644 src/components/ApplicationLayout/Application/Application.test.tsx create mode 100644 src/components/ApplicationLayout/Application/Application.tsx create mode 100644 src/components/ApplicationLayout/Application/index.ts create mode 100644 src/components/ApplicationLayout/ApplicationLayout.stories.tsx create mode 100644 src/components/ApplicationLayout/ApplicationLayout.test.tsx create mode 100644 src/components/ApplicationLayout/ApplicationLayout.tsx create mode 100644 src/components/ApplicationLayout/index.ts diff --git a/package.json b/package.json index d134d8c32..4f3d7672e 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,10 @@ "version": "0.47.3", "main": "dist/index.js", "module": "dist/index.js", - "author": "Huw Wilkins ", + "author": { + "email": "webteam@canonical.com", + "name": "Canonical Webteam" + }, "license": "LGPL-3.0", "files": [ "dist/**/*.js", diff --git a/src/components/ApplicationLayout/AppAside/AppAside.stories.tsx b/src/components/ApplicationLayout/AppAside/AppAside.stories.tsx new file mode 100644 index 000000000..96509d3f2 --- /dev/null +++ b/src/components/ApplicationLayout/AppAside/AppAside.stories.tsx @@ -0,0 +1,145 @@ +/* eslint-disable react-hooks/rules-of-hooks */ +import React, { useState } from "react"; +import type { Meta, StoryObj } from "@storybook/react"; + +import Application from "components/ApplicationLayout/Application"; +import AppMain from "components/ApplicationLayout/AppMain"; +import Button from "components/Button"; +import Col from "components/Col"; +import Form from "components/Form"; +import Icon from "components/Icon"; +import Input from "components/Input"; +import Panel from "components/Panel"; +import Row from "components/Row"; + +import AppAside from "./AppAside"; + +const meta: Meta = { + component: AppAside, + tags: ["autodocs"], + argTypes: { + children: { + control: false, + }, + }, +}; + +export default meta; + +type Story = StoryObj; + +/** + * In most common cases an `AppAside` should contain a `` to display the + * content as intended in the application layout. + * + * `AppAside` should be a direct child of an `` or passed to the + * application layout `}>`. + */ +export const Default: Story = { + args: { + children: "AppAside", + }, +}; + +export const States: Story = { + render: (args) => { + const [pinned, setPinned] = useState(false); + const [width, setWidth] = useState(null); + const [collapsed, setCollapsed] = useState(false); + return ( + + +

Scroll to the right to see the panel.

+ + + + +
+ + + + + + } + title="App aside" + > +
+ + + + + + + + + + +
+
+
+
+ ); + }, +}; diff --git a/src/components/ApplicationLayout/AppAside/AppAside.test.tsx b/src/components/ApplicationLayout/AppAside/AppAside.test.tsx new file mode 100644 index 000000000..e746e7562 --- /dev/null +++ b/src/components/ApplicationLayout/AppAside/AppAside.test.tsx @@ -0,0 +1,24 @@ +import React from "react"; +import { render, screen } from "@testing-library/react"; + +import AppAside from "./AppAside"; + +it("displays collapsed", async () => { + render(Content); + expect(screen.queryByRole("complementary")).toHaveClass("is-collapsed"); +}); + +it("displays as narrow", async () => { + render(Content); + expect(screen.queryByRole("complementary")).toHaveClass("is-narrow"); +}); + +it("displays pinned", async () => { + render(Content); + expect(screen.queryByRole("complementary")).toHaveClass("is-pinned"); +}); + +it("displays as wide", async () => { + render(Content); + expect(screen.queryByRole("complementary")).toHaveClass("is-wide"); +}); diff --git a/src/components/ApplicationLayout/AppAside/AppAside.tsx b/src/components/ApplicationLayout/AppAside/AppAside.tsx new file mode 100644 index 000000000..2cb15b63e --- /dev/null +++ b/src/components/ApplicationLayout/AppAside/AppAside.tsx @@ -0,0 +1,63 @@ +import React from "react"; +import type { PropsWithSpread } from "types"; +import classNames from "classnames"; +import { type HTMLProps, type PropsWithChildren } from "react"; + +export type Props = PropsWithSpread< + { + /** + * Whether the aside panel should be collapsed. Toggling this state will animate + * the panel open or closed. + */ + collapsed?: boolean; + /** + * The panel content. + */ + children?: PropsWithChildren["children"]; + /** + * A ref that will be passed to the wrapping `