agroptima-design-system 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.storybook/main.ts +0 -1
- package/package.json +2 -3
- package/src/atoms/Button.scss +2 -0
- package/src/atoms/Button.tsx +33 -9
- package/src/atoms/{CardsTableList.scss → CardsTable.scss} +16 -0
- package/src/atoms/CardsTable.tsx +23 -0
- package/src/atoms/CardsTableBody.tsx +16 -0
- package/src/atoms/CardsTableCell.tsx +32 -0
- package/src/atoms/CardsTableHead.tsx +16 -0
- package/src/atoms/CardsTableHeader.tsx +15 -0
- package/src/atoms/CardsTableList.tsx +53 -27
- package/src/atoms/CardsTableRow.tsx +20 -0
- package/src/atoms/EmptyState.tsx +4 -10
- package/src/icons/show-off.svg +1 -1
- package/src/icons/show.svg +1 -1
- package/src/stories/Button.stories.ts +14 -0
- package/src/stories/CardsTable.stories.js +60 -0
- package/src/stories/Changelog.stories.mdx +12 -0
- package/src/stories/EmptyState.stories.ts +4 -2
- package/src/utils/sort.ts +2 -1
- package/tsconfig.json +1 -1
- package/src/atoms/CardsTableListHeader.tsx +0 -32
- package/src/atoms/CardsTableListRow.tsx +0 -15
package/.storybook/main.ts
CHANGED
|
@@ -13,7 +13,6 @@ const config: StorybookConfig = {
|
|
|
13
13
|
addons: [
|
|
14
14
|
getAbsolutePath('@storybook/addon-links'),
|
|
15
15
|
getAbsolutePath('@storybook/addon-essentials'),
|
|
16
|
-
getAbsolutePath('@storybook/addon-onboarding'),
|
|
17
16
|
getAbsolutePath('@storybook/addon-interactions'),
|
|
18
17
|
'@storybook/addon-a11y',
|
|
19
18
|
'@storybook/addon-designs',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agroptima-design-system",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"dev": "npm run storybook",
|
|
6
6
|
"storybook": "storybook dev -p 6006 --ci",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"build-storybook": "storybook build",
|
|
9
9
|
"lint": "eslint",
|
|
10
10
|
"lint:fix": "eslint src --fix",
|
|
11
|
-
"
|
|
11
|
+
"chromatic": "npx chromatic --exit-zero-on-changes"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@storybook/addon-designs": "^7.0.5",
|
|
@@ -23,7 +23,6 @@
|
|
|
23
23
|
"@storybook/addon-essentials": "^7.5.0",
|
|
24
24
|
"@storybook/addon-interactions": "^7.5.0",
|
|
25
25
|
"@storybook/addon-links": "^7.5.0",
|
|
26
|
-
"@storybook/addon-onboarding": "^1.0.8",
|
|
27
26
|
"@storybook/blocks": "^7.5.0",
|
|
28
27
|
"@storybook/nextjs": "^7.5.0",
|
|
29
28
|
"@storybook/react": "^7.5.0",
|
package/src/atoms/Button.scss
CHANGED
package/src/atoms/Button.tsx
CHANGED
|
@@ -1,6 +1,27 @@
|
|
|
1
|
+
import NextLink from 'next/link'
|
|
1
2
|
import './Button.scss'
|
|
2
3
|
import { Icon, IconType } from './Icon'
|
|
3
4
|
|
|
5
|
+
export interface BaseButtonProps {
|
|
6
|
+
label: string
|
|
7
|
+
leftIcon?: IconType
|
|
8
|
+
rightIcon?: IconType
|
|
9
|
+
variant?: ButtonVariant
|
|
10
|
+
loading?: boolean
|
|
11
|
+
disabled?: boolean
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
type HtmlButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement>
|
|
15
|
+
|
|
16
|
+
type AnchorProps = React.AnchorHTMLAttributes<HTMLAnchorElement>
|
|
17
|
+
|
|
18
|
+
export type ButtonProps =
|
|
19
|
+
| (HtmlButtonProps & BaseButtonProps)
|
|
20
|
+
| (AnchorProps & BaseButtonProps)
|
|
21
|
+
|
|
22
|
+
const hasHref = (props: HtmlButtonProps | AnchorProps): props is AnchorProps =>
|
|
23
|
+
'href' in props
|
|
24
|
+
|
|
4
25
|
export type ButtonVariant =
|
|
5
26
|
| 'primary'
|
|
6
27
|
| 'primary-ghost'
|
|
@@ -21,14 +42,6 @@ export type ButtonVariant =
|
|
|
21
42
|
| 'warning-ghost'
|
|
22
43
|
| 'warning-outlined'
|
|
23
44
|
|
|
24
|
-
export interface ButtonProps extends React.ComponentPropsWithoutRef<'button'> {
|
|
25
|
-
label: string
|
|
26
|
-
leftIcon?: IconType
|
|
27
|
-
rightIcon?: IconType
|
|
28
|
-
variant?: ButtonVariant
|
|
29
|
-
loading?: boolean
|
|
30
|
-
}
|
|
31
|
-
|
|
32
45
|
export function Button({
|
|
33
46
|
label,
|
|
34
47
|
leftIcon,
|
|
@@ -37,11 +50,22 @@ export function Button({
|
|
|
37
50
|
variant = 'primary',
|
|
38
51
|
loading = false,
|
|
39
52
|
...props
|
|
40
|
-
}: ButtonProps)
|
|
53
|
+
}: ButtonProps) {
|
|
41
54
|
if (loading) {
|
|
42
55
|
leftIcon = 'Loading'
|
|
43
56
|
}
|
|
44
57
|
const cssClasses = ['button', variant].join(' ')
|
|
58
|
+
|
|
59
|
+
if (hasHref(props)) {
|
|
60
|
+
return (
|
|
61
|
+
<NextLink href={props.href || ''} className={cssClasses} {...props}>
|
|
62
|
+
{leftIcon && <Icon name={leftIcon} />}
|
|
63
|
+
{label}
|
|
64
|
+
{rightIcon && <Icon name={rightIcon} />}
|
|
65
|
+
</NextLink>
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
|
|
45
69
|
return (
|
|
46
70
|
<button className={cssClasses} disabled={loading || disabled} {...props}>
|
|
47
71
|
{leftIcon && <Icon name={leftIcon} />}
|
|
@@ -48,6 +48,22 @@
|
|
|
48
48
|
padding: config.$space-5x config.$space-3x;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
.no-wrap {
|
|
52
|
+
white-space: nowrap;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.alignment-left {
|
|
56
|
+
text-align: left;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.alignment-center {
|
|
60
|
+
text-align: center;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.alignment-right {
|
|
64
|
+
text-align: right;
|
|
65
|
+
}
|
|
66
|
+
|
|
51
67
|
&.primary {
|
|
52
68
|
thead > tr {
|
|
53
69
|
@include typography.cards-table-list-header;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import './CardsTable.scss'
|
|
2
|
+
|
|
3
|
+
export type Variant = 'primary'
|
|
4
|
+
|
|
5
|
+
export interface CardsTableProps
|
|
6
|
+
extends React.ComponentPropsWithoutRef<'table'> {
|
|
7
|
+
variant?: Variant
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function CardsTable({
|
|
11
|
+
summary,
|
|
12
|
+
variant = 'primary',
|
|
13
|
+
children,
|
|
14
|
+
...props
|
|
15
|
+
}: CardsTableProps): React.JSX.Element {
|
|
16
|
+
const cssClasses = ['cards-table-list', variant].join(' ')
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<table summary={summary} role="table" className={cssClasses} {...props}>
|
|
20
|
+
{children}
|
|
21
|
+
</table>
|
|
22
|
+
)
|
|
23
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import './CardsTable.scss'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
|
|
4
|
+
export interface CardsTableBodyProps
|
|
5
|
+
extends React.ComponentPropsWithoutRef<'tbody'> {}
|
|
6
|
+
|
|
7
|
+
export function CardsTableBody({
|
|
8
|
+
children,
|
|
9
|
+
...props
|
|
10
|
+
}: CardsTableBodyProps): React.JSX.Element {
|
|
11
|
+
return (
|
|
12
|
+
<tbody role="rowgroup" {...props}>
|
|
13
|
+
{children}
|
|
14
|
+
</tbody>
|
|
15
|
+
)
|
|
16
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import './CardsTable.scss'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
|
|
4
|
+
export enum Alignment {
|
|
5
|
+
Left = 'left',
|
|
6
|
+
Right = 'right',
|
|
7
|
+
Center = 'center',
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface CardsTableCellProps
|
|
11
|
+
extends React.ComponentPropsWithoutRef<'td'> {
|
|
12
|
+
noWrap?: boolean
|
|
13
|
+
align?: Alignment
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function CardsTableCell({
|
|
17
|
+
noWrap = false,
|
|
18
|
+
align = Alignment.Left,
|
|
19
|
+
children,
|
|
20
|
+
...props
|
|
21
|
+
}: CardsTableCellProps): React.JSX.Element {
|
|
22
|
+
const cssClasses = [
|
|
23
|
+
'cell',
|
|
24
|
+
noWrap ? 'no-wrap' : '',
|
|
25
|
+
`alignment-${align}`,
|
|
26
|
+
].join(' ')
|
|
27
|
+
return (
|
|
28
|
+
<td role="cell" className={cssClasses} {...props}>
|
|
29
|
+
{children}
|
|
30
|
+
</td>
|
|
31
|
+
)
|
|
32
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import './CardsTable.scss'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
|
|
4
|
+
export interface CardsTableHeadProps
|
|
5
|
+
extends React.ComponentPropsWithoutRef<'thead'> {}
|
|
6
|
+
|
|
7
|
+
export function CardsTableHead({
|
|
8
|
+
children,
|
|
9
|
+
...props
|
|
10
|
+
}: CardsTableHeadProps): React.JSX.Element {
|
|
11
|
+
return (
|
|
12
|
+
<thead role="rowgroup" {...props}>
|
|
13
|
+
{children}
|
|
14
|
+
</thead>
|
|
15
|
+
)
|
|
16
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface CardsTableHeaderProps
|
|
2
|
+
extends React.ComponentPropsWithoutRef<'th'> {}
|
|
3
|
+
|
|
4
|
+
export function CardsTableHeader({
|
|
5
|
+
children,
|
|
6
|
+
className,
|
|
7
|
+
...props
|
|
8
|
+
}: CardsTableHeaderProps) {
|
|
9
|
+
const cssClasses = ['header', className].join(' ')
|
|
10
|
+
return (
|
|
11
|
+
<th scope="col" role="columnheader" className={cssClasses} {...props}>
|
|
12
|
+
{children}
|
|
13
|
+
</th>
|
|
14
|
+
)
|
|
15
|
+
}
|
|
@@ -1,29 +1,34 @@
|
|
|
1
|
-
import './
|
|
1
|
+
import './CardsTable.scss'
|
|
2
2
|
import React, { useState } from 'react'
|
|
3
3
|
import { sortBy } from '../utils/sort'
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import { CardsTableHeader } from './CardsTableHeader'
|
|
5
|
+
import { CardsTableCell } from './CardsTableCell'
|
|
6
|
+
import { CardsTableRow } from './CardsTableRow'
|
|
7
|
+
import { Icon, IconType } from './Icon'
|
|
8
|
+
import { CardsTable } from './CardsTable'
|
|
9
|
+
import { CardsTableHead } from './CardsTableHead'
|
|
10
|
+
import { CardsTableBody } from './CardsTableBody'
|
|
7
11
|
|
|
8
12
|
export type Variant = 'primary'
|
|
9
13
|
|
|
14
|
+
export enum Order {
|
|
15
|
+
Ascending = 'ascending',
|
|
16
|
+
Descending = 'descending',
|
|
17
|
+
None = 'none',
|
|
18
|
+
}
|
|
19
|
+
|
|
10
20
|
export type Header = {
|
|
11
21
|
label: string
|
|
12
22
|
icon?: IconType
|
|
13
23
|
columnId: string
|
|
14
24
|
isSortable?: boolean
|
|
15
25
|
}
|
|
26
|
+
|
|
16
27
|
export type Column = {
|
|
17
28
|
[key: string]: string
|
|
18
29
|
}
|
|
19
30
|
export type Row = { id: string; isDisabled?: boolean; columns: Column }
|
|
20
31
|
|
|
21
|
-
export enum Order {
|
|
22
|
-
Ascending = 'ascending',
|
|
23
|
-
Descending = 'descending',
|
|
24
|
-
None = 'none',
|
|
25
|
-
}
|
|
26
|
-
|
|
27
32
|
export type SortState = { columnId: string; order: Order }
|
|
28
33
|
|
|
29
34
|
export interface CardsTableListProps
|
|
@@ -45,8 +50,6 @@ export function CardsTableList({
|
|
|
45
50
|
: null
|
|
46
51
|
})
|
|
47
52
|
|
|
48
|
-
const cssClasses = ['cards-table-list', variant].join(' ')
|
|
49
|
-
|
|
50
53
|
function checkColumnOrder(columnId: string) {
|
|
51
54
|
if (sortState?.columnId === columnId) {
|
|
52
55
|
return sortState.order
|
|
@@ -74,25 +77,48 @@ export function CardsTableList({
|
|
|
74
77
|
order: sortState?.order,
|
|
75
78
|
})
|
|
76
79
|
: rows
|
|
80
|
+
|
|
77
81
|
return (
|
|
78
|
-
<
|
|
79
|
-
<
|
|
80
|
-
<
|
|
82
|
+
<CardsTable summary={summary} variant={variant}>
|
|
83
|
+
<CardsTableHead>
|
|
84
|
+
<CardsTableRow>
|
|
81
85
|
{headers.map((header) => (
|
|
82
|
-
<
|
|
86
|
+
<CardsTableHeader
|
|
83
87
|
key={header.columnId}
|
|
84
|
-
|
|
85
|
-
|
|
88
|
+
aria-sort={checkColumnOrder(header.columnId)}
|
|
89
|
+
className={header.isSortable ? 'sortable' : ''}
|
|
86
90
|
onClick={() => applySort(header.columnId)}
|
|
87
|
-
|
|
91
|
+
>
|
|
92
|
+
<div className="container">
|
|
93
|
+
<div>
|
|
94
|
+
<span>{header.label}</span>
|
|
95
|
+
{header.icon && <Icon name={header.icon} />}
|
|
96
|
+
</div>
|
|
97
|
+
{header.isSortable && (
|
|
98
|
+
<Icon
|
|
99
|
+
name="Sorter"
|
|
100
|
+
className={checkColumnOrder(header.columnId)}
|
|
101
|
+
/>
|
|
102
|
+
)}
|
|
103
|
+
</div>
|
|
104
|
+
</CardsTableHeader>
|
|
88
105
|
))}
|
|
89
|
-
</
|
|
90
|
-
</
|
|
91
|
-
<
|
|
92
|
-
{sortedRows.map((row: Row) =>
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
106
|
+
</CardsTableRow>
|
|
107
|
+
</CardsTableHead>
|
|
108
|
+
<CardsTableBody>
|
|
109
|
+
{sortedRows.map((row: Row) => {
|
|
110
|
+
const cells = Object.entries(row.columns)
|
|
111
|
+
return (
|
|
112
|
+
<CardsTableRow key={row.id} isDisabled={row.isDisabled}>
|
|
113
|
+
{cells.map(([columnId, value]) => (
|
|
114
|
+
<CardsTableCell key={`${row.id}${columnId}`}>
|
|
115
|
+
{value}
|
|
116
|
+
</CardsTableCell>
|
|
117
|
+
))}
|
|
118
|
+
</CardsTableRow>
|
|
119
|
+
)
|
|
120
|
+
})}
|
|
121
|
+
</CardsTableBody>
|
|
122
|
+
</CardsTable>
|
|
97
123
|
)
|
|
98
124
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import './CardsTable.scss'
|
|
3
|
+
|
|
4
|
+
export interface CardsTableRowProps
|
|
5
|
+
extends React.ComponentPropsWithoutRef<'tr'> {
|
|
6
|
+
isDisabled?: boolean
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function CardsTableRow({
|
|
10
|
+
isDisabled = false,
|
|
11
|
+
children,
|
|
12
|
+
...props
|
|
13
|
+
}: CardsTableRowProps): React.JSX.Element {
|
|
14
|
+
const disabledClass = isDisabled ? 'disabled' : ''
|
|
15
|
+
return (
|
|
16
|
+
<tr role="row" className={`row ${disabledClass}`} {...props}>
|
|
17
|
+
{children}
|
|
18
|
+
</tr>
|
|
19
|
+
)
|
|
20
|
+
}
|
package/src/atoms/EmptyState.tsx
CHANGED
|
@@ -1,27 +1,21 @@
|
|
|
1
|
-
import { Button } from './Button'
|
|
1
|
+
import { Button, ButtonProps } from './Button'
|
|
2
2
|
import './EmptyState.scss'
|
|
3
3
|
import { Icon, IconType } from './Icon'
|
|
4
4
|
|
|
5
5
|
export type Variant = 'primary'
|
|
6
6
|
|
|
7
|
-
interface callToAction {
|
|
8
|
-
(event: React.MouseEvent<HTMLButtonElement, MouseEvent>): any
|
|
9
|
-
}
|
|
10
|
-
|
|
11
7
|
export interface EmptyStateProps extends React.ComponentPropsWithoutRef<'div'> {
|
|
12
8
|
icon?: IconType
|
|
13
9
|
text?: string
|
|
14
10
|
variant?: Variant
|
|
15
|
-
|
|
16
|
-
action?: callToAction
|
|
11
|
+
button?: ButtonProps
|
|
17
12
|
}
|
|
18
13
|
|
|
19
14
|
export function EmptyState({
|
|
20
15
|
icon = 'EmptyState',
|
|
21
16
|
text = 'No data',
|
|
22
17
|
variant = 'primary',
|
|
23
|
-
|
|
24
|
-
action,
|
|
18
|
+
button,
|
|
25
19
|
}: EmptyStateProps): React.JSX.Element {
|
|
26
20
|
const cssClasses = ['empty-state', variant].join(' ')
|
|
27
21
|
|
|
@@ -29,7 +23,7 @@ export function EmptyState({
|
|
|
29
23
|
<div className={cssClasses}>
|
|
30
24
|
<Icon name={icon} />
|
|
31
25
|
<p>{text}</p>
|
|
32
|
-
{
|
|
26
|
+
{button?.label && <Button {...button} />}
|
|
33
27
|
</div>
|
|
34
28
|
)
|
|
35
29
|
}
|
package/src/icons/show-off.svg
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><g clip-path="url(#show-off)"><path d="M10 4.5a8.956 8.956 0 0 1 8.085 5.042 8.843 8.843 0 0 1-2.21 2.86l1.293 1.292a10.818 10.818 0 0 0 2.915-4.152C18.498 5.518 14.583 2.667 10 2.667c-1.164 0-2.282.183-3.337.522l1.513 1.513c.596-.12 1.2-.202 1.824-.202Zm-.98 1.045 1.897 1.897c.522.23.944.651 1.173 1.174l1.898 1.897a4.29 4.29 0 0 0 .128-.98c.009-2.274-1.843-4.116-4.116-4.116-.34 0-.66.046-.98.128ZM.842 2.547l2.456 2.457A10.76 10.76 0 0 0-.083 9.542c1.585 4.024 5.5 6.875 10.083 6.875 1.393 0 2.732-.266 3.96-.752l3.135 3.135 1.293-1.293L2.134 1.247l-1.291 1.3Zm6.875 6.875 2.392 2.393a.458.458 0 0 1-.11.018 2.292 2.292 0 0 1-2.292-2.291c0-.046.01-.074.01-.12ZM4.6 6.306 6.205 7.91a4.217 4.217 0 0 0-.33 1.632 4.131 4.131 0 0 0 5.748 3.795l.898.898c-.807.22-1.65.348-2.521.348a8.956 8.956 0 0 1-8.085-5.041 9.077 9.077 0 0 1 2.686-3.236Z" fill="#444"/></g><defs><clipPath id="show-off"><path fill="#fff" d="M0 0h20v20H0z"/></clipPath></defs></svg>
|
package/src/icons/show.svg
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><g clip-path="url(#show)"><path d="M10 4.5a8.956 8.956 0 0 1 8.085 5.042A8.956 8.956 0 0 1 10 14.583a8.956 8.956 0 0 1-8.085-5.041A8.956 8.956 0 0 1 10 4.5Zm0-1.833c-4.583 0-8.498 2.85-10.083 6.875 1.585 4.024 5.5 6.875 10.083 6.875s8.497-2.851 10.083-6.875C18.498 5.518 14.583 2.667 10 2.667Zm0 4.583a2.293 2.293 0 1 1-.002 4.585A2.293 2.293 0 0 1 10 7.25Zm0-1.833a4.131 4.131 0 0 0-4.125 4.125A4.131 4.131 0 0 0 10 13.667a4.131 4.131 0 0 0 4.125-4.125A4.131 4.131 0 0 0 10 5.417Z" fill="#444"/></g><defs><clipPath id="show"><path fill="#fff" d="M0 0h20v20H0z"/></clipPath></defs></svg>
|
|
@@ -29,6 +29,10 @@ const meta = {
|
|
|
29
29
|
description: 'Button right icon from a list of values',
|
|
30
30
|
control: { type: 'select' },
|
|
31
31
|
},
|
|
32
|
+
href: {
|
|
33
|
+
description:
|
|
34
|
+
'If a link is provided, the component will be rendered as NextLink, otherwise as button',
|
|
35
|
+
},
|
|
32
36
|
},
|
|
33
37
|
}
|
|
34
38
|
|
|
@@ -77,6 +81,16 @@ const figmaInfoDesign = {
|
|
|
77
81
|
export default meta
|
|
78
82
|
type Story = StoryObj<typeof meta>
|
|
79
83
|
|
|
84
|
+
export const Link: Story = {
|
|
85
|
+
args: {
|
|
86
|
+
variant: 'primary',
|
|
87
|
+
disabled: false,
|
|
88
|
+
loading: false,
|
|
89
|
+
href: 'link.com',
|
|
90
|
+
},
|
|
91
|
+
parameters: figmaPrimaryDesign,
|
|
92
|
+
}
|
|
93
|
+
|
|
80
94
|
export const Primary: Story = {
|
|
81
95
|
args: {
|
|
82
96
|
variant: 'primary',
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import { CardsTable } from '../atoms/CardsTable'
|
|
4
|
+
import { CardsTableHead } from '../atoms/CardsTableHead'
|
|
5
|
+
import { CardsTableHeader } from '../atoms/CardsTableHeader'
|
|
6
|
+
import { CardsTableRow } from '../atoms/CardsTableRow'
|
|
7
|
+
import { CardsTableBody } from '../atoms/CardsTableBody'
|
|
8
|
+
import { CardsTableCell } from '../atoms/CardsTableCell'
|
|
9
|
+
import { Button } from '../atoms/Button'
|
|
10
|
+
|
|
11
|
+
const meta = {
|
|
12
|
+
title: 'Design System/Atoms/CardsTable',
|
|
13
|
+
component: CardsTable,
|
|
14
|
+
tags: ['autodocs'],
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default meta
|
|
18
|
+
|
|
19
|
+
export const Primary = {
|
|
20
|
+
render: (args) => (
|
|
21
|
+
<CardsTable {...args}>
|
|
22
|
+
<CardsTableHead>
|
|
23
|
+
<CardsTableRow>
|
|
24
|
+
<CardsTableHeader>Game title</CardsTableHeader>
|
|
25
|
+
<CardsTableHeader>Company address</CardsTableHeader>
|
|
26
|
+
<CardsTableHeader>Customer service email</CardsTableHeader>
|
|
27
|
+
</CardsTableRow>
|
|
28
|
+
</CardsTableHead>
|
|
29
|
+
<CardsTableBody>
|
|
30
|
+
<CardsTableRow>
|
|
31
|
+
<CardsTableCell>Metal Gear Solid 5: The Phantom Pain</CardsTableCell>
|
|
32
|
+
<CardsTableCell noWrap>
|
|
33
|
+
Konami Digital Entertainment Co., Ltd. 1-11-1, Ginza, Chuo-ku,
|
|
34
|
+
Tokyo, 104-0061 Japan
|
|
35
|
+
</CardsTableCell>
|
|
36
|
+
<CardsTableCell align="right">konami@fakemail.com</CardsTableCell>
|
|
37
|
+
</CardsTableRow>
|
|
38
|
+
|
|
39
|
+
<CardsTableRow>
|
|
40
|
+
<CardsTableCell>The Witcher 3</CardsTableCell>
|
|
41
|
+
<CardsTableCell noWrap>
|
|
42
|
+
CD PROJEKT S.A. ul. Jagiellońska 74 03-301 Warszawa Poland
|
|
43
|
+
</CardsTableCell>
|
|
44
|
+
<CardsTableCell align="right">cdprojekt@fakemail.com</CardsTableCell>
|
|
45
|
+
</CardsTableRow>
|
|
46
|
+
|
|
47
|
+
<CardsTableRow>
|
|
48
|
+
<CardsTableCell>Tekken 8</CardsTableCell>
|
|
49
|
+
<CardsTableCell noWrap>
|
|
50
|
+
Bandai Namco Studios Inc. ; Address: 2-37-25 Eitai, Koto-ku, Tokyo
|
|
51
|
+
135-0034, Japan
|
|
52
|
+
</CardsTableCell>
|
|
53
|
+
<CardsTableCell align="right">
|
|
54
|
+
namco@fakemail.com <Button label="click" />
|
|
55
|
+
</CardsTableCell>
|
|
56
|
+
</CardsTableRow>
|
|
57
|
+
</CardsTableBody>
|
|
58
|
+
</CardsTable>
|
|
59
|
+
),
|
|
60
|
+
}
|
|
@@ -3,6 +3,18 @@ import { Meta } from "@storybook/addon-docs";
|
|
|
3
3
|
<Meta title="Changelog" />
|
|
4
4
|
# Changelog
|
|
5
5
|
|
|
6
|
+
## 0.4.0
|
|
7
|
+
|
|
8
|
+
- CardsTable component suitable to create custom tables is added to Storybook.
|
|
9
|
+
- Cell `align` property has been added to CardsTableCell component.
|
|
10
|
+
- Cell `noWrap` property has been added to CardsTableCell component.
|
|
11
|
+
- Button component can be rendered as NextLink if the `href` prop is provided.
|
|
12
|
+
- Empty State component now accepts Button props.
|
|
13
|
+
|
|
14
|
+
## 0.3.2
|
|
15
|
+
|
|
16
|
+
- Updated show and show-off icons.
|
|
17
|
+
|
|
6
18
|
## 0.3.1
|
|
7
19
|
|
|
8
20
|
- Fixed input height not matching other components'.
|
|
@@ -38,8 +38,10 @@ export const PrimaryCustom: Story = {
|
|
|
38
38
|
args: {
|
|
39
39
|
variant: 'primary',
|
|
40
40
|
text: 'There are no videogames yet. You can import videogames to your list.',
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
button: {
|
|
42
|
+
label: 'Import videogames',
|
|
43
|
+
onClick: () => alert('click'),
|
|
44
|
+
},
|
|
43
45
|
},
|
|
44
46
|
parameters: figmaPrimaryDesign,
|
|
45
47
|
}
|
package/src/utils/sort.ts
CHANGED
package/tsconfig.json
CHANGED
|
@@ -22,6 +22,6 @@
|
|
|
22
22
|
"@/*": ["./src/*"]
|
|
23
23
|
}
|
|
24
24
|
},
|
|
25
|
-
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
|
25
|
+
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "src/stories/CardsTable.stories.js"],
|
|
26
26
|
"exclude": ["node_modules"]
|
|
27
27
|
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { Icon } from './Icon'
|
|
2
|
-
import { Header, Order } from './CardsTableList'
|
|
3
|
-
|
|
4
|
-
export interface CardsTableListHeaderProps {
|
|
5
|
-
header: Header
|
|
6
|
-
order: Order
|
|
7
|
-
onClick: () => void
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function CardsTableListHeader({
|
|
11
|
-
header,
|
|
12
|
-
order,
|
|
13
|
-
onClick,
|
|
14
|
-
}: CardsTableListHeaderProps) {
|
|
15
|
-
return (
|
|
16
|
-
<th
|
|
17
|
-
scope="col"
|
|
18
|
-
role="columnheader"
|
|
19
|
-
className={`header ${header.isSortable ? 'sortable' : ''}`}
|
|
20
|
-
aria-sort={order}
|
|
21
|
-
onClick={onClick}
|
|
22
|
-
>
|
|
23
|
-
<div className="container">
|
|
24
|
-
<div className="title-container">
|
|
25
|
-
<span>{header.label}</span>
|
|
26
|
-
{header.icon && <Icon name={header.icon} />}
|
|
27
|
-
</div>
|
|
28
|
-
{header.isSortable && <Icon name="Sorter" className={order} />}
|
|
29
|
-
</div>
|
|
30
|
-
</th>
|
|
31
|
-
)
|
|
32
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { Row } from './CardsTableList'
|
|
2
|
-
|
|
3
|
-
export function CardsTableListRow({ isDisabled, columns, id }: Row) {
|
|
4
|
-
const disabledClass = isDisabled ? 'disabled' : ''
|
|
5
|
-
const cells = Object.entries(columns)
|
|
6
|
-
return (
|
|
7
|
-
<tr role="row" className={`row ${disabledClass}`}>
|
|
8
|
-
{cells.map(([columnId, value]) => (
|
|
9
|
-
<td role="cell" key={`${id}${columnId}`} className="cell">
|
|
10
|
-
{value}
|
|
11
|
-
</td>
|
|
12
|
-
))}
|
|
13
|
-
</tr>
|
|
14
|
-
)
|
|
15
|
-
}
|