Skip to content

Commit

Permalink
code connect for accordion alert and avatar
Browse files Browse the repository at this point in the history
  • Loading branch information
jake-figma committed May 23, 2024
1 parent 9063a73 commit 1490205
Show file tree
Hide file tree
Showing 23 changed files with 390 additions and 404 deletions.
48 changes: 22 additions & 26 deletions src/ui/Accordion/Accordion.figma.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,27 @@
import figma from "@figma/code-connect";
import { Accordion, AccordionItem } from "./Accordion";

figma.connect(
Accordion,
"https://staging.figma.com/design/YfiqA0yWMXuLJAzkZNpBdy/SDS?node-id=7753-4779&t=KZPvI7iHa8LdRxX1-11",
{
props: {
children: figma.children("Accordion Item"),
showTitle: figma.boolean("Show Title"),
},
example: ({ children }) => <Accordion>{children}</Accordion>,
const FIGMA_URL_ACCORDION =
"https://staging.figma.com/design/YfiqA0yWMXuLJAzkZNpBdy/SDS?node-id=7753-4779&t=KZPvI7iHa8LdRxX1-11";
const FIGMA_URL_ACCORDION_ITEM =
"https://staging.figma.com/design/YfiqA0yWMXuLJAzkZNpBdy/SDS?node-id=7753-4634&t=KZPvI7iHa8LdRxX1-11";

figma.connect(Accordion, FIGMA_URL_ACCORDION, {
props: {
children: figma.children("Accordion Item"),
},
);
figma.connect(
AccordionItem,
"https://staging.figma.com/design/YfiqA0yWMXuLJAzkZNpBdy/SDS?node-id=7753-4634&t=KZPvI7iHa8LdRxX1-11",
{
props: {
isSelected: figma.enum("State", {
Closed: false,
Open: true,
}),
title: figma.string("Title"),
content: figma.string("Content"),
},
example: ({ title, content }) => (
<AccordionItem title={title}>{content}</AccordionItem>
),
example: ({ children }) => <Accordion>{children}</Accordion>,
});
figma.connect(AccordionItem, FIGMA_URL_ACCORDION_ITEM, {
props: {
isSelected: figma.enum("State", {
Closed: false,
Open: true,
}),
title: figma.string("Title"),
content: figma.string("Content"),
},
);
example: ({ title, content }) => (
<AccordionItem title={title}>{content}</AccordionItem>
),
});
25 changes: 18 additions & 7 deletions src/ui/Accordion/Accordion.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,41 @@
import type { Meta, StoryObj } from "@storybook/react";
import "react";
import { Accordion, AccordionItem } from "ui/Accordion/Accordion";
import { Text, TextSubtitle } from "ui/Text/Text";
import { Text, TextHeading } from "ui/Text/Text";

const meta: Meta<typeof Accordion> = {
component: Accordion,
title: "ui/Accordion",
parameters: { layout: "centered" },
};
export default meta;
type Story = StoryObj<typeof Accordion>;

export const Default: Story = {
export const AccordionStory: StoryObj<typeof Accordion> = {
args: {},
render: () => (
<Accordion>
<AccordionItem title="Your files">
<AccordionItem title="Item 1">
Answer the frequently asked question in a simple sentence, a longish
paragraph, or even in a list.
</AccordionItem>
<AccordionItem title="Shared with you">
<AccordionItem title="Item 2">
Answer the frequently asked question in a simple sentence, a longish
paragraph, or even in a list.
</AccordionItem>
<AccordionItem title="Last item" hasChildItems={false}>
<TextSubtitle>Subtitle</TextSubtitle>
<AccordionItem title="Item 3">
Answer the frequently asked question in a simple sentence, a longish
paragraph, or even in a list.
</AccordionItem>
</Accordion>
),
};

export const AccordionItemStory: StoryObj<typeof AccordionItem> = {
args: {},
render: () => (
<Accordion>
<AccordionItem title="Complex Content" hasChildItems={false}>
<TextHeading>Heading</TextHeading>
<Text>
Answer the frequently asked question in a simple sentence, a longish
paragraph, or even in a list.
Expand Down
34 changes: 34 additions & 0 deletions src/ui/Alert/Alert.figma.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import figma from "@figma/code-connect";
import { Alert, AlertActions, AlertBody, AlertTitle } from "./Alert";

const FIGMA_URL_ALERT =
"https://staging.figma.com/design/YfiqA0yWMXuLJAzkZNpBdy/SDS?node-id=2093-2151&m=dev";

figma.connect(Alert, FIGMA_URL_ALERT, {
props: {
title: figma.string("Title"),
hasIcon: figma.boolean("Has Icon"),
isDismissible: figma.boolean("Is Dismissible"),
actions: figma.enum("Scheme", {
Message: figma.children("Button"),
Alert: undefined,
}),
body: figma.boolean("Has Body", {
true: figma.string("Body"),
false: undefined,
}),
scheme: figma.enum("Scheme", {
Message: "message",
Warning: "warning",
Danger: "danger",
Neutral: "neutral",
}),
},
example: ({ hasIcon, isDismissible, actions, body, title }) => (
<Alert hasIcon={hasIcon} isDismissible={isDismissible}>
<AlertTitle>{title}</AlertTitle>
<AlertBody>{body}</AlertBody>
<AlertActions>{actions}</AlertActions>
</Alert>
),
});
31 changes: 31 additions & 0 deletions src/ui/Alert/Alert.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { Meta, StoryObj } from "@storybook/react";
import { Alert, AlertActions, AlertBody, AlertTitle } from "ui/Alert/Alert";
import { Button, ButtonGroup } from "ui/Button/Button";

const meta: Meta<typeof Alert> = {
component: Alert,
title: "ui/Alert",
parameters: { layout: "centered" },
};
export default meta;
type Story = StoryObj<typeof Alert>;

export const Default: Story = {
args: { isDismissible: true },
argTypes: {},
render: (args) => {
return (
<Alert {...args}>
<AlertTitle>Alert Title</AlertTitle>
<AlertBody>Hello there! This is a message</AlertBody>
<AlertActions>
<ButtonGroup>
<Button variant="secondary" size="sm">
Hello
</Button>
</ButtonGroup>
</AlertActions>
</Alert>
);
},
};
69 changes: 69 additions & 0 deletions src/ui/Alert/Alert.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import clsx from "clsx";
import { IconAlertTriangle, IconInfo, IconX } from "icons";
import { DestructiveIconButton, IconButton } from "ui/IconButton/IconButton";
import { Text, TextProps, TextStrong, TextStrongProps } from "ui/Text/Text";
import "./alert.css";

type AlertScheme = "default" | "danger";

const iconFromScheme = (scheme: AlertScheme): React.ReactNode => {
switch (scheme) {
case "default":
return <IconInfo size="20" />;
case "danger":
return <IconAlertTriangle size="20" />;
}
};

// TODO: alert still needs an onDismiss handler or something
export type AlertProps = React.ComponentPropsWithoutRef<"div"> & {
isDismissible?: boolean;
hasIcon?: boolean;
scheme?: AlertScheme;
};
export function Alert({
children,
className,
isDismissible,
hasIcon = true,
scheme = "default",
...props
}: AlertProps) {
const classNames = clsx(className, "alert", `alert-scheme-${scheme}`);
return (
<div className={classNames} {...props}>
{hasIcon && <span className="alert-icon">{iconFromScheme(scheme)}</span>}
<div className="alert-content">{children}</div>
{isDismissible &&
(scheme === "danger" ? (
<DestructiveIconButton size="sm" aria-label="Dismiss alert">
<IconX />
</DestructiveIconButton>
) : (
<IconButton size="sm" aria-label="Dismiss alert">
<IconX />
</IconButton>
))}
</div>
);
}

export type AlertTitleProps = TextStrongProps;
export function AlertTitle({ className, ...props }: AlertTitleProps) {
const classNames = clsx(className, "alert-title");
return (
<Text className={classNames}>
<TextStrong {...props} />
</Text>
);
}
export type AlertBodyProps = TextProps;
export function AlertBody({ className, ...props }: AlertBodyProps) {
const classNames = clsx(className, "alert-body");
return <Text className={classNames} {...props} />;
}
export type AlertActionsProps = React.ComponentPropsWithoutRef<"div">;
export function AlertActions({ className, ...props }: AlertActionsProps) {
const classNames = clsx(className, "alert-actions");
return <div className={classNames} {...props} />;
}
86 changes: 86 additions & 0 deletions src/ui/Alert/alert.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
.alert {
--border-radius: var(--sds-size-radius-xs);
align-items: center;
background-color: var(--alert-background-color);
border-radius: var(--border-radius);
color: var(--alert-color);
display: grid;
grid-template-areas: "icon content" "icon content" "icon content";
grid-template-columns: min-content 1fr;
justify-content: center;
line-height: 1;
padding: var(--sds-size-padding-lg) var(--sds-size-padding-xl)
var(--sds-size-padding-lg) var(--sds-size-padding-lg);
position: relative;
width: 100%;

> .alert-icon {
align-self: flex-start;
grid-area: icon;
+ .alert-content {
margin-left: var(--sds-size-gap-md);
}
}

> .alert-content {
grid-area: content;
> .alert-title + .alert-body {
margin-top: var(--sds-size-gap-cs);
}
> .alert-title {
font: var(--sds-font-body-strong);
}
> .alert-actions {
margin-top: var(--sds-size-gap-md);
}
}

> .alert-icon > .icon {
--icon-color: var(--alert-icon);
}

> .icon-button {
position: absolute;
right: var(--sds-size-padding-sm);
top: var(--sds-size-padding-sm);
}
}
.alert-variant-secondary {
box-shadow: inset 0 0 0 var(--sds-responsive-border-width)
var(--alert-border-color);
}

.alert-scheme-default {
--alert-color: var(--sds-color-text-brand-onbrand);
--alert-icon: var(--sds-color-icon-brand-onbrand);
--alert-background-color: var(--sds-color-bg-brand-default);

&[data-hovered],
&:has(.alert-remove-button[data-hovered]) {
--alert-background-color: var(--sds-color-bg-brand-hover);
}

&.alert-variant-secondary {
--alert-color: var(--sds-color-text-brand-onbrand-secondary);
--alert-icon: var(--sds-color-icon-brand-onbrand-secondary);
--alert-background-color: var(--sds-color-bg-brand-secondary);
--alert-border-color: var(--sds-color-border-brand-secondary);
}
}
.alert-scheme-danger {
--alert-color: var(--sds-color-text-danger-ondanger);
--alert-icon: var(--sds-color-icon-danger-ondanger);
--alert-background-color: var(--sds-color-bg-danger-default);

&[data-hovered],
&:has(.alert-remove-button[data-hovered]) {
--alert-background-color: var(--sds-color-bg-danger-hover);
}

&.alert-variant-secondary {
--alert-color: var(--sds-color-text-danger-ondanger-secondary);
--alert-icon: var(--sds-color-icon-danger-ondanger-secondary);
--alert-background-color: var(--sds-color-bg-danger-secondary);
--alert-border-color: var(--sds-color-border-danger-secondary);
}
}
22 changes: 19 additions & 3 deletions src/ui/Avatar/Avatar.figma.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import figma from "@figma/code-connect";
import { Avatar, AvatarGroup } from "./Avatar";
import { Description, Label } from "ui/Fieldset/Fieldset";
import { Avatar, AvatarBlock, AvatarGroup } from "./Avatar";

const FIGMA_URL_AVATAR =
"https://staging.figma.com/design/YfiqA0yWMXuLJAzkZNpBdy?node-id=9762:1103";
// "https://www.figma.com/file/4HOiV2Yd9xDbTnp0j8hU6m?node-id=24-9238"
const FIGMA_URL_AVATAR_GROUP =
"https://staging.figma.com/design/YfiqA0yWMXuLJAzkZNpBdy?node-id=56-15608";
// "https://www.figma.com/file/4HOiV2Yd9xDbTnp0j8hU6m?node-id=24-9238"
const FIGMA_URL_AVATAR_BLOCK =
"https://staging.figma.com/design/YfiqA0yWMXuLJAzkZNpBdy/SDS?node-id=2010-15581&t=piSsjqZPlyn7qp8D-11";

figma.connect(AvatarGroup, FIGMA_URL_AVATAR_GROUP, {
props: {
Expand Down Expand Up @@ -47,3 +48,18 @@ figma.connect(Avatar, FIGMA_URL_AVATAR, {
<Avatar square={square} size={size} src={src} initials={initials} />
),
});

figma.connect(AvatarBlock, FIGMA_URL_AVATAR_BLOCK, {
props: {
title: figma.string("Title"),
description: figma.string("Description"),
avatar: figma.children("Avatar"),
},
example: ({ title, description, avatar }) => (
<AvatarBlock>
{avatar}
<Label>{title}</Label>
<Description>{description}</Description>
</AvatarBlock>
),
});
Loading

0 comments on commit 1490205

Please sign in to comment.