@loadsmart/loadsmart-ui 6.1.4 → 6.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/components/Table/Table.d.ts +7 -5
- package/dist/components/Table/Table.types.d.ts +4 -1
- package/dist/index.js +110 -77
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Table/Table.stories.tsx +8 -10
- package/src/components/Table/Table.test.tsx +1 -4
- package/src/components/Table/Table.tsx +77 -19
- package/src/components/Table/Table.types.ts +5 -1
package/package.json
CHANGED
|
@@ -518,19 +518,18 @@ export function WithExpandableRow(args: TableProps): JSX.Element {
|
|
|
518
518
|
|
|
519
519
|
return (
|
|
520
520
|
<div className="p-4 bg-neutral-white">
|
|
521
|
-
<Table {...args}>
|
|
522
|
-
<Table.Head>
|
|
521
|
+
<Table withExpandableRows {...args}>
|
|
522
|
+
<Table.Expandable.Head>
|
|
523
523
|
<Table.Row>
|
|
524
524
|
<Table.Expandable.HeadCell />
|
|
525
|
-
<Table.Expandable.HeadCell>
|
|
526
|
-
<Table.Expandable.HeadCell>
|
|
527
|
-
<Table.Expandable.HeadCell>
|
|
525
|
+
<Table.Expandable.HeadCell>reference</Table.Expandable.HeadCell>
|
|
526
|
+
<Table.Expandable.HeadCell>product</Table.Expandable.HeadCell>
|
|
527
|
+
<Table.Expandable.HeadCell>price</Table.Expandable.HeadCell>
|
|
528
528
|
</Table.Row>
|
|
529
|
-
</Table.Head>
|
|
529
|
+
</Table.Expandable.Head>
|
|
530
530
|
|
|
531
531
|
<Table.Body>
|
|
532
532
|
<Table.Expandable.Row
|
|
533
|
-
index={0}
|
|
534
533
|
leading={leading}
|
|
535
534
|
expandableContent={<div>Forced expanded with custom leading</div>}
|
|
536
535
|
expanded
|
|
@@ -540,7 +539,6 @@ export function WithExpandableRow(args: TableProps): JSX.Element {
|
|
|
540
539
|
<Table.Expandable.Cell>12345</Table.Expandable.Cell>
|
|
541
540
|
</Table.Expandable.Row>
|
|
542
541
|
<Table.Expandable.Row
|
|
543
|
-
index={1}
|
|
544
542
|
leading={leading}
|
|
545
543
|
expandableContent={<div>Initial expanded row with custom leading</div>}
|
|
546
544
|
initialExpanded
|
|
@@ -549,12 +547,12 @@ export function WithExpandableRow(args: TableProps): JSX.Element {
|
|
|
549
547
|
<Table.Expandable.Cell>Body 2</Table.Expandable.Cell>
|
|
550
548
|
<Table.Expandable.Cell>12345</Table.Expandable.Cell>
|
|
551
549
|
</Table.Expandable.Row>
|
|
552
|
-
<Table.Expandable.Row
|
|
550
|
+
<Table.Expandable.Row expandableContent={<div>Expandable row</div>}>
|
|
553
551
|
<Table.Expandable.Cell>123456</Table.Expandable.Cell>
|
|
554
552
|
<Table.Expandable.Cell>Body 3</Table.Expandable.Cell>
|
|
555
553
|
<Table.Expandable.Cell>12345</Table.Expandable.Cell>
|
|
556
554
|
</Table.Expandable.Row>
|
|
557
|
-
<Table.Expandable.Row
|
|
555
|
+
<Table.Expandable.Row expanded>
|
|
558
556
|
<Table.Expandable.Cell>123456</Table.Expandable.Cell>
|
|
559
557
|
<Table.Expandable.Cell>Body 5</Table.Expandable.Cell>
|
|
560
558
|
<Table.Expandable.Cell>12345</Table.Expandable.Cell>
|
|
@@ -198,7 +198,6 @@ describe('<Table />', () => {
|
|
|
198
198
|
</Table.Head>
|
|
199
199
|
<Table.Body>
|
|
200
200
|
<Table.Expandable.Row
|
|
201
|
-
index={0}
|
|
202
201
|
expandableContent={<div>This is an expandable content on index 0</div>}
|
|
203
202
|
expanded
|
|
204
203
|
>
|
|
@@ -208,7 +207,7 @@ describe('<Table />', () => {
|
|
|
208
207
|
$9876,50
|
|
209
208
|
</Table.Cell>
|
|
210
209
|
</Table.Expandable.Row>
|
|
211
|
-
<Table.Expandable.Row
|
|
210
|
+
<Table.Expandable.Row>
|
|
212
211
|
<Table.Cell format="number">#000000-2</Table.Cell>
|
|
213
212
|
<Table.Cell>Modal X 21</Table.Cell>
|
|
214
213
|
<Table.Cell format="currency" alignment="right">
|
|
@@ -216,7 +215,6 @@ describe('<Table />', () => {
|
|
|
216
215
|
</Table.Cell>
|
|
217
216
|
</Table.Expandable.Row>
|
|
218
217
|
<Table.Expandable.Row
|
|
219
|
-
index={2}
|
|
220
218
|
expandableContent={<div>This is an expandable content on index 2</div>}
|
|
221
219
|
leading={(expanded) => (expanded ? 'open' : 'closed')}
|
|
222
220
|
onExpandedChange={onExpandedChange}
|
|
@@ -228,7 +226,6 @@ describe('<Table />', () => {
|
|
|
228
226
|
</Table.Cell>
|
|
229
227
|
</Table.Expandable.Row>
|
|
230
228
|
<Table.Expandable.Row
|
|
231
|
-
index={3}
|
|
232
229
|
expandableContent={<div>This is an expandable content on index 3</div>}
|
|
233
230
|
expanded={controlledExpanded4}
|
|
234
231
|
>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { Children, Fragment, isValidElement,
|
|
1
|
+
import React, { Children, Fragment, isValidElement, useEffect, useState } from 'react'
|
|
2
2
|
import styled, { css } from 'styled-components'
|
|
3
3
|
import type { ReactNode } from 'react'
|
|
4
4
|
import { isFunction } from '@loadsmart/utils-function'
|
|
@@ -36,6 +36,7 @@ import type {
|
|
|
36
36
|
TablePickerItemProps,
|
|
37
37
|
TablePickerProps,
|
|
38
38
|
ExpandableTableRowProps,
|
|
39
|
+
TableHeadCellProps,
|
|
39
40
|
} from './Table.types'
|
|
40
41
|
|
|
41
42
|
const StyledTableBody = styled.tbody`
|
|
@@ -79,14 +80,21 @@ const StyledTableCell = styled.td<{ alignment?: string; format?: string }>`
|
|
|
79
80
|
})};
|
|
80
81
|
`
|
|
81
82
|
|
|
82
|
-
const StyledTableHeadCell = styled.th<{
|
|
83
|
+
const StyledTableHeadCell = styled.th<{
|
|
84
|
+
alignment?: string
|
|
85
|
+
clickable: boolean
|
|
86
|
+
capitalized?: boolean
|
|
87
|
+
}>`
|
|
83
88
|
${StyledCell}
|
|
84
89
|
|
|
85
90
|
font-family: ${token('font-family-default')};
|
|
86
91
|
|
|
87
92
|
font-weight: ${token('font-weight-bold')};
|
|
88
93
|
|
|
89
|
-
text-transform:
|
|
94
|
+
text-transform: ${conditional({
|
|
95
|
+
uppercase: whenProps({ capitalized: false }),
|
|
96
|
+
capitalize: whenProps({ capitalized: true }),
|
|
97
|
+
})};
|
|
90
98
|
|
|
91
99
|
cursor: ${conditional({
|
|
92
100
|
pointer: whenProps({ clickable: true }),
|
|
@@ -105,6 +113,17 @@ const StyledTableHead = styled.thead`
|
|
|
105
113
|
}
|
|
106
114
|
`
|
|
107
115
|
|
|
116
|
+
const StyledExpandableTableHead = styled.thead`
|
|
117
|
+
border: 1px solid ${token('color-neutral-lighter')};
|
|
118
|
+
|
|
119
|
+
${StyledTableCell} {
|
|
120
|
+
padding: ${token('space-s')};
|
|
121
|
+
|
|
122
|
+
font-weight: ${token('font-weight-bold')};
|
|
123
|
+
text-transform: capitalize;
|
|
124
|
+
}
|
|
125
|
+
`
|
|
126
|
+
|
|
108
127
|
const BaseStyledTableRow = styled.tr`
|
|
109
128
|
${StyledTableHead} > & {
|
|
110
129
|
height: 36px;
|
|
@@ -140,19 +159,51 @@ const StyledTableRow = styled(BaseStyledTableRow)<{ selected?: boolean }>`
|
|
|
140
159
|
}
|
|
141
160
|
`
|
|
142
161
|
|
|
143
|
-
const StyledExpandableTableRow = styled
|
|
144
|
-
background-color: ${
|
|
145
|
-
|
|
146
|
-
|
|
162
|
+
const StyledExpandableTableRow = styled.tr<{ $isExpanded: boolean }>`
|
|
163
|
+
background-color: ${token('color-neutral-white')};
|
|
164
|
+
|
|
165
|
+
border-color: ${token('color-neutral-lighter')};
|
|
166
|
+
border-width: 1px;
|
|
167
|
+
border-top-style: solid;
|
|
168
|
+
border-right-style: solid;
|
|
169
|
+
border-left-style: solid;
|
|
170
|
+
border-bottom-style: ${conditional({
|
|
171
|
+
solid: whenProps({ $isExpanded: false }),
|
|
172
|
+
hidden: whenProps({ $isExpanded: true }),
|
|
173
|
+
})};
|
|
174
|
+
|
|
175
|
+
box-shadow: ${conditional({
|
|
176
|
+
'0px 3px 3px 0px #C1CED9': whenProps({ $isExpanded: true }),
|
|
177
|
+
none: whenProps({ $isExpanded: false }),
|
|
147
178
|
})};
|
|
179
|
+
|
|
180
|
+
${hoverable`
|
|
181
|
+
background-color: ${token('color-neutral-lighter')};
|
|
182
|
+
`}
|
|
183
|
+
|
|
184
|
+
${focusable`
|
|
185
|
+
box-shadow: inset ${token('shadow-glow-primary')};
|
|
186
|
+
`}
|
|
187
|
+
`
|
|
188
|
+
|
|
189
|
+
const StyledExpandableContentRow = styled.tr`
|
|
190
|
+
border-color: ${token('color-neutral-lighter')};
|
|
191
|
+
border-width: 1px;
|
|
192
|
+
border-top-style: hidden;
|
|
193
|
+
border-right-style: solid;
|
|
194
|
+
border-left-style: solid;
|
|
195
|
+
border-bottom-style: solid;
|
|
148
196
|
`
|
|
149
197
|
|
|
150
|
-
const StyledTable = styled.table<{ scale?: string }>`
|
|
198
|
+
const StyledTable = styled.table<{ scale?: string; withExpandableRows?: boolean }>`
|
|
151
199
|
width: 100%;
|
|
152
200
|
|
|
153
201
|
white-space: nowrap;
|
|
154
202
|
|
|
155
|
-
background-color: ${
|
|
203
|
+
background-color: ${conditional({
|
|
204
|
+
'color-neutral-lightest': whenProps({ withExpandableRows: true }),
|
|
205
|
+
'color-neutral-white': whenProps({ withExpandableRows: false }),
|
|
206
|
+
})};
|
|
156
207
|
|
|
157
208
|
border-collapse: collapse;
|
|
158
209
|
|
|
@@ -189,13 +240,14 @@ function Table<T>({
|
|
|
189
240
|
children,
|
|
190
241
|
selection,
|
|
191
242
|
scale = 'default',
|
|
243
|
+
withExpandableRows,
|
|
192
244
|
...others
|
|
193
245
|
}: TableProps<T>): JSX.Element {
|
|
194
246
|
return (
|
|
195
247
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
196
248
|
// @ts-ignore
|
|
197
249
|
<TableSelectionProvider selection={selection}>
|
|
198
|
-
<StyledTable scale={scale} {...others}>
|
|
250
|
+
<StyledTable scale={scale} withExpandableRows={withExpandableRows} {...others}>
|
|
199
251
|
{children}
|
|
200
252
|
</StyledTable>
|
|
201
253
|
</TableSelectionProvider>
|
|
@@ -221,6 +273,10 @@ function TableHead({ children, ...others }: TableSectionProps): JSX.Element {
|
|
|
221
273
|
return <StyledTableHead {...others}>{children}</StyledTableHead>
|
|
222
274
|
}
|
|
223
275
|
|
|
276
|
+
function ExpandableTableHead({ children, ...others }: TableSectionProps): JSX.Element {
|
|
277
|
+
return <StyledExpandableTableHead {...others}>{children}</StyledExpandableTableHead>
|
|
278
|
+
}
|
|
279
|
+
|
|
224
280
|
function TableBody({ children, ...others }: TableSectionProps): JSX.Element {
|
|
225
281
|
return <StyledTableBody {...others}>{children}</StyledTableBody>
|
|
226
282
|
}
|
|
@@ -288,8 +344,8 @@ function SelectionHeadCell<T>(props: SelectionCellProps<T>): JSX.Element {
|
|
|
288
344
|
)
|
|
289
345
|
}
|
|
290
346
|
|
|
291
|
-
function ExpandableHeadCell(props:
|
|
292
|
-
return <TableHeadCell {...props} />
|
|
347
|
+
function ExpandableHeadCell(props: TableHeadCellProps): JSX.Element {
|
|
348
|
+
return <TableHeadCell capitalized {...props} />
|
|
293
349
|
}
|
|
294
350
|
|
|
295
351
|
function ExpandableCell(props: TableCellProps): JSX.Element {
|
|
@@ -307,7 +363,6 @@ function TableRow({ children, ...others }: TableRowProps): JSX.Element {
|
|
|
307
363
|
}
|
|
308
364
|
|
|
309
365
|
function ExpandableTableRow({
|
|
310
|
-
index,
|
|
311
366
|
expandableContent,
|
|
312
367
|
expanded,
|
|
313
368
|
leading: propsLeading,
|
|
@@ -319,8 +374,8 @@ function ExpandableTableRow({
|
|
|
319
374
|
const [openState, setOpenState] = useState(initialExpanded)
|
|
320
375
|
|
|
321
376
|
const open = expanded ?? openState
|
|
377
|
+
const isExpanded = Boolean(open && expandableContent)
|
|
322
378
|
const colSpan = Array.isArray(children) ? children.length + 1 : 1
|
|
323
|
-
const isEven = index % 2 === 0
|
|
324
379
|
|
|
325
380
|
let leading: ReactNode = <RotatableIcon name="caret-right" $rotate={open} />
|
|
326
381
|
if (propsLeading) {
|
|
@@ -336,14 +391,14 @@ function ExpandableTableRow({
|
|
|
336
391
|
|
|
337
392
|
return (
|
|
338
393
|
<>
|
|
339
|
-
<StyledExpandableTableRow {...others} onClick={toggle} $
|
|
394
|
+
<StyledExpandableTableRow {...others} onClick={toggle} $isExpanded={isExpanded}>
|
|
340
395
|
<ExpandableCell>{expandableContent && leading}</ExpandableCell>
|
|
341
396
|
{children}
|
|
342
397
|
</StyledExpandableTableRow>
|
|
343
|
-
{
|
|
344
|
-
<
|
|
398
|
+
{isExpanded && (
|
|
399
|
+
<StyledExpandableContentRow>
|
|
345
400
|
<StyledTableCell colSpan={colSpan}>{expandableContent}</StyledTableCell>
|
|
346
|
-
</
|
|
401
|
+
</StyledExpandableContentRow>
|
|
347
402
|
)}
|
|
348
403
|
</>
|
|
349
404
|
)
|
|
@@ -353,13 +408,15 @@ function TableHeadCell({
|
|
|
353
408
|
alignment = 'left',
|
|
354
409
|
children,
|
|
355
410
|
onClick,
|
|
411
|
+
capitalized = false,
|
|
356
412
|
...others
|
|
357
|
-
}:
|
|
413
|
+
}: TableHeadCellProps): JSX.Element {
|
|
358
414
|
return (
|
|
359
415
|
<StyledTableHeadCell
|
|
360
416
|
clickable={onClick != null}
|
|
361
417
|
alignment={alignment}
|
|
362
418
|
onClick={onClick}
|
|
419
|
+
capitalized={capitalized}
|
|
363
420
|
{...others}
|
|
364
421
|
>
|
|
365
422
|
<Layout.Group space="xs" align="center">
|
|
@@ -507,6 +564,7 @@ Table.Selection = {
|
|
|
507
564
|
HeadCell: SelectionHeadCell,
|
|
508
565
|
}
|
|
509
566
|
Table.Expandable = {
|
|
567
|
+
Head: ExpandableTableHead,
|
|
510
568
|
HeadCell: ExpandableHeadCell,
|
|
511
569
|
Cell: ExpandableCell,
|
|
512
570
|
Row: ExpandableTableRow,
|
|
@@ -17,6 +17,7 @@ export interface TableProps<T extends Selectable = TableSelectableRow>
|
|
|
17
17
|
extends HTMLAttributes<HTMLTableElement> {
|
|
18
18
|
scale?: Scale
|
|
19
19
|
selection?: TableSelectionConfig<T>
|
|
20
|
+
withExpandableRows?: boolean
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
export interface TableCaptionProps extends HTMLAttributes<HTMLTableCaptionElement> {
|
|
@@ -41,7 +42,6 @@ export interface TableSectionProps extends HTMLAttributes<HTMLTableSectionElemen
|
|
|
41
42
|
export type TableRowProps = HTMLAttributes<HTMLTableRowElement>
|
|
42
43
|
|
|
43
44
|
export type ExpandableTableRowProps = TableRowProps & {
|
|
44
|
-
index: number
|
|
45
45
|
expandableContent?: ReactNode
|
|
46
46
|
leading?: ReactNode | ((expanded: boolean) => ReactNode)
|
|
47
47
|
initialExpanded?: boolean
|
|
@@ -57,6 +57,10 @@ export interface TableCellProps extends HTMLAttributes<HTMLTableCellElement> {
|
|
|
57
57
|
selected?: boolean
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
export interface TableHeadCellProps extends TableCellProps {
|
|
61
|
+
capitalized?: boolean
|
|
62
|
+
}
|
|
63
|
+
|
|
60
64
|
export type TableColumn<T = Record<string, unknown>> = {
|
|
61
65
|
/**
|
|
62
66
|
* The accessor of you entry interface
|