Skip to content

Commit

Permalink
[PBNTR-738] Collapsible Rows for Basic Table (#3967)
Browse files Browse the repository at this point in the history
[Runway Story](https://runway.powerhrg.com/backlog_items/PBNTR-738)

Original POC story
[here](https://runway.powerhrg.com/backlog_items/PBNTR-656)

This PR:
- ✅ Adds the `tag` prop to Collapsible kit
- ✅ Adds collapsible kit to Table kit behind the `collapsible` prop
- ✅ Adds `collapsibleContent` prop that consumes a component that will
render within the collapsible
- ✅ Adds `collapsibleSideHighlight` which renders the sidehighlight
(true by default but can be set to false).
- ✅ Adds prop to make it so devs can set only icon cell be clickable
- ✅ Adds doc examples for each of the designs under 'collapsed content'
in the handoff


<img width="755" alt="Screenshot 2024-12-03 at 10 00 45 PM"
src="https://github.com/user-attachments/assets/5c612d83-e806-4169-8265-85937659e649">

<img width="769" alt="Screenshot 2024-12-03 at 10 00 54 PM"
src="https://github.com/user-attachments/assets/e67c008e-c678-4cd8-a6f9-353060afe6fc">

<img width="769" alt="Screenshot 2024-12-03 at 10 01 01 PM"
src="https://github.com/user-attachments/assets/0b2d9e43-15e7-4a1e-83c2-905840c9c370">

<img width="770" alt="Screenshot 2024-12-03 at 10 01 08 PM"
src="https://github.com/user-attachments/assets/99e00519-31f7-4d72-977d-5f53811c0655">

<img width="764" alt="Screenshot 2024-12-03 at 10 01 15 PM"
src="https://github.com/user-attachments/assets/e5e498b2-946d-44d2-a6c9-c785acab4a34">
  • Loading branch information
nidaqg authored Dec 12, 2024
1 parent b72846a commit f9be357
Show file tree
Hide file tree
Showing 18 changed files with 653 additions and 10 deletions.
13 changes: 9 additions & 4 deletions playbook/app/pb_kits/playbook/pb_collapsible/_collapsible.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useEffect, ReactElement } from 'react'
import classnames from 'classnames'
import useCollapsible from './useCollapsible'

import { globalProps, globalInlineProps } from '../utilities/globalProps'
import { globalProps, globalInlineProps, GlobalProps } from '../utilities/globalProps'
import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'

import CollapsibleContent from './child_kits/CollapsibleContent'
Expand Down Expand Up @@ -32,6 +32,7 @@ type CollapsibleProps = {
onClick?: ()=> void,
htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
id?: string,
tag?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span' | 'div' | 'tr' | 'th' | 'td' | 'thead' | 'col',
}

const Collapsible = ({
Expand All @@ -47,8 +48,9 @@ const Collapsible = ({
onIconClick,
onClick,
id,
tag = 'div',
...props
}: CollapsibleProps): React.ReactElement => {
}: CollapsibleProps & GlobalProps): React.ReactElement => {
const [isCollapsed, toggle, setIsCollapsed] = useCollapsible(collapsed)

useEffect(()=> {
Expand Down Expand Up @@ -76,9 +78,12 @@ const Collapsible = ({
className
)
const dynamicInlineProps = globalInlineProps(props)

const Tag: React.ReactElement | any = `${tag}`;

return (
<CollapsibleContext.Provider value={{ collapsed: isCollapsed, toggle, icon, iconSize, iconColor, onIconClick, onClick }}>
<div
<Tag
{...ariaProps}
{...dataProps}
{...htmlProps}
Expand All @@ -96,7 +101,7 @@ const Collapsible = ({
<CollapsibleContent {...contentProps}>
{contentChildren}
</CollapsibleContent>
</div>
</Tag>
</CollapsibleContext.Provider>
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import classnames from 'classnames'
import React, { useContext, useRef, useEffect } from 'react'
import { buildCss } from '../../utilities/props'
import { globalProps } from '../../utilities/globalProps'
import { globalProps, GlobalProps } from '../../utilities/globalProps'
import { hideElement, showElement } from '../_helper_functions'

import CollapsibleContext from '../context'
Expand All @@ -15,7 +15,7 @@ const CollapsibleContent = ({
children,
className,
...props
}: CollapsibleContentProps): React.ReactElement => {
}: CollapsibleContentProps & GlobalProps): React.ReactElement => {
const context: {[key: string]: boolean | string} = useContext(CollapsibleContext)
const contentCSS = buildCss('pb_collapsible_content_kit')
const contentSpacing = globalProps(props)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import classnames from 'classnames'
import React, { useContext } from 'react'
import { buildCss } from '../../utilities/props'
import { globalProps } from '../../utilities/globalProps'
import { globalProps, GlobalProps } from '../../utilities/globalProps'

import Flex from '../../pb_flex/_flex'
import FlexItem from '../../pb_flex/_flex_item'
Expand All @@ -25,7 +25,7 @@ const CollapsibleMain = ({
className,
cursor = 'pointer',
...props
}: CollapsibleMainProps): React.ReactElement=> {
}: CollapsibleMainProps & GlobalProps): React.ReactElement=> {
const {collapsed, toggle, icon, iconSize, iconColor, onIconClick, onClick}: any = useContext(CollapsibleContext)
const mainCSS = buildCss('pb_collapsible_main_kit')
const mainSpacing = globalProps(props, { cursor })
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import React from 'react'
import { Table, Icon, Body, Card } from 'playbook-ui'

const TableWithCollapsible = (props) => {

const Content = () => {
return (
<Card
borderNone
borderRadius="none"
padding="md"
{...props}
>
<Body {...props}>Nested content inside a Table Row</Body>
</Card>
);
};

return (
<Table
size="sm"
{...props}
>
<Table.Head>
<Table.Row>
<Table.Header>{'Column 1'}</Table.Header>
<Table.Header>{'Column 2'}</Table.Header>
<Table.Header>{'Column 3'}</Table.Header>
<Table.Header>{'Column 4'}</Table.Header>
<Table.Header>{'Column 5'}</Table.Header>
<Table.Header>{''}</Table.Header>
</Table.Row>

</Table.Head>
<Table.Body>
<Table.Row collapsible
collapsibleContent={<Content/>}
{...props}
>
<Table.Cell>{'Value 1'}</Table.Cell>
<Table.Cell>{'Value 2'}</Table.Cell>
<Table.Cell>{'Value 3'}</Table.Cell>
<Table.Cell>{'Value 4'}</Table.Cell>
<Table.Cell>{'Value 5'}</Table.Cell>
<Table.Cell textAlign="right">{
<Icon
color="primary"
fixedWidth
icon="chevron-down"
/>}
</Table.Cell>

</Table.Row>
<Table.Row>
<Table.Cell>{'Value 1'}</Table.Cell>
<Table.Cell>{'Value 2'}</Table.Cell>
<Table.Cell>{'Value 3'}</Table.Cell>
<Table.Cell>{'Value 4'}</Table.Cell>
<Table.Cell>{'Value 5'}</Table.Cell>
<Table.Cell>{''}</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>{'Value 1'}</Table.Cell>
<Table.Cell>{'Value 2'}</Table.Cell>
<Table.Cell>{'Value 3'}</Table.Cell>
<Table.Cell>{'Value 4'}</Table.Cell>
<Table.Cell>{'Value 5'}</Table.Cell>
<Table.Cell>{''}</Table.Cell>
</Table.Row>
</Table.Body>
</Table>
)
}

export default TableWithCollapsible
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The `collapsible` prop can be used on any Table Row to add a collapsible area. Use the additional `collapsibleContent` prop to add any content to the collapsible Row.
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import React from 'react'
import { Table, Card, Icon, Body } from 'playbook-ui'

const TableWithCollapsibleWithCustomClick = (props) => {

const Content = () => {
return (
<Card
borderNone
borderRadius="none"
padding="md"
{...props}
>
<Body {...props}>Nested content inside a Table Row</Body>
</Card>
);
};


return (
<Table
size="sm"
{...props}
>
<Table.Head>
<Table.Row>
<Table.Header>{'Column 1'}</Table.Header>
<Table.Header>{'Column 2'}</Table.Header>
<Table.Header>{'Column 3'}</Table.Header>
<Table.Header>{'Column 4'}</Table.Header>
<Table.Header>{'Column 5'}</Table.Header>
<Table.Header>{''}</Table.Header>
</Table.Row>

</Table.Head>
<Table.Body>
<Table.Row collapsible
collapsibleContent={<Content/>}
toggleCellId="cell-1"
{...props}
>
<Table.Cell>{'Value 1'}</Table.Cell>
<Table.Cell>{'Value 2'}</Table.Cell>
<Table.Cell>{'Value 3'}</Table.Cell>
<Table.Cell>{'Value 4'}</Table.Cell>
<Table.Cell>{'Value 5'}</Table.Cell>
<Table.Cell cursor="pointer"
id="cell-1"
textAlign="right"
>
<Icon
color="primary"
fixedWidth
icon="chevron-down"
/>
</Table.Cell>

</Table.Row>
<Table.Row collapsible
collapsibleContent={<Content/>}
toggleCellId="cell-2"
{...props}
>
<Table.Cell>{'Value 1'}</Table.Cell>
<Table.Cell>{'Value 2'}</Table.Cell>
<Table.Cell>{'Value 3'}</Table.Cell>
<Table.Cell>{'Value 4'}</Table.Cell>
<Table.Cell>{'Value 5'}</Table.Cell>
<Table.Cell cursor="pointer"
id="cell-2"
textAlign="right"
>
<Icon
color="primary"
fixedWidth
icon="chevron-down"
/>
</Table.Cell>

</Table.Row>
<Table.Row collapsible
collapsibleContent={<Content/>}
toggleCellId="cell-3"
{...props}
>
<Table.Cell>{'Value 1'}</Table.Cell>
<Table.Cell>{'Value 2'}</Table.Cell>
<Table.Cell>{'Value 3'}</Table.Cell>
<Table.Cell>{'Value 4'}</Table.Cell>
<Table.Cell>{'Value 5'}</Table.Cell>
<Table.Cell cursor="pointer"
id="cell-3"
textAlign="right"
>
<Icon
color="primary"
fixedWidth
icon="chevron-down"
/>
</Table.Cell>

</Table.Row>
</Table.Body>
</Table>
)
}

export default TableWithCollapsibleWithCustomClick
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
When using the `collapsible` prop, the default functionality is that the entire Row will be clickable to toggle the Row. To limit the click event to a specific Table Cell, you can use the `toggleCellId` prop to pass in the id of the Cell you want to use as the trigger.
__NOTE__: `toggleCellId` and the id on the Cell you want to use as the trigger MUST be the same.
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import React from 'react'
import { Table, Icon, Card, Body, Image, Flex } from 'playbook-ui'

const TableWithCollapsibleWithCustomContent = (props) => {

const Content = () => {
return (
<Card
borderNone
borderRadius="none"
color="light"
paddingX="xl"
paddingY="md"
{...props}
>
<Body paddingBottom="sm"
text="Expanded Custom Layout"
{...props}
/>
<Flex justify="between">
<Image
url="https://via.placeholder.com/150"
/>
<Image
url="https://via.placeholder.com/150"
/>
<Image
url="https://via.placeholder.com/150"
/>
<Image
url="https://via.placeholder.com/150"
/>
</Flex>
</Card>
);
};

return (
<Table
size="sm"
{...props}
>
<Table.Head>
<Table.Row>
<Table.Header>{'Column 1'}</Table.Header>
<Table.Header>{'Column 2'}</Table.Header>
<Table.Header>{'Column 3'}</Table.Header>
<Table.Header>{'Column 4'}</Table.Header>
<Table.Header>{'Column 5'}</Table.Header>
<Table.Header>{''}</Table.Header>
</Table.Row>

</Table.Head>
<Table.Body>
<Table.Row collapsible
collapsibleContent={<Content/>}
{...props}
>
<Table.Cell>{'Value 1'}</Table.Cell>
<Table.Cell>{'Value 2'}</Table.Cell>
<Table.Cell>{'Value 3'}</Table.Cell>
<Table.Cell>{'Value 4'}</Table.Cell>
<Table.Cell>{'Value 5'}</Table.Cell>
<Table.Cell textAlign="right">{
<Icon
color="primary"
fixedWidth
icon="chevron-down"
/>}
</Table.Cell>

</Table.Row>
<Table.Row>
<Table.Cell>{'Value 1'}</Table.Cell>
<Table.Cell>{'Value 2'}</Table.Cell>
<Table.Cell>{'Value 3'}</Table.Cell>
<Table.Cell>{'Value 4'}</Table.Cell>
<Table.Cell>{'Value 5'}</Table.Cell>
<Table.Cell>{''}</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>{'Value 1'}</Table.Cell>
<Table.Cell>{'Value 2'}</Table.Cell>
<Table.Cell>{'Value 3'}</Table.Cell>
<Table.Cell>{'Value 4'}</Table.Cell>
<Table.Cell>{'Value 5'}</Table.Cell>
<Table.Cell>{''}</Table.Cell>
</Table.Row>
</Table.Body>
</Table>
)
}

export default TableWithCollapsibleWithCustomContent
Empty file.
Loading

0 comments on commit f9be357

Please sign in to comment.