Skip to content

Commit

Permalink
Resource Headers
Browse files Browse the repository at this point in the history
  • Loading branch information
dani-moreno committed Nov 14, 2024
1 parent 0c5458d commit eda8d7b
Show file tree
Hide file tree
Showing 8 changed files with 329 additions and 1 deletion.
92 changes: 92 additions & 0 deletions lib/experimental/Information/Headers/BaseHeader/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { Button } from "@/components/Actions/Button"
import { IconType } from "@/components/Utilities/Icon"
import {
AvatarVariant,
renderAvatar,
} from "@/experimental/Information/Avatars/utils"
import { cn } from "@/lib/utils"

interface BaseHeaderProps {
title: string
avatar?: AvatarVariant
description?: string
eyebrow?: React.ReactNode
footer?: React.ReactNode
primaryAction?: {
label: string
icon?: IconType
onClick: () => void
}
secondaryActions?: Array<{
label: string
icon?: IconType
onClick: () => void
variant?: "outline" | "critical"
}>
}

export function BaseHeader({
title,
avatar,
description,
eyebrow,
footer,
primaryAction,
secondaryActions,
}: BaseHeaderProps) {
return (
<div className="flex flex-col items-start justify-start gap-4 p-8 md:flex-row">
<div className="flex grow flex-col items-start justify-start gap-4 md:flex-row md:items-center">
{avatar && (
<div className="flex items-start">
{renderAvatar(avatar, "large")}
</div>
)}
<div className="flex flex-col gap-1">
{eyebrow && (
<div className="w-fit text-f1-foreground-secondary">{eyebrow}</div>
)}
<span className="text-xl font-semibold text-f1-foreground">
{title}
</span>
{description && (
<div className="text-lg text-f1-foreground-secondary">
{description}
</div>
)}
{footer && (
<div className="w-fit text-f1-foreground-secondary">{footer}</div>
)}
</div>
</div>
<div
className={cn(
"flex shrink-0 flex-wrap items-center gap-x-3 gap-y-2 overflow-x-auto md:flex-row-reverse",
avatar && "md:pt-1.5"
)}
>
{primaryAction && (
<Button
label={primaryAction.label}
onClick={primaryAction.onClick}
variant="default"
icon={primaryAction.icon}
/>
)}
{primaryAction && secondaryActions && (
<div className="hidden h-4 w-px bg-f1-background-secondary md:block" />
)}
{secondaryActions &&
secondaryActions.map((action) => (
<Button
key={action.label}
label={action.label}
onClick={action.onClick}
variant={action.variant ?? "outline"}
icon={action.icon}
/>
))}
</div>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import * as Icon from "@/icons/app/"
import type { Meta, StoryObj } from "@storybook/react"
import { CompanyHeader } from "./index"

const meta: Meta<typeof CompanyHeader> = {
component: CompanyHeader,
parameters: {
layout: "centered",
},
}

export default meta

type Story = StoryObj<typeof CompanyHeader>

export const Default: Story = {
parameters: {
layout: "fullscreen",
},
args: {
name: "Factorial",
description: "HR Software to Empower Your Team",
src: "https://github.com/factorialco.png",
primaryAction: {
label: "Edit",
icon: Icon.Pencil,
onClick: () => console.log("Edit clicked"),
},
secondaryActions: [
{
label: "Promote",
onClick: () => console.log("Promote clicked"),
},
{
label: "Remove",
icon: Icon.Delete,
variant: "critical",
onClick: () => console.log("Remove clicked"),
},
],
},
}
32 changes: 32 additions & 0 deletions lib/experimental/Information/Headers/CompanyHeader/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { ComponentProps } from "react"
import { BaseHeader } from "../BaseHeader"

type BaseHeaderProps = ComponentProps<typeof BaseHeader>

type Props = {
name: string
description: string
src?: string
} & Pick<BaseHeaderProps, "primaryAction" | "secondaryActions">

export const CompanyHeader = ({
name,
description,
src,
primaryAction,
secondaryActions,
}: Props) => {
return (
<BaseHeader
title={name}
description={description}
avatar={{
type: "company",
name,
src,
}}
primaryAction={primaryAction}
secondaryActions={secondaryActions}
/>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import * as Icon from "@/icons/app/"
import type { Meta, StoryObj } from "@storybook/react"
import { PersonHeader } from "./index"

const meta: Meta<typeof PersonHeader> = {
component: PersonHeader,
parameters: {
layout: "centered",
},
}

export default meta

type Story = StoryObj<typeof PersonHeader>

export const Default: Story = {
parameters: {
layout: "fullscreen",
},
args: {
firstName: "Josep Jaume",
lastName: "Rey",
description: "Chief Confetti Officer",
src: "https://github.com/josepjaume.png",
primaryAction: {
label: "Edit",
icon: Icon.Pencil,
onClick: () => console.log("Edit clicked"),
},
secondaryActions: [
{
label: "Promote",
onClick: () => console.log("Promote clicked"),
},
{
label: "Remove",
icon: Icon.Delete,
variant: "critical",
onClick: () => console.log("Remove clicked"),
},
],
},
}
35 changes: 35 additions & 0 deletions lib/experimental/Information/Headers/PersonHeader/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { ComponentProps } from "react"
import { BaseHeader } from "../BaseHeader"

type BaseHeaderProps = ComponentProps<typeof BaseHeader>

type Props = {
firstName: string
lastName: string
description: string
src?: string
} & Pick<BaseHeaderProps, "primaryAction" | "secondaryActions">

export const PersonHeader = ({
firstName,
lastName,
description,
src,
primaryAction,
secondaryActions,
}: Props) => {
return (
<BaseHeader
title={`${firstName} ${lastName}`}
description={description}
avatar={{
type: "person",
firstName,
lastName,
src,
}}
primaryAction={primaryAction}
secondaryActions={secondaryActions}
/>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import * as Icon from "@/icons/app/"
import type { Meta, StoryObj } from "@storybook/react"
import { ResourceHeader } from "./index"

const meta: Meta<typeof ResourceHeader> = {
component: ResourceHeader,
parameters: {
layout: "centered",
},
}

export default meta

type Story = StoryObj<typeof ResourceHeader>

export const Default: Story = {
parameters: {
layout: "fullscreen",
},
args: {
title: "Senior Product Designer",
description:
"Open position on our team, seeking an experienced product designer to lead design initiatives",
status: {
label: "Published",
variant: "positive",
},
primaryAction: {
label: "Edit",
icon: Icon.Pencil,
onClick: () => console.log("Edit clicked"),
},
secondaryActions: [
{
label: "Promote",
onClick: () => console.log("Promote clicked"),
},
{
label: "Remove",
icon: Icon.Delete,
variant: "critical",
onClick: () => console.log("Remove clicked"),
},
],
},
}
38 changes: 38 additions & 0 deletions lib/experimental/Information/Headers/ResourceHeader/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import {
StatusTag,
StatusVariant,
} from "@/experimental/Information/Tags/StatusTag"
import { ComponentProps } from "react"
import { BaseHeader } from "../BaseHeader"

type BaseHeaderProps = ComponentProps<typeof BaseHeader>

type Props = {
status?: {
label: string
variant: StatusVariant
}
} & Pick<
BaseHeaderProps,
"title" | "description" | "primaryAction" | "secondaryActions"
>

export const ResourceHeader = ({
title,
description,
primaryAction,
secondaryActions,
status,
}: Props) => {
return (
<BaseHeader
title={title}
description={description}
primaryAction={primaryAction}
secondaryActions={secondaryActions}
eyebrow={
status && <StatusTag text={status.label} variant={status.variant} />
}
/>
)
}
2 changes: 1 addition & 1 deletion lib/ui/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const buttonVariants = cva(
neutral:
"bg-f1-background-secondary text-f1-foreground hover:bg-f1-background-secondary-hover",
critical:
"border border-solid border-f1-border bg-f1-background-secondary text-f1-foreground-critical hover:border-none hover:bg-f1-background-critical-bold hover:text-f1-foreground-inverse",
"border border-solid border-f1-border bg-f1-background-secondary text-f1-foreground-critical hover:border-transparent hover:bg-f1-background-critical-bold hover:text-f1-foreground-inverse",
ghost:
"bg-transparent text-f1-foreground hover:bg-f1-background-secondary-hover",
promote:
Expand Down

0 comments on commit eda8d7b

Please sign in to comment.