Skip to content

Commit

Permalink
create LockedState component and add new lock icon
Browse files Browse the repository at this point in the history
  • Loading branch information
btarver40 committed Dec 13, 2024
1 parent d8969a5 commit 7d0ab12
Show file tree
Hide file tree
Showing 6 changed files with 289 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .changeset/spotty-tables-happen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@easypost/easy-ui-icons": minor
"@easypost/easy-ui": minor
---

Add lock icon and create LockedState component
5 changes: 5 additions & 0 deletions easy-ui-icons/src/Lock.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "lock",
"style": "outlined",
"source": "@material-symbols/svg-300"
}
48 changes: 48 additions & 0 deletions easy-ui-react/src/LockedStateCard/LockedStateCard.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from "react";
import { ArgTypes, Canvas, Meta, Controls } from "@storybook/blocks";
import { LockedStateCard } from "./LockedStateCard";
import * as LockedStateCardStories from "./LockedStateCard.stories";

<Meta of={LockedStateCardStories} />

# LockedStateCard

A `<LockedStateCard />` is a styled container designed to display relevant information when a user is locked out of a feature or functionality.

It is a compound component consisting of `<LockedStateCard.Section />`, `<LockedStateCard.TextGroup />`, `<LockedStateCard.HeaderText />`, `<LockedStateCard.BodyText />`, and `<LockedStateCard.ActionGroup />`

## Simple

<Canvas of={LockedStateCardStories.Simple} />

## Alignment

`<LockedStateCard.Section />` and `<LockedStateCard.TextGroup />` can accept `VerticalStack` props to override defaults and to assist with alignment. Similarly, `<LockedStateCard.ActionGroup />` can accept `HorizontalStack` props.

<Canvas of={LockedStateCardStories.Alignment} />

## Properties

### LockedStateCard

<ArgTypes of={LockedStateCard} />

### LockedStateCard.Section

<ArgTypes of={LockedStateCard.Section} />

### LockedStateCard.TextGroup

<ArgTypes of={LockedStateCard.TextGroup} />

### LockedStateCard.HeaderText

<ArgTypes of={LockedStateCard.TextGroup} />

### LockedStateCard.BodyText

<ArgTypes of={LockedStateCard.BodyText} />

### LockedStateCard.ActionGroup

<ArgTypes of={LockedStateCard.ActionGroup} />
8 changes: 8 additions & 0 deletions easy-ui-react/src/LockedStateCard/LockedStateCard.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.container {
max-width: 695px;
position: relative;
}

.inlineMargin {
margin: 0 auto;
}
67 changes: 67 additions & 0 deletions easy-ui-react/src/LockedStateCard/LockedStateCard.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import React from "react";
import { Meta, StoryObj } from "@storybook/react";
import { LockedStateCard, LockedStateCardProps } from "./LockedStateCard";
import { Button } from "../Button";
import { Icon } from "../Icon";
import Visibility from "@easypost/easy-ui-icons/Visibility";

type Story = StoryObj<typeof LockedStateCard>;

const Template = (args: LockedStateCardProps) => {
const { children, ...restArgs } = args;
return <LockedStateCard {...restArgs}>{children}</LockedStateCard>;
};

const meta: Meta<typeof LockedStateCard> = {
title: "Components/Cards/LockedStateCard",
component: LockedStateCard,
};

export default meta;

export const Simple: Story = {
render: Template.bind({}),
args: {
children: (
<LockedStateCard.Section>
<LockedStateCard.TextGroup>
<LockedStateCard.HeaderText>
Looking to create something more advanced?
</LockedStateCard.HeaderText>
<LockedStateCard.BodyText>
EasyPost’s API Suite delivers the best developer experience by
offering a comprehensive suite of tools and features to ensure we
meet the shipping needs of every single shipper. 
</LockedStateCard.BodyText>
</LockedStateCard.TextGroup>
<LockedStateCard.ActionGroup>
<Button color="secondary">Upgrade Plans</Button>
</LockedStateCard.ActionGroup>
</LockedStateCard.Section>
),
},
};

export const Alignment: Story = {
render: Template.bind({}),
args: {
children: (
<LockedStateCard.Section inlineAlign="center">
<LockedStateCard.TextGroup gap="2">
<Icon color="secondary.500" size="3xl" symbol={Visibility} />
<LockedStateCard.HeaderText>
Looking to create something more advanced?
</LockedStateCard.HeaderText>
<LockedStateCard.BodyText>
EasyPost’s API Suite delivers the best developer experience by
offering a comprehensive suite of tools and features to ensure we
meet the shipping needs of every single shipper. 
</LockedStateCard.BodyText>
</LockedStateCard.TextGroup>
<LockedStateCard.ActionGroup gap="2">
<Button color="secondary">Upgrade Plan</Button>
</LockedStateCard.ActionGroup>
</LockedStateCard.Section>
),
},
};
155 changes: 155 additions & 0 deletions easy-ui-react/src/LockedStateCard/LockedStateCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import React, { ReactNode } from "react";
import { Text, TextProps } from "../Text";
import { Card, CardProps } from "../Card";
import { VerticalStack, VerticalStackProps } from "../VerticalStack";
import { HorizontalStack, HorizontalStackProps } from "../HorizontalStack";
import { classNames } from "../utilities/css";

