-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into feature/external-images-remove
- Loading branch information
Showing
22 changed files
with
1,714 additions
and
0 deletions.
There are no files selected for viewing
111 changes: 111 additions & 0 deletions
111
packages/react-components/src/components/Table/Table.mdx
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,111 @@ | ||
import { Meta, Title, Canvas, ArgTypes } from '@storybook/blocks'; | ||
|
||
import * as Stories from './Table.stories'; | ||
|
||
<Title>Table</Title> | ||
|
||
[Intro](#Intro) | [Component API](#ComponentAPI) | [Content Spec](#ContentSpec) | ||
|
||
## Intro <a id="Intro" /> | ||
|
||
`Table` component is a flexible and interactive table designed for displaying structured data. It supports key features such as sorting, column resizing, row selection, and a customizable layout. | ||
|
||
|
||
<Canvas of={Stories.Default} sourceState="none" /> | ||
|
||
#### Example implementation | ||
|
||
```jsx | ||
|
||
import React from 'react'; | ||
import { Button, Column, Table } from '@livechat/design-system-react-components'; | ||
|
||
type Data = { | ||
id: number; | ||
name: string; | ||
age: number; | ||
role: string; | ||
action: React.ReactNode; | ||
}; | ||
|
||
const columns: Column<Data>[] = [ | ||
{ | ||
key: 'id', | ||
header: 'ID', | ||
sortable: true, | ||
sortValue: (item: Data) => item.id, | ||
}, | ||
{ | ||
key: 'name', | ||
header: 'Name', | ||
sortable: true, | ||
sortValue: (item: Data) => item.name.toLowerCase(), | ||
}, | ||
{ | ||
key: 'age', | ||
header: 'Age', | ||
sortable: true, | ||
sortValue: (item: Data) => item.age, | ||
}, | ||
{ | ||
key: 'role', | ||
header: 'Role', | ||
sortable: true, | ||
sortValue: (item: Data) => item.role, | ||
}, | ||
{ | ||
key: 'action', | ||
header: 'Action', | ||
}, | ||
]; | ||
|
||
const data: Data[] = [ | ||
{ | ||
id: 1, | ||
name: 'John Doe', | ||
age: 28, | ||
role: 'Developer', | ||
action: <Button size="xcompact">Edit</Button>, | ||
}, | ||
{ | ||
id: 2, | ||
name: 'Jane Smith', | ||
age: 34, | ||
role: 'Designer', | ||
action: <Button size="xcompact">Edit</Button>, | ||
}, | ||
{ | ||
id: 3, | ||
name: 'Alice Johnson', | ||
age: 42, | ||
role: 'Manager', | ||
action: <Button size="xcompact">Edit</Button>, | ||
}, | ||
{ | ||
id: 4, | ||
name: 'Mike Williams', | ||
age: 25, | ||
role: 'Intern', | ||
action: <Button size="xcompact">Edit</Button>, | ||
}, | ||
]; | ||
|
||
const getRowId = (row: Data) => row.id; | ||
|
||
<Table size="medium" data={data} columns={columns} getRowId={getRowId} /> | ||
|
||
``` | ||
|
||
## Component API <a id="ComponentAPI" /> | ||
|
||
<ArgTypes of={Stories.Default} /> | ||
|
||
## Content Spec <a id="ContentSpec" /> | ||
|
||
<a | ||
className="sb-unstyled" | ||
href="https://www.figma.com/design/9FDwjR8lYvincseDkKypC4/Component-Documentations?node-id=21446-18742&node-type=canvas&t=XufCAXr9dcNjfXDk-0" | ||
target="_blank" | ||
> | ||
Go to Figma documentation | ||
</a> |
98 changes: 98 additions & 0 deletions
98
packages/react-components/src/components/Table/Table.module.scss
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,98 @@ | ||
@use './styles/pin'; | ||
@use './styles/size'; | ||
@use './styles/strips'; | ||
|
||
$base-class: 'table'; | ||
$action-bar-class: 'action-bar'; | ||
|
||
.#{$base-class} { | ||
width: 100%; | ||
border-collapse: collapse; | ||
contain: paint; | ||
|
||
&--small { | ||
@include size.table-size(48px, 8px, 16px); | ||
} | ||
|
||
&--medium { | ||
@include size.table-size(56px, 12px, 16px); | ||
} | ||
|
||
&--large { | ||
@include size.table-size(64px, 14px, 16px); | ||
} | ||
|
||
&--pinned_header { | ||
@include pin.generatePin('header'); | ||
} | ||
|
||
&--pinned_leftColumn { | ||
@include pin.generatePin('leftColumn'); | ||
} | ||
|
||
&__cell { | ||
text-align: start; | ||
line-height: 21px; | ||
font-size: 14px; | ||
} | ||
|
||
&__selected { | ||
display: flex; | ||
gap: var(--spacing-1); | ||
align-items: center; | ||
padding: var(--spacing-2); | ||
font-weight: 500; | ||
|
||
> p { | ||
margin: 0; | ||
font-weight: 500; | ||
} | ||
|
||
> div:first-child { | ||
display: flex; | ||
align-items: center; | ||
margin-right: var(--spacing-1); | ||
} | ||
} | ||
|
||
&--stripped_rows { | ||
@include strips.generateStrips('rows'); | ||
} | ||
|
||
&--stripped_columns { | ||
@include strips.generateStrips('columns'); | ||
} | ||
|
||
tbody { | ||
width: 100%; | ||
} | ||
|
||
td, | ||
th { | ||
text-align: left; | ||
} | ||
|
||
th > div { | ||
display: flex; | ||
} | ||
} | ||
|
||
.#{$action-bar-class} { | ||
display: flex; | ||
gap: var(--spacing-2); | ||
|
||
&__divider { | ||
position: relative; | ||
|
||
&::before { | ||
position: absolute; | ||
top: 0; | ||
bottom: 0; | ||
margin-right: var(--spacing-2); | ||
background-color: var(--border-basic-secondary); | ||
width: 1px; | ||
height: var(--spacing-6); | ||
content: ''; | ||
} | ||
} | ||
} |
49 changes: 49 additions & 0 deletions
49
packages/react-components/src/components/Table/Table.spec.tsx
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,49 @@ | ||
import { render, fireEvent, vi } from 'test-utils'; | ||
|
||
import { Table } from './Table'; | ||
import { Column } from './types'; | ||
|
||
type Data = { | ||
id: number; | ||
name: string; | ||
age: number; | ||
role: string; | ||
}; | ||
|
||
const columns: Column<Data>[] = [ | ||
{ key: 'id', header: 'ID' }, | ||
{ key: 'name', header: 'Name' }, | ||
{ key: 'age', header: 'Age' }, | ||
{ key: 'role', header: 'Role' }, | ||
]; | ||
|
||
const data: Data[] = [ | ||
{ id: 1, name: 'John Doe', age: 28, role: 'Developer' }, | ||
{ id: 2, name: 'Jane Smith', age: 34, role: 'Designer' }, | ||
{ id: 3, name: 'Alice Johnson', age: 42, role: 'Manager' }, | ||
]; | ||
|
||
describe('<Table> component', () => { | ||
const getRowId = (row: Data) => row.id; | ||
|
||
it('should allow row selection if selectable prop is enabled', () => { | ||
const onSelectionChange = vi.fn(); | ||
const selectedRows = new Set<string>(); | ||
const { getAllByRole } = render( | ||
<Table | ||
data={data} | ||
columns={columns} | ||
getRowId={getRowId} | ||
selectable={true} | ||
selectedRows={selectedRows} | ||
onSelectionChange={onSelectionChange} | ||
/> | ||
); | ||
|
||
const checkboxes = getAllByRole('checkbox'); | ||
expect(checkboxes.length).toBe(data.length + 1); | ||
|
||
fireEvent.click(checkboxes[1]); | ||
expect(onSelectionChange).toHaveBeenCalledWith(new Set([1])); | ||
}); | ||
}); |
Oops, something went wrong.