Skip to content

Commit

Permalink
refactor(EmptyState): update styles using container queries (#5287)
Browse files Browse the repository at this point in the history
* refactor(EmptyState): revert styles without responsive behaviuor

* refactor(EmptyState): add responsive styles using container queries

* docs: add new StickerSheet using grid

* fix(EmptyState): reduce illustration size ratio

* fix(EmptyState): fix styles to work on FF and Safari
  • Loading branch information
HeartSquared authored Nov 19, 2024
1 parent b611388 commit e4b189b
Show file tree
Hide file tree
Showing 19 changed files with 426 additions and 337 deletions.
5 changes: 5 additions & 0 deletions .changeset/red-badgers-sing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@kaizen/components": patch
---

Fix EmptyState responsive styles using container queries.
18 changes: 18 additions & 0 deletions docs/components/_future/StickerSheet/StickerSheet.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.stickerSheetSectionHeading {
margin-bottom: var(--spacing-12);

.stickerSheetContainer + .stickerSheetContainer & {
margin-top: var(--spacing-40);
}
}

.stickerSheet {
display: grid;
gap: var(--spacing-32);
}

.stickerSheetHeaders {
display: grid;
grid-template-columns: subgrid;
grid-column: 1 / -1;
}
101 changes: 101 additions & 0 deletions docs/components/_future/StickerSheet/StickerSheet.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import React, { HTMLAttributes } from "react"
import classnames from "classnames"
import { Heading } from "~components/Heading"
import { StickerSheetCell } from "./components/StickerSheetCell"
import { StickerSheetHeader } from "./components/StickerSheetHeader"
import {
StickerSheetRow,
StickerSheetRowProps,
} from "./components/StickerSheetRow"
import styles from "./StickerSheet.module.css"

const countMaxColumns = (children: React.ReactNode): number =>
React.Children.toArray(children).reduce<number>((acc, child) => {
if (React.isValidElement(child) && child.type === StickerSheetRow) {
return Math.max(acc, React.Children.count(child.props.children))
}
return acc
}, 0)

type ReversibleSubcomponents = StickerSheetRowProps

const isReversibleSubcomponent = (
child: React.ReactNode
): child is React.ReactElement<ReversibleSubcomponents> =>
React.isValidElement<ReversibleSubcomponents>(child) &&
child.type === StickerSheetRow

export type StickerSheetProps = {
children: React.ReactNode
title?: string
headers?: string[]
isReversed?: boolean
} & HTMLAttributes<HTMLDivElement>

export const StickerSheet = ({
children,
title,
headers,
isReversed = false,
className,
style,
...restProps
}: StickerSheetProps): JSX.Element => {
const hasVerticalHeaders = React.Children.toArray(children).some(
child =>
React.isValidElement(child) &&
child.type === StickerSheetRow &&
child.props.header !== undefined
)

const colCount = headers?.length ?? countMaxColumns(children)

const gridTemplateColumns = hasVerticalHeaders
? `fit-content(100%) repeat(${colCount}, 1fr)`
: `repeat(${colCount}, 1fr)`

return (
<div className={styles.stickerSheetContainer}>
{title && (
<Heading
variant="heading-3"
tag="h1"
color={isReversed ? "white" : "dark"}
classNameOverride={styles.stickerSheetSectionHeading}
>
{title}
</Heading>
)}

<div
className={classnames(styles.stickerSheet, className)}
style={{ gridTemplateColumns, ...style }}
{...restProps}
>
{headers && (
<div className={styles.stickerSheetHeaders}>
{hasVerticalHeaders && <div />}
{headers.map(heading => (
<StickerSheetHeader key={heading} isReversed={isReversed}>
{heading}
</StickerSheetHeader>
))}
</div>
)}
{React.Children.map(children, child => {
if (isReversibleSubcomponent(child)) {
return React.cloneElement(child, {
isReversed,
})
}
return child
})}
</div>
</div>
)
}

StickerSheet.Row = StickerSheetRow
StickerSheet.Cell = StickerSheetCell

StickerSheet.displayName = "StickerSheet"
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React, { HTMLAttributes } from "react"

export type StickerSheetCellProps = {
children: React.ReactNode
} & HTMLAttributes<HTMLDivElement>

export const StickerSheetCell = ({
children,
...restProps
}: StickerSheetCellProps): JSX.Element => <div {...restProps}>{children}</div>

StickerSheetCell.displayName = "StickerSheet.Cell"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./StickerSheetCell"
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.stickerSheetHeader {
text-align: start;
font-family: var(--typography-heading-5-font-family);
font-weight: var(--typography-heading-5-font-weight);
font-size: var(--typography-heading-5-font-size);
line-height: var(--typography-heading-5-line-height);
letter-spacing: var(--typography-heading-5-letter-spacing);
color: var(--stickersheet-header-color, var(--color-purple-800));
}

.isReversed {
--stickersheet-header-color: var(--color-white);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React, { HTMLAttributes } from "react"
import classnames from "classnames"
import styles from "./StickerSheetHeader.module.css"

export type StickerSheetHeaderProps = {
children: React.ReactNode
isReversed?: boolean
} & HTMLAttributes<HTMLDivElement>

export const StickerSheetHeader = ({
children,
isReversed = false,
className,
...restProps
}: StickerSheetHeaderProps): JSX.Element => (
<div
className={classnames(
styles.stickerSheetHeader,
isReversed && styles.isReversed,
className
)}
{...restProps}
>
{children}
</div>
)

StickerSheetHeader.displayName = "StickerSheet.Header"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./StickerSheetHeader"
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.stickerSheetRow {
display: grid;
grid-template-columns: subgrid;
grid-column: 1 / -1;
}

.header {
display: flex;
align-items: center;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React, { HTMLAttributes } from "react"
import classnames from "classnames"
import { StickerSheetCell } from "../StickerSheetCell"
import { StickerSheetHeader } from "../StickerSheetHeader"
import styles from "./StickerSheetRow.module.css"

export type StickerSheetRowProps = {
children: React.ReactNode
header?: string
isReversed?: boolean
} & HTMLAttributes<HTMLDivElement>

export const StickerSheetRow = ({
children,
header,
isReversed = false,
dir,
className,
...restProps
}: StickerSheetRowProps): JSX.Element => (
<div className={classnames(styles.stickerSheetRow, className)} {...restProps}>
{header && (
<StickerSheetHeader className={styles.header} isReversed={isReversed}>
{header}
</StickerSheetHeader>
)}
{React.Children.map(children, child => {
if (React.isValidElement(child) && child.type === StickerSheetCell) {
return child
}

return <StickerSheetCell dir={dir}>{child}</StickerSheetCell>
})}
</div>
)

StickerSheetRow.displayName = "StickerSheet.Row"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./StickerSheetRow"
2 changes: 2 additions & 0 deletions docs/components/_future/StickerSheet/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./StickerSheet"
export * from "./types"
10 changes: 10 additions & 0 deletions docs/components/_future/StickerSheet/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// eslint-disable-next-line import/no-extraneous-dependencies
import { StoryObj } from "@storybook/react"
import type { ColorSchema } from "~components/LikertScaleLegacy"

export type StickerSheetArgs = {
isReversed?: boolean
colorSchema?: ColorSchema
}

export type StickerSheetStory = StoryObj<StickerSheetArgs>
114 changes: 114 additions & 0 deletions packages/components/src/EmptyState/EmptyState.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
.container {
--empty-state-border-width: var(--border-width-1);
--empty-state-illustration-max-height: 366px;
--empty-state-illustration-max-width: 420px;
--empty-state-text-container-max-width: 426px;

container-type: inline-size;
width: 100%;
border: var(--empty-state-border-width) solid var(--empty-state-border-color);
border-radius: var(--border-solid-border-radius);
background-color: var(--empty-state-background-color);
color: var(--color-purple-800);
}

.straightCorners {
border-radius: 0;
}

/** @deprecated */
.positive {
--empty-state-border-color: var(--color-green-500);
--empty-state-background-color: var(--color-green-100);
}

.negative,
.action {
--empty-state-border-color: var(--color-red-500);
--empty-state-background-color: var(--color-red-100);
}

.neutral {
--empty-state-border-color: var(--color-purple-400);
--empty-state-background-color: var(--color-purple-100);
}

/** end @deprecated */
.success {
--empty-state-border-color: var(--color-green-500);
--empty-state-background-color: var(--color-green-100);
}

.warning {
--empty-state-border-color: var(--color-red-500);
--empty-state-background-color: var(--color-red-100);
}

.informative {
--empty-state-border-color: var(--color-blue-400);
--empty-state-background-color: var(--color-blue-100);
}

.expert-advice {
--empty-state-border-color: var(--color-purple-400);
--empty-state-background-color: var(--color-purple-100);
}

.content {
justify-content: center;
display: grid;
grid-template-columns: minmax(auto, var(--empty-state-illustration-max-width)) minmax(
auto,
var(--empty-state-text-container-max-width)
);
grid-template-rows: minmax(auto, var(--empty-state-illustration-max-height)) auto;
padding: var(--spacing-24);
grid-column-gap: var(--spacing-32);
}

.illustrationContainer {
display: flex;
align-items: center;
}

.illustration,
.illustrationContainer video {
max-width: 100%;
max-height: var(--empty-state-illustration-max-height);
height: 100%;
width: auto;
}

.textContainer {
display: flex;
flex-direction: column;
justify-content: center;
gap: var(--spacing-24);
}

@container (width <=1024px) {
.content {
padding: var(--spacing-16);
}
}

@container (width <=560px) {
.content {
grid-template-columns: 1fr;
grid-template-rows: auto;
grid-column-gap: unset;
grid-row-gap: var(--spacing-24);
padding: var(--spacing-24);
}

.illustrationContainer {
--empty-state-illustration-max-height: 210px;

justify-content: center;
}

.heading {
font-size: 1.25rem;
line-height: 1.5rem;
}
}
Loading

0 comments on commit e4b189b

Please sign in to comment.