From 44702a7321d7b933d2f2b5603c7f3654151edba6 Mon Sep 17 00:00:00 2001 From: ssingh Date: Thu, 19 Dec 2024 10:48:09 -0800 Subject: [PATCH 1/9] WIP: feat(ForgeLayout): add modeswitcher, breadcrumb navigation, and search --- .changeset/unlucky-seas-allow.md | 5 + .../src/ForgeLayout/ForgeLayout.module.scss | 6 - .../src/ForgeLayout/ForgeLayout.stories.tsx | 13 +- easy-ui-react/src/ForgeLayout/ForgeLayout.tsx | 63 +++-- .../ForgeLayoutControls.module.scss | 69 +++++ .../src/ForgeLayout/ForgeLayoutControls.tsx | 244 ++++++++++++++++++ 6 files changed, 369 insertions(+), 31 deletions(-) create mode 100644 .changeset/unlucky-seas-allow.md create mode 100644 easy-ui-react/src/ForgeLayout/ForgeLayoutControls.module.scss create mode 100644 easy-ui-react/src/ForgeLayout/ForgeLayoutControls.tsx diff --git a/.changeset/unlucky-seas-allow.md b/.changeset/unlucky-seas-allow.md new file mode 100644 index 00000000..b108f198 --- /dev/null +++ b/.changeset/unlucky-seas-allow.md @@ -0,0 +1,5 @@ +--- +"@easypost/easy-ui": minor +--- + +feat(ForgeLayout): add modeswitcher, breadcrumb navigation, and search diff --git a/easy-ui-react/src/ForgeLayout/ForgeLayout.module.scss b/easy-ui-react/src/ForgeLayout/ForgeLayout.module.scss index 7697b155..b172b92c 100644 --- a/easy-ui-react/src/ForgeLayout/ForgeLayout.module.scss +++ b/easy-ui-react/src/ForgeLayout/ForgeLayout.module.scss @@ -67,12 +67,6 @@ padding-bottom: component-token("forge-layout", "shell-gutter"); } -.controls { - display: flex; - align-items: center; - gap: design-token("space.2"); -} - .fauxContainer { position: absolute; top: 0; diff --git a/easy-ui-react/src/ForgeLayout/ForgeLayout.stories.tsx b/easy-ui-react/src/ForgeLayout/ForgeLayout.stories.tsx index 5a165022..c75fdad4 100644 --- a/easy-ui-react/src/ForgeLayout/ForgeLayout.stories.tsx +++ b/easy-ui-react/src/ForgeLayout/ForgeLayout.stories.tsx @@ -67,10 +67,19 @@ const Template = (args: Partial) => { -
Controls when collapsed
+ + {}}> + Back + + + Breadcrumb + Breadcrumb + +
-
Controls when expanded
+ +
{children}; } -function ForgeLayoutControls(props: ForgeLayoutControlsProps) { - const { navState } = useForgeLayout(); - const { children, visibleWhenNavStateIs = "expanded" } = props; - - if (navState !== visibleWhenNavStateIs) { - return null; - } - - return
{children}
; -} - function ForgeLayoutBody(props: ForgeLayoutContentProps) { const { children } = props; return
{children}
; @@ -243,6 +230,36 @@ ForgeLayout.Header = ForgeLayoutHeader; */ ForgeLayout.Controls = ForgeLayoutControls; +/** + * Represents the breadcrumbs and navigation in a ``. + */ +ForgeLayout.BreadcrumbsNavigation = ForgeLayoutBreadcrumbsNavigation; + +/** + * Represents a navigation back button in a ``. + */ +ForgeLayout.BackButton = ForgeLayoutBackButton; + +/** + * Represents breadcrumbs in a ``. + */ +ForgeLayout.Breadcrumbs = ForgeLayoutBreadcrumbs; + +/** + * Represents a breadcrumb in a ``. + */ +ForgeLayout.Breadcrumb = ForgeLayoutBreadcrumb; + +/** + * Represents a mode switcher in a ``. + */ +ForgeLayout.ModeSwitcher = ForgeLayoutModeSwitcher; + +/** + * Represents a search input in a ``. + */ +ForgeLayout.Search = ForgeLayoutSearch; + /** * Represents the secondary actions of a ``. */ diff --git a/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.module.scss b/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.module.scss new file mode 100644 index 00000000..ea9445de --- /dev/null +++ b/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.module.scss @@ -0,0 +1,69 @@ +@use "../styles/common" as *; +@use "../styles/unstyled"; + +.controls { + display: flex; + align-items: center; + gap: design-token("space.2"); +} + +.breadcrumbNavigationContainer { + border: design-token("shape.border_width.1") solid + theme-token("color.neutral.300"); + display: inline-flex; +} + +.backButtonContainer { + background: theme-token("color.neutral.050"); + border-right: design-token("shape.border_width.1") solid + theme-token("color.neutral.300"); + padding: design-token("space.0-5") design-token("space.1.5") + design-token("space.0-5") design-token("space.1"); + display: inline-flex; + align-items: center; +} + +.backButton { + display: inline-flex; + align-items: center; + cursor: pointer; + color: theme-token("color.primary.600"); +} + +.breadcrumbsContainer { + padding: design-token("space.0-5") design-token("space.1"); +} + +.trigger { + @include unstyled.button; + display: flex; + align-items: center; + justify-content: space-between; + gap: design-token("space.1"); + border: design-token("shape.border_width.1") solid + theme-token("color.neutral.300"); + padding: calc( + #{design-token("space.1")} - #{design-token("shape.border_width.1")} + ); + border-radius: design-token("shape.border_radius.md"); + cursor: pointer; + width: 100%; + max-width: 133px; +} + +.triggerPopoverOpen { + border-color: theme-token("color.neutral.800"); +} + +.popover { + border: design-token("shape.border_width.1") solid + theme-token("color.neutral.300"); + border-radius: design-token("shape.border_radius.md"); + background-color: white; + padding: design-token("space.2"); + box-shadow: design-token("shadow.overlay"); +} + +.searchContainer { + position: relative; +} diff --git a/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.tsx b/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.tsx new file mode 100644 index 00000000..07a8a982 --- /dev/null +++ b/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.tsx @@ -0,0 +1,244 @@ +import React, { ReactNode, useMemo, useState, Fragment } from "react"; +import { Button, Dialog, DialogTrigger, Popover } from "react-aria-components"; +import ArrowBackIcon from "@easypost/easy-ui-icons/ArrowBack"; +import SearchIcon from "@easypost/easy-ui-icons/Search"; +import ExpandMoreIcon400 from "@easypost/easy-ui-icons/ExpandMore400"; +import { useForgeLayout } from "./ForgeLayout"; +import type { NavState } from "./ForgeLayout"; +import { UnstyledButton } from "../UnstyledButton"; +import type { UnstyledButtonProps } from "../UnstyledButton"; +import { Text } from "../Text"; +import { Icon } from "../Icon"; +import { + RadioGroup, + RadioGroupItemProps, + useRadioGroupContext, +} from "../RadioGroup"; +import type { TextFieldProps } from "../TextField"; +import { TextField } from "../TextField"; +import { HorizontalStack } from "../HorizontalStack"; +import { VerticalStack } from "../VerticalStack"; +import { flattenChildren } from "../utilities/react"; +import { classNames } from "../utilities/css"; + +import styles from "./ForgeLayoutControls.module.scss"; + +const TEST_MODE = "Test"; +const PRODUCTION_MODE = "Production"; + +export type ForgeLayoutControlsProps = { + /** Controls children. */ + children: ReactNode; + + /** + * Display state of the nav menu for when these controls show. + * + * @default expanded + */ + visibleWhenNavStateIs?: NavState; +}; + +export function ForgeLayoutControls(props: ForgeLayoutControlsProps) { + const { navState } = useForgeLayout(); + const { children, visibleWhenNavStateIs = "expanded" } = props; + + if (navState !== visibleWhenNavStateIs) { + return null; + } + + return
{children}
; +} + +export type ForgeLayoutBreadcrumbsNavigationProps = { + /** Renders ForgeLayout.BackButton and ForgeLayout.Breadcrumbs */ + children?: ReactNode; +}; + +export function ForgeLayoutBreadcrumbsNavigation( + props: ForgeLayoutBreadcrumbsNavigationProps, +) { + const { children } = props; + const { backButton, breadcrumbs } = useMemo(() => { + const breadcrumbNavigationChildren = flattenChildren(children); + const backButton = + breadcrumbNavigationChildren.length > 0 + ? breadcrumbNavigationChildren[0] + : null; + + const breadcrumbs = + breadcrumbNavigationChildren.length > 1 + ? breadcrumbNavigationChildren[1] + : null; + + if (!backButton || !breadcrumbs) { + throw new Error( + "ForgeLayout.BreadcrumbNavigation must contain ForgeLayout.BackButton and ForgeLayout.Breadcrumbs", + ); + } + return { + backButton, + breadcrumbs, + }; + }, [children]); + + return ( +
+
{backButton}
+
{breadcrumbs}
+
+ ); +} + +export function ForgeLayoutBackButton(props: UnstyledButtonProps) { + const { children, ...restButtonProps } = props; + + return ( + + + {children} + + ); +} + +export type ForgeLayoutBreadcrumbsProps = { + /** Renders breadcrumbs */ + children?: ReactNode; +}; + +export function ForgeLayoutBreadcrumbs(props: ForgeLayoutBreadcrumbsProps) { + const { children } = props; + + const breadcrumbs = useMemo(() => flattenChildren(children), [children]); + + return ( + + {breadcrumbs.map((breadcrumb, idx) => { + if (idx === 0) { + return {breadcrumb}; + } else { + return ( + + {">"} + {breadcrumb} + + ); + } + })} + + ); +} + +export type ForgeLayoutBreadcrumbProps = { + /** Breadcrum content */ + children?: ReactNode; +}; + +export function ForgeLayoutBreadcrumb(props: ForgeLayoutBreadcrumbProps) { + const { children } = props; + + return ( + + {children} + + ); +} + +export type ForgeLayoutModeSwitcherProps = { + /** Mode change callback function */ + onModeChange?: (value: string) => void; +}; + +export function ForgeLayoutModeSwitcher(props: ForgeLayoutModeSwitcherProps) { + const { onModeChange } = props; + const { mode } = useForgeLayout(); + const [isOpen, setIsOpen] = useState(false); + + return ( + + + + + + + Instance Switcher + + + + + + + + + + ); +} + +function ForgeLayoutModeSwitcherRadioGroupItem( + props: Omit, +) { + const { value, ...restProps } = props; + const state = useRadioGroupContext(); + const isSelected = value === state.selectedValue; + return ( + + + + {value === "test" ? TEST_MODE : PRODUCTION_MODE} + + + View data using the{" "} + + {value === "test" + ? TEST_MODE.toUpperCase() + : PRODUCTION_MODE.toUpperCase()}{" "} + API{" "} + + keys + + + + ); +} + +export function ForgeLayoutSearch(props: TextFieldProps) { + const { "aria-label": ariaLabel = "Search for content", ...textFieldProps } = + props; + return ( + + ); +} From 4b3e7d95378823014103bccd71ab62359efb2031 Mon Sep 17 00:00:00 2001 From: ssingh Date: Thu, 19 Dec 2024 14:59:11 -0800 Subject: [PATCH 2/9] controls spacing and fix some styles --- .../src/ForgeLayout/ForgeLayout.module.scss | 27 ----------- easy-ui-react/src/ForgeLayout/ForgeLayout.tsx | 17 +------ .../ForgeLayoutControls.module.scss | 7 ++- .../src/ForgeLayout/ForgeLayoutControls.tsx | 26 +++++++---- .../ForgeLayout/ForgeLayoutHeader.module.scss | 28 +++++++++++ .../src/ForgeLayout/ForgeLayoutHeader.tsx | 46 +++++++++++++++++++ 6 files changed, 98 insertions(+), 53 deletions(-) create mode 100644 easy-ui-react/src/ForgeLayout/ForgeLayoutHeader.module.scss create mode 100644 easy-ui-react/src/ForgeLayout/ForgeLayoutHeader.tsx diff --git a/easy-ui-react/src/ForgeLayout/ForgeLayout.module.scss b/easy-ui-react/src/ForgeLayout/ForgeLayout.module.scss index 20621c9c..e3b719c1 100644 --- a/easy-ui-react/src/ForgeLayout/ForgeLayout.module.scss +++ b/easy-ui-react/src/ForgeLayout/ForgeLayout.module.scss @@ -61,33 +61,6 @@ flex-direction: column; } -.header { - position: sticky; - top: 0; - height: component-token("forge-layout", "header-height"); - - display: flex; - flex-wrap: nowrap; - align-items: center; - justify-content: space-between; - min-width: 0; - - border-bottom: 2px solid transparent; - z-index: design-token("z-index.nav"); -} - -.headerBg { - position: absolute; - top: 0; - left: -100vw; - width: 300vw; - height: component-token("forge-layout", "header-height"); - - background-color: design-token("color.neutral.025"); - border-bottom: component-token("forge-layout", "header-border-width") solid - component-token("forge-layout", "header-border-color"); -} - .content { padding-top: component-token("forge-layout", "shell-gutter"); padding-bottom: component-token("forge-layout", "shell-gutter"); diff --git a/easy-ui-react/src/ForgeLayout/ForgeLayout.tsx b/easy-ui-react/src/ForgeLayout/ForgeLayout.tsx index d7f71d85..b2f7856f 100644 --- a/easy-ui-react/src/ForgeLayout/ForgeLayout.tsx +++ b/easy-ui-react/src/ForgeLayout/ForgeLayout.tsx @@ -13,7 +13,7 @@ import { ForgeLayoutNavSection, useForgeLayoutNav, } from "./ForgeLayoutNav"; - +import { ForgeLayoutHeader } from "./ForgeLayoutHeader"; import { ForgeLayoutControls, ForgeLayoutBreadcrumbsNavigation, @@ -56,11 +56,6 @@ export type ForgeLayoutProps = { backgroundDecoration?: "01"; }; -export type ForgeLayoutHeaderProps = { - /** Header children. */ - children: ReactNode; -}; - export type ForgeLayoutContentProps = { /** Content children. */ children: ReactNode; @@ -186,16 +181,6 @@ export function ForgeLayout(props: ForgeLayoutProps) { ); } -function ForgeLayoutHeader(props: ForgeLayoutHeaderProps) { - const { children } = props; - return ( -
-
- {children} -
- ); -} - function ForgeLayoutBody(props: ForgeLayoutContentProps) { const { children } = props; return
{children}
; diff --git a/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.module.scss b/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.module.scss index ea9445de..9ca9d764 100644 --- a/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.module.scss +++ b/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.module.scss @@ -5,12 +5,14 @@ display: flex; align-items: center; gap: design-token("space.2"); + width: 100%; } .breadcrumbNavigationContainer { border: design-token("shape.border_width.1") solid theme-token("color.neutral.300"); display: inline-flex; + z-index: 1; } .backButtonContainer { @@ -49,6 +51,7 @@ cursor: pointer; width: 100%; max-width: 133px; + z-index: 1; } .triggerPopoverOpen { @@ -65,5 +68,7 @@ } .searchContainer { - position: relative; + width: 100%; + max-width: 715px; + padding-right: design-token("space.3"); } diff --git a/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.tsx b/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.tsx index 07a8a982..04954353 100644 --- a/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.tsx +++ b/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.tsx @@ -5,6 +5,7 @@ import SearchIcon from "@easypost/easy-ui-icons/Search"; import ExpandMoreIcon400 from "@easypost/easy-ui-icons/ExpandMore400"; import { useForgeLayout } from "./ForgeLayout"; import type { NavState } from "./ForgeLayout"; +import { useForgeLayoutHeader } from "./ForgeLayoutHeader"; import { UnstyledButton } from "../UnstyledButton"; import type { UnstyledButtonProps } from "../UnstyledButton"; import { Text } from "../Text"; @@ -40,13 +41,18 @@ export type ForgeLayoutControlsProps = { export function ForgeLayoutControls(props: ForgeLayoutControlsProps) { const { navState } = useForgeLayout(); + const { areControlsGrouped } = useForgeLayoutHeader(); const { children, visibleWhenNavStateIs = "expanded" } = props; if (navState !== visibleWhenNavStateIs) { return null; } - return
{children}
; + if (areControlsGrouped) { + return
{children}
; + } + + return <>{children}; } export type ForgeLayoutBreadcrumbsNavigationProps = { @@ -232,13 +238,15 @@ export function ForgeLayoutSearch(props: TextFieldProps) { const { "aria-label": ariaLabel = "Search for content", ...textFieldProps } = props; return ( - +
+ +
); } diff --git a/easy-ui-react/src/ForgeLayout/ForgeLayoutHeader.module.scss b/easy-ui-react/src/ForgeLayout/ForgeLayoutHeader.module.scss new file mode 100644 index 00000000..18f42d6c --- /dev/null +++ b/easy-ui-react/src/ForgeLayout/ForgeLayoutHeader.module.scss @@ -0,0 +1,28 @@ +@use "../styles/common" as *; + +.header { + position: sticky; + top: 0; + height: component-token("forge-layout", "header-height"); + + display: flex; + flex-wrap: nowrap; + align-items: center; + justify-content: space-between; + min-width: 0; + + border-bottom: 2px solid transparent; + z-index: design-token("z-index.nav"); +} + +.headerBg { + position: absolute; + top: 0; + left: -100vw; + width: 300vw; + height: component-token("forge-layout", "header-height"); + + background-color: design-token("color.neutral.025"); + border-bottom: component-token("forge-layout", "header-border-width") solid + component-token("forge-layout", "header-border-color"); +} diff --git a/easy-ui-react/src/ForgeLayout/ForgeLayoutHeader.tsx b/easy-ui-react/src/ForgeLayout/ForgeLayoutHeader.tsx new file mode 100644 index 00000000..9cb81d7b --- /dev/null +++ b/easy-ui-react/src/ForgeLayout/ForgeLayoutHeader.tsx @@ -0,0 +1,46 @@ +import React, { createContext, useContext, ReactNode } from "react"; + +import styles from "./ForgeLayoutHeader.module.scss"; + +export type ForgeLayoutHeaderProps = { + /** + * Whether ForgeLayout.Controls are grouped together or + * spaced evenly with ForgeLayout.Actions + * + * @default true + */ + areControlsGrouped?: boolean; + + /** Header children. */ + children: ReactNode; +}; + +export type ForgeLayoutHeaderContextType = { + areControlsGrouped?: boolean; +}; + +const ForgeLayoutHeaderContext = + createContext(null); + +export const useForgeLayoutHeader = () => { + const context = useContext(ForgeLayoutHeaderContext); + if (!context) { + throw new Error( + "useForgeLayoutHeader must be used within a ForgeLayoutHeader", + ); + } + return context; +}; + +export function ForgeLayoutHeader(props: ForgeLayoutHeaderProps) { + const { areControlsGrouped = true, children } = props; + + return ( + +
+
+ {children} +
+
+ ); +} From 4824affa20abbd5b41312d28458f93abeff84da3 Mon Sep 17 00:00:00 2001 From: ssingh Date: Thu, 19 Dec 2024 16:22:15 -0800 Subject: [PATCH 3/9] unit tests --- .../src/ForgeLayout/ForgeLayout.stories.tsx | 11 ++-- .../src/ForgeLayout/ForgeLayout.test.tsx | 50 ++++++++++++++++--- 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/easy-ui-react/src/ForgeLayout/ForgeLayout.stories.tsx b/easy-ui-react/src/ForgeLayout/ForgeLayout.stories.tsx index b474e5c3..afd7d7b1 100644 --- a/easy-ui-react/src/ForgeLayout/ForgeLayout.stories.tsx +++ b/easy-ui-react/src/ForgeLayout/ForgeLayout.stories.tsx @@ -68,12 +68,15 @@ const Template = (args: Partial) => { - {}}> + Back - Breadcrumb - Breadcrumb + Breadcrumb One + Breadcrumb Two + + Breadcrumb Three + @@ -115,7 +118,7 @@ const Template = (args: Partial) => { -
Page Content
+
Page Content
diff --git a/easy-ui-react/src/ForgeLayout/ForgeLayout.test.tsx b/easy-ui-react/src/ForgeLayout/ForgeLayout.test.tsx index a7eda77d..439ebd5a 100644 --- a/easy-ui-react/src/ForgeLayout/ForgeLayout.test.tsx +++ b/easy-ui-react/src/ForgeLayout/ForgeLayout.test.tsx @@ -28,11 +28,13 @@ describe("", () => { it("should render a forge layout", async () => { const handleMenuAction1 = vi.fn(); + const handleModeChange = vi.fn(); const { user } = render( createForgeLayout({ selectedHref: "/1", onMenuAction1: handleMenuAction1, + onModeChange: handleModeChange, }), ); @@ -58,22 +60,44 @@ describe("", () => { ); expect(handleMenuAction1).toBeCalled(); + + expect( + screen.getByRole("button", { name: "Production" }), + ).toBeInTheDocument(); + expect( + screen.getByRole("searchbox", { name: "Search for content" }), + ).toBeInTheDocument(); + + await userClick(user, screen.getByRole("button", { name: "Production" })); + const radios = screen.getAllByRole("radio"); + expect(radios[0]).not.toBeChecked(); + expect(radios[1]).toBeChecked(); + await userClick(user, radios[0]); + + expect(handleModeChange).toBeCalled(); }); it("should render collapsed state", async () => { - render( + const handleBackButton = vi.fn(); + const { user } = render( createForgeLayout({ navState: "collapsed", selectedHref: "/1", + onBackButton: handleBackButton, }), ); + expect(screen.getByRole("button", { name: "Back" })).toBeInTheDocument(); + expect(screen.queryByText("Breadcrumb One")).toBeInTheDocument(); + expect(screen.queryByText("Breadcrumb Two")).toBeInTheDocument(); + expect(screen.queryByText("Breadcrumb Three")).toBeInTheDocument(); expect( - screen.queryByRole("navigation", { name: "Main" }), + screen.queryByRole("button", { name: "Production" }), ).not.toBeInTheDocument(); expect( - screen.queryByText("Controls when expanded"), + screen.queryByRole("searchbox", { name: "Search for content" }), ).not.toBeInTheDocument(); - expect(screen.queryByText("Controls when collapsed")).toBeInTheDocument(); + await userClick(user, screen.getByRole("button", { name: "Back" })); + expect(handleBackButton).toBeCalled(); }); it("should render test mode", async () => { @@ -98,6 +122,8 @@ function createForgeLayout( selectedHref?: string; onMenuAction1?: () => void; onMenuAction2?: () => void; + onBackButton?: () => void; + onModeChange?: () => void; } = {}, ) { const { @@ -107,6 +133,8 @@ function createForgeLayout( selectedHref = "/1", onMenuAction1 = vi.fn(), onMenuAction2 = vi.fn(), + onBackButton = vi.fn(), + onModeChange = vi.fn(), } = props; return ( @@ -125,10 +153,20 @@ function createForgeLayout( -
Controls when collapsed
+ + + Back + + + Breadcrumb One + Breadcrumb Two + Breadcrumb Three + +
-
Controls when expanded
+ +
Date: Thu, 19 Dec 2024 17:00:35 -0800 Subject: [PATCH 4/9] cleanup --- easy-ui-react/src/ForgeLayout/ForgeLayoutControls.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.tsx b/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.tsx index 04954353..429340cc 100644 --- a/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.tsx +++ b/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.tsx @@ -52,7 +52,15 @@ export function ForgeLayoutControls(props: ForgeLayoutControlsProps) { return
{children}
; } - return <>{children}; + return ( + <> + {areControlsGrouped ? ( +
{children}
+ ) : ( + <>{children} + )} + + ); } export type ForgeLayoutBreadcrumbsNavigationProps = { From b71f68614a86168c74cd9d461bae908d6e249d26 Mon Sep 17 00:00:00 2001 From: ssingh Date: Fri, 20 Dec 2024 11:57:00 -0800 Subject: [PATCH 5/9] breadcrumb navigation padding and adjust popover offset values --- .../src/ForgeLayout/ForgeLayoutControls.module.scss | 3 ++- easy-ui-react/src/ForgeLayout/ForgeLayoutControls.tsx | 11 +++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.module.scss b/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.module.scss index 9ca9d764..6d58bcca 100644 --- a/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.module.scss +++ b/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.module.scss @@ -11,6 +11,7 @@ .breadcrumbNavigationContainer { border: design-token("shape.border_width.1") solid theme-token("color.neutral.300"); + padding-right: design-token("space.3"); display: inline-flex; z-index: 1; } @@ -62,7 +63,7 @@ border: design-token("shape.border_width.1") solid theme-token("color.neutral.300"); border-radius: design-token("shape.border_radius.md"); - background-color: white; + background-color: theme-token("color.neutral.000"); padding: design-token("space.2"); box-shadow: design-token("shadow.overlay"); } diff --git a/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.tsx b/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.tsx index 429340cc..f527a6b6 100644 --- a/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.tsx +++ b/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.tsx @@ -27,6 +27,9 @@ import styles from "./ForgeLayoutControls.module.scss"; const TEST_MODE = "Test"; const PRODUCTION_MODE = "Production"; +const POPOVER_CROSS_OFFSET = 116; +const POPOVER_OFFSET = 2; + export type ForgeLayoutControlsProps = { /** Controls children. */ children: ReactNode; @@ -48,10 +51,6 @@ export function ForgeLayoutControls(props: ForgeLayoutControlsProps) { return null; } - if (areControlsGrouped) { - return
{children}
; - } - return ( <> {areControlsGrouped ? ( @@ -187,8 +186,8 @@ export function ForgeLayoutModeSwitcher(props: ForgeLayoutModeSwitcherProps) { From 1f97f16f4263602c2715bad7065e45bbfe3426bd Mon Sep 17 00:00:00 2001 From: ssingh Date: Fri, 20 Dec 2024 16:40:12 -0800 Subject: [PATCH 6/9] add gap padding --- easy-ui-react/src/ForgeLayout/ForgeLayoutControls.module.scss | 4 ++-- easy-ui-react/src/ForgeLayout/ForgeLayoutHeader.module.scss | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.module.scss b/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.module.scss index 6d58bcca..2b32daeb 100644 --- a/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.module.scss +++ b/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.module.scss @@ -11,7 +11,7 @@ .breadcrumbNavigationContainer { border: design-token("shape.border_width.1") solid theme-token("color.neutral.300"); - padding-right: design-token("space.3"); + margin-right: design-token("space.3"); display: inline-flex; z-index: 1; } @@ -71,5 +71,5 @@ .searchContainer { width: 100%; max-width: 715px; - padding-right: design-token("space.3"); + margin-right: design-token("space.3"); } diff --git a/easy-ui-react/src/ForgeLayout/ForgeLayoutHeader.module.scss b/easy-ui-react/src/ForgeLayout/ForgeLayoutHeader.module.scss index 18f42d6c..9fc83513 100644 --- a/easy-ui-react/src/ForgeLayout/ForgeLayoutHeader.module.scss +++ b/easy-ui-react/src/ForgeLayout/ForgeLayoutHeader.module.scss @@ -13,6 +13,7 @@ border-bottom: 2px solid transparent; z-index: design-token("z-index.nav"); + gap: design-token("space.1"); } .headerBg { From 46a47fb5fd09eae19df82a2ec202cd8cc02a2024 Mon Sep 17 00:00:00 2001 From: ssingh Date: Fri, 20 Dec 2024 16:42:58 -0800 Subject: [PATCH 7/9] update story --- easy-ui-react/src/ForgeLayout/ForgeLayout.stories.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/easy-ui-react/src/ForgeLayout/ForgeLayout.stories.tsx b/easy-ui-react/src/ForgeLayout/ForgeLayout.stories.tsx index afd7d7b1..747cdc33 100644 --- a/easy-ui-react/src/ForgeLayout/ForgeLayout.stories.tsx +++ b/easy-ui-react/src/ForgeLayout/ForgeLayout.stories.tsx @@ -72,10 +72,9 @@ const Template = (args: Partial) => { Back - Breadcrumb One - Breadcrumb Two + Sub Account - Breadcrumb Three + Sub Account Name From dc1fae7f1e4592d40c45d6f6c2b63fa6724188e6 Mon Sep 17 00:00:00 2001 From: ssingh Date: Mon, 23 Dec 2024 10:17:09 -0800 Subject: [PATCH 8/9] typo jsdoc --- easy-ui-react/src/ForgeLayout/ForgeLayout.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/easy-ui-react/src/ForgeLayout/ForgeLayout.tsx b/easy-ui-react/src/ForgeLayout/ForgeLayout.tsx index b2f7856f..d16cb424 100644 --- a/easy-ui-react/src/ForgeLayout/ForgeLayout.tsx +++ b/easy-ui-react/src/ForgeLayout/ForgeLayout.tsx @@ -107,15 +107,15 @@ export const useForgeLayout = () => { * * * - * + * * {}}> * Back * - * - * Breadcrumb - * Breadcrumb - * - * + * + * Breadcrumb + * Breadcrumb + * + * * * * From 95e8b0afc997ebfce899b36dcef43d1b1767c051 Mon Sep 17 00:00:00 2001 From: ssingh Date: Mon, 23 Dec 2024 10:25:11 -0800 Subject: [PATCH 9/9] use nav zindex --- easy-ui-react/src/ForgeLayout/ForgeLayoutControls.module.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.module.scss b/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.module.scss index 2b32daeb..108db44e 100644 --- a/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.module.scss +++ b/easy-ui-react/src/ForgeLayout/ForgeLayoutControls.module.scss @@ -13,7 +13,7 @@ theme-token("color.neutral.300"); margin-right: design-token("space.3"); display: inline-flex; - z-index: 1; + z-index: design-token("z-index.nav"); } .backButtonContainer { @@ -52,7 +52,7 @@ cursor: pointer; width: 100%; max-width: 133px; - z-index: 1; + z-index: design-token("z-index.nav"); } .triggerPopoverOpen {