From 93f457bad3d2450b0e37515ad98ae745601465df Mon Sep 17 00:00:00 2001 From: Cahllagerfeld <43843195+Cahllagerfeld@users.noreply.github.com> Date: Mon, 16 Oct 2023 11:25:00 +0200 Subject: [PATCH 01/10] feat: init sidebar component --- .storybook/assets/Appshell.tsx | 12 ++++ .storybook/assets/CPU.tsx | 27 +++++++ src/components/Sidebar/Sidebar.stories.tsx | 33 +++++++++ src/components/Sidebar/Sidebar.tsx | 82 ++++++++++++++++++++++ src/components/Sidebar/index.tsx | 1 + src/components/index.ts | 1 + src/tailwind/index.ts | 2 +- 7 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 .storybook/assets/Appshell.tsx create mode 100644 .storybook/assets/CPU.tsx create mode 100644 src/components/Sidebar/Sidebar.stories.tsx create mode 100644 src/components/Sidebar/Sidebar.tsx create mode 100644 src/components/Sidebar/index.tsx diff --git a/.storybook/assets/Appshell.tsx b/.storybook/assets/Appshell.tsx new file mode 100644 index 0000000..37ff9cf --- /dev/null +++ b/.storybook/assets/Appshell.tsx @@ -0,0 +1,12 @@ +import React, { ReactNode } from "react"; + +export function AppShell({ children }: { children: ReactNode }) { + return ( +
+
+ {children} +
+ ); +} diff --git a/.storybook/assets/CPU.tsx b/.storybook/assets/CPU.tsx new file mode 100644 index 0000000..c5f958e --- /dev/null +++ b/.storybook/assets/CPU.tsx @@ -0,0 +1,27 @@ +import React from "react"; +export default function CPU({ className = "" }: { className?: string }) { + return ( + + + + + + + + + + + + + + ); +} diff --git a/src/components/Sidebar/Sidebar.stories.tsx b/src/components/Sidebar/Sidebar.stories.tsx new file mode 100644 index 0000000..b13e5dd --- /dev/null +++ b/src/components/Sidebar/Sidebar.stories.tsx @@ -0,0 +1,33 @@ +import { Meta } from "@storybook/react"; +import React from "react"; +import { Sidebar } from "./index"; +import CPU from "../../../.storybook/assets/CPU"; +import { StoryObj } from "@storybook/react"; +import { AppShell } from "../../../.storybook/assets/Appshell"; + +const meta = { + title: "UI/Sidebar", + component: Sidebar, + parameters: { + layout: "fullscreen" + }, + decorators: [ + (Story) => ( + + + + ) + ], + tags: ["autodocs"] +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const small: Story = { + name: "Sidebar" + // args: { + // children: } label="Models" /> + // } +}; diff --git a/src/components/Sidebar/Sidebar.tsx b/src/components/Sidebar/Sidebar.tsx new file mode 100644 index 0000000..d3405e3 --- /dev/null +++ b/src/components/Sidebar/Sidebar.tsx @@ -0,0 +1,82 @@ +import React from "react"; +import { Slot } from "@radix-ui/react-slot"; +import CPU from "../../../.storybook/assets/CPU"; + +type SidebarProps = { + children?: React.ReactNode; +}; + +const isActive = true; + +export function Sidebar({ children }: SidebarProps) { + return ( + + ); +} + +// type SidebarItemProps = { +// icon: React.ReactNode; +// label: string; +// }; + +// export function SidebarItem({ label, icon }: SidebarItemProps) { +// return ( +//
+// {icon} +//
{label}
+//
+// ); +// } diff --git a/src/components/Sidebar/index.tsx b/src/components/Sidebar/index.tsx new file mode 100644 index 0000000..d678998 --- /dev/null +++ b/src/components/Sidebar/index.tsx @@ -0,0 +1 @@ +export * from "./Sidebar"; diff --git a/src/components/index.ts b/src/components/index.ts index e22c29a..f063219 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -1 +1,2 @@ export * from "./Button"; +export * from "./Sidebar"; diff --git a/src/tailwind/index.ts b/src/tailwind/index.ts index 3d684b8..d5583c4 100644 --- a/src/tailwind/index.ts +++ b/src/tailwind/index.ts @@ -73,7 +73,7 @@ export const zenmlPlugin = plugin( "--color-blue-025": "208 88% 90%", "--color-text-primary": "var(--color-primary-900)", "--color-text-secondary": "var(--color-neutral-500)", - "--color-text-tertiary": "var(--color-neutral-300)", + "--color-text-tertiary": "var(--color-neutral-400)", "--color-text-negative": "var(--color-neutral-000)", "--color-text-brand": "var(--color-primary-500)", "--color-text-error": "var(--color-error-500)", From 7952b968e49304f855aa212a8e45dd09156ecb0f Mon Sep 17 00:00:00 2001 From: Cahllagerfeld <43843195+Cahllagerfeld@users.noreply.github.com> Date: Mon, 16 Oct 2023 10:15:02 +0000 Subject: [PATCH 02/10] chore: more adjustments --- src/components/Sidebar/Sidebar.stories.tsx | 17 ++- src/components/Sidebar/Sidebar.tsx | 120 +++++++++------------ 2 files changed, 63 insertions(+), 74 deletions(-) diff --git a/src/components/Sidebar/Sidebar.stories.tsx b/src/components/Sidebar/Sidebar.stories.tsx index b13e5dd..4f59ca0 100644 --- a/src/components/Sidebar/Sidebar.stories.tsx +++ b/src/components/Sidebar/Sidebar.stories.tsx @@ -1,6 +1,6 @@ import { Meta } from "@storybook/react"; import React from "react"; -import { Sidebar } from "./index"; +import { Sidebar, SidebarMain, SidebarHeader, SidebarItem } from "./index"; import CPU from "../../../.storybook/assets/CPU"; import { StoryObj } from "@storybook/react"; import { AppShell } from "../../../.storybook/assets/Appshell"; @@ -26,8 +26,15 @@ export default meta; type Story = StoryObj; export const small: Story = { - name: "Sidebar" - // args: { - // children: } label="Models" /> - // } + name: "Sidebar", + args: { + children: ( + <> + + + } label="Models" /> + + + ) + } }; diff --git a/src/components/Sidebar/Sidebar.tsx b/src/components/Sidebar/Sidebar.tsx index d3405e3..e89fdd1 100644 --- a/src/components/Sidebar/Sidebar.tsx +++ b/src/components/Sidebar/Sidebar.tsx @@ -1,82 +1,64 @@ -import React from "react"; -import { Slot } from "@radix-ui/react-slot"; -import CPU from "../../../.storybook/assets/CPU"; +import React, { AnchorHTMLAttributes, cloneElement, forwardRef, isValidElement } from "react"; type SidebarProps = { children?: React.ReactNode; }; -const isActive = true; - export function Sidebar({ children }: SidebarProps) { return ( ); } -// type SidebarItemProps = { -// icon: React.ReactNode; -// label: string; -// }; +type SidebarHeaderProps = { + title: string; +}; + +export function SidebarHeader({ title }: SidebarHeaderProps) { + return ( +
+ +

{title}

+
+ ); +} + +export function SidebarMain({ children }: { children?: React.ReactNode }) { + return
    {children}
; +} + +type SidebarItemProps = Omit, "className"> & { + icon: React.ReactNode; + label: string; + isActive?: boolean; +}; + +export const SidebarItem = forwardRef( + ({ icon, isActive, label, ...rest }, ref) => { + const existingIconClasses = isValidElement(icon) ? icon.props.className || "" : ""; + + const iconClasses = `${existingIconClasses} w-5 h-5 shrink-0 ${ + isActive ? "stroke-primary-400" : "stroke-theme-text-tertiary" + }`; + + return ( + + {cloneElement(icon as React.ReactElement, { className: iconClasses })} +
{label}
+
+ ); + } +); -// export function SidebarItem({ label, icon }: SidebarItemProps) { -// return ( -//
-// {icon} -//
{label}
-//
-// ); -// } +SidebarItem.displayName = "SidebarItem"; From 470946ff825ce3aff1c29b8794a987ad2f873a19 Mon Sep 17 00:00:00 2001 From: Cahllagerfeld <43843195+Cahllagerfeld@users.noreply.github.com> Date: Mon, 16 Oct 2023 12:44:34 +0000 Subject: [PATCH 03/10] feat: use slot for Item --- src/components/Sidebar/Sidebar.tsx | 57 +++++++++++++++++------------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/src/components/Sidebar/Sidebar.tsx b/src/components/Sidebar/Sidebar.tsx index e89fdd1..654e76b 100644 --- a/src/components/Sidebar/Sidebar.tsx +++ b/src/components/Sidebar/Sidebar.tsx @@ -1,4 +1,5 @@ -import React, { AnchorHTMLAttributes, cloneElement, forwardRef, isValidElement } from "react"; +import React, { ReactNode, cloneElement, isValidElement } from "react"; +import { Slot } from "@radix-ui/react-slot"; type SidebarProps = { children?: React.ReactNode; @@ -32,33 +33,39 @@ export function SidebarMain({ children }: { children?: React.ReactNode }) { return
    {children}
