Skip to content

Commit

Permalink
Adapts Blankslate to render proportionally in narrow areas (#3869)
Browse files Browse the repository at this point in the history
* adapts Blankslate to render proportionally in narrow areas

* adds color token fallbacks

* adds changeset

* formats CSS with Prettier

* rm dead css module style

* uses smarter primitives

* tweaks type scale

* improves token usage

* upgrades styled-components, converts Blankslate styles back to styled-components

* adds comment explaining why 34rem for min-width

* renders an inline style block to get around styled-component 5.x limitations around container blocks

* Update src/Blankslate/Blankslate.tsx

Co-authored-by: Siddharth Kshetrapal <siddharthkp@github.com>

---------

Co-authored-by: Siddharth Kshetrapal <siddharthkp@github.com>
  • Loading branch information
mperrotti and siddharthkp authored Dec 8, 2023
1 parent 5f94644 commit 57fcfe6
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 49 deletions.
7 changes: 7 additions & 0 deletions .changeset/many-ants-pump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@primer/react': patch
---

Adapts Blankslate to render proportionally in narrow areas.

<!-- Changed components: Blankslate -->
12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

158 changes: 115 additions & 43 deletions src/Blankslate/Blankslate.tsx
Original file line number Diff line number Diff line change
@@ -1,71 +1,147 @@
import React from 'react'
import styled from 'styled-components'
import Box from '../Box'
import {Button} from '../Button'
import {get} from '../constants'
import Link from '../Link'
import {get} from '../constants'
import styled from 'styled-components'

export type BlankslateProps = React.PropsWithChildren<{
/**
* Add a border around this component
*/
border?: boolean

/**
* Constrain the maximum width of this component
*/
narrow?: boolean

/**
* Increase the padding of this component
*/
spacious?: boolean
}>

const StyledBlankslate = styled.div`
display: grid;
justify-items: center;
padding: ${get('space.5')};
container-type: inline-size;
.Blankslate {
--blankslate-outer-padding-block: var(--base-size-32);
--blankslate-outer-padding-inline: var(--base-size-32);
display: grid;
justify-items: center;
padding: var(--blankslate-outer-padding-block) var(--blankslate-outer-padding-inline);
}
.Blankslate[data-spacious='true'] {
--blankslate-outer-padding-block: var(--base-size-80);
--blankslate-outer-padding-inline: var(--base-size-40);
}
&[data-border='true'] {
border: ${get('borderWidths.1')} solid ${get('colors.border.default')};
border-radius: ${get('radii.2')};
.Blankslate[data-border='true'] {
border: var(--borderWidth-thin) solid var(--borderColor-default, ${get('colors.border.default')});
border-radius: var(--borderRadius-medium);
}
&[data-narrow='true'] {
.Blankslate[data-narrow='true'] {
margin: 0 auto;
max-width: 485px;
}
&[data-spacious='true'] {
padding: ${get('space.9')} ${get('space.6')};
.Blankslate-Heading,
.Blankslate-Description {
margin: 0;
margin-bottom: var(--stack-gap-condensed);
}
.BlankSlateAction {
margin-top: ${get('space.3')};
.Blankslate-Heading {
font-size: var(--text-title-size-medium);
font-weight: var(--text-title-weight-medium);
}
.BlankSlateAction:first-of-type {
margin-top: ${get('space.4')};
.Blankslate-Description {
color: var(--fgColor-muted, ${get('colors.fg.muted')});
font-size: var(--text-body-size-large);
}
.BlankSlateAction:last-of-type {
margin-bottom: ${get('space.2')};
.Blankslate-Action {
margin-top: var(--stack-gap-normal);
}
.Blankslate-Action:first-of-type {
margin-top: var(--stack-gap-spacious);
}
.Blankslate-Action:last-of-type {
margin-bottom: var(--stack-gap-condensed);
}
`

export type BlankslateProps = React.PropsWithChildren<{
/**
* Add a border around this component
*/
border?: boolean
const BlankslateContainerQuery = `
/* At the time these styles were written,
34rem was our "small" breakpoint width */
@container (max-width: 34rem) {
${StyledBlankslate} .Blankslate {
--blankslate-outer-padding-block: var(--base-size-20);
--blankslate-outer-padding-inline: var(--base-size-20);
}
/**
* Constrain the maximum width of this component
*/
narrow?: boolean
${StyledBlankslate} .Blankslate[data-spacious='true'] {
--blankslate-outer-padding-block: var(--base-size-44);
--blankslate-outer-padding-inline: var(--base-size-28);
}
/**
* Increase the padding of this component
*/
spacious?: boolean
}>
${StyledBlankslate} .Blankslate-Visual {
margin-bottom: var(--stack-gap-condensed);
max-width: var(--base-size-24);
}
${StyledBlankslate} .Blankslate-Visual svg {
width: 100%;
}
${StyledBlankslate} .Blankslate-Heading {
font-size: var(--text-title-size-small);
}
${StyledBlankslate} .Blankslate-Description {
font-size: var(--text-body-size-medium);
}
${StyledBlankslate} .Blankslate-Action {
margin-top: var(--stack-gap-condensed);
}
${StyledBlankslate} .Blankslate-Action:first-of-type {
margin-top: var(--stack-gap-normal);
}
${StyledBlankslate} .Blankslate-Action:last-of-type {
margin-bottom: calc(var(--stack-gap-condensed) / 2);
}
`

function Blankslate({border, children, narrow, spacious}: BlankslateProps) {
return (
<StyledBlankslate data-border={border} data-narrow={narrow} data-spacious={spacious}>
{children}
</StyledBlankslate>
<>
{/*
This is a workaround so we can use `@container` without upgrading `styled-components` to 6.x
See [this comment](https://github.com/primer/react/pull/3869#discussion_r1392523030) for more info
*/}
<style type="text/css">{BlankslateContainerQuery}</style>
<StyledBlankslate>
<div className="Blankslate" data-border={border} data-narrow={narrow} data-spacious={spacious}>
{children}
</div>
</StyledBlankslate>
</>
)
}

export type VisualProps = React.PropsWithChildren

function Visual({children}: VisualProps) {
return <Box sx={{color: 'fg.muted', mb: 3}}>{children}</Box>
return <span className="Blankslate-Visual">{children}</span>
}

export type HeadingProps = React.PropsWithChildren<{
Expand All @@ -74,7 +150,7 @@ export type HeadingProps = React.PropsWithChildren<{

function Heading({as = 'h2', children}: HeadingProps) {
return (
<Box as={as} sx={{m: 0, mb: 2}}>
<Box as={as} className="Blankslate-Heading">
{children}
</Box>
)
Expand All @@ -83,11 +159,7 @@ function Heading({as = 'h2', children}: HeadingProps) {
export type DescriptionProps = React.PropsWithChildren

function Description({children}: DescriptionProps) {
return (
<Box as="p" sx={{color: 'fg.muted', m: 0, mb: 2}}>
{children}
</Box>
)
return <p className="Blankslate-Description">{children}</p>
}

export type PrimaryActionProps = React.PropsWithChildren<{
Expand All @@ -96,7 +168,7 @@ export type PrimaryActionProps = React.PropsWithChildren<{

function PrimaryAction({children, href}: PrimaryActionProps) {
return (
<div className="BlankSlateAction">
<div className="Blankslate-Action">
<Button as="a" href={href} variant="primary">
{children}
</Button>
Expand All @@ -110,7 +182,7 @@ export type SecondaryActionProps = React.PropsWithChildren<{

function SecondaryAction({children, href}: SecondaryActionProps) {
return (
<div className="BlankSlateAction">
<div className="Blankslate-Action">
<Link href={href}>{children}</Link>
</div>
)
Expand Down

0 comments on commit 57fcfe6

Please sign in to comment.