Skip to content

Commit

Permalink
feat: add empty state component (#179)
Browse files Browse the repository at this point in the history
* feat: add empty state component

* chore: deprecate old empty state component

* docs: update empty state docs
  • Loading branch information
rsbh authored Nov 19, 2024
1 parent f43eb36 commit bae2a70
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 19 deletions.
50 changes: 32 additions & 18 deletions apps/www/content/primitives/components/emptystate.mdx
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
---
title: Empty State
description:
description:
---

## Preview

<Preview>
<Flex
style={{
flexDirection: "column",
alignItems: "center",
gap: "8px",
}}
>
<EmptyState>
<Title>No Design Systems</Title>
<Text>You can create a new Design System by clicking the button.</Text>
</EmptyState>
<Flex direction="column" align="center">
<EmptyState
icon={<InfoCircledIcon />}
heading="Looking for new components"
subHeading="Check out new components in @raystack/apsara"
primaryAction={<Button>Primary Action</Button>}
secondaryAction={<Button variant="text">Secondary Action</Button>}
/>

</Flex>
</Preview>

Expand All @@ -24,20 +23,35 @@ description:
Install the component from your command line.

<LiveProvider>
<LiveEditor code={`npm install @raystack/apsara`} border/>
<LiveEditor code={`npm install @raystack/apsara`} border />
</LiveProvider>

## Props

The `Flex` component accepts the following props:

- `icon`: Icon to show in top of empty state
- `heading`: primary heading message
- `subHeading`: secondary heading message
- `primaryAction`: action to show in empty state like button or link
- `secondaryAction`: secondary action to show in empty state like button or link
- `classNames`: Map of className with internal components
- `container`
- `iconContainer`
- `icon`
- `heading`
- `subHeading`

## Anatomy

Import all parts and piece them together.

<LiveProvider>
<LiveEditor code={`
import { EmptyState } from '@raystack/apsara'
import { EmptyState } from '@raystack/apsara/v1'
<EmptyState headerText="Looking for new components" />
<EmptyState style={{ marginTop: 160 }}>
<h3>No Design Systems</h3>
<p>You can create a new Design System by clicking the button.</p>
</EmptyState>
`} border />

</LiveProvider>
6 changes: 5 additions & 1 deletion apps/www/utils/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ export const primitivesRoutes = [
slug: "docs/primitives/components/dropdownmenu",
newBadge: true,
},
{ title: "Empty State", slug: "docs/primitives/components/emptystate" },
{
title: "Empty State",
slug: "docs/primitives/components/emptystate",
newBadge: true,
},
{ title: "ErrorState", slug: "docs/primitives/components/errorstate" },
{
title: "Flex",
Expand Down
3 changes: 3 additions & 0 deletions packages/raystack/emptystate/emptystate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ const emptystate = cva(styles.emptystate);
type EmptystateProps = PropsWithChildren<VariantProps<typeof emptystate>> &
HTMLAttributes<HTMLElement>;

/**
* @deprecated Use EmptyState from '@raystack/apsara/v1' instead.
*/
export function EmptyState({ children, className, ...props }: EmptystateProps) {
return (
<div className={emptystate({ className })} {...props}>
Expand Down
53 changes: 53 additions & 0 deletions packages/raystack/v1/components/emptystate/emptystate.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
.emptyState {
padding: var(--rs-space-9) var(--rs-space-5);
width: 100%;
height: 100%;
text-align: center;
}

.iconContainer {
position: relative;
z-index: 2;
}

.icon {
height: 32px;
width: 32px;
padding: var(--rs-space-3);
box-sizing: content-box;
border: 1px solid var(--rs-color-border-base-primary);
background-color: var(--rs-color-background-base-secondary);
border-radius: var(--rs-radius-4);
color: var(--rs-color-text-base-secondary);
box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.08),
0px -3px 0px 0px rgba(0, 0, 0, 0.03) inset;
}

.icon > svg {
fill: currentColor;
height: 100%;
width: 100%;
}

.icon::before {
content: "";
position: absolute;
height: 100%;
width: 100%;
top: -10px;
left: calc(50% - 15px);
border: inherit;
border-radius: inherit;
background-color: inherit;
z-index: -10;
transform: rotate(-42deg);
box-shadow: 0px -1.5px 0px 0px rgba(0, 0, 0, 0.02) inset;
}

.headerText {
max-width: 360px;
}

.subHeaderText {
max-width: 288px;
}
70 changes: 70 additions & 0 deletions packages/raystack/v1/components/emptystate/emptystate.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { cva } from "class-variance-authority";
import styles from "./emptystate.module.css";
const emptystate = cva(styles.emptystate);
import { Flex } from "../flex";
import { Text } from "../text";
import clsx from "clsx";

type classNameKeys =
| "container"
| "iconContainer"
| "icon"
| "heading"
| "subHeading";

interface EmptystateProps {
icon: React.ReactNode;
heading?: React.ReactNode;
subHeading?: React.ReactNode;
primaryAction?: React.ReactNode;
secondaryAction?: React.ReactNode;
classNames?: Partial<Record<classNameKeys, string>>;
}

export const EmptyState = ({
icon,
heading,
subHeading,
primaryAction,
secondaryAction,
classNames,
}: EmptystateProps) => {
return (
<Flex
direction="column"
align="center"
gap="medium"
className={clsx(styles.emptyState, classNames?.container)}
>
<div className={clsx(styles.iconContainer, classNames?.iconContainer)}>
<div className={clsx(styles.icon, classNames?.icon)}>{icon}</div>
</div>

<Flex direction="column" gap="small" align="center">
{heading && (
<Text
size={5}
weight={500}
className={clsx(styles.headerText, classNames?.heading)}
>
{heading}
</Text>
)}

{subHeading && (
<Text
size={4}
weight={400}
className={clsx(styles.subHeaderText, classNames?.subHeading)}
>
{subHeading}
</Text>
)}
</Flex>

{primaryAction}

{secondaryAction}
</Flex>
);
};
1 change: 1 addition & 0 deletions packages/raystack/v1/components/emptystate/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { EmptyState } from "./emptystate";
2 changes: 2 additions & 0 deletions packages/raystack/v1/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export { ToastContainer, toast } from "./components/toast";
export { DropdownMenu } from "./components/dropdownMenu";
export { Text } from "./components/text";
export { Flex } from "./components/flex";
export { EmptyState } from "./components/emptystate";

export {
ThemeProvider,
ThemeProviderProps,
Expand Down

0 comments on commit bae2a70

Please sign in to comment.