@soul-refiner/design-system 0.1.7 → 0.1.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soul-refiner/design-system",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "main": "src/index.ts",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -46,13 +46,14 @@ export interface BoxProps
46
46
  Styleable,
47
47
  NativeProps {
48
48
  $display?: 'block' | 'flex';
49
+ sx?: string;
49
50
  }
50
51
 
51
- export const Box = ({ $display = 'flex', ...args }: BoxProps) => (
52
- <Component $display={$display} {...args} />
52
+ export const Box = ({ $display = 'flex', sx, ...args }: BoxProps) => (
53
+ <Component $display={$display} $sx={sx} {...args} />
53
54
  );
54
55
 
55
- export const Component = styled.div<BoxProps>`
56
+ export const Component = styled.div<BoxProps & { $sx?: string }>`
56
57
  ${({ $display }) => ($display === 'flex' ? 'display: flex;' : '')}
57
58
  ${Styles.flex}
58
59
  ${Styles.backgroundColor}
@@ -61,4 +62,5 @@ export const Component = styled.div<BoxProps>`
61
62
  ${Styles.margin}
62
63
  ${Styles.padding}
63
64
  ${Styles.styleable}
65
+ ${({ $sx }) => ($sx ? $sx : '')}
64
66
  `;
@@ -0,0 +1,7 @@
1
+ export { Table } from './table';
2
+ export type {
3
+ TableCellProps,
4
+ TableHeaderCellProps,
5
+ TableProps,
6
+ TableRowProps,
7
+ } from './table';
@@ -0,0 +1,7 @@
1
+ export { Table } from './table';
2
+ export type {
3
+ TableCellProps,
4
+ TableHeaderCellProps,
5
+ TableProps,
6
+ TableRowProps,
7
+ } from './table';
@@ -0,0 +1,382 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+ import { Box } from 'components';
4
+
5
+ /********************************************************
6
+ * Table
7
+ */
8
+ export interface TableProps extends React.PropsWithChildren {
9
+ border?: boolean;
10
+ compact?: boolean;
11
+ footer?: React.ReactNode;
12
+ header?: React.ReactNode;
13
+ separated?: boolean;
14
+ striped?: boolean;
15
+ sx?: string;
16
+ }
17
+
18
+ const Table = ({
19
+ border = true,
20
+ children,
21
+ compact,
22
+ footer,
23
+ header,
24
+ separated,
25
+ striped,
26
+ sx,
27
+ }: TableProps) => {
28
+ return (
29
+ <Box
30
+ $backgroundColor="white"
31
+ $borderRadius="large"
32
+ $display="flex"
33
+ $dir="column"
34
+ $gap={32}
35
+ $padding={32}
36
+ >
37
+ {!!header && header}
38
+ <Box
39
+ $borderRadius="small"
40
+ sx={border ? 'border: 1px solid var(--color-grey-8);' : ''}
41
+ >
42
+ <TableElement
43
+ $compact={compact}
44
+ $separated={separated}
45
+ $striped={striped}
46
+ $sx={sx}
47
+ >
48
+ {children}
49
+ </TableElement>
50
+ </Box>
51
+ {!!footer && footer}
52
+ </Box>
53
+ );
54
+ };
55
+
56
+ const TableElement = styled.table<{
57
+ $compact?: boolean;
58
+ $separated?: boolean;
59
+ $striped?: boolean;
60
+ $sx?: string;
61
+ }>`
62
+ width: max-content;
63
+ border-collapse: collapse;
64
+ border-spacing: 0;
65
+ ${({ $compact }) => ($compact ? 'width: fit-content;' : '')}
66
+ ${({ $separated }) =>
67
+ $separated
68
+ ? `
69
+ & > tbody > * {
70
+ border-bottom: 1px solid var(--color-grey-9);
71
+ &:last-child {
72
+ border-bottom: none;
73
+ }
74
+ }`
75
+ : ''}
76
+ ${({ $striped }) =>
77
+ $striped
78
+ ? `
79
+ & > tbody > *:nth-of-type(even) {
80
+ background-color: var(--color-grey-10);
81
+ }`
82
+ : ''}
83
+ ${({ $sx }) => ($sx ? $sx : '')}
84
+ `;
85
+
86
+ /********************************************************
87
+ * Table Head
88
+ */
89
+
90
+ const Head = ({ children, ...rest }: React.PropsWithChildren) => {
91
+ return <HeadElement {...rest}>{children}</HeadElement>;
92
+ };
93
+
94
+ const HeadElement = styled.thead`
95
+ tr {
96
+ background-color: var(--color-grey-10);
97
+ border-top-left-radius: 8px;
98
+ border-top-right-radius: 8px;
99
+
100
+ & > *:first-of-type {
101
+ border-top-left-radius: 8px;
102
+ }
103
+
104
+ & > *:last-of-type {
105
+ border-top-right-radius: 8px;
106
+ }
107
+ }
108
+ `;
109
+
110
+ Head.displayName = 'Table.Head';
111
+ Table.Head = Head;
112
+
113
+ /********************************************************
114
+ * Table Body
115
+ */
116
+
117
+ const Body = ({ children, ...rest }: React.PropsWithChildren) => {
118
+ return <BodyElement {...rest}>{children}</BodyElement>;
119
+ };
120
+
121
+ const BodyElement = styled.tbody`
122
+ & > tr:last-of-type {
123
+ & > *:first-child {
124
+ border-bottom-left-radius: 8px;
125
+ }
126
+
127
+ & > *:last-child {
128
+ border-bottom-right-radius: 8px;
129
+ }
130
+ }
131
+ `;
132
+
133
+ Body.displayName = 'Table.Body';
134
+ Table.Body = Body;
135
+
136
+ /********************************************************
137
+ * Table Foot
138
+ */
139
+
140
+ const Foot = ({ children, ...rest }: React.PropsWithChildren) => {
141
+ return <tfoot {...rest}>{children}</tfoot>;
142
+ };
143
+
144
+ Foot.displayName = 'Table.Foot';
145
+ Table.Footer = Foot;
146
+
147
+ /********************************************************
148
+ * Table Row
149
+ */
150
+
151
+ export interface TableRowProps extends React.PropsWithChildren {
152
+ disabled?: boolean;
153
+ href?: string;
154
+ hoverable?: boolean;
155
+ onClick?: (event: React.MouseEvent<HTMLTableRowElement>) => void;
156
+ padding?: string;
157
+ selected?: boolean;
158
+ sx?: string;
159
+ }
160
+
161
+ const Row = ({
162
+ children,
163
+ disabled,
164
+ href,
165
+ hoverable = false,
166
+ onClick,
167
+ selected,
168
+ sx,
169
+ ...rest
170
+ }: TableRowProps) => {
171
+ const handleClick = href
172
+ ? (event: React.MouseEvent<HTMLTableRowElement, MouseEvent>) => {
173
+ if (event.metaKey || event.ctrlKey) {
174
+ const win = window.open(href, '_blank');
175
+ win?.focus();
176
+ } else {
177
+ window.location.href = href;
178
+ }
179
+ }
180
+ : onClick
181
+ ? (event: React.MouseEvent<HTMLTableRowElement, MouseEvent>) => {
182
+ onClick(event);
183
+ }
184
+ : undefined;
185
+
186
+ return (
187
+ <RowElement
188
+ onClick={handleClick}
189
+ $disabled={disabled}
190
+ $hoverable={hoverable}
191
+ $isAnchor={!!href}
192
+ $selected={selected}
193
+ $sx={sx}
194
+ {...rest}
195
+ >
196
+ {children}
197
+ </RowElement>
198
+ );
199
+ };
200
+
201
+ const RowElement = styled.tr<{
202
+ $disabled?: boolean;
203
+ $hoverable?: boolean;
204
+ $isAnchor?: boolean;
205
+ $selected?: boolean;
206
+ $sx?: string;
207
+ }>`
208
+ display: table-row;
209
+
210
+ ${({ $disabled }) =>
211
+ $disabled
212
+ ? `
213
+ background-color: var(--color-grey-9) !important;
214
+ color: var(--color-grey-7);
215
+ & > * {
216
+ color: var(--color-grey-7) !important;
217
+ }`
218
+ : ''}
219
+
220
+ ${({ $disabled, $hoverable }) =>
221
+ !$disabled && $hoverable ? 'background-color: var(--color-grey-9);' : ''}
222
+
223
+ ${({ $disabled, $selected }) =>
224
+ !$disabled && $selected ? 'background-color: var(--color-grey-8;' : ''}
225
+
226
+ ${({ $disabled, $isAnchor }) =>
227
+ !$disabled && $isAnchor
228
+ ? `
229
+ cursor: pointer;
230
+ padding-right: 24px;
231
+
232
+ &:hover {
233
+ background-color: var(--color-grey-10);
234
+
235
+ & > td:last-child {
236
+ position: relative;
237
+ }
238
+ & > td:last-child::after {
239
+ content: "❯";
240
+ color: var(--color-blue-3);
241
+ position: absolute;
242
+ right: 12px;
243
+ top: calc(50% - 11px);
244
+ }
245
+ }`
246
+ : ''}
247
+ ${({ $sx }) => ($sx ? $sx : '')}
248
+ `;
249
+
250
+ Row.displayName = 'Table.Row';
251
+ Table.Row = Row;
252
+
253
+ /********************************************************
254
+ * Table Cell
255
+ */
256
+
257
+ export interface TableCellProps extends React.PropsWithChildren {
258
+ lines?: number;
259
+ padding?: string;
260
+ sx?: string;
261
+ textAlign?: 'left' | 'center' | 'right';
262
+ verticalAlign?: 'top' | 'middle' | 'bottom';
263
+ width?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16;
264
+ }
265
+
266
+ const Cell = ({
267
+ children,
268
+ lines,
269
+ padding = '16px 24px',
270
+ sx,
271
+ textAlign = 'left',
272
+ verticalAlign = 'middle',
273
+ width,
274
+ }: TableCellProps) => {
275
+ const percentageWidth = width ? width * (1 / 16) + '%' : undefined;
276
+
277
+ return (
278
+ <CellElement
279
+ $clamp={lines}
280
+ $padding={padding}
281
+ $sx={sx}
282
+ $textAlign={textAlign}
283
+ $verticalAlign={verticalAlign}
284
+ $width={percentageWidth ? percentageWidth : 'fit-content'}
285
+ >
286
+ <div>{children}</div>
287
+ </CellElement>
288
+ );
289
+ };
290
+
291
+ const CellElement = styled.td<{
292
+ $clamp?: number;
293
+ $padding: string;
294
+ $sx?: string;
295
+ $textAlign: string;
296
+ $verticalAlign: string;
297
+ $width?: string;
298
+ }>`
299
+ width: ${({ $width }) => $width};
300
+ height: 20px;
301
+ font-family: Inter;
302
+ font-size: 14px;
303
+ font-weight: 400;
304
+ line-height: 20px;
305
+ color: var(--color-grey-3);
306
+ vertical-align: ${({ $verticalAlign }) =>
307
+ $verticalAlign ? $verticalAlign : ''};
308
+ text-align: ${({ $textAlign }) => ($textAlign ? $textAlign : '')};
309
+ padding: ${({ $padding }) => $padding};
310
+ ${({ $clamp }) =>
311
+ $clamp
312
+ ? `
313
+ & > div {
314
+ overflow: hidden;
315
+ text-overflow: ellipsis;
316
+ display: -webkit-box;
317
+ line-clamp: ${$clamp};
318
+ -webkit-line-clamp: ${$clamp};
319
+ -webkit-box-orient: vertical;
320
+ }`
321
+ : ''}
322
+ ${({ $sx }) => ($sx ? $sx : '')}
323
+ `;
324
+
325
+ Cell.displayName = 'Table.Cell';
326
+ Table.Cell = Cell;
327
+
328
+ export { Table };
329
+
330
+ /********************************************************
331
+ * Table Header Cell
332
+ */
333
+
334
+ export interface TableHeaderCellProps extends React.PropsWithChildren {
335
+ lines?: number;
336
+ padding?: string;
337
+ sx?: string;
338
+ textAlign?: 'left' | 'center' | 'right';
339
+ verticalAlign?: 'top' | 'middle' | 'bottom';
340
+ width?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16;
341
+ }
342
+
343
+ const HeaderCell = ({
344
+ children,
345
+ lines,
346
+ padding = '16px 24px',
347
+ sx,
348
+ textAlign = 'left',
349
+ verticalAlign = 'middle',
350
+ width,
351
+ }: TableHeaderCellProps) => {
352
+ const percentageWidth = width ? width * (100 / 16) + '%' : undefined;
353
+
354
+ return (
355
+ <HeadCellElement
356
+ as="th"
357
+ $clamp={lines}
358
+ $padding={padding}
359
+ $sx={sx}
360
+ $textAlign={textAlign}
361
+ $verticalAlign={verticalAlign}
362
+ $width={percentageWidth ? percentageWidth : 'fit-content'}
363
+ >
364
+ {children}
365
+ </HeadCellElement>
366
+ );
367
+ };
368
+
369
+ const HeadCellElement = styled(CellElement)<{
370
+ $clamp?: number;
371
+ $sx?: string;
372
+ $textAlign: string;
373
+ $verticalAlign: string;
374
+ $width?: string;
375
+ }>`
376
+ font-size: 16px;
377
+ font-weight: 700;
378
+ line-height: 24px;
379
+ `;
380
+
381
+ HeaderCell.displayName = 'Table.HeaderCell';
382
+ Table.HeaderCell = HeaderCell;