; } -type SidebarItemProps = Omit, "className"> & { +export function SidebarItem({ + isActive = false, + ...rest +}: { + children: ReactNode; + isActive?: boolean; +}) { + return ( + + ); +} + +type SidebarItemContentProps = { icon: React.ReactNode; label: string; isActive?: boolean; }; -export const SidebarItem = forwardRef( - ({ icon, isActive, label, ...rest }, ref) => { - const existingIconClasses = isValidElement(icon) ? icon.props.className || "" : ""; +export function SidebarItemContent({ icon, label, isActive }: SidebarItemContentProps) { + const existingIconClasses = isValidElement(icon) ? icon.props.className || "" : ""; - const iconClasses = `${existingIconClasses} w-5 h-5 shrink-0 ${ - isActive ? "stroke-primary-400" : "stroke-theme-text-tertiary" - }`; - - return ( - - {cloneElement(icon as React.ReactElement, { className: iconClasses })} -
{label}
-
- ); - } -); - -SidebarItem.displayName = "SidebarItem"; + const iconClasses = `${existingIconClasses} w-5 h-5 shrink-0 ${ + isActive ? "stroke-primary-400" : "stroke-theme-text-tertiary" + }`; + return ( + <> + {cloneElement(icon as React.ReactElement, { className: iconClasses })} +
{label}
+ + ); +} From 57a854ae64d4c10a167076ff7dae6592c00048d0 Mon Sep 17 00:00:00 2001 From: Cahllagerfeld <43843195+Cahllagerfeld@users.noreply.github.com> Date: Mon, 16 Oct 2023 13:26:28 +0000 Subject: [PATCH 04/10] feat: add icon in header --- .storybook/assets/icons.tsx | 44 ++++++++++++++++++++++ src/components/Sidebar/Sidebar.stories.tsx | 22 +++++++++-- src/components/Sidebar/Sidebar.tsx | 27 +++++++++---- 3 files changed, 82 insertions(+), 11 deletions(-) create mode 100644 .storybook/assets/icons.tsx diff --git a/.storybook/assets/icons.tsx b/.storybook/assets/icons.tsx new file mode 100644 index 0000000..92f6fb3 --- /dev/null +++ b/.storybook/assets/icons.tsx @@ -0,0 +1,44 @@ +import React from "react"; +export function CPU({ className = "" }: { className?: string }) { + return ( + + + + + + + + + + + + + + ); +} + +export function CloseButton({ className = "" }: { className?: string }) { + return ( + + + + ); +} diff --git a/src/components/Sidebar/Sidebar.stories.tsx b/src/components/Sidebar/Sidebar.stories.tsx index 4f59ca0..357ea6a 100644 --- a/src/components/Sidebar/Sidebar.stories.tsx +++ b/src/components/Sidebar/Sidebar.stories.tsx @@ -1,7 +1,7 @@ import { Meta } from "@storybook/react"; import React from "react"; -import { Sidebar, SidebarMain, SidebarHeader, SidebarItem } from "./index"; -import CPU from "../../../.storybook/assets/CPU"; +import { Sidebar, SidebarMain, SidebarHeader, SidebarItem, SidebarItemContent } from "./index"; +import { CPU, CloseButton } from "../../../.storybook/assets/icons"; import { StoryObj } from "@storybook/react"; import { AppShell } from "../../../.storybook/assets/Appshell"; @@ -30,9 +30,23 @@ export const small: Story = { args: { children: ( <> - + } title="ZenML Tenant" /> - } label="Models" /> + +
+ } label="Models" /> +
+
+ +
+ } label="Models" /> +
+
+ +
+ } label="Models" /> +
+
) diff --git a/src/components/Sidebar/Sidebar.tsx b/src/components/Sidebar/Sidebar.tsx index 654e76b..ce9b591 100644 --- a/src/components/Sidebar/Sidebar.tsx +++ b/src/components/Sidebar/Sidebar.tsx @@ -1,5 +1,6 @@ import React, { ReactNode, cloneElement, isValidElement } from "react"; import { Slot } from "@radix-ui/react-slot"; +import { cn } from "../../utilities/index"; type SidebarProps = { children?: React.ReactNode; @@ -15,16 +16,27 @@ export function Sidebar({ children }: SidebarProps) { type SidebarHeaderProps = { title: string; + icon?: React.ReactNode; }; -export function SidebarHeader({ title }: SidebarHeaderProps) { +export function SidebarHeader({ title, icon }: SidebarHeaderProps) { + const existingIconClasses = isValidElement(icon) ? icon.props.className || "" : ""; + + const iconClasses = cn( + existingIconClasses, + "w-6 ml-auto shrink-0 h-6 opacity-0 group-hover:opacity-100 duration-300 transition-all" + ); + return ( -
+
-

{title}

+

+ {title} +

+ {icon && cloneElement(icon as React.ReactElement, { className: iconClasses })}
); } @@ -42,7 +54,7 @@ export function SidebarItem({ }) { return ( {cloneElement(icon as React.ReactElement, { className: iconClasses })} From d70498fbebd273b6b34936e7509bac097445afbd Mon Sep 17 00:00:00 2001 From: Cahllagerfeld <43843195+Cahllagerfeld@users.noreply.github.com> Date: Mon, 16 Oct 2023 20:00:58 +0200 Subject: [PATCH 05/10] fix: add more improvements --- .storybook/preview.ts | 7 +++ src/components/Sidebar/Sidebar.stories.tsx | 54 ++++++++++++------- src/components/Sidebar/Sidebar.tsx | 45 ++++++++++------ .../Sidebar/SidebarHeader.stories.tsx | 30 +++++++++++ .../Sidebar/SidebarItem.stories.tsx | 46 ++++++++++++++++ 5 files changed, 148 insertions(+), 34 deletions(-) create mode 100644 src/components/Sidebar/SidebarHeader.stories.tsx create mode 100644 src/components/Sidebar/SidebarItem.stories.tsx diff --git a/.storybook/preview.ts b/.storybook/preview.ts index cd70a32..4be460a 100644 --- a/.storybook/preview.ts +++ b/.storybook/preview.ts @@ -7,6 +7,13 @@ import "../src/index.css"; const preview: Preview = { parameters: { + backgrounds: { + default: "light", + values: [ + { name: "light", value: "#F9FAFB" }, + { name: "dark", value: "#1F2937" } + ] + }, actions: { argTypesRegex: "^on[A-Z].*" }, controls: { matchers: { diff --git a/src/components/Sidebar/Sidebar.stories.tsx b/src/components/Sidebar/Sidebar.stories.tsx index 357ea6a..292063c 100644 --- a/src/components/Sidebar/Sidebar.stories.tsx +++ b/src/components/Sidebar/Sidebar.stories.tsx @@ -1,6 +1,13 @@ import { Meta } from "@storybook/react"; import React from "react"; -import { Sidebar, SidebarMain, SidebarHeader, SidebarItem, SidebarItemContent } from "./index"; +import { + Sidebar, + SidebarList, + SidebarHeader, + SidebarItem, + SidebarItemContent, + SidebarBody +} from "./index"; import { CPU, CloseButton } from "../../../.storybook/assets/icons"; import { StoryObj } from "@storybook/react"; import { AppShell } from "../../../.storybook/assets/Appshell"; @@ -31,23 +38,34 @@ export const small: Story = { children: ( <> } title="ZenML Tenant" /> - - -
- } label="Models" /> -
-
- -
- } label="Models" /> -
-
- -
- } label="Models" /> -
-
-
+ + + +
+ } label="Models" /> +
+
+ +
+ } label="Models" /> +
+
+ +
+ } label="Models" /> +
+
+
+
+ + +
+ } label="Models" /> +
+
+
+
+
) } diff --git a/src/components/Sidebar/Sidebar.tsx b/src/components/Sidebar/Sidebar.tsx index ce9b591..207e66f 100644 --- a/src/components/Sidebar/Sidebar.tsx +++ b/src/components/Sidebar/Sidebar.tsx @@ -1,15 +1,17 @@ -import React, { ReactNode, cloneElement, isValidElement } from "react"; +import React, { HTMLAttributes, ReactNode, cloneElement, isValidElement } from "react"; import { Slot } from "@radix-ui/react-slot"; import { cn } from "../../utilities/index"; -type SidebarProps = { - children?: React.ReactNode; -}; - -export function Sidebar({ children }: SidebarProps) { +export function Sidebar({ className, children, ...rest }: HTMLAttributes) { return ( -