@spaced-out/ui-design-system 0.0.37 → 0.0.39
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/.cspell/custom-words.txt +2 -0
- package/CHANGELOG.md +14 -0
- package/design-tokens/size/base-size.json +6 -0
- package/lib/components/Checkbox/Checkbox.js.flow +5 -0
- package/lib/components/Checkbox/Checkbox.module.css +1 -1
- package/lib/components/Menu/Menu.js.flow +1 -1
- package/lib/components/Menu/MenuOptionButton.js +3 -2
- package/lib/components/Menu/MenuOptionButton.js.flow +15 -10
- package/lib/components/Table/Cell.js +114 -0
- package/lib/components/Table/Cell.js.flow +123 -0
- package/lib/components/Table/Row.js +96 -0
- package/lib/components/Table/Row.js.flow +145 -0
- package/lib/components/Table/StaticTable.js +124 -0
- package/lib/components/Table/StaticTable.js.flow +170 -0
- package/lib/components/Table/Table.js +61 -0
- package/lib/components/Table/Table.js.flow +101 -0
- package/lib/components/Table/Table.module.css +252 -0
- package/lib/components/Table/TableHeader.js +146 -0
- package/lib/components/Table/TableHeader.js.flow +236 -0
- package/lib/components/Table/hooks.js +68 -0
- package/lib/components/Table/hooks.js.flow +91 -0
- package/lib/components/Table/index.js +63 -0
- package/lib/components/Table/index.js.flow +14 -0
- package/lib/styles/variables/_size.css +4 -0
- package/lib/styles/variables/_size.js +6 -2
- package/lib/styles/variables/_size.js.flow +4 -0
- package/lib/utils/makeClassNameComponent.js +1 -1
- package/lib/utils/makeClassNameComponent.js.flow +1 -1
- package/package.json +4 -3
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.BasicTableBody = exports.BasicTable = void 0;
|
|
7
|
+
exports.StaticTable = StaticTable;
|
|
8
|
+
var React = _interopRequireWildcard(require("react"));
|
|
9
|
+
var _get = _interopRequireDefault(require("lodash/get"));
|
|
10
|
+
var _xor = _interopRequireDefault(require("lodash/xor"));
|
|
11
|
+
var _makeClassNameComponent = require("../../utils/makeClassNameComponent");
|
|
12
|
+
var _Row = require("./Row");
|
|
13
|
+
var _TableHeader = require("./TableHeader");
|
|
14
|
+
var _TableModule = _interopRequireDefault(require("./Table.module.css"));
|
|
15
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
16
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
17
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
18
|
+
|
|
19
|
+
const BasicTable = (0, _makeClassNameComponent.makeClassNameComponent)(_TableModule.default.defaultTable, 'table');
|
|
20
|
+
exports.BasicTable = BasicTable;
|
|
21
|
+
const BasicTableBody = (0, _makeClassNameComponent.makeClassNameComponent)(_TableModule.default.defaultTableBody, 'tbody');
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* A Static Default Table.
|
|
25
|
+
*
|
|
26
|
+
* Our
|
|
27
|
+
*/
|
|
28
|
+
exports.BasicTableBody = BasicTableBody;
|
|
29
|
+
function StaticTable(props) {
|
|
30
|
+
const {
|
|
31
|
+
className,
|
|
32
|
+
Row,
|
|
33
|
+
entries,
|
|
34
|
+
extras,
|
|
35
|
+
rowKeys,
|
|
36
|
+
headers,
|
|
37
|
+
showHeader = true,
|
|
38
|
+
tableHeaderClassName,
|
|
39
|
+
sortable,
|
|
40
|
+
defaultSortKey,
|
|
41
|
+
defaultSortDirection = 'original',
|
|
42
|
+
onSort,
|
|
43
|
+
handleSortClick,
|
|
44
|
+
sortKey,
|
|
45
|
+
sortDirection,
|
|
46
|
+
selectedKeys,
|
|
47
|
+
onSelect,
|
|
48
|
+
isLoading,
|
|
49
|
+
idName = 'id',
|
|
50
|
+
emptyText,
|
|
51
|
+
disabled,
|
|
52
|
+
customLoader
|
|
53
|
+
} = props;
|
|
54
|
+
|
|
55
|
+
// this is a fallback and honestly probably doesn't need the
|
|
56
|
+
// memo'ing
|
|
57
|
+
const mappedKeys = React.useMemo(() => rowKeys ?? entries.map(e => (0, _get.default)(e, idName)), [entries, idName, rowKeys]);
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* this function is also used to decide weather to show checkbox in header or not. so it's value is undefined incase selectedKeys is not there.
|
|
61
|
+
*/
|
|
62
|
+
|
|
63
|
+
const handleHeaderCheckboxClick = selectedKeys ? _ref => {
|
|
64
|
+
let {
|
|
65
|
+
checked
|
|
66
|
+
} = _ref;
|
|
67
|
+
let selectedRowIds = [];
|
|
68
|
+
if (selectedKeys) {
|
|
69
|
+
if (checked === true) {
|
|
70
|
+
selectedRowIds = entries.map(singleRowObj => (0, _get.default)(singleRowObj, idName));
|
|
71
|
+
}
|
|
72
|
+
onSelect?.(selectedRowIds);
|
|
73
|
+
}
|
|
74
|
+
} : undefined;
|
|
75
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
76
|
+
className: _TableModule.default.tableContainer,
|
|
77
|
+
"data-id": "table-wrap"
|
|
78
|
+
}, /*#__PURE__*/React.createElement(BasicTable, {
|
|
79
|
+
"data-id": "basic-table",
|
|
80
|
+
className: className
|
|
81
|
+
}, showHeader && /*#__PURE__*/React.createElement(_TableHeader.DefaultTableHeader, {
|
|
82
|
+
tableHeaderClassName: tableHeaderClassName,
|
|
83
|
+
className: tableHeaderClassName,
|
|
84
|
+
sortable: sortable,
|
|
85
|
+
columns: headers,
|
|
86
|
+
handleSortClick: handleSortClick,
|
|
87
|
+
sortKey: sortKey,
|
|
88
|
+
sortDirection: sortDirection,
|
|
89
|
+
disabled: disabled,
|
|
90
|
+
handleCheckboxClick: handleHeaderCheckboxClick,
|
|
91
|
+
checked: selectedKeys == null || selectedKeys.length === 0 ? 'false' : selectedKeys.length < entries.length ? 'mixed' : 'true'
|
|
92
|
+
}), /*#__PURE__*/React.createElement(BasicTableBody, null, isLoading || !entries.length ? /*#__PURE__*/React.createElement(_Row.EmptyRow, {
|
|
93
|
+
isLoading: isLoading,
|
|
94
|
+
emptyText: emptyText,
|
|
95
|
+
headersLength: handleHeaderCheckboxClick ? headers.length + 1 : headers.length,
|
|
96
|
+
customLoader: customLoader
|
|
97
|
+
}) : mappedKeys.map(key => {
|
|
98
|
+
const data = entries.find(e => (0, _get.default)(e, idName) === key);
|
|
99
|
+
if (data == null) {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
data;
|
|
103
|
+
const selected = selectedKeys?.includes((0, _get.default)(data, idName)) ?? undefined;
|
|
104
|
+
return Row ? /*#__PURE__*/React.createElement(Row, {
|
|
105
|
+
key: key,
|
|
106
|
+
data: data,
|
|
107
|
+
headers: headers
|
|
108
|
+
// extras and rowKeys are both 'optional'
|
|
109
|
+
,
|
|
110
|
+
extras: extras,
|
|
111
|
+
sortedKeys: rowKeys ?? mappedKeys,
|
|
112
|
+
selected: selected,
|
|
113
|
+
disabled: disabled
|
|
114
|
+
}) : /*#__PURE__*/React.createElement(_Row.DefaultRow, {
|
|
115
|
+
key: key,
|
|
116
|
+
data: data,
|
|
117
|
+
extras: extras,
|
|
118
|
+
headers: headers,
|
|
119
|
+
selected: selected,
|
|
120
|
+
onSelect: selectedKeys != null ? _v => onSelect?.((0, _xor.default)(selectedKeys ?? [], [key])) : undefined,
|
|
121
|
+
disabled: disabled
|
|
122
|
+
});
|
|
123
|
+
}))));
|
|
124
|
+
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
// @flow strict
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import get from 'lodash/get';
|
|
5
|
+
import xor from 'lodash/xor';
|
|
6
|
+
|
|
7
|
+
import type {ClassNameComponent} from '../../utils/makeClassNameComponent';
|
|
8
|
+
import {makeClassNameComponent} from '../../utils/makeClassNameComponent';
|
|
9
|
+
|
|
10
|
+
import type {SortDirection} from './hooks';
|
|
11
|
+
import {DefaultRow, EmptyRow} from './Row';
|
|
12
|
+
import type {GenericObject, TableProps} from './Table';
|
|
13
|
+
import {DefaultTableHeader} from './TableHeader';
|
|
14
|
+
|
|
15
|
+
import css from './Table.module.css';
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
export const BasicTable: ClassNameComponent<'table'> = makeClassNameComponent(
|
|
19
|
+
css.defaultTable,
|
|
20
|
+
'table',
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
export const BasicTableBody: ClassNameComponent<'tbody'> =
|
|
24
|
+
makeClassNameComponent(css.defaultTableBody, 'tbody');
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* A Static Default Table.
|
|
28
|
+
*
|
|
29
|
+
* Our
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
export function StaticTable<Data: GenericObject, Extras: GenericObject>(props: {
|
|
33
|
+
...TableProps<Data, Extras>,
|
|
34
|
+
handleSortClick?: (sortKey: string) => mixed,
|
|
35
|
+
sortKey?: string,
|
|
36
|
+
sortDirection?: SortDirection,
|
|
37
|
+
rowKeys?: string[],
|
|
38
|
+
}): React.Node {
|
|
39
|
+
const {
|
|
40
|
+
className,
|
|
41
|
+
|
|
42
|
+
Row,
|
|
43
|
+
|
|
44
|
+
entries,
|
|
45
|
+
extras,
|
|
46
|
+
rowKeys,
|
|
47
|
+
|
|
48
|
+
headers,
|
|
49
|
+
showHeader = true,
|
|
50
|
+
tableHeaderClassName,
|
|
51
|
+
|
|
52
|
+
sortable,
|
|
53
|
+
defaultSortKey,
|
|
54
|
+
defaultSortDirection = 'original',
|
|
55
|
+
onSort,
|
|
56
|
+
handleSortClick,
|
|
57
|
+
sortKey,
|
|
58
|
+
sortDirection,
|
|
59
|
+
selectedKeys,
|
|
60
|
+
onSelect,
|
|
61
|
+
|
|
62
|
+
isLoading,
|
|
63
|
+
idName = 'id',
|
|
64
|
+
emptyText,
|
|
65
|
+
disabled,
|
|
66
|
+
customLoader,
|
|
67
|
+
} = props;
|
|
68
|
+
|
|
69
|
+
// this is a fallback and honestly probably doesn't need the
|
|
70
|
+
// memo'ing
|
|
71
|
+
const mappedKeys = React.useMemo(
|
|
72
|
+
() => rowKeys ?? entries.map((e) => get(e, idName)),
|
|
73
|
+
[entries, idName, rowKeys],
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* this function is also used to decide weather to show checkbox in header or not. so it's value is undefined incase selectedKeys is not there.
|
|
78
|
+
*/
|
|
79
|
+
|
|
80
|
+
const handleHeaderCheckboxClick = selectedKeys
|
|
81
|
+
? ({checked}: {value: string, checked: boolean}) => {
|
|
82
|
+
let selectedRowIds = [];
|
|
83
|
+
if (selectedKeys) {
|
|
84
|
+
if (checked === true) {
|
|
85
|
+
selectedRowIds = entries.map((singleRowObj) =>
|
|
86
|
+
get(singleRowObj, idName),
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
onSelect?.(selectedRowIds);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
: undefined;
|
|
93
|
+
|
|
94
|
+
return (
|
|
95
|
+
<div className={css.tableContainer} data-id="table-wrap">
|
|
96
|
+
<BasicTable data-id="basic-table" className={className}>
|
|
97
|
+
{showHeader && (
|
|
98
|
+
<DefaultTableHeader
|
|
99
|
+
tableHeaderClassName={tableHeaderClassName}
|
|
100
|
+
className={tableHeaderClassName}
|
|
101
|
+
sortable={sortable}
|
|
102
|
+
columns={headers}
|
|
103
|
+
handleSortClick={handleSortClick}
|
|
104
|
+
sortKey={sortKey}
|
|
105
|
+
sortDirection={sortDirection}
|
|
106
|
+
disabled={disabled}
|
|
107
|
+
handleCheckboxClick={handleHeaderCheckboxClick}
|
|
108
|
+
checked={
|
|
109
|
+
selectedKeys == null || selectedKeys.length === 0
|
|
110
|
+
? 'false'
|
|
111
|
+
: selectedKeys.length < entries.length
|
|
112
|
+
? 'mixed'
|
|
113
|
+
: 'true'
|
|
114
|
+
}
|
|
115
|
+
/>
|
|
116
|
+
)}
|
|
117
|
+
|
|
118
|
+
<BasicTableBody>
|
|
119
|
+
{isLoading || !entries.length ? (
|
|
120
|
+
<EmptyRow
|
|
121
|
+
isLoading={isLoading}
|
|
122
|
+
emptyText={emptyText}
|
|
123
|
+
headersLength={
|
|
124
|
+
handleHeaderCheckboxClick ? headers.length + 1 : headers.length
|
|
125
|
+
}
|
|
126
|
+
customLoader={customLoader}
|
|
127
|
+
/>
|
|
128
|
+
) : (
|
|
129
|
+
mappedKeys.map((key) => {
|
|
130
|
+
const data = entries.find((e) => get(e, idName) === key);
|
|
131
|
+
if (data == null) {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
(data: Data);
|
|
135
|
+
const selected =
|
|
136
|
+
selectedKeys?.includes(get(data, idName)) ?? undefined;
|
|
137
|
+
|
|
138
|
+
return Row ? (
|
|
139
|
+
<Row
|
|
140
|
+
key={key}
|
|
141
|
+
data={data}
|
|
142
|
+
headers={headers}
|
|
143
|
+
// extras and rowKeys are both 'optional'
|
|
144
|
+
extras={extras}
|
|
145
|
+
sortedKeys={rowKeys ?? mappedKeys}
|
|
146
|
+
selected={selected}
|
|
147
|
+
disabled={disabled}
|
|
148
|
+
/>
|
|
149
|
+
) : (
|
|
150
|
+
<DefaultRow
|
|
151
|
+
key={key}
|
|
152
|
+
data={data}
|
|
153
|
+
extras={extras}
|
|
154
|
+
headers={headers}
|
|
155
|
+
selected={selected}
|
|
156
|
+
onSelect={
|
|
157
|
+
selectedKeys != null
|
|
158
|
+
? (_v) => onSelect?.(xor(selectedKeys ?? [], [key]))
|
|
159
|
+
: undefined
|
|
160
|
+
}
|
|
161
|
+
disabled={disabled}
|
|
162
|
+
/>
|
|
163
|
+
);
|
|
164
|
+
})
|
|
165
|
+
)}
|
|
166
|
+
</BasicTableBody>
|
|
167
|
+
</BasicTable>
|
|
168
|
+
</div>
|
|
169
|
+
);
|
|
170
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.Table = Table;
|
|
7
|
+
var React = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _hooks = require("./hooks");
|
|
9
|
+
var _StaticTable = require("./StaticTable");
|
|
10
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
11
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
12
|
+
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
13
|
+
/**
|
|
14
|
+
* Table
|
|
15
|
+
* @param {React.ComponentType} Row - React.ComponentType<{data: Data, extras?: Extras, sortedKeys?: string[]}>
|
|
16
|
+
* @param {string} className - string
|
|
17
|
+
*
|
|
18
|
+
**/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Table
|
|
22
|
+
* @param {React.ComponentType} Row - React.ComponentType<{data: Data, extras?: Extras, sortedKeys?: string[]}>
|
|
23
|
+
* @param {string} className - string
|
|
24
|
+
*
|
|
25
|
+
*/
|
|
26
|
+
function Table(props) {
|
|
27
|
+
const {
|
|
28
|
+
className,
|
|
29
|
+
Row,
|
|
30
|
+
entries,
|
|
31
|
+
extras,
|
|
32
|
+
headers,
|
|
33
|
+
showHeader = true,
|
|
34
|
+
tableHeaderClassName,
|
|
35
|
+
sortable = true,
|
|
36
|
+
defaultSortKey,
|
|
37
|
+
defaultSortDirection = 'original',
|
|
38
|
+
onSort,
|
|
39
|
+
isLoading,
|
|
40
|
+
idName = 'id',
|
|
41
|
+
emptyText
|
|
42
|
+
} = props;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
*
|
|
46
|
+
*/
|
|
47
|
+
const {
|
|
48
|
+
sortedEntries,
|
|
49
|
+
sortedKeys,
|
|
50
|
+
...sortableProps
|
|
51
|
+
} = (0, _hooks.useSortableEntries)(entries, idName, {
|
|
52
|
+
defaultSortKey,
|
|
53
|
+
defaultSortDirection,
|
|
54
|
+
onSort
|
|
55
|
+
});
|
|
56
|
+
return /*#__PURE__*/React.createElement(_StaticTable.StaticTable, _extends({}, props, sortableProps, {
|
|
57
|
+
sortable: sortable,
|
|
58
|
+
entries: entries,
|
|
59
|
+
rowKeys: sortedKeys
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// @flow strict
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
|
|
5
|
+
import type {SortDirection} from './hooks';
|
|
6
|
+
import {useSortableEntries} from './hooks';
|
|
7
|
+
import type {TableRow} from './Row';
|
|
8
|
+
import {StaticTable} from './StaticTable';
|
|
9
|
+
import type {GenericHeaderItems} from './TableHeader';
|
|
10
|
+
|
|
11
|
+
// type ClassNames = $ReadOnly<{wrapper?: string}>;
|
|
12
|
+
|
|
13
|
+
export type GenericObject = {
|
|
14
|
+
// the + here (not well doc'd by flow) makes all object properties covariant
|
|
15
|
+
// meaning that the value of any string-keyed property is allowed to have a more
|
|
16
|
+
// specific type than `mixed` (i.e. string, number fn, etc)
|
|
17
|
+
// (ie. the likely case for all real instances of GenericObject)
|
|
18
|
+
// learn more here https://flow.org/blog/2016/10/04/Property-Variance/
|
|
19
|
+
+[key: string]: mixed,
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export type TableProps<T, U> = {
|
|
23
|
+
className?: string,
|
|
24
|
+
Row?: TableRow<T, U>,
|
|
25
|
+
headers: GenericHeaderItems<T, U>,
|
|
26
|
+
entries: Array<T>,
|
|
27
|
+
extras?: U,
|
|
28
|
+
sortable?: boolean,
|
|
29
|
+
showHeader?: boolean,
|
|
30
|
+
tableHeaderClassName?: string,
|
|
31
|
+
headerIconClassName?: string,
|
|
32
|
+
defaultSortKey?: string,
|
|
33
|
+
defaultSortDirection?: 'asc' | 'desc' | 'original',
|
|
34
|
+
|
|
35
|
+
selectedKeys?: string[],
|
|
36
|
+
onSelect?: (keys: string[]) => mixed,
|
|
37
|
+
|
|
38
|
+
idName?: $Keys<T>,
|
|
39
|
+
onSort?: (key: $Keys<T>, direction: SortDirection) => void,
|
|
40
|
+
isLoading?: boolean,
|
|
41
|
+
emptyText?: React.Node,
|
|
42
|
+
disabled?: boolean,
|
|
43
|
+
customLoader?: React.Node,
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Table
|
|
48
|
+
* @param {React.ComponentType} Row - React.ComponentType<{data: Data, extras?: Extras, sortedKeys?: string[]}>
|
|
49
|
+
* @param {string} className - string
|
|
50
|
+
*
|
|
51
|
+
**/
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Table
|
|
55
|
+
* @param {React.ComponentType} Row - React.ComponentType<{data: Data, extras?: Extras, sortedKeys?: string[]}>
|
|
56
|
+
* @param {string} className - string
|
|
57
|
+
*
|
|
58
|
+
*/
|
|
59
|
+
export function Table<Data: GenericObject, Extras: GenericObject>(
|
|
60
|
+
props: TableProps<Data, Extras>,
|
|
61
|
+
): React.Node {
|
|
62
|
+
const {
|
|
63
|
+
className,
|
|
64
|
+
Row,
|
|
65
|
+
entries,
|
|
66
|
+
extras,
|
|
67
|
+
headers,
|
|
68
|
+
showHeader = true,
|
|
69
|
+
tableHeaderClassName,
|
|
70
|
+
sortable = true,
|
|
71
|
+
defaultSortKey,
|
|
72
|
+
defaultSortDirection = 'original',
|
|
73
|
+
onSort,
|
|
74
|
+
isLoading,
|
|
75
|
+
idName = 'id',
|
|
76
|
+
emptyText,
|
|
77
|
+
} = props;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
*
|
|
81
|
+
*/
|
|
82
|
+
const {sortedEntries, sortedKeys, ...sortableProps} = useSortableEntries(
|
|
83
|
+
entries,
|
|
84
|
+
idName,
|
|
85
|
+
{
|
|
86
|
+
defaultSortKey,
|
|
87
|
+
defaultSortDirection,
|
|
88
|
+
onSort,
|
|
89
|
+
},
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
return (
|
|
93
|
+
<StaticTable
|
|
94
|
+
{...props}
|
|
95
|
+
{...sortableProps}
|
|
96
|
+
sortable={sortable}
|
|
97
|
+
entries={entries}
|
|
98
|
+
rowKeys={sortedKeys}
|
|
99
|
+
/>
|
|
100
|
+
);
|
|
101
|
+
}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
@value (
|
|
2
|
+
colorFillPrimary,
|
|
3
|
+
colorFillSecondary,
|
|
4
|
+
colorTextPrimary,
|
|
5
|
+
colorTextSecondary,
|
|
6
|
+
colorBorderPrimary,
|
|
7
|
+
colorBorderSecondary,
|
|
8
|
+
colorFillSecondary,
|
|
9
|
+
colorBackgroundPrimary,
|
|
10
|
+
colorBackgroundTertiary,
|
|
11
|
+
colorGrayLightest
|
|
12
|
+
) from '../../styles/variables/_color.css';
|
|
13
|
+
@value (spaceNone, spaceXXSmall, spaceXSmall, spaceSmall, spaceMedium) from '../../styles/variables/_space.css';
|
|
14
|
+
@value (sizeFluid, size48, size60, size240, size300) from '../../styles/variables/_size.css';
|
|
15
|
+
@value (borderWidthNone, borderWidthPrimary, borderRadiusNone, borderRadiusMedium) from '../../styles/variables/_border.css';
|
|
16
|
+
@value (fontLineHeight170) from '../../styles/variables/_font.css';
|
|
17
|
+
@value (elevationCard) from '../../styles/variables/_elevation.css';
|
|
18
|
+
|
|
19
|
+
.fooBar {
|
|
20
|
+
color: colorFillPrimary;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.tableContainer {
|
|
24
|
+
composes: borderPrimary from '../../styles/border.module.css';
|
|
25
|
+
width: sizeFluid;
|
|
26
|
+
overflow-x: scroll;
|
|
27
|
+
border-radius: borderRadiusMedium;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.defaultTable {
|
|
31
|
+
min-width: sizeFluid;
|
|
32
|
+
flex-flow: column;
|
|
33
|
+
overflow-x: scroll;
|
|
34
|
+
border-collapse: collapse;
|
|
35
|
+
box-sizing: border-box;
|
|
36
|
+
border-radius: borderRadiusMedium;
|
|
37
|
+
box-shadow: borderWidthNone borderWidthNone borderWidthNone borderWidthPrimary
|
|
38
|
+
colorBorderPrimary;
|
|
39
|
+
table-layout: fixed;
|
|
40
|
+
white-space: nowrap;
|
|
41
|
+
}
|
|
42
|
+
.defaultTableBody {
|
|
43
|
+
flex-flow: column;
|
|
44
|
+
border-radius: borderRadiusNone borderRadiusNone borderRadiusMedium
|
|
45
|
+
borderRadiusMedium;
|
|
46
|
+
background: colorBackgroundTertiary;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.defaultSelectedBodyRow {
|
|
50
|
+
background: colorFillSecondary;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.labelContents {
|
|
54
|
+
display: flex;
|
|
55
|
+
justify-content: space-between;
|
|
56
|
+
flex: 1;
|
|
57
|
+
}
|
|
58
|
+
.labelContainer {
|
|
59
|
+
align-items: center;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.defaultHeaderCellSortable.sorted .sortArrow {
|
|
63
|
+
visibility: visible;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.defaultCell,
|
|
67
|
+
.defaultSingleCell,
|
|
68
|
+
.defaultDoubleCell {
|
|
69
|
+
height: size48;
|
|
70
|
+
align-items: center;
|
|
71
|
+
padding: spaceNone spaceXSmall;
|
|
72
|
+
background: colorBackgroundTertiary;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.defaultDoubleCell {
|
|
76
|
+
display: flex;
|
|
77
|
+
flex-direction: column;
|
|
78
|
+
align-items: flex-start;
|
|
79
|
+
justify-content: center;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.paddedTitleBlock {
|
|
83
|
+
display: flex;
|
|
84
|
+
flex-direction: column;
|
|
85
|
+
align-items: flex-start;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.defaultSingleCell {
|
|
89
|
+
/*used to retain bottom border on cell if content is full-bleed */
|
|
90
|
+
padding-bottom: borderWidthPrimary;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.defaultHeadCell {
|
|
94
|
+
composes: defaultCell;
|
|
95
|
+
background: colorBackgroundPrimary;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.defaultDoubleCell {
|
|
99
|
+
height: size60;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.singleContentCell {
|
|
103
|
+
composes: defaultCell;
|
|
104
|
+
padding: spaceNone spaceXSmall;
|
|
105
|
+
}
|
|
106
|
+
.doubleContentCell {
|
|
107
|
+
composes: defaultDoubleCell;
|
|
108
|
+
padding: spaceNone spaceXSmall;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.doubleTitle {
|
|
112
|
+
margin: spaceNone;
|
|
113
|
+
}
|
|
114
|
+
.doubleSubtitle {
|
|
115
|
+
display: block;
|
|
116
|
+
height: fontLineHeight170;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.stickyHeaderCell,
|
|
120
|
+
.stickyCell {
|
|
121
|
+
position: sticky;
|
|
122
|
+
left: spaceNone;
|
|
123
|
+
z-index: elevationCard;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.stickyHeaderCell {
|
|
127
|
+
background: colorBackgroundPrimary;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.stickyCell {
|
|
131
|
+
background: colorBackgroundPrimary;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
Row CSS
|
|
136
|
+
*/
|
|
137
|
+
|
|
138
|
+
.defaultRow {
|
|
139
|
+
composes: borderBottomPrimary from '../../styles/border.module.css';
|
|
140
|
+
height: size48;
|
|
141
|
+
background: colorBackgroundTertiary;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.defaultTable .defaultRow:last-child td:first-child {
|
|
145
|
+
border-bottom-left-radius: borderRadiusMedium;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.defaultTable .defaultRow:last-child td:last-child {
|
|
149
|
+
border-bottom-right-radius: borderRadiusMedium;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.defaultTable .defaultRow:last-child {
|
|
153
|
+
border-bottom: none;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.emptyRow {
|
|
157
|
+
display: flex;
|
|
158
|
+
flex: 0 0 auto;
|
|
159
|
+
align-items: center;
|
|
160
|
+
justify-content: center;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.defaultLoader {
|
|
164
|
+
display: flex;
|
|
165
|
+
align-items: center;
|
|
166
|
+
justify-content: center;
|
|
167
|
+
height: size240;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.defaultEmptyText {
|
|
171
|
+
display: flex;
|
|
172
|
+
align-items: center;
|
|
173
|
+
justify-content: center;
|
|
174
|
+
height: size240;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.checkbox {
|
|
178
|
+
padding: spaceSmall spaceMedium spaceSmall spaceNone;
|
|
179
|
+
max-width: size60;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.defaultTable td:first-child,
|
|
183
|
+
th:first-child {
|
|
184
|
+
padding-left: spaceMedium;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/* Header CSS */
|
|
188
|
+
|
|
189
|
+
.defaultTableHead {
|
|
190
|
+
flex-flow: column;
|
|
191
|
+
border-radius: borderRadiusMedium borderRadiusMedium borderRadiusNone
|
|
192
|
+
borderRadiusNone;
|
|
193
|
+
composes: borderBottomPrimary from '../../styles/border.module.css';
|
|
194
|
+
padding: spaceSmall;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.defaultHeaderRow {
|
|
198
|
+
box-sizing: border-box;
|
|
199
|
+
background: colorBackgroundPrimary;
|
|
200
|
+
border-radius: borderRadiusMedium borderRadiusMedium borderRadiusNone
|
|
201
|
+
borderRadiusNone;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.labelContents {
|
|
205
|
+
display: flex;
|
|
206
|
+
justify-content: flex-start;
|
|
207
|
+
flex: 1;
|
|
208
|
+
flex-direction: row;
|
|
209
|
+
align-items: flex-start;
|
|
210
|
+
padding: spaceNone;
|
|
211
|
+
gap: spaceXXSmall;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.labelContainer {
|
|
215
|
+
align-items: center;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.defaultHeaderCellSortable {
|
|
219
|
+
cursor: pointer;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.defaultHeaderCell,
|
|
223
|
+
.defaultHeaderCellSortable {
|
|
224
|
+
padding: spaceNone spaceXSmall;
|
|
225
|
+
text-align: left;
|
|
226
|
+
align-items: center;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
.defaultHeaderCell:first-child {
|
|
230
|
+
border-top-left-radius: borderRadiusMedium;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.defaultHeaderCell:last-child {
|
|
234
|
+
border-top-right-radius: borderRadiusMedium;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.defaultHeaderCell:not(.selectedHeader):hover {
|
|
238
|
+
background: colorGrayLightest;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
.selectedHeader {
|
|
242
|
+
color: colorTextPrimary;
|
|
243
|
+
background: colorFillSecondary;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
.sortArrow {
|
|
247
|
+
color: colorTextSecondary;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.selectedSortArrow {
|
|
251
|
+
color: colorTextPrimary;
|
|
252
|
+
}
|