import styles from "./LockedStateCard.module.scss";

export type LockedStateCardProps = CardProps & {
/**
* The children of the <LockedStateCard> element.
*/
children: ReactNode;
};

/**
* A `<LockedStateCard />` is a styled container designed to display relevant information when a user is locked out of a feature or functionality.
*
* @remarks
* Supports custom spacing and alignment between elements.
*
* @example
* _Basic:_
* ```tsx
* <LockedStateCard>
<LockedStateCard.Section>
<LockedStateCard.TextGroup>
<LockedStateCard.HeaderText>
Looking to create something more advanced?
</LockedStateCard.HeaderText>
<LockedStateCard.BodyText>
EasyPost’s API Suite delivers the best developer experience by
offering a comprehensive suite of tools and features to ensure we
meet the shipping needs of every single shipper. 
</LockedStateCard.BodyText>
</LockedStateCard.TextGroup>
<LockedStateCard.ActionGroup>
<Button color="secondary">Upgrade Plans</Button>
</LockedStateCard.ActionGroup>
</LockedStateCard.Section>
* </LockedStateCard>
* ```
*
* @example
* _Alignment:_
* ```tsx
* <LockedStateCard>
<LockedStateCard.Section inlineAlign="center">
<LockedStateCard.TextGroup gap="2">
<Icon />
<LockedStateCard.HeaderText>
Looking to create something more advanced?
</LockedStateCard.HeaderText>
<LockedStateCard.BodyText>
EasyPost’s API Suite delivers the best developer experience by
offering a comprehensive suite of tools and features to ensure we
meet the shipping needs of every single shipper. 
</LockedStateCard.BodyText>
</LockedStateCard.TextGroup>
<LockedStateCard.ActionGroup gap="2">
<Button color="secondary">Upgrade Plan</Button>
</LockedStateCard.ActionGroup>
</LockedStateCard.Section>
* </LockedStateCard>
* ```
*/
export function LockedStateCard(props: LockedStateCardProps) {
const { children, ...cardProps } = props;

return (
<Card
variant="solid"
background="secondary.050"
borderRadius="lg"
padding="0"
boxShadow="1"
{...cardProps}
>
{children}
</Card>
);
}

function LockedStateCardSection(props: VerticalStackProps) {
const { gap = "2", inlineAlign = "start", children, ...restProps } = props;

const isInlineSection = inlineAlign === "center";

const sectionClassName = classNames(
styles.container,
isInlineSection && styles.inlineMargin,
);

return (
<div className={sectionClassName}>
<Card.Area padding="5">
<VerticalStack gap={gap} inlineAlign={inlineAlign} {...restProps}>
{children}
</VerticalStack>
</Card.Area>
</div>
);
}

function LockedStateCardTextGroup(props: VerticalStackProps) {
const { gap = "1", children, ...restProps } = props;
return (
<VerticalStack gap={gap} {...restProps}>
{children}
</VerticalStack>
);
}

function LockedStateCardActionGroup(props: HorizontalStackProps) {
const { gap = "1", align = "space-between", children, ...restProps } = props;
return (
<HorizontalStack gap={gap} align={align} {...restProps}>
{children}
</HorizontalStack>
);
}

function LockedStateCardHeaderText(props: TextProps) {
const {
variant = "subtitle1",
color = "neutral.900",
...restTextProps
} = props;

return <Text variant={variant} color={color} {...restTextProps} />;
}

function LockedStateCardBodyText(props: TextProps) {
const { variant = "body2", color = "neutral.900", ...restTextProps } = props;

return <Text variant={variant} color={color} {...restTextProps} />;
}

LockedStateCard.displayName = "LockedStateCard";

/** Represents a section in a `<LockedStateCard />`*/
LockedStateCard.Section = LockedStateCardSection;

/** Represents the text group in a `<LockedStateCard />`*/
LockedStateCard.TextGroup = LockedStateCardTextGroup;

/** Represents header text in a `<LockedStateCard />`*/
LockedStateCard.HeaderText = LockedStateCardHeaderText;

/** Represents body text in a `<LockedStateCard />`*/
LockedStateCard.BodyText = LockedStateCardBodyText;

/** Represents the action group in a `<LockedStateCard />`*/
LockedStateCard.ActionGroup = LockedStateCardActionGroup;

0 comments on commit 7d0ab12

Please sign in to comment.