@kenpan/zds-r8f3v1 0.2.0 → 0.3.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/dist/_virtual/index.js +5 -3
- package/dist/_virtual/index.js.map +1 -1
- package/dist/_virtual/index2.js +3 -2
- package/dist/_virtual/index2.js.map +1 -1
- package/dist/_virtual/index3.js +2 -2
- package/dist/_virtual/index5.js +2 -5
- package/dist/_virtual/index5.js.map +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/AppBar/AppBar.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Autocomplete/Autocomplete.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Avatar/Avatar.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Backdrop/Backdrop.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Box/Box.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Button/Button.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/ButtonBase/ButtonBase.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/ButtonBase/Ripple.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/ButtonBase/TouchRipple.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Checkbox/Checkbox.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Chip/Chip.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/CircularProgress/CircularProgress.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/ClickAwayListener/ClickAwayListener.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Collapse/Collapse.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/DefaultPropsProvider/DefaultPropsProvider.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Dialog/Dialog.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Divider/Divider.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Drawer/Drawer.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Fade/Fade.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/FilledInput/FilledInput.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/FormControl/FormControl.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/FormGroup/FormGroup.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/FormHelperText/FormHelperText.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/FormLabel/FormLabel.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/GlobalStyles/GlobalStyles.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Grow/Grow.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/IconButton/IconButton.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Input/Input.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/InputAdornment/InputAdornment.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/InputBase/InputBase.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/InputLabel/InputLabel.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/LinearProgress/LinearProgress.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/List/List.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/ListItemButton/ListItemButton.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/ListItemIcon/ListItemIcon.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/ListItemText/ListItemText.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/ListSubheader/ListSubheader.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Menu/Menu.js +2 -2
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/MenuItem/MenuItem.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/MenuList/MenuList.js +2 -2
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Modal/Modal.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/NativeSelect/NativeSelectInput.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/OutlinedInput/NotchedOutline.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/OutlinedInput/OutlinedInput.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Paper/Paper.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Popover/Popover.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Popper/BasePopper.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Popper/Popper.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Portal/Portal.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Radio/Radio.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Radio/RadioButtonIcon.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/RadioGroup/RadioGroup.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Select/Select.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Select/SelectInput.js +2 -2
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Skeleton/Skeleton.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Slide/Slide.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Slider/Slider.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Slider/SliderValueLabel.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Snackbar/Snackbar.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/SnackbarContent/SnackbarContent.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Stack/Stack.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Step/Step.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/StepConnector/StepConnector.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/StepIcon/StepIcon.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/StepLabel/StepLabel.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Stepper/Stepper.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/SvgIcon/SvgIcon.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Switch/Switch.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Tab/Tab.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/TabScrollButton/TabScrollButton.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Tabs/ScrollbarSize.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Tabs/Tabs.js +2 -2
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/TextField/TextField.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/TextareaAutosize/TextareaAutosize.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Toolbar/Toolbar.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Tooltip/Tooltip.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Typography/Typography.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/Unstable_TrapFocus/FocusTrap.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/material/esm/internal/SwitchBase.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/system/esm/DefaultPropsProvider/DefaultPropsProvider.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/system/esm/RtlProvider/index.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/system/esm/responsivePropType/responsivePropType.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/utils/esm/deepmerge/deepmerge.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/utils/esm/elementAcceptingRef/elementAcceptingRef.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/utils/esm/elementTypeAcceptingRef/elementTypeAcceptingRef.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/utils/esm/getDisplayName/getDisplayName.js +1 -1
- package/dist/packages/zenith-ui/node_modules/@mui/utils/esm/refType/refType.js +1 -1
- package/dist/packages/zenith-ui/node_modules/prop-types/index.js +1 -1
- package/dist/packages/zenith-ui/node_modules/prop-types/node_modules/react-is/index.js +1 -1
- package/dist/packages/zenith-ui/node_modules/react-is/index.js +1 -1
- package/dist/packages/zenith-ui/node_modules/react-transition-group/esm/Transition.js +1 -1
- package/dist/packages/zenith-ui/node_modules/react-transition-group/esm/TransitionGroup.js +1 -1
- package/dist/packages/zenith-ui/node_modules/react-transition-group/esm/utils/PropTypes.js +1 -1
- package/guidelines/Guidelines.md +67 -0
- package/guidelines/components/button.md +127 -43
- package/guidelines/components/dialog.md +164 -87
- package/guidelines/components/forms.md +239 -77
- package/guidelines/components/table.md +221 -87
- package/guidelines/design-tokens/colors.md +181 -0
- package/guidelines/design-tokens/spacing.md +135 -0
- package/guidelines/design-tokens/typography.md +146 -0
- package/guidelines/overview-components.md +136 -0
- package/guidelines/overview-icons.md +144 -0
- package/package.json +1 -1
- package/guidelines/overview.md +0 -81
- package/guidelines/tokens.md +0 -149
|
@@ -1,150 +1,284 @@
|
|
|
1
1
|
# Table Component
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Purpose**: Display tabular data with sorting, pagination, and row actions.
|
|
4
|
+
|
|
5
|
+
**Import**:
|
|
6
|
+
```tsx
|
|
7
|
+
import { Table, TableCell } from '@kenpan/zds-r8f3v1'
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## Props
|
|
11
|
+
|
|
12
|
+
### Table Props
|
|
13
|
+
|
|
14
|
+
| Prop | Type | Default | Description |
|
|
15
|
+
|------|------|---------|-------------|
|
|
16
|
+
| `columns` | `TableColumnDef[]` | - | **Required**. Column definitions |
|
|
17
|
+
| `data` | `any[]` | - | **Required**. Row data array |
|
|
18
|
+
| `loading` | `boolean` | `false` | Show loading state |
|
|
19
|
+
| `emptyMessage` | `string` | `'No data'` | Empty state message |
|
|
20
|
+
| `onRowClick` | `(row) => void` | - | Row click handler |
|
|
21
|
+
| `pagination` | `object` | - | Pagination config |
|
|
22
|
+
| `sorting` | `object` | - | Sorting config |
|
|
23
|
+
|
|
24
|
+
### TableColumnDef
|
|
25
|
+
|
|
26
|
+
| Prop | Type | Description |
|
|
27
|
+
|------|------|-------------|
|
|
28
|
+
| `field` | `string` | Data field key |
|
|
29
|
+
| `headerName` | `string` | Column header text |
|
|
30
|
+
| `width` | `number \| string` | Column width |
|
|
31
|
+
| `align` | `'left' \| 'center' \| 'right'` | Text alignment |
|
|
32
|
+
| `sortable` | `boolean` | Enable sorting |
|
|
33
|
+
| `renderCell` | `(params) => ReactNode` | Custom cell renderer |
|
|
4
34
|
|
|
5
35
|
## Basic Usage
|
|
6
36
|
|
|
7
37
|
```tsx
|
|
8
|
-
import { Table } from '@kenpan/zds-r8f3v1'
|
|
9
|
-
|
|
10
38
|
const columns = [
|
|
39
|
+
{ field: 'id', headerName: 'ID', width: 80 },
|
|
11
40
|
{ field: 'name', headerName: 'Name', width: 200 },
|
|
12
|
-
{ field: 'email', headerName: 'Email',
|
|
41
|
+
{ field: 'email', headerName: 'Email', flex: 1 },
|
|
13
42
|
{ field: 'status', headerName: 'Status', width: 120 },
|
|
14
43
|
]
|
|
15
44
|
|
|
16
|
-
const
|
|
45
|
+
const data = [
|
|
17
46
|
{ id: 1, name: 'John Doe', email: 'john@example.com', status: 'Active' },
|
|
18
47
|
{ id: 2, name: 'Jane Smith', email: 'jane@example.com', status: 'Pending' },
|
|
19
48
|
]
|
|
20
49
|
|
|
21
|
-
<Table columns={columns}
|
|
50
|
+
<Table columns={columns} data={data} />
|
|
22
51
|
```
|
|
23
52
|
|
|
24
|
-
##
|
|
53
|
+
## With Custom Cell Rendering
|
|
25
54
|
|
|
26
55
|
```tsx
|
|
56
|
+
import { Badge, Button } from '@kenpan/zds-r8f3v1'
|
|
57
|
+
import { EditOneIcon, TrashOneIcon } from '@kenpan/zds-r8f3v1/icons'
|
|
58
|
+
|
|
27
59
|
const columns = [
|
|
28
|
-
// Basic column
|
|
29
60
|
{ field: 'name', headerName: 'Name', width: 200 },
|
|
30
|
-
|
|
31
|
-
// Sortable column
|
|
32
|
-
{ field: 'date', headerName: 'Date', width: 150, sortable: true },
|
|
33
|
-
|
|
34
|
-
// Flex column (takes remaining space)
|
|
35
|
-
{ field: 'description', headerName: 'Description', flex: 1 },
|
|
36
|
-
|
|
37
|
-
// With custom cell renderer
|
|
38
61
|
{
|
|
39
62
|
field: 'status',
|
|
40
|
-
headerName: 'Status',
|
|
41
|
-
|
|
63
|
+
headerName: 'Status',
|
|
64
|
+
width: 120,
|
|
65
|
+
renderCell: (params) => (
|
|
66
|
+
<Badge
|
|
67
|
+
status={params.value === 'Active' ? 'success' : 'warning'}
|
|
68
|
+
>
|
|
69
|
+
{params.value}
|
|
70
|
+
</Badge>
|
|
71
|
+
)
|
|
42
72
|
},
|
|
43
|
-
|
|
44
|
-
// Actions column
|
|
45
73
|
{
|
|
46
74
|
field: 'actions',
|
|
47
75
|
headerName: '',
|
|
48
76
|
width: 100,
|
|
49
|
-
|
|
77
|
+
align: 'right',
|
|
50
78
|
renderCell: (params) => (
|
|
51
|
-
<
|
|
52
|
-
<
|
|
53
|
-
|
|
54
|
-
|
|
79
|
+
<Stack direction="row" spacing={1}>
|
|
80
|
+
<Button
|
|
81
|
+
variant="tertiary-gray"
|
|
82
|
+
iconOnly
|
|
83
|
+
iconLeading={<EditOneIcon size={16} />}
|
|
84
|
+
onClick={() => handleEdit(params.row)}
|
|
85
|
+
/>
|
|
86
|
+
<Button
|
|
87
|
+
variant="tertiary-gray"
|
|
88
|
+
iconOnly
|
|
89
|
+
destructive
|
|
90
|
+
iconLeading={<TrashOneIcon size={16} />}
|
|
91
|
+
onClick={() => handleDelete(params.row)}
|
|
92
|
+
/>
|
|
93
|
+
</Stack>
|
|
55
94
|
)
|
|
56
|
-
}
|
|
95
|
+
},
|
|
57
96
|
]
|
|
58
97
|
```
|
|
59
98
|
|
|
60
|
-
##
|
|
99
|
+
## With Sorting
|
|
61
100
|
|
|
62
101
|
```tsx
|
|
63
|
-
|
|
102
|
+
const [sortModel, setSortModel] = useState([
|
|
103
|
+
{ field: 'name', sort: 'asc' }
|
|
104
|
+
])
|
|
64
105
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
106
|
+
<Table
|
|
107
|
+
columns={columns}
|
|
108
|
+
data={data}
|
|
109
|
+
sorting={{
|
|
110
|
+
sortModel,
|
|
111
|
+
onSortModelChange: setSortModel,
|
|
112
|
+
}}
|
|
69
113
|
/>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## With Pagination
|
|
117
|
+
|
|
118
|
+
```tsx
|
|
119
|
+
const [page, setPage] = useState(0)
|
|
120
|
+
const [pageSize, setPageSize] = useState(10)
|
|
70
121
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
122
|
+
<Table
|
|
123
|
+
columns={columns}
|
|
124
|
+
data={data}
|
|
125
|
+
pagination={{
|
|
126
|
+
page,
|
|
127
|
+
pageSize,
|
|
128
|
+
totalRows: 100,
|
|
129
|
+
onPageChange: setPage,
|
|
130
|
+
onPageSizeChange: setPageSize,
|
|
131
|
+
pageSizeOptions: [10, 25, 50],
|
|
132
|
+
}}
|
|
78
133
|
/>
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## With Row Click
|
|
79
137
|
|
|
80
|
-
|
|
81
|
-
<
|
|
82
|
-
|
|
83
|
-
|
|
138
|
+
```tsx
|
|
139
|
+
<Table
|
|
140
|
+
columns={columns}
|
|
141
|
+
data={data}
|
|
142
|
+
onRowClick={(row) => {
|
|
143
|
+
console.log('Clicked row:', row)
|
|
144
|
+
navigate(`/details/${row.id}`)
|
|
145
|
+
}}
|
|
84
146
|
/>
|
|
85
147
|
```
|
|
86
148
|
|
|
87
|
-
##
|
|
149
|
+
## Loading State
|
|
88
150
|
|
|
89
151
|
```tsx
|
|
90
|
-
<Table
|
|
91
|
-
columns={columns}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
pageSize={10}
|
|
95
|
-
pageSizeOptions={[10, 25, 50]}
|
|
96
|
-
onPageChange={handlePageChange}
|
|
152
|
+
<Table
|
|
153
|
+
columns={columns}
|
|
154
|
+
data={data}
|
|
155
|
+
loading={isLoading}
|
|
97
156
|
/>
|
|
98
157
|
```
|
|
99
158
|
|
|
100
|
-
##
|
|
159
|
+
## Empty State
|
|
101
160
|
|
|
102
161
|
```tsx
|
|
103
|
-
<Table
|
|
104
|
-
columns={columns}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
onRowSelectionModelChange={handleSelectionChange}
|
|
162
|
+
<Table
|
|
163
|
+
columns={columns}
|
|
164
|
+
data={[]}
|
|
165
|
+
emptyMessage="No items found. Create your first item."
|
|
108
166
|
/>
|
|
109
167
|
```
|
|
110
168
|
|
|
111
|
-
##
|
|
169
|
+
## TableCell Component
|
|
112
170
|
|
|
113
|
-
|
|
171
|
+
For custom cell styling:
|
|
114
172
|
|
|
115
173
|
```tsx
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
174
|
+
import { TableCell } from '@kenpan/zds-r8f3v1'
|
|
175
|
+
|
|
176
|
+
// In renderCell
|
|
177
|
+
renderCell: (params) => (
|
|
178
|
+
<TableCell
|
|
179
|
+
type="text"
|
|
180
|
+
text={params.value}
|
|
181
|
+
subText={params.row.subtitle}
|
|
182
|
+
/>
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
// With badge
|
|
186
|
+
renderCell: (params) => (
|
|
187
|
+
<TableCell
|
|
188
|
+
type="badge"
|
|
189
|
+
badge={{ status: 'success', label: params.value }}
|
|
190
|
+
/>
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
// With avatar
|
|
194
|
+
renderCell: (params) => (
|
|
195
|
+
<TableCell
|
|
196
|
+
type="avatar"
|
|
197
|
+
avatar={{ src: params.row.avatar, name: params.value }}
|
|
198
|
+
text={params.value}
|
|
199
|
+
/>
|
|
200
|
+
)
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Full Example
|
|
204
|
+
|
|
205
|
+
```tsx
|
|
206
|
+
import { useState } from 'react'
|
|
207
|
+
import { Table, Badge, Button, Card, CardHeader } from '@kenpan/zds-r8f3v1'
|
|
208
|
+
import { PlusIcon, EditOneIcon, TrashOneIcon } from '@kenpan/zds-r8f3v1/icons'
|
|
209
|
+
|
|
210
|
+
function UsersTable() {
|
|
211
|
+
const [page, setPage] = useState(0)
|
|
212
|
+
const [users, setUsers] = useState([
|
|
213
|
+
{ id: 1, name: 'John Doe', email: 'john@example.com', role: 'Admin', status: 'Active' },
|
|
214
|
+
{ id: 2, name: 'Jane Smith', email: 'jane@example.com', role: 'User', status: 'Pending' },
|
|
215
|
+
])
|
|
216
|
+
|
|
217
|
+
const columns = [
|
|
218
|
+
{ field: 'name', headerName: 'Name', width: 200, sortable: true },
|
|
219
|
+
{ field: 'email', headerName: 'Email', flex: 1 },
|
|
220
|
+
{ field: 'role', headerName: 'Role', width: 120 },
|
|
221
|
+
{
|
|
222
|
+
field: 'status',
|
|
223
|
+
headerName: 'Status',
|
|
224
|
+
width: 120,
|
|
225
|
+
renderCell: ({ value }) => (
|
|
226
|
+
<Badge status={value === 'Active' ? 'success' : 'warning'}>
|
|
227
|
+
{value}
|
|
228
|
+
</Badge>
|
|
229
|
+
)
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
field: 'actions',
|
|
233
|
+
headerName: '',
|
|
234
|
+
width: 80,
|
|
235
|
+
renderCell: ({ row }) => (
|
|
236
|
+
<Button
|
|
237
|
+
variant="tertiary-gray"
|
|
238
|
+
iconOnly
|
|
239
|
+
iconLeading={<EditOneIcon size={16} />}
|
|
240
|
+
onClick={() => handleEdit(row)}
|
|
129
241
|
/>
|
|
130
|
-
)
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
242
|
+
)
|
|
243
|
+
},
|
|
244
|
+
]
|
|
245
|
+
|
|
246
|
+
return (
|
|
247
|
+
<Card>
|
|
248
|
+
<CardHeader
|
|
249
|
+
title="Users"
|
|
250
|
+
actions={
|
|
251
|
+
<Button variant="primary" iconLeading={<PlusIcon size={20} />}>
|
|
252
|
+
Add User
|
|
253
|
+
</Button>
|
|
254
|
+
}
|
|
137
255
|
/>
|
|
138
|
-
|
|
256
|
+
<Table
|
|
257
|
+
columns={columns}
|
|
258
|
+
data={users}
|
|
259
|
+
pagination={{
|
|
260
|
+
page,
|
|
261
|
+
pageSize: 10,
|
|
262
|
+
totalRows: users.length,
|
|
263
|
+
onPageChange: setPage,
|
|
264
|
+
}}
|
|
265
|
+
/>
|
|
266
|
+
</Card>
|
|
139
267
|
)
|
|
140
268
|
}
|
|
141
269
|
```
|
|
142
270
|
|
|
143
|
-
##
|
|
271
|
+
## Usage Guidelines
|
|
272
|
+
|
|
273
|
+
### Do:
|
|
274
|
+
- Define clear, descriptive column headers
|
|
275
|
+
- Use appropriate column widths
|
|
276
|
+
- Provide loading and empty states
|
|
277
|
+
- Use custom cell renderers for complex data
|
|
278
|
+
- Enable sorting for sortable columns
|
|
144
279
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
6. **Actions** - Place row actions in the last column
|
|
280
|
+
### Don't:
|
|
281
|
+
- Don't show too many columns (use detail views instead)
|
|
282
|
+
- Don't use tables for simple lists (use List component)
|
|
283
|
+
- Don't hide important data in scroll
|
|
284
|
+
- Don't forget pagination for large datasets
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# ZDS Color Design Tokens
|
|
2
|
+
|
|
3
|
+
ZDS uses a comprehensive color system with semantic tokens for consistent theming across components.
|
|
4
|
+
|
|
5
|
+
## Color Philosophy
|
|
6
|
+
|
|
7
|
+
- Use semantic color tokens rather than raw color values
|
|
8
|
+
- Colors are organized into scales (50-950) for each color family
|
|
9
|
+
- Semantic tokens provide meaning-based color access
|
|
10
|
+
- State layers provide consistent interaction feedback
|
|
11
|
+
|
|
12
|
+
## Color Scales
|
|
13
|
+
|
|
14
|
+
Each color family includes shades from 50 (lightest) to 950 (darkest):
|
|
15
|
+
|
|
16
|
+
### Primary (Blue)
|
|
17
|
+
The primary brand color used for primary actions and emphasis.
|
|
18
|
+
|
|
19
|
+
| Token | Value | Usage |
|
|
20
|
+
|-------|-------|-------|
|
|
21
|
+
| `primary.50` | `#EEF3FF` | Lightest background |
|
|
22
|
+
| `primary.100` | `#DEE9FE` | Light background |
|
|
23
|
+
| `primary.200` | `#C4D8FE` | Hover states |
|
|
24
|
+
| `primary.300` | `#9ABAFD` | Borders |
|
|
25
|
+
| `primary.400` | `#5D87FC` | - |
|
|
26
|
+
| `primary.500` | `#376BFD` | **Main primary color** |
|
|
27
|
+
| `primary.600` | `#1D47EF` | Pressed states |
|
|
28
|
+
| `primary.700` | `#1C3ED8` | - |
|
|
29
|
+
| `primary.800` | `#1C35AF` | - |
|
|
30
|
+
| `primary.900` | `#1C3289` | Dark text |
|
|
31
|
+
|
|
32
|
+
### Gray (Neutral)
|
|
33
|
+
Used for text, borders, backgrounds, and disabled states.
|
|
34
|
+
|
|
35
|
+
| Token | Value | Usage |
|
|
36
|
+
|-------|-------|-------|
|
|
37
|
+
| `gray.50` | `#F8FAFC` | Page background |
|
|
38
|
+
| `gray.100` | `#EEF2F6` | Container background |
|
|
39
|
+
| `gray.200` | `#E3E8EF` | Borders, dividers |
|
|
40
|
+
| `gray.300` | `#CDD5DF` | Disabled borders |
|
|
41
|
+
| `gray.400` | `#9AA4B2` | Placeholder text |
|
|
42
|
+
| `gray.500` | `#697586` | Secondary text |
|
|
43
|
+
| `gray.600` | `#4B5565` | Body text |
|
|
44
|
+
| `gray.700` | `#364152` | **Primary text** |
|
|
45
|
+
| `gray.800` | `#202939` | Headings |
|
|
46
|
+
| `gray.900` | `#121926` | Darkest text |
|
|
47
|
+
|
|
48
|
+
### Success (Green)
|
|
49
|
+
Used for success states, confirmations, and positive actions.
|
|
50
|
+
|
|
51
|
+
| Token | Value | Usage |
|
|
52
|
+
|-------|-------|-------|
|
|
53
|
+
| `success.50` | `#ECFDF3` | Success background |
|
|
54
|
+
| `success.500` | `#17B26A` | **Main success color** |
|
|
55
|
+
| `success.700` | `#079455` | Success text |
|
|
56
|
+
|
|
57
|
+
### Error (Red)
|
|
58
|
+
Used for errors, destructive actions, and critical alerts.
|
|
59
|
+
|
|
60
|
+
| Token | Value | Usage |
|
|
61
|
+
|-------|-------|-------|
|
|
62
|
+
| `error.50` | `#FEF3F2` | Error background |
|
|
63
|
+
| `error.500` | `#F04438` | **Main error color** |
|
|
64
|
+
| `error.700` | `#B42318` | Error text |
|
|
65
|
+
|
|
66
|
+
### Warning (Orange/Yellow)
|
|
67
|
+
Used for warnings and attention-requiring states.
|
|
68
|
+
|
|
69
|
+
| Token | Value | Usage |
|
|
70
|
+
|-------|-------|-------|
|
|
71
|
+
| `warning.50` | `#FFFAEB` | Warning background |
|
|
72
|
+
| `warning.500` | `#F79009` | **Main warning color** |
|
|
73
|
+
| `warning.700` | `#B54708` | Warning text |
|
|
74
|
+
|
|
75
|
+
## Semantic Tokens
|
|
76
|
+
|
|
77
|
+
Semantic tokens provide meaning-based color access through `theme.palette.ds`:
|
|
78
|
+
|
|
79
|
+
### Surface Colors
|
|
80
|
+
```tsx
|
|
81
|
+
theme.palette.ds.surface // Default surface (#FFFFFF)
|
|
82
|
+
theme.palette.ds.surfacecontainer // Container background
|
|
83
|
+
theme.palette.ds.surfacecontainerlow // Lower elevation
|
|
84
|
+
theme.palette.ds.surfacecontainerhigh // Higher elevation
|
|
85
|
+
theme.palette.ds.surfacecontainerlowest // Lowest (white)
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Text Colors
|
|
89
|
+
```tsx
|
|
90
|
+
theme.palette.ds.onsurface // Primary text (#364152)
|
|
91
|
+
theme.palette.ds.onsurfacevariant // Secondary text (#697586)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Outline Colors
|
|
95
|
+
```tsx
|
|
96
|
+
theme.palette.ds.outline // Default border (#AFBACA)
|
|
97
|
+
theme.palette.ds.outlinevariant // Light border (#D4DCE7)
|
|
98
|
+
theme.palette.ds.outlineerror // Error border
|
|
99
|
+
theme.palette.ds.outlinewarning // Warning border
|
|
100
|
+
theme.palette.ds.outlinesuccess // Success border
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Semantic Colors
|
|
104
|
+
```tsx
|
|
105
|
+
theme.palette.ds.onprimary // Text on primary (#FFFFFF)
|
|
106
|
+
theme.palette.ds.primarycontainer // Primary container bg
|
|
107
|
+
theme.palette.ds.onerror // Text on error
|
|
108
|
+
theme.palette.ds.errorcontainer // Error container bg
|
|
109
|
+
theme.palette.ds.onsuccess // Text on success
|
|
110
|
+
theme.palette.ds.successcontainer // Success container bg
|
|
111
|
+
theme.palette.ds.onwarning // Text on warning
|
|
112
|
+
theme.palette.ds.warningcontainer // Warning container bg
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## State Layers
|
|
116
|
+
|
|
117
|
+
State layers provide consistent hover/pressed/focus visual feedback:
|
|
118
|
+
|
|
119
|
+
```tsx
|
|
120
|
+
// Hover states (8% opacity)
|
|
121
|
+
theme.palette.dsTokens.stateLayers['state-layers-onsurface-opacity-8']
|
|
122
|
+
theme.palette.dsTokens.stateLayers['state-layers-primary-opacity-8']
|
|
123
|
+
|
|
124
|
+
// Pressed states (10% opacity)
|
|
125
|
+
theme.palette.dsTokens.stateLayers['state-layers-onsurface-opacity-10']
|
|
126
|
+
|
|
127
|
+
// Disabled states (38% opacity)
|
|
128
|
+
theme.palette.dsTokens.stateLayers['state-layers-onsurface-opacity-38']
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Usage Examples
|
|
132
|
+
|
|
133
|
+
### Background Colors
|
|
134
|
+
|
|
135
|
+
```tsx
|
|
136
|
+
// Default page background
|
|
137
|
+
<Box sx={{ bgcolor: 'background.default' }}>
|
|
138
|
+
|
|
139
|
+
// Container background
|
|
140
|
+
<Box sx={(theme) => ({ bgcolor: theme.palette.ds.surfacecontainer })}>
|
|
141
|
+
|
|
142
|
+
// Primary accent background
|
|
143
|
+
<Box sx={{ bgcolor: 'primary.50' }}>
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Text Colors
|
|
147
|
+
|
|
148
|
+
```tsx
|
|
149
|
+
// Primary text
|
|
150
|
+
<Typography sx={(theme) => ({ color: theme.palette.ds.onsurface })}>
|
|
151
|
+
|
|
152
|
+
// Secondary text
|
|
153
|
+
<Typography sx={(theme) => ({ color: theme.palette.ds.onsurfacevariant })}>
|
|
154
|
+
|
|
155
|
+
// Error text
|
|
156
|
+
<Typography color="error.main">
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Interactive States
|
|
160
|
+
|
|
161
|
+
```tsx
|
|
162
|
+
<Box
|
|
163
|
+
sx={(theme) => ({
|
|
164
|
+
bgcolor: 'transparent',
|
|
165
|
+
'&:hover': {
|
|
166
|
+
bgcolor: theme.palette.dsTokens?.stateLayers?.['state-layers-onsurface-opacity-8'] ?? 'rgba(54, 65, 82, 0.08)',
|
|
167
|
+
},
|
|
168
|
+
'&:active': {
|
|
169
|
+
bgcolor: theme.palette.dsTokens?.stateLayers?.['state-layers-onsurface-opacity-10'] ?? 'rgba(54, 65, 82, 0.10)',
|
|
170
|
+
},
|
|
171
|
+
})}
|
|
172
|
+
>
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Best Practices
|
|
176
|
+
|
|
177
|
+
1. **Use semantic tokens**: Prefer `theme.palette.ds.onsurface` over `gray.700`
|
|
178
|
+
2. **Contrast matters**: Ensure sufficient contrast between text and backgrounds
|
|
179
|
+
3. **Use state layers**: Apply consistent hover/pressed effects with state layers
|
|
180
|
+
4. **Don't hardcode colors**: Always use theme tokens for maintainability
|
|
181
|
+
5. **Fallback values**: When accessing custom tokens, provide fallback values for compatibility
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# ZDS Spacing Design Tokens
|
|
2
|
+
|
|
3
|
+
ZDS uses a consistent 4px-based spacing scale for margins, padding, and gaps.
|
|
4
|
+
|
|
5
|
+
## Spacing Scale
|
|
6
|
+
|
|
7
|
+
The spacing scale is based on MUI's default 8px multiplier but uses 4px as the base unit:
|
|
8
|
+
|
|
9
|
+
| Token | Value | Usage |
|
|
10
|
+
|-------|-------|-------|
|
|
11
|
+
| `0` | 0px | No spacing |
|
|
12
|
+
| `0.5` | 2px | Micro spacing |
|
|
13
|
+
| `1` | 4px | Tight spacing |
|
|
14
|
+
| `1.5` | 6px | Compact spacing |
|
|
15
|
+
| `2` | 8px | Small spacing |
|
|
16
|
+
| `2.5` | 10px | - |
|
|
17
|
+
| `3` | 12px | Medium spacing |
|
|
18
|
+
| `4` | 16px | **Standard spacing** |
|
|
19
|
+
| `5` | 20px | Large spacing |
|
|
20
|
+
| `6` | 24px | Section spacing |
|
|
21
|
+
| `8` | 32px | Major section gaps |
|
|
22
|
+
| `10` | 40px | Page section gaps |
|
|
23
|
+
| `12` | 48px | Large gaps |
|
|
24
|
+
| `16` | 64px | Extra large gaps |
|
|
25
|
+
| `20` | 80px | Page-level spacing |
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
### With theme.spacing()
|
|
30
|
+
|
|
31
|
+
```tsx
|
|
32
|
+
// Single value
|
|
33
|
+
<Box sx={{ p: 4 }}> // padding: 16px
|
|
34
|
+
<Box sx={{ m: 2 }}> // margin: 8px
|
|
35
|
+
<Box sx={{ gap: 3 }}> // gap: 12px
|
|
36
|
+
|
|
37
|
+
// Using theme.spacing function
|
|
38
|
+
<Box sx={(theme) => ({
|
|
39
|
+
padding: theme.spacing(4), // 16px
|
|
40
|
+
marginBottom: theme.spacing(2), // 8px
|
|
41
|
+
gap: theme.spacing(3), // 12px
|
|
42
|
+
})}>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Common Patterns
|
|
46
|
+
|
|
47
|
+
#### Container Padding
|
|
48
|
+
```tsx
|
|
49
|
+
// Card/container padding
|
|
50
|
+
<Card sx={{ p: 4 }}> // 16px all sides
|
|
51
|
+
<Card sx={{ p: 6 }}> // 24px for larger cards
|
|
52
|
+
|
|
53
|
+
// Asymmetric padding
|
|
54
|
+
<Box sx={{ px: 4, py: 3 }}> // 16px horizontal, 12px vertical
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
#### Element Spacing
|
|
58
|
+
```tsx
|
|
59
|
+
// Gap between elements
|
|
60
|
+
<Stack spacing={2}> // 8px gap
|
|
61
|
+
<Stack spacing={3}> // 12px gap
|
|
62
|
+
<Stack spacing={4}> // 16px gap (standard)
|
|
63
|
+
|
|
64
|
+
// Flex gap
|
|
65
|
+
<Box sx={{ display: 'flex', gap: 2 }}> // 8px gap
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
#### Margins
|
|
69
|
+
```tsx
|
|
70
|
+
// Section margins
|
|
71
|
+
<Box sx={{ mb: 4 }}> // margin-bottom: 16px
|
|
72
|
+
<Box sx={{ mt: 6 }}> // margin-top: 24px
|
|
73
|
+
|
|
74
|
+
// Component margins
|
|
75
|
+
<Button sx={{ ml: 2 }}> // margin-left: 8px
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Component Spacing Guidelines
|
|
79
|
+
|
|
80
|
+
### Buttons
|
|
81
|
+
- Gap between icon and text: 8px (spacing 2)
|
|
82
|
+
- Gap between buttons: 12px (spacing 3)
|
|
83
|
+
- Button padding: 8-16px depending on size
|
|
84
|
+
|
|
85
|
+
### Cards
|
|
86
|
+
- Card padding: 16-24px (spacing 4-6)
|
|
87
|
+
- Gap between card elements: 12-16px (spacing 3-4)
|
|
88
|
+
- Card header margin-bottom: 16px (spacing 4)
|
|
89
|
+
|
|
90
|
+
### Forms
|
|
91
|
+
- Gap between form fields: 16-24px (spacing 4-6)
|
|
92
|
+
- Label margin-bottom: 4-8px (spacing 1-2)
|
|
93
|
+
- Hint text margin-top: 4px (spacing 1)
|
|
94
|
+
|
|
95
|
+
### Lists
|
|
96
|
+
- Gap between list items: 8-12px (spacing 2-3)
|
|
97
|
+
- List item padding: 8-16px (spacing 2-4)
|
|
98
|
+
|
|
99
|
+
### Tables
|
|
100
|
+
- Cell padding: 12-16px (spacing 3-4)
|
|
101
|
+
- Header padding: 12-16px (spacing 3-4)
|
|
102
|
+
|
|
103
|
+
### Dialogs
|
|
104
|
+
- Dialog padding: 24px (spacing 6)
|
|
105
|
+
- Gap between dialog sections: 16-24px (spacing 4-6)
|
|
106
|
+
- Dialog actions gap: 12px (spacing 3)
|
|
107
|
+
|
|
108
|
+
## Best Practices
|
|
109
|
+
|
|
110
|
+
1. **Use the spacing scale**: Always use theme.spacing() instead of arbitrary px values
|
|
111
|
+
2. **Consistent gaps**: Use spacing(3) (12px) or spacing(4) (16px) for most gaps
|
|
112
|
+
3. **Breathing room**: Larger containers need more padding (24-32px)
|
|
113
|
+
4. **Tight UI**: Compact elements use spacing(1-2) (4-8px)
|
|
114
|
+
5. **Vertical rhythm**: Keep consistent vertical spacing between sections
|
|
115
|
+
|
|
116
|
+
## Quick Reference
|
|
117
|
+
|
|
118
|
+
```tsx
|
|
119
|
+
// Most common spacing values
|
|
120
|
+
<Box sx={{
|
|
121
|
+
p: 4, // 16px - standard padding
|
|
122
|
+
m: 2, // 8px - small margin
|
|
123
|
+
gap: 3, // 12px - element gap
|
|
124
|
+
mb: 4, // 16px - section margin
|
|
125
|
+
}}>
|
|
126
|
+
|
|
127
|
+
// Form layout
|
|
128
|
+
<Stack spacing={4}> // 16px between fields
|
|
129
|
+
|
|
130
|
+
// Button group
|
|
131
|
+
<Stack direction="row" spacing={3}> // 12px between buttons
|
|
132
|
+
|
|
133
|
+
// Card content
|
|
134
|
+
<Box sx={{ p: 6 }}> // 24px padding
|
|
135
|
+
```
|