Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(EmptyState): update styles using container queries #5287

Merged
merged 11 commits into from
Nov 19, 2024
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.
12 changes: 12 additions & 0 deletions docs/components/_future/StickerSheet/StickerSheet.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.stickerSheetSectionHeading {
margin-bottom: var(--spacing-12);

.stickerSheetContainer + .stickerSheetContainer & {
margin-top: var(--spacing-lg);
HeartSquared marked this conversation as resolved.
Show resolved Hide resolved
}
}

.stickerSheet {
display: grid;
gap: var(--spacing-16);
}
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 && (
<StickerSheetRow>
{hasVerticalHeaders && <div />}
{headers.map(heading => (
<StickerSheetHeader key={heading} isReversed={isReversed}>
{heading}
</StickerSheetHeader>
))}
</StickerSheetRow>
)}
{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,5 @@
.stickerSheetRow {
display: grid;
grid-template-columns: subgrid;
grid-column: 1 / -1;
mcwinter07 marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
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 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
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whut -_- Will kill in the follow up PR

}

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-min-width: 224px;
--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(var(--empty-state-illustration-min-width), auto) 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);
HeartSquared marked this conversation as resolved.
Show resolved Hide resolved
}

.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