-
Notifications
You must be signed in to change notification settings - Fork 119
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Grid component to pcln-design-system (#1303)
* add Grid component to core pcln-design-system * Disable color props for Grid
- Loading branch information
Showing
6 changed files
with
324 additions
and
0 deletions.
There are no files selected for viewing
10 changes: 10 additions & 0 deletions
10
common/changes/pcln-design-system/add-grid-component_2023-05-26-13-28.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"changes": [ | ||
{ | ||
"packageName": "pcln-design-system", | ||
"comment": "Add Grid component", | ||
"type": "minor" | ||
} | ||
], | ||
"packageName": "pcln-design-system" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { render } from '@testing-library/react' | ||
import React from 'react' | ||
import { Grid, IGridProps } from './Grid' | ||
|
||
describe('Grid', () => { | ||
const testProps: IGridProps = { | ||
gap: '10px', | ||
rowGap: '20px', | ||
columnGap: '30px', | ||
column: '1 / 3', | ||
row: '1 / span 2', | ||
area: 'header', | ||
autoFlow: 'row dense', | ||
autoRows: 'minmax(100px, auto)', | ||
autoColumns: 'repeat(2, 1fr)', | ||
templateRows: 'repeat(2, 1fr)', | ||
templateColumns: 'repeat(3, 1fr)', | ||
templateAreas: '"header header header" "main main sidebar"', | ||
placeItems: 'center', | ||
} | ||
|
||
it('applies grid styles correctly', () => { | ||
const { container } = render(<Grid {...testProps} />) | ||
const gridElement = container.firstChild | ||
|
||
expect(gridElement).toHaveStyleRule('display: grid') | ||
expect(gridElement).toHaveStyleRule('grid-gap: 10px') | ||
expect(gridElement).toHaveStyleRule('grid-row-gap: 20px') | ||
expect(gridElement).toHaveStyleRule('grid-column-gap: 30px') | ||
expect(gridElement).toHaveStyleRule('grid-column: 1 / 3') | ||
expect(gridElement).toHaveStyleRule('grid-row: 1 / span 2') | ||
expect(gridElement).toHaveStyleRule('grid-area: header') | ||
expect(gridElement).toHaveStyleRule('grid-auto-flow: row dense') | ||
expect(gridElement).toHaveStyleRule('grid-auto-rows: minmax(100px, auto)') | ||
expect(gridElement).toHaveStyleRule('grid-auto-columns: repeat(2, 1fr)') | ||
expect(gridElement).toHaveStyleRule('grid-template-rows: repeat(2, 1fr)') | ||
expect(gridElement).toHaveStyleRule('grid-template-columns: repeat(3, 1fr)') | ||
expect(gridElement).toHaveStyleRule('grid-template-areas: "header header header" "main main sidebar"') | ||
expect(gridElement).toHaveStyleRule('place-items: center') | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
import { ArgsTable, PRIMARY_STORY, Primary } from '@storybook/addon-docs' | ||
import { Meta, StoryObj } from '@storybook/react' | ||
import { | ||
Hero, | ||
LiveDemo, | ||
RelatedComponent, | ||
RelatedComponentContainer, | ||
Section, | ||
StoryHeading, | ||
TableOfContents, | ||
} from 'pcln-docs-utils' | ||
import React from 'react' | ||
import { Box, Flex, Grid, IGridProps, Text, ThemeProvider } from '..' | ||
|
||
type GridStory = StoryObj<IGridProps> | ||
|
||
const GridItem = (props: IGridProps) => <Grid p={4} width={1} placeItems='center' {...props} /> | ||
|
||
export const Playground: GridStory = { | ||
render: () => ( | ||
<Grid templateColumns={['1fr', '1fr 1fr', '1fr 1fr 1fr']} placeItems={'center'} gap={2}> | ||
<GridItem style={{ background: '#00f8' }}>A</GridItem> | ||
<GridItem style={{ background: '#0f08' }}>B</GridItem> | ||
<GridItem style={{ background: '#0ff8' }}>C</GridItem> | ||
<GridItem style={{ background: '#f008' }}>D</GridItem> | ||
<GridItem style={{ background: '#f0f8' }}>E</GridItem> | ||
<GridItem style={{ background: '#ff08' }}>F</GridItem> | ||
</Grid> | ||
), | ||
} | ||
|
||
export const TemplateAreas: GridStory = { | ||
render: () => ( | ||
<Grid | ||
templateAreas={` | ||
'header header' | ||
'sidebar content' | ||
'footer footer' | ||
`} | ||
placeItems={'center'} | ||
minHeight={'calc(100vh - 5rem)'} | ||
templateRows={'auto 1fr auto'} | ||
templateColumns={'15em 1fr'} | ||
gap={2} | ||
> | ||
<GridItem gridArea='header' style={{ background: '#00f8' }}> | ||
Header | ||
</GridItem> | ||
<GridItem gridArea='sidebar' height='100%' style={{ background: '#0f08' }}> | ||
Sidebar | ||
</GridItem> | ||
<GridItem gridArea='content' height='100%' style={{ background: '#0ff8' }}> | ||
Content | ||
</GridItem> | ||
<GridItem gridArea='footer' mt='auto' style={{ background: '#f008' }}> | ||
Footer | ||
</GridItem> | ||
</Grid> | ||
), | ||
} | ||
|
||
export const NestedGrids: GridStory = { | ||
render: () => ( | ||
<Grid templateColumns='1fr 1fr' placeItems='center' gap={2}> | ||
<GridItem style={{ background: '#00f8' }}>A</GridItem> | ||
<GridItem style={{ background: '#0f08' }}>B</GridItem> | ||
<GridItem style={{ background: '#0ff8' }}>C</GridItem> | ||
<Grid width={1} templateColumns='1fr 1fr 1fr' placeItems='center' gap={2}> | ||
<GridItem style={{ background: '#f008' }}>D</GridItem> | ||
<GridItem style={{ background: '#f0f8' }}>E</GridItem> | ||
<GridItem style={{ background: '#ff08' }}>F</GridItem> | ||
</Grid> | ||
</Grid> | ||
), | ||
} | ||
|
||
export const ResponsiveLayout: GridStory = { | ||
render: () => ( | ||
<Grid | ||
templateColumns={[ | ||
'1fr', | ||
'1fr 1fr', | ||
'1fr 1fr 1fr', | ||
'1fr 1fr 1fr 1fr', | ||
'1fr 1fr 1fr 1fr 1fr', | ||
'1fr 1fr 1fr 1fr 1fr 1fr', | ||
]} | ||
placeItems='center' | ||
gap={2} | ||
> | ||
<GridItem style={{ background: '#00f8' }}>A</GridItem> | ||
<GridItem style={{ background: '#0f08' }}>B</GridItem> | ||
<GridItem style={{ background: '#0ff8' }}>C</GridItem> | ||
<GridItem style={{ background: '#f008' }}>D</GridItem> | ||
<GridItem style={{ background: '#f0f8' }}>E</GridItem> | ||
<GridItem style={{ background: '#ff08' }}>F</GridItem> | ||
</Grid> | ||
), | ||
} | ||
|
||
const meta: Meta<typeof Grid> = { | ||
title: 'Layout/Grid', | ||
component: Grid, | ||
parameters: { | ||
docs: { | ||
page: () => ( | ||
<ThemeProvider> | ||
<Hero name='Grid' img={''}> | ||
Grids divide a web page into rows and columns and offer comprehensive features for controlling the | ||
sizing and positioning of grid items, including the ability to define grid areas, set grid gaps, | ||
and control the alignment and distribution of grid items | ||
</Hero> | ||
|
||
<TableOfContents links={['Overview', 'Props', 'Examples', 'Related Components']} /> | ||
|
||
<Section heading='Overview'> | ||
<Text textStyle='paragraph'> | ||
Grid is based on the CSS Grid Layout Module, which provides a two-dimensional grid-based layout | ||
system, with rows and columns, making it easier to design web pages and components. | ||
</Text> | ||
</Section> | ||
|
||
<Section heading='Props'> | ||
<Primary /> | ||
<ArgsTable story={PRIMARY_STORY} /> | ||
</Section> | ||
|
||
<Section heading='Examples'> | ||
<StoryHeading storyName='Template Areas' storyTitle={meta.title} /> | ||
<Text textStyle='paragraph'> | ||
Using the <code>gridTemplateAreas</code> prop, you can define grid areas and assign grid items | ||
to them. The grid areas are defined by using the <code>grid-area</code> property on the grid | ||
items. The <code>grid-area</code> property can be used to assign a name to a grid item, which | ||
can then be used as a value of the <code>grid-template-areas</code> property. | ||
</Text> | ||
<LiveDemo code={TemplateAreas} /> | ||
|
||
<StoryHeading storyName='Nested Grids' storyTitle={meta.title} /> | ||
<Text textStyle='paragraph'> | ||
Grids can be nested inside other grids. This allows you to create more complex layouts. | ||
</Text> | ||
<LiveDemo code={NestedGrids} /> | ||
|
||
<StoryHeading storyName='Responsive Layout' storyTitle={meta.title} /> | ||
<Text textStyle='paragraph'> | ||
Grids can be responsive. You can define the number of columns for each breakpoint using the | ||
<code>templateColumns</code> prop. | ||
</Text> | ||
<LiveDemo code={ResponsiveLayout} /> | ||
</Section> | ||
|
||
<Section heading='Related Components'> | ||
<RelatedComponentContainer> | ||
<RelatedComponent name='Box'> | ||
<Box width='75%' height='75%' bg='background.lightest'> | ||
Box | ||
</Box> | ||
</RelatedComponent> | ||
<RelatedComponent name='Flex'> | ||
<Flex | ||
justifyContent='center' | ||
alignItems='center' | ||
width='75%' | ||
height='75%' | ||
bg='background.lightest' | ||
> | ||
Flex | ||
</Flex> | ||
</RelatedComponent> | ||
</RelatedComponentContainer> | ||
</Section> | ||
</ThemeProvider> | ||
), | ||
}, | ||
}, | ||
} | ||
export default meta |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import React from 'react' | ||
import styled from 'styled-components' | ||
import { | ||
background, | ||
BackgroundProps, | ||
border, | ||
BorderProps, | ||
// color, | ||
// ColorProps, | ||
compose, | ||
flexbox, | ||
FlexboxProps, | ||
grid, | ||
GridProps, | ||
layout, | ||
LayoutProps, | ||
position, | ||
PositionProps, | ||
shadow, | ||
ShadowProps, | ||
space, | ||
SpaceProps, | ||
system, | ||
typography, | ||
TypographyProps, | ||
} from 'styled-system' | ||
|
||
export interface IStyledSystemProps | ||
extends BackgroundProps, | ||
BorderProps, | ||
// ColorProps, | ||
FlexboxProps, | ||
GridProps, | ||
LayoutProps, | ||
PositionProps, | ||
ShadowProps, | ||
SpaceProps, | ||
TypographyProps { | ||
style?: React.CSSProperties | ||
} | ||
|
||
const ComposedStyleFns = compose( | ||
background, | ||
border, | ||
// color, | ||
flexbox, | ||
grid, | ||
layout, | ||
position, | ||
shadow, | ||
space, | ||
typography | ||
) | ||
|
||
export interface IGridProps extends IStyledSystemProps { | ||
children?: React.ReactNode | ||
gap?: GridProps['gridGap'] | ||
rowGap?: GridProps['gridRowGap'] | ||
columnGap?: GridProps['gridColumnGap'] | ||
column?: GridProps['gridColumn'] | ||
row?: GridProps['gridRow'] | ||
area?: GridProps['gridArea'] | ||
autoFlow?: GridProps['gridAutoFlow'] | ||
autoRows?: GridProps['gridAutoRows'] | ||
autoColumns?: GridProps['gridAutoColumns'] | ||
templateRows?: GridProps['gridTemplateRows'] | ||
templateColumns?: GridProps['gridTemplateColumns'] | ||
templateAreas?: GridProps['gridTemplateAreas'] | ||
placeItems?: FlexboxProps['alignItems'] | ||
} | ||
|
||
const GridStyleFns = system({ | ||
gap: { property: 'gridGap', scale: 'space' }, | ||
rowGap: { property: 'gridRowGap', scale: 'space' }, | ||
columnGap: { property: 'gridColumnGap', scale: 'space' }, | ||
column: { property: 'gridColumn' }, | ||
row: { property: 'gridRow' }, | ||
area: { property: 'gridArea' }, | ||
autoFlow: { property: 'gridAutoFlow' }, | ||
autoRows: { property: 'gridAutoRows' }, | ||
autoColumns: { property: 'gridAutoColumns' }, | ||
templateRows: { property: 'gridTemplateRows' }, | ||
templateColumns: { property: 'gridTemplateColumns' }, | ||
templateAreas: { property: 'gridTemplateAreas' }, | ||
placeItems: { property: 'placeItems' }, | ||
}) | ||
|
||
const StyledGrid = styled.div<IGridProps>` | ||
${ComposedStyleFns} | ||
${GridStyleFns} | ||
display: grid; | ||
` | ||
|
||
export const Grid = (props: IGridProps) => <StyledGrid {...props} /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './Grid' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters