Skip to content

Commit

Permalink
Mark up Tiles in TileGrid as List (#5368)
Browse files Browse the repository at this point in the history
* TileGrid changes

* Add tests

* Add changeset

* FIx styling, render Tiles as <li> inline, clarify test purpose

* Simply Tile <li> key

* Account for non fragments

* Covered edgecases, added tests to stickersheet.

* Remove comments

---------

Co-authored-by: Christian Moore <[email protected]>
  • Loading branch information
Zystix and Christian Moore authored Dec 10, 2024
1 parent 58b5118 commit d3ae52d
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 8 deletions.
5 changes: 5 additions & 0 deletions .changeset/afraid-dolls-visit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@kaizen/components': patch
---

TileGrid renders Tiles in a <ul>, wrapping each Tile in an <li>
1 change: 1 addition & 0 deletions packages/components/src/Tile/TileGrid/TileGrid.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
@import '../subcomponents/GenericTile/variables';

.grid {
list-style-type: none;
display: grid;
// the more we shave off the width here,
// the less the tiles will grow when they lose one from the row
Expand Down
39 changes: 32 additions & 7 deletions packages/components/src/Tile/TileGrid/TileGrid.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { HTMLAttributes, ReactElement } from 'react'
import React, { HTMLAttributes, ReactElement, ReactNode } from 'react'
import classnames from 'classnames'
import { OverrideClassName } from '~components/types/OverrideClassName'
import { InformationTileProps } from '../InformationTile'
Expand All @@ -9,7 +9,7 @@ type TileProps = InformationTileProps | MultiActionTileProps

export type TileElement = ReactElement<TileProps>

export interface TileGridProps extends OverrideClassName<HTMLAttributes<HTMLDivElement>> {
export interface TileGridProps extends OverrideClassName<HTMLAttributes<HTMLUListElement>> {
children: TileElement[] | TileElement
}

Expand All @@ -21,10 +21,35 @@ export const TileGrid = ({
children,
classNameOverride,
...restProps
}: TileGridProps): JSX.Element => (
<div className={classnames(styles.grid, classNameOverride)} data-tile-grid {...restProps}>
{children}
</div>
)
}: TileGridProps): JSX.Element => {
const isFragment = !Array.isArray(children) && children.type === React.Fragment

return (
<ul className={classnames(styles.grid, classNameOverride)} data-tile-grid {...restProps}>
{isFragment ? (
children?.props?.children ? (
<TileListItem tiles={children.props.children} />
) : null
) : (
<TileListItem tiles={children} />
)}
</ul>
)
}
TileGrid.displayName = 'TileGrid'

type TileListItemProps = { tiles: ReactNode }

const TileListItem = ({ tiles }: TileListItemProps): JSX.Element => {
if (Array.isArray(tiles)) {
return (
<>
{tiles.map((tile: TileElement, index) => (
<li key={`${tile.props.title}-${index}`}>{tile}</li>
))}
</>
)
}

return <li>{tiles}</li>
}
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,46 @@ const StickerSheetTemplate: StickerSheetStory = {
/>
</TileGrid>
</StickerSheet.Row>
<StickerSheet.Row header="Single Tile">
<TileGrid>
<InformationTile
title="Title"
metadata="Side A"
information="Side B"
footer={<>Footer</>}
/>
</TileGrid>
</StickerSheet.Row>
<StickerSheet.Row header="Fragment">
<TileGrid>
<>
<InformationTile
title="Title"
metadata="Side A"
information="Side B"
footer={<>Footer</>}
/>
<InformationTile
title="Title"
metadata="Side A"
information="Side B"
footer={<>Footer</>}
/>
<InformationTile
title="Title"
metadata="Side A"
information="Side B"
footer={<>Footer</>}
/>
<InformationTile
title="Title"
metadata="Side A"
information="Side B"
footer={<>Footer</>}
/>
</>
</TileGrid>
</StickerSheet.Row>
</StickerSheet>
),
}
Expand Down
79 changes: 78 additions & 1 deletion packages/components/src/Tile/TileGrid/_docs/TileGrid.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ export const Playground: Story = {
},
}

// Test for multiple tiles, flipping one doesn't flip others
export const FlipOneNotOthers: Story = {
play: async ({ canvasElement, step }) => {
const canvas = within(canvasElement)
Expand Down Expand Up @@ -78,3 +77,81 @@ export const FlipOneNotOthers: Story = {
})
},
}

export const OneTile: Story = {
args: {
children: (
<InformationTile
title="Title A"
metadata="Side A"
information="Side A - Back"
footer={<>Footer</>}
/>
),
},
play: async ({ canvasElement, step }) => {
const canvas = within(canvasElement)

await step('Tile renders as <li>', async () => {
await waitFor(() => {
expect(canvas.getByRole('listitem')).toBeInTheDocument()
})
})
},
}

export const MultipleTiles: Story = {
render: () => {
return (
<TileGrid>
<InformationTile
title="Title A"
metadata="Side A"
information="Side A - Back"
footer={<>Footer</>}
/>
<InformationTile
title="Title B"
metadata="Side B"
information="Side B - Back"
footer={<>Footer</>}
/>
<InformationTile
title="Title C"
metadata="Side C"
information="Side C - Back"
footer={<>Footer</>}
/>
</TileGrid>
)
},
play: async ({ canvasElement, step }) => {
const canvas = within(canvasElement)

await step('All Tiles marked up as individual <li> elements', async () => {
await waitFor(() => {
const listOfTiles = canvas.getByRole('list')
const { getAllByRole } = within(listOfTiles)
const tiles = getAllByRole('listitem')

expect(tiles.length).toBe(3)
})
})
},
}

export const Fragment: Story = {
play: async ({ canvasElement, step }) => {
const canvas = within(canvasElement)

await step('All Tiles marked up as individual <li> elements', async () => {
await waitFor(() => {
const listOfTiles = canvas.getByRole('list')
const { getAllByRole } = within(listOfTiles)
const tiles = getAllByRole('listitem')

expect(tiles.length).toBe(3)
})
})
},
}

0 comments on commit d3ae52d

Please sign in to comment.