@ltht-react/table 2.0.192 → 2.0.194
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/README.md +15 -15
- package/package.json +8 -8
- package/src/atoms/questionnaire-withdrawn-table-cell.tsx +15 -15
- package/src/index.tsx +8 -8
- package/src/molecules/table-cell.tsx +111 -111
- package/src/molecules/table-component.tsx +123 -123
- package/src/molecules/table-header.tsx +38 -38
- package/src/molecules/table-methods.tsx +238 -238
- package/src/molecules/table-styled-components.tsx +249 -249
- package/src/molecules/table.tsx +166 -166
- package/src/molecules/useDimensionRef.tsx +37 -37
- package/src/molecules/useScrollRef.tsx +40 -40
- package/src/organisms/generic-table.tsx +34 -34
- package/src/organisms/questionnaire-table-methods.tsx +351 -351
- package/src/organisms/questionnaire-table.tsx +56 -56
- package/lib/atoms/questionnaire-withdrawn-table-cell.d.ts +0 -6
- package/lib/atoms/questionnaire-withdrawn-table-cell.js +0 -19
- package/lib/atoms/questionnaire-withdrawn-table-cell.js.map +0 -1
- package/lib/index.d.ts +0 -7
- package/lib/index.js +0 -15
- package/lib/index.js.map +0 -1
- package/lib/molecules/table-cell.d.ts +0 -17
- package/lib/molecules/table-cell.js +0 -109
- package/lib/molecules/table-cell.js.map +0 -1
- package/lib/molecules/table-component.d.ts +0 -20
- package/lib/molecules/table-component.js +0 -78
- package/lib/molecules/table-component.js.map +0 -1
- package/lib/molecules/table-header.d.ts +0 -12
- package/lib/molecules/table-header.js +0 -33
- package/lib/molecules/table-header.js.map +0 -1
- package/lib/molecules/table-methods.d.ts +0 -14
- package/lib/molecules/table-methods.js +0 -198
- package/lib/molecules/table-methods.js.map +0 -1
- package/lib/molecules/table-styled-components.d.ts +0 -81
- package/lib/molecules/table-styled-components.js +0 -112
- package/lib/molecules/table-styled-components.js.map +0 -1
- package/lib/molecules/table.d.ts +0 -44
- package/lib/molecules/table.js +0 -95
- package/lib/molecules/table.js.map +0 -1
- package/lib/molecules/useDimensionRef.d.ts +0 -5
- package/lib/molecules/useDimensionRef.js +0 -31
- package/lib/molecules/useDimensionRef.js.map +0 -1
- package/lib/molecules/useScrollRef.d.ts +0 -8
- package/lib/molecules/useScrollRef.js +0 -30
- package/lib/molecules/useScrollRef.js.map +0 -1
- package/lib/organisms/generic-table.d.ts +0 -9
- package/lib/organisms/generic-table.js +0 -36
- package/lib/organisms/generic-table.js.map +0 -1
- package/lib/organisms/questionnaire-table-methods.d.ts +0 -9
- package/lib/organisms/questionnaire-table-methods.js +0 -247
- package/lib/organisms/questionnaire-table-methods.js.map +0 -1
- package/lib/organisms/questionnaire-table.d.ts +0 -12
- package/lib/organisms/questionnaire-table.js +0 -44
- package/lib/organisms/questionnaire-table.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
# Select
|
|
2
|
-
|
|
3
|
-
<!-- STORY -->
|
|
4
|
-
|
|
5
|
-
### Import
|
|
6
|
-
|
|
7
|
-
```js
|
|
8
|
-
import Select from '@ltht-react/table'
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
### Usage
|
|
12
|
-
|
|
13
|
-
```jsx
|
|
14
|
-
<Table />
|
|
15
|
-
```
|
|
1
|
+
# Select
|
|
2
|
+
|
|
3
|
+
<!-- STORY -->
|
|
4
|
+
|
|
5
|
+
### Import
|
|
6
|
+
|
|
7
|
+
```js
|
|
8
|
+
import Select from '@ltht-react/table'
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### Usage
|
|
12
|
+
|
|
13
|
+
```jsx
|
|
14
|
+
<Table />
|
|
15
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ltht-react/table",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.194",
|
|
4
4
|
"description": "ltht-react Table component.",
|
|
5
5
|
"author": "LTHT",
|
|
6
6
|
"homepage": "",
|
|
@@ -28,15 +28,15 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@emotion/react": "^11.0.0",
|
|
30
30
|
"@emotion/styled": "^11.0.0",
|
|
31
|
-
"@ltht-react/button": "^2.0.
|
|
32
|
-
"@ltht-react/icon": "^2.0.
|
|
33
|
-
"@ltht-react/menu": "^2.0.
|
|
34
|
-
"@ltht-react/styles": "^2.0.
|
|
35
|
-
"@ltht-react/types": "^2.0.
|
|
36
|
-
"@ltht-react/utils": "^2.0.
|
|
31
|
+
"@ltht-react/button": "^2.0.194",
|
|
32
|
+
"@ltht-react/icon": "^2.0.194",
|
|
33
|
+
"@ltht-react/menu": "^2.0.194",
|
|
34
|
+
"@ltht-react/styles": "^2.0.194",
|
|
35
|
+
"@ltht-react/types": "^2.0.194",
|
|
36
|
+
"@ltht-react/utils": "^2.0.194",
|
|
37
37
|
"@tanstack/react-table": "^8.10.7",
|
|
38
38
|
"react": "^18.2.0",
|
|
39
39
|
"react-uuid": "^2.0.0"
|
|
40
40
|
},
|
|
41
|
-
"gitHead": "
|
|
41
|
+
"gitHead": "2eb4b88fa2bc19baa1be9433dbe29fe1a947dc62"
|
|
42
42
|
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { FC } from 'react'
|
|
2
|
-
import styled from '@emotion/styled'
|
|
3
|
-
|
|
4
|
-
const StyledText = styled.div`
|
|
5
|
-
text-decoration: line-through;
|
|
6
|
-
color: gray;
|
|
7
|
-
`
|
|
8
|
-
|
|
9
|
-
const QuestionnaireWithdrawnTableCell: FC<WithdrawnCellProps> = ({ text }) => <StyledText>{text ?? ''}</StyledText>
|
|
10
|
-
|
|
11
|
-
export interface WithdrawnCellProps {
|
|
12
|
-
text?: string
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export default QuestionnaireWithdrawnTableCell
|
|
1
|
+
import { FC } from 'react'
|
|
2
|
+
import styled from '@emotion/styled'
|
|
3
|
+
|
|
4
|
+
const StyledText = styled.div`
|
|
5
|
+
text-decoration: line-through;
|
|
6
|
+
color: gray;
|
|
7
|
+
`
|
|
8
|
+
|
|
9
|
+
const QuestionnaireWithdrawnTableCell: FC<WithdrawnCellProps> = ({ text }) => <StyledText>{text ?? ''}</StyledText>
|
|
10
|
+
|
|
11
|
+
export interface WithdrawnCellProps {
|
|
12
|
+
text?: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default QuestionnaireWithdrawnTableCell
|
package/src/index.tsx
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import Table, { Header, DataEntity, TableData, CellProps } from './molecules/table'
|
|
2
|
-
import GenericTable from './organisms/generic-table'
|
|
3
|
-
import QuestionnaireTable from './organisms/questionnaire-table'
|
|
4
|
-
import { AdminActionsForQuestionnaire } from './organisms/questionnaire-table-methods'
|
|
5
|
-
|
|
6
|
-
export default Table
|
|
7
|
-
export { Header, TableData, DataEntity, CellProps, GenericTable, QuestionnaireTable, AdminActionsForQuestionnaire }
|
|
8
|
-
export { default as mapQuestionnaireToTableData } from './organisms/questionnaire-table-methods'
|
|
1
|
+
import Table, { Header, DataEntity, TableData, CellProps } from './molecules/table'
|
|
2
|
+
import GenericTable from './organisms/generic-table'
|
|
3
|
+
import QuestionnaireTable from './organisms/questionnaire-table'
|
|
4
|
+
import { AdminActionsForQuestionnaire } from './organisms/questionnaire-table-methods'
|
|
5
|
+
|
|
6
|
+
export default Table
|
|
7
|
+
export { Header, TableData, DataEntity, CellProps, GenericTable, QuestionnaireTable, AdminActionsForQuestionnaire }
|
|
8
|
+
export { default as mapQuestionnaireToTableData } from './organisms/questionnaire-table-methods'
|
|
@@ -1,111 +1,111 @@
|
|
|
1
|
-
import { FC, useRef } from 'react'
|
|
2
|
-
import { Button } from '@ltht-react/button'
|
|
3
|
-
import styled from '@emotion/styled'
|
|
4
|
-
import Icon, { IconButton, IconProps } from '@ltht-react/icon'
|
|
5
|
-
import ActionMenu, { ActionMenuOption } from '@ltht-react/menu'
|
|
6
|
-
import { BTN_COLOURS } from '@ltht-react/styles'
|
|
7
|
-
import { Axis } from '@ltht-react/types'
|
|
8
|
-
|
|
9
|
-
const StyledIconText = styled.span`
|
|
10
|
-
margin-left: 0.4rem;
|
|
11
|
-
`
|
|
12
|
-
const StyledActionMenuContainer = styled.div`
|
|
13
|
-
display: flex;
|
|
14
|
-
justify-content: center;
|
|
15
|
-
`
|
|
16
|
-
|
|
17
|
-
// TODO: This component is still a WIP and will be re-factored soon!
|
|
18
|
-
// May be best to split it out into different components, the important part is unifying Type used by React-Table so the mapping can be simplified
|
|
19
|
-
// It will need to facilitate the Actions list capability Jonny Dyson has requested
|
|
20
|
-
// Betters ways of handling the customComponentOverride will be considered too
|
|
21
|
-
const TableCell: FC<CellProps> = ({
|
|
22
|
-
id,
|
|
23
|
-
adminActions,
|
|
24
|
-
isButton = false,
|
|
25
|
-
text,
|
|
26
|
-
iconProps,
|
|
27
|
-
headerAxis = 'x',
|
|
28
|
-
clickHandler,
|
|
29
|
-
customComponentOverride,
|
|
30
|
-
}) => {
|
|
31
|
-
/*
|
|
32
|
-
* Ensures the action menu popup is rendered within the table’s DOM.
|
|
33
|
-
* Needed for Fullscreen API, since only elements inside the fullscreen subtree are visible.
|
|
34
|
-
* Using this ref as the portal root keeps the popup visible on top of the table in fullscreen.
|
|
35
|
-
*/
|
|
36
|
-
const actionMenuRootElementRef = useRef<HTMLDivElement>(null)
|
|
37
|
-
|
|
38
|
-
if (customComponentOverride) {
|
|
39
|
-
return customComponentOverride
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
if (adminActions) {
|
|
43
|
-
if (adminActions.length === 0) {
|
|
44
|
-
return <></>
|
|
45
|
-
}
|
|
46
|
-
return (
|
|
47
|
-
<StyledActionMenuContainer ref={actionMenuRootElementRef}>
|
|
48
|
-
<ActionMenu
|
|
49
|
-
root={actionMenuRootElementRef}
|
|
50
|
-
id={`${`${id ?? ''}-`}action-menu-button`}
|
|
51
|
-
actions={adminActions}
|
|
52
|
-
menuButtonOptions={{
|
|
53
|
-
type: 'button',
|
|
54
|
-
text: '',
|
|
55
|
-
buttonProps: {
|
|
56
|
-
styling: {
|
|
57
|
-
buttonStyle: 'standard',
|
|
58
|
-
padding: headerAxis === 'x' ? '0.3rem 0.5rem' : '0.15rem 0.3rem',
|
|
59
|
-
},
|
|
60
|
-
icon: (
|
|
61
|
-
<Icon {...{ type: headerAxis === 'x' ? 'ellipsis-vertical' : 'ellipsis-horizontal', size: 'medium' }} />
|
|
62
|
-
),
|
|
63
|
-
iconPlacement: 'center',
|
|
64
|
-
color: `${BTN_COLOURS.DANGER.VALUE}`,
|
|
65
|
-
},
|
|
66
|
-
}}
|
|
67
|
-
style={{
|
|
68
|
-
width: 'fit-content',
|
|
69
|
-
}}
|
|
70
|
-
/>
|
|
71
|
-
</StyledActionMenuContainer>
|
|
72
|
-
)
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if (isButton) {
|
|
76
|
-
return <Button id={id} value={text} icon={iconProps && <Icon {...iconProps} />} onClick={clickHandler} />
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if (clickHandler && iconProps) {
|
|
80
|
-
return <IconButton id={id} iconProps={iconProps} text={text} onClick={clickHandler} />
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (iconProps) {
|
|
84
|
-
return (
|
|
85
|
-
<>
|
|
86
|
-
<Icon {...iconProps} />
|
|
87
|
-
{text && <StyledIconText>{text}</StyledIconText>}
|
|
88
|
-
</>
|
|
89
|
-
)
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (text) {
|
|
93
|
-
return <div id={id}>{text ?? ''}</div>
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return <></>
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export interface CellProps {
|
|
100
|
-
adminActions?: ActionMenuOption[]
|
|
101
|
-
isButton?: boolean
|
|
102
|
-
text?: string
|
|
103
|
-
iconProps?: IconProps
|
|
104
|
-
clickHandler?: React.MouseEventHandler<HTMLButtonElement>
|
|
105
|
-
customComponentOverride?: JSX.Element
|
|
106
|
-
parentStyle?: React.CSSProperties
|
|
107
|
-
headerAxis?: Axis
|
|
108
|
-
id?: string
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
export default TableCell
|
|
1
|
+
import { FC, useRef } from 'react'
|
|
2
|
+
import { Button } from '@ltht-react/button'
|
|
3
|
+
import styled from '@emotion/styled'
|
|
4
|
+
import Icon, { IconButton, IconProps } from '@ltht-react/icon'
|
|
5
|
+
import ActionMenu, { ActionMenuOption } from '@ltht-react/menu'
|
|
6
|
+
import { BTN_COLOURS } from '@ltht-react/styles'
|
|
7
|
+
import { Axis } from '@ltht-react/types'
|
|
8
|
+
|
|
9
|
+
const StyledIconText = styled.span`
|
|
10
|
+
margin-left: 0.4rem;
|
|
11
|
+
`
|
|
12
|
+
const StyledActionMenuContainer = styled.div`
|
|
13
|
+
display: flex;
|
|
14
|
+
justify-content: center;
|
|
15
|
+
`
|
|
16
|
+
|
|
17
|
+
// TODO: This component is still a WIP and will be re-factored soon!
|
|
18
|
+
// May be best to split it out into different components, the important part is unifying Type used by React-Table so the mapping can be simplified
|
|
19
|
+
// It will need to facilitate the Actions list capability Jonny Dyson has requested
|
|
20
|
+
// Betters ways of handling the customComponentOverride will be considered too
|
|
21
|
+
const TableCell: FC<CellProps> = ({
|
|
22
|
+
id,
|
|
23
|
+
adminActions,
|
|
24
|
+
isButton = false,
|
|
25
|
+
text,
|
|
26
|
+
iconProps,
|
|
27
|
+
headerAxis = 'x',
|
|
28
|
+
clickHandler,
|
|
29
|
+
customComponentOverride,
|
|
30
|
+
}) => {
|
|
31
|
+
/*
|
|
32
|
+
* Ensures the action menu popup is rendered within the table’s DOM.
|
|
33
|
+
* Needed for Fullscreen API, since only elements inside the fullscreen subtree are visible.
|
|
34
|
+
* Using this ref as the portal root keeps the popup visible on top of the table in fullscreen.
|
|
35
|
+
*/
|
|
36
|
+
const actionMenuRootElementRef = useRef<HTMLDivElement>(null)
|
|
37
|
+
|
|
38
|
+
if (customComponentOverride) {
|
|
39
|
+
return customComponentOverride
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (adminActions) {
|
|
43
|
+
if (adminActions.length === 0) {
|
|
44
|
+
return <></>
|
|
45
|
+
}
|
|
46
|
+
return (
|
|
47
|
+
<StyledActionMenuContainer ref={actionMenuRootElementRef}>
|
|
48
|
+
<ActionMenu
|
|
49
|
+
root={actionMenuRootElementRef}
|
|
50
|
+
id={`${`${id ?? ''}-`}action-menu-button`}
|
|
51
|
+
actions={adminActions}
|
|
52
|
+
menuButtonOptions={{
|
|
53
|
+
type: 'button',
|
|
54
|
+
text: '',
|
|
55
|
+
buttonProps: {
|
|
56
|
+
styling: {
|
|
57
|
+
buttonStyle: 'standard',
|
|
58
|
+
padding: headerAxis === 'x' ? '0.3rem 0.5rem' : '0.15rem 0.3rem',
|
|
59
|
+
},
|
|
60
|
+
icon: (
|
|
61
|
+
<Icon {...{ type: headerAxis === 'x' ? 'ellipsis-vertical' : 'ellipsis-horizontal', size: 'medium' }} />
|
|
62
|
+
),
|
|
63
|
+
iconPlacement: 'center',
|
|
64
|
+
color: `${BTN_COLOURS.DANGER.VALUE}`,
|
|
65
|
+
},
|
|
66
|
+
}}
|
|
67
|
+
style={{
|
|
68
|
+
width: 'fit-content',
|
|
69
|
+
}}
|
|
70
|
+
/>
|
|
71
|
+
</StyledActionMenuContainer>
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (isButton) {
|
|
76
|
+
return <Button id={id} value={text} icon={iconProps && <Icon {...iconProps} />} onClick={clickHandler} />
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (clickHandler && iconProps) {
|
|
80
|
+
return <IconButton id={id} iconProps={iconProps} text={text} onClick={clickHandler} />
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (iconProps) {
|
|
84
|
+
return (
|
|
85
|
+
<>
|
|
86
|
+
<Icon {...iconProps} />
|
|
87
|
+
{text && <StyledIconText>{text}</StyledIconText>}
|
|
88
|
+
</>
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (text) {
|
|
93
|
+
return <div id={id}>{text ?? ''}</div>
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return <></>
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface CellProps {
|
|
100
|
+
adminActions?: ActionMenuOption[]
|
|
101
|
+
isButton?: boolean
|
|
102
|
+
text?: string
|
|
103
|
+
iconProps?: IconProps
|
|
104
|
+
clickHandler?: React.MouseEventHandler<HTMLButtonElement>
|
|
105
|
+
customComponentOverride?: JSX.Element
|
|
106
|
+
parentStyle?: React.CSSProperties
|
|
107
|
+
headerAxis?: Axis
|
|
108
|
+
id?: string
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export default TableCell
|
|
@@ -1,123 +1,123 @@
|
|
|
1
|
-
import Icon from '@ltht-react/icon'
|
|
2
|
-
import { flexRender, Header as ReactTableHeader, Table } from '@tanstack/react-table'
|
|
3
|
-
import { HTMLAttributes, useMemo, useRef } from 'react'
|
|
4
|
-
import { calculateStaticColumnOffset } from './table-methods'
|
|
5
|
-
import {
|
|
6
|
-
StyledNextPageButtonContainer,
|
|
7
|
-
StyledSpinnerContainer,
|
|
8
|
-
StyledTable,
|
|
9
|
-
StyledTableRow,
|
|
10
|
-
StyledTableData,
|
|
11
|
-
StyledTHead,
|
|
12
|
-
} from './table-styled-components'
|
|
13
|
-
import useDimensionsRef from './useDimensionRef'
|
|
14
|
-
import { CellProps } from './table-cell'
|
|
15
|
-
import { ITableConfig } from './table'
|
|
16
|
-
import TableHeader from './table-header'
|
|
17
|
-
|
|
18
|
-
const TableComponent = <T,>({ table, staticColumns = 0, headerAxis, ...rest }: ITableHeadProps<T>): JSX.Element => {
|
|
19
|
-
const tableIdPrefix = rest.id ? `${rest.id}-` : ''
|
|
20
|
-
|
|
21
|
-
const firstColumn = useRef(null)
|
|
22
|
-
const secondColumn = useRef(null)
|
|
23
|
-
const tableElement = useRef(null)
|
|
24
|
-
const { width: firstColumnWidth } = useDimensionsRef(firstColumn, tableElement)
|
|
25
|
-
const { width: secondColumnWidth } = useDimensionsRef(secondColumn, tableElement)
|
|
26
|
-
|
|
27
|
-
const usingExpanderColumn = table.getHeaderGroups().some((x) => x.headers.some((h) => h.column.id === 'expander'))
|
|
28
|
-
const totalStaticColumns = useMemo(
|
|
29
|
-
() => (usingExpanderColumn ? staticColumns + 1 : staticColumns),
|
|
30
|
-
[usingExpanderColumn, staticColumns]
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
const getHeaderColumn = <TData, TValue>(header: ReactTableHeader<TData, TValue>, headerIndex: number) => {
|
|
34
|
-
const stickyWidth = calculateStaticColumnOffset(
|
|
35
|
-
headerIndex,
|
|
36
|
-
totalStaticColumns,
|
|
37
|
-
firstColumnWidth,
|
|
38
|
-
secondColumnWidth
|
|
39
|
-
)
|
|
40
|
-
const headerProps = {
|
|
41
|
-
header,
|
|
42
|
-
stickyWidth,
|
|
43
|
-
}
|
|
44
|
-
switch (headerIndex) {
|
|
45
|
-
case 0:
|
|
46
|
-
return <TableHeader key={header.id} tableId={tableIdPrefix} ref={firstColumn} {...headerProps} />
|
|
47
|
-
case 1:
|
|
48
|
-
return <TableHeader key={header.id} tableId={tableIdPrefix} ref={secondColumn} {...headerProps} />
|
|
49
|
-
default:
|
|
50
|
-
return <TableHeader key={header.id} tableId={tableIdPrefix} {...headerProps} />
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return (
|
|
55
|
-
<StyledTable ref={tableElement} {...rest}>
|
|
56
|
-
<StyledTHead>
|
|
57
|
-
{table.getHeaderGroups().map((headerGroup) => (
|
|
58
|
-
<tr key={headerGroup.id} id={`${tableIdPrefix}${headerGroup.id}`} role="row">
|
|
59
|
-
{headerGroup.headers.map((header, headerIndex) => getHeaderColumn(header, headerIndex))}
|
|
60
|
-
</tr>
|
|
61
|
-
))}
|
|
62
|
-
</StyledTHead>
|
|
63
|
-
<tbody>
|
|
64
|
-
{table.getRowModel().rows.map((row) => (
|
|
65
|
-
<StyledTableRow tableHeaderAxis={headerAxis} key={row.id} role="row">
|
|
66
|
-
{row.getVisibleCells().map((cell, cellIdx) => (
|
|
67
|
-
<StyledTableData
|
|
68
|
-
tableHeaderAxis={headerAxis}
|
|
69
|
-
stickyWidth={calculateStaticColumnOffset(
|
|
70
|
-
cellIdx,
|
|
71
|
-
totalStaticColumns,
|
|
72
|
-
firstColumnWidth,
|
|
73
|
-
secondColumnWidth
|
|
74
|
-
)}
|
|
75
|
-
key={cell.id}
|
|
76
|
-
id={`${tableIdPrefix}${cell.id}`}
|
|
77
|
-
role="cell"
|
|
78
|
-
style={(cell.getValue() as CellProps)?.parentStyle}
|
|
79
|
-
>
|
|
80
|
-
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
|
81
|
-
</StyledTableData>
|
|
82
|
-
))}
|
|
83
|
-
</StyledTableRow>
|
|
84
|
-
))}
|
|
85
|
-
</tbody>
|
|
86
|
-
</StyledTable>
|
|
87
|
-
)
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const TableNavigationButton = ({ position, hidden, clickHandler }: ITableNavButtonProps) => (
|
|
91
|
-
<StyledNextPageButtonContainer
|
|
92
|
-
role="button"
|
|
93
|
-
elementPosition={position}
|
|
94
|
-
onClick={() => clickHandler()}
|
|
95
|
-
hidden={hidden}
|
|
96
|
-
>
|
|
97
|
-
<Icon type="chevron" direction={position === 'bottom' ? 'down' : 'right'} size="medium" />
|
|
98
|
-
</StyledNextPageButtonContainer>
|
|
99
|
-
)
|
|
100
|
-
|
|
101
|
-
const TableSpinner = ({ position, hidden }: ITableSpinnerProps) => (
|
|
102
|
-
<StyledSpinnerContainer elementPosition={position} hidden={hidden}>
|
|
103
|
-
<Icon type="spinner" size="medium" title="Loading..." />
|
|
104
|
-
</StyledSpinnerContainer>
|
|
105
|
-
)
|
|
106
|
-
|
|
107
|
-
interface ITableNavButtonProps {
|
|
108
|
-
position: 'bottom' | 'right'
|
|
109
|
-
hidden: boolean
|
|
110
|
-
clickHandler: () => void
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
interface ITableSpinnerProps {
|
|
114
|
-
position: 'bottom' | 'right'
|
|
115
|
-
hidden: boolean
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
interface ITableHeadProps<T> extends ITableConfig, HTMLAttributes<HTMLTableElement> {
|
|
119
|
-
table: Table<T>
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
export default TableComponent
|
|
123
|
-
export { TableNavigationButton, TableSpinner }
|
|
1
|
+
import Icon from '@ltht-react/icon'
|
|
2
|
+
import { flexRender, Header as ReactTableHeader, Table } from '@tanstack/react-table'
|
|
3
|
+
import { HTMLAttributes, useMemo, useRef } from 'react'
|
|
4
|
+
import { calculateStaticColumnOffset } from './table-methods'
|
|
5
|
+
import {
|
|
6
|
+
StyledNextPageButtonContainer,
|
|
7
|
+
StyledSpinnerContainer,
|
|
8
|
+
StyledTable,
|
|
9
|
+
StyledTableRow,
|
|
10
|
+
StyledTableData,
|
|
11
|
+
StyledTHead,
|
|
12
|
+
} from './table-styled-components'
|
|
13
|
+
import useDimensionsRef from './useDimensionRef'
|
|
14
|
+
import { CellProps } from './table-cell'
|
|
15
|
+
import { ITableConfig } from './table'
|
|
16
|
+
import TableHeader from './table-header'
|
|
17
|
+
|
|
18
|
+
const TableComponent = <T,>({ table, staticColumns = 0, headerAxis, ...rest }: ITableHeadProps<T>): JSX.Element => {
|
|
19
|
+
const tableIdPrefix = rest.id ? `${rest.id}-` : ''
|
|
20
|
+
|
|
21
|
+
const firstColumn = useRef(null)
|
|
22
|
+
const secondColumn = useRef(null)
|
|
23
|
+
const tableElement = useRef(null)
|
|
24
|
+
const { width: firstColumnWidth } = useDimensionsRef(firstColumn, tableElement)
|
|
25
|
+
const { width: secondColumnWidth } = useDimensionsRef(secondColumn, tableElement)
|
|
26
|
+
|
|
27
|
+
const usingExpanderColumn = table.getHeaderGroups().some((x) => x.headers.some((h) => h.column.id === 'expander'))
|
|
28
|
+
const totalStaticColumns = useMemo(
|
|
29
|
+
() => (usingExpanderColumn ? staticColumns + 1 : staticColumns),
|
|
30
|
+
[usingExpanderColumn, staticColumns]
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
const getHeaderColumn = <TData, TValue>(header: ReactTableHeader<TData, TValue>, headerIndex: number) => {
|
|
34
|
+
const stickyWidth = calculateStaticColumnOffset(
|
|
35
|
+
headerIndex,
|
|
36
|
+
totalStaticColumns,
|
|
37
|
+
firstColumnWidth,
|
|
38
|
+
secondColumnWidth
|
|
39
|
+
)
|
|
40
|
+
const headerProps = {
|
|
41
|
+
header,
|
|
42
|
+
stickyWidth,
|
|
43
|
+
}
|
|
44
|
+
switch (headerIndex) {
|
|
45
|
+
case 0:
|
|
46
|
+
return <TableHeader key={header.id} tableId={tableIdPrefix} ref={firstColumn} {...headerProps} />
|
|
47
|
+
case 1:
|
|
48
|
+
return <TableHeader key={header.id} tableId={tableIdPrefix} ref={secondColumn} {...headerProps} />
|
|
49
|
+
default:
|
|
50
|
+
return <TableHeader key={header.id} tableId={tableIdPrefix} {...headerProps} />
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<StyledTable ref={tableElement} {...rest}>
|
|
56
|
+
<StyledTHead>
|
|
57
|
+
{table.getHeaderGroups().map((headerGroup) => (
|
|
58
|
+
<tr key={headerGroup.id} id={`${tableIdPrefix}${headerGroup.id}`} role="row">
|
|
59
|
+
{headerGroup.headers.map((header, headerIndex) => getHeaderColumn(header, headerIndex))}
|
|
60
|
+
</tr>
|
|
61
|
+
))}
|
|
62
|
+
</StyledTHead>
|
|
63
|
+
<tbody>
|
|
64
|
+
{table.getRowModel().rows.map((row) => (
|
|
65
|
+
<StyledTableRow tableHeaderAxis={headerAxis} key={row.id} role="row">
|
|
66
|
+
{row.getVisibleCells().map((cell, cellIdx) => (
|
|
67
|
+
<StyledTableData
|
|
68
|
+
tableHeaderAxis={headerAxis}
|
|
69
|
+
stickyWidth={calculateStaticColumnOffset(
|
|
70
|
+
cellIdx,
|
|
71
|
+
totalStaticColumns,
|
|
72
|
+
firstColumnWidth,
|
|
73
|
+
secondColumnWidth
|
|
74
|
+
)}
|
|
75
|
+
key={cell.id}
|
|
76
|
+
id={`${tableIdPrefix}${cell.id}`}
|
|
77
|
+
role="cell"
|
|
78
|
+
style={(cell.getValue() as CellProps)?.parentStyle}
|
|
79
|
+
>
|
|
80
|
+
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
|
81
|
+
</StyledTableData>
|
|
82
|
+
))}
|
|
83
|
+
</StyledTableRow>
|
|
84
|
+
))}
|
|
85
|
+
</tbody>
|
|
86
|
+
</StyledTable>
|
|
87
|
+
)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const TableNavigationButton = ({ position, hidden, clickHandler }: ITableNavButtonProps) => (
|
|
91
|
+
<StyledNextPageButtonContainer
|
|
92
|
+
role="button"
|
|
93
|
+
elementPosition={position}
|
|
94
|
+
onClick={() => clickHandler()}
|
|
95
|
+
hidden={hidden}
|
|
96
|
+
>
|
|
97
|
+
<Icon type="chevron" direction={position === 'bottom' ? 'down' : 'right'} size="medium" />
|
|
98
|
+
</StyledNextPageButtonContainer>
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
const TableSpinner = ({ position, hidden }: ITableSpinnerProps) => (
|
|
102
|
+
<StyledSpinnerContainer elementPosition={position} hidden={hidden}>
|
|
103
|
+
<Icon type="spinner" size="medium" title="Loading..." />
|
|
104
|
+
</StyledSpinnerContainer>
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
interface ITableNavButtonProps {
|
|
108
|
+
position: 'bottom' | 'right'
|
|
109
|
+
hidden: boolean
|
|
110
|
+
clickHandler: () => void
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
interface ITableSpinnerProps {
|
|
114
|
+
position: 'bottom' | 'right'
|
|
115
|
+
hidden: boolean
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
interface ITableHeadProps<T> extends ITableConfig, HTMLAttributes<HTMLTableElement> {
|
|
119
|
+
table: Table<T>
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export default TableComponent
|
|
123
|
+
export { TableNavigationButton, TableSpinner }
|
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
import { forwardRef, Ref } from 'react'
|
|
2
|
-
import { flexRender, Header as ReactTableHeader } from '@tanstack/react-table'
|
|
3
|
-
import { StyledTableHeader } from './table-styled-components'
|
|
4
|
-
|
|
5
|
-
interface TableHeaderProps<TData, TValue> {
|
|
6
|
-
tableId?: string
|
|
7
|
-
header: ReactTableHeader<TData, TValue>
|
|
8
|
-
stickyWidth?: number
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export const Wrapper = <TData, TValue>(
|
|
12
|
-
{ tableId, header, stickyWidth }: TableHeaderProps<TData, TValue>,
|
|
13
|
-
ref?: Ref<HTMLTableCellElement>
|
|
14
|
-
) => (
|
|
15
|
-
<StyledTableHeader
|
|
16
|
-
id={`${tableId}${header.id}`}
|
|
17
|
-
ref={ref}
|
|
18
|
-
stickyWidth={stickyWidth}
|
|
19
|
-
colSpan={header.colSpan}
|
|
20
|
-
role="columnheader"
|
|
21
|
-
{...(header.column.id !== 'expander'
|
|
22
|
-
? {
|
|
23
|
-
style: {
|
|
24
|
-
cursor: header.column.getCanSort() ? 'pointer' : '',
|
|
25
|
-
},
|
|
26
|
-
onClick: header.column.getToggleSortingHandler(),
|
|
27
|
-
}
|
|
28
|
-
: {})}
|
|
29
|
-
>
|
|
30
|
-
{header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}
|
|
31
|
-
</StyledTableHeader>
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
const TableHeader = forwardRef(Wrapper) as <TData, TValue>(
|
|
35
|
-
props: TableHeaderProps<TData, TValue> & { ref?: Ref<HTMLTableCellElement> }
|
|
36
|
-
) => ReturnType<typeof Wrapper>
|
|
37
|
-
|
|
38
|
-
export default TableHeader
|
|
1
|
+
import { forwardRef, Ref } from 'react'
|
|
2
|
+
import { flexRender, Header as ReactTableHeader } from '@tanstack/react-table'
|
|
3
|
+
import { StyledTableHeader } from './table-styled-components'
|
|
4
|
+
|
|
5
|
+
interface TableHeaderProps<TData, TValue> {
|
|
6
|
+
tableId?: string
|
|
7
|
+
header: ReactTableHeader<TData, TValue>
|
|
8
|
+
stickyWidth?: number
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const Wrapper = <TData, TValue>(
|
|
12
|
+
{ tableId, header, stickyWidth }: TableHeaderProps<TData, TValue>,
|
|
13
|
+
ref?: Ref<HTMLTableCellElement>
|
|
14
|
+
) => (
|
|
15
|
+
<StyledTableHeader
|
|
16
|
+
id={`${tableId}${header.id}`}
|
|
17
|
+
ref={ref}
|
|
18
|
+
stickyWidth={stickyWidth}
|
|
19
|
+
colSpan={header.colSpan}
|
|
20
|
+
role="columnheader"
|
|
21
|
+
{...(header.column.id !== 'expander'
|
|
22
|
+
? {
|
|
23
|
+
style: {
|
|
24
|
+
cursor: header.column.getCanSort() ? 'pointer' : '',
|
|
25
|
+
},
|
|
26
|
+
onClick: header.column.getToggleSortingHandler(),
|
|
27
|
+
}
|
|
28
|
+
: {})}
|
|
29
|
+
>
|
|
30
|
+
{header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}
|
|
31
|
+
</StyledTableHeader>
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
const TableHeader = forwardRef(Wrapper) as <TData, TValue>(
|
|
35
|
+
props: TableHeaderProps<TData, TValue> & { ref?: Ref<HTMLTableCellElement> }
|
|
36
|
+
) => ReturnType<typeof Wrapper>
|
|
37
|
+
|
|
38
|
+
export default TableHeader
|