diff --git a/.changeset/spotty-tables-happen.md b/.changeset/spotty-tables-happen.md new file mode 100644 index 00000000..04384883 --- /dev/null +++ b/.changeset/spotty-tables-happen.md @@ -0,0 +1,6 @@ +--- +"@easypost/easy-ui-icons": minor +"@easypost/easy-ui": minor +--- + +Add lock icon and create LockedState component diff --git a/easy-ui-icons/src/Lock.json b/easy-ui-icons/src/Lock.json new file mode 100644 index 00000000..17962095 --- /dev/null +++ b/easy-ui-icons/src/Lock.json @@ -0,0 +1,5 @@ +{ + "name": "lock", + "style": "outlined", + "source": "@material-symbols/svg-300" +} diff --git a/easy-ui-react/src/LockedStateCard/LockedStateCard.mdx b/easy-ui-react/src/LockedStateCard/LockedStateCard.mdx new file mode 100644 index 00000000..57ef326e --- /dev/null +++ b/easy-ui-react/src/LockedStateCard/LockedStateCard.mdx @@ -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"; + + + +# LockedStateCard + +A `` 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 ``, ``, ``, ``, and `` + +## Simple + + + +## Alignment + +`` and `` can accept `VerticalStack` props to override defaults and to assist with alignment. Similarly, `` can accept `HorizontalStack` props. + + + +## Properties + +### LockedStateCard + + + +### LockedStateCard.Section + + + +### LockedStateCard.TextGroup + + + +### LockedStateCard.HeaderText + + + +### LockedStateCard.BodyText + + + +### LockedStateCard.ActionGroup + + diff --git a/easy-ui-react/src/LockedStateCard/LockedStateCard.module.scss b/easy-ui-react/src/LockedStateCard/LockedStateCard.module.scss new file mode 100644 index 00000000..9dde556f --- /dev/null +++ b/easy-ui-react/src/LockedStateCard/LockedStateCard.module.scss @@ -0,0 +1,8 @@ +.container { + max-width: 695px; + position: relative; +} + +.inlineMargin { + margin: 0 auto; +} diff --git a/easy-ui-react/src/LockedStateCard/LockedStateCard.stories.tsx b/easy-ui-react/src/LockedStateCard/LockedStateCard.stories.tsx new file mode 100644 index 00000000..cc65e887 --- /dev/null +++ b/easy-ui-react/src/LockedStateCard/LockedStateCard.stories.tsx @@ -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; + +const Template = (args: LockedStateCardProps) => { + const { children, ...restArgs } = args; + return {children}; +}; + +const meta: Meta = { + title: "Components/Cards/LockedStateCard", + component: LockedStateCard, +}; + +export default meta; + +export const Simple: Story = { + render: Template.bind({}), + args: { + children: ( + + + + Looking to create something more advanced? + + + 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.  + + + + + + + ), + }, +}; + +export const Alignment: Story = { + render: Template.bind({}), + args: { + children: ( + + + + + Looking to create something more advanced? + + + 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.  + + + + + + + ), + }, +}; diff --git a/easy-ui-react/src/LockedStateCard/LockedStateCard.tsx b/easy-ui-react/src/LockedStateCard/LockedStateCard.tsx new file mode 100644 index 00000000..f9efb5a5 --- /dev/null +++ b/easy-ui-react/src/LockedStateCard/LockedStateCard.tsx @@ -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 element. + */ + children: ReactNode; +}; + +/** + * A `` 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 + * + + + + Looking to create something more advanced? + + + 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.  + + + + + + + * + * ``` +* +* @example +* _Alignment:_ +* ```tsx +* + + + + + Looking to create something more advanced? + + + 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.  + + + + + + + * + * ``` + */ +export function LockedStateCard(props: LockedStateCardProps) { + const { children, ...cardProps } = props; + + return ( + + {children} + + ); +} + +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 ( +
+ + + {children} + + +
+ ); +} + +function LockedStateCardTextGroup(props: VerticalStackProps) { + const { gap = "1", children, ...restProps } = props; + return ( + + {children} + + ); +} + +function LockedStateCardActionGroup(props: HorizontalStackProps) { + const { gap = "1", align = "space-between", children, ...restProps } = props; + return ( + + {children} + + ); +} + +function LockedStateCardHeaderText(props: TextProps) { + const { + variant = "subtitle1", + color = "neutral.900", + ...restTextProps + } = props; + + return ; +} + +function LockedStateCardBodyText(props: TextProps) { + const { variant = "body2", color = "neutral.900", ...restTextProps } = props; + + return ; +} + +LockedStateCard.displayName = "LockedStateCard"; + +/** Represents a section in a ``*/ +LockedStateCard.Section = LockedStateCardSection; + +/** Represents the text group in a ``*/ +LockedStateCard.TextGroup = LockedStateCardTextGroup; + +/** Represents header text in a ``*/ +LockedStateCard.HeaderText = LockedStateCardHeaderText; + +/** Represents body text in a ``*/ +LockedStateCard.BodyText = LockedStateCardBodyText; + +/** Represents the action group in a ``*/ +LockedStateCard.ActionGroup = LockedStateCardActionGroup;