@semcore/data-table 3.0.10 → 3.1.2

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/src/Head.tsx DELETED
@@ -1,142 +0,0 @@
1
- import React from 'react';
2
- import { Component, sstyled, Root } from '@semcore/core';
3
- import { Box, Flex } from '@semcore/flex-box';
4
- import ScrollArea from '@semcore/scroll-area';
5
- import SortDesc from '@semcore/icon/SortDesc/m';
6
- import SortAsc from '@semcore/icon/SortAsc/m';
7
- import { callAllEventHandlers } from '@semcore/utils/lib/assignProps';
8
- import { flattenColumns, getFixedStyle, getScrollOffsetValue } from './utils';
9
- import type { Column } from './types';
10
- import logger from '@semcore/utils/lib/logger';
11
- import 'resize-observer-polyfill';
12
-
13
- import scrollStyles from './style/scroll-area.shadow.css';
14
-
15
- const SORTING_ICON = {
16
- desc: SortDesc,
17
- asc: SortAsc,
18
- } as const;
19
-
20
- type AsProps = {
21
- $onSortClick: (name: string, event: React.MouseEvent | React.KeyboardEvent) => void;
22
- $scrollRef: (instance: unknown) => void;
23
- use: 'primary' | 'secondary';
24
- columnsChildren: Column[];
25
- onResize: ResizeObserverCallback;
26
- sticky: boolean;
27
- ['data-ui-name']: string;
28
- };
29
-
30
- class Head extends Component<AsProps> {
31
- columns: Column[] = [];
32
-
33
- static displayName: string;
34
-
35
- bindHandlerSortClick = (name: string) => (event: React.MouseEvent) => {
36
- this.asProps.$onSortClick(name, event);
37
- };
38
-
39
- bindHandlerKeyDown = (name: string) => (event: React.KeyboardEvent) => {
40
- if (event.code === 'Enter') {
41
- this.asProps.$onSortClick(name, event);
42
- }
43
- };
44
-
45
- renderColumns(columns: Column[], width: number) {
46
- return columns.map((column) => this.renderColumn(column, width));
47
- }
48
-
49
- renderColumn(column: Column, width: number) {
50
- const { styles, use, hidden } = this.asProps;
51
- const SColumn = Flex;
52
- const SHead = Box;
53
- const SSortIcon = SORTING_ICON[column.sortDirection];
54
- const isGroup = column.columns?.length > 0;
55
- const cSize = isGroup ? flattenColumns(column.columns).length : 1;
56
- const [name, value] = getFixedStyle(column, this.columns);
57
-
58
- const style = {
59
- flexBasis: column.props.flex === undefined && `${width * cSize}%`,
60
- ...column.props.style,
61
- };
62
-
63
- if (name !== undefined && value !== undefined) {
64
- style[name] = value;
65
- }
66
-
67
- return sstyled(styles)(
68
- <SColumn
69
- key={column.name}
70
- use={use}
71
- fixed={column.fixed}
72
- resizable={column.resizable}
73
- sortable={column.sortable}
74
- active={column.active}
75
- group={isGroup}
76
- tabIndex={column.sortable && 0}
77
- {...column.props}
78
- onClick={callAllEventHandlers(
79
- column.props.onClick,
80
- column.sortable ? this.bindHandlerSortClick(column.name) : undefined,
81
- )}
82
- onKeyDown={callAllEventHandlers(
83
- column.props.onKeyDown,
84
- column.sortable ? this.bindHandlerKeyDown(column.name) : undefined,
85
- )}
86
- style={style}
87
- hidden={hidden}
88
- >
89
- {isGroup ? (
90
- <>
91
- <SColumn groupHead use={use}>
92
- <div>{column.props.children}</div>
93
- </SColumn>
94
- <SHead>{this.renderColumns(column.columns, 100 / cSize)}</SHead>
95
- </>
96
- ) : (
97
- <>
98
- <div>{column.props.children}</div>
99
- {column.sortable ? <SSortIcon active={column.active} /> : null}
100
- </>
101
- )}
102
- </SColumn>,
103
- );
104
- }
105
-
106
- render() {
107
- const SHead = Root;
108
- const { Children, styles, columnsChildren, onResize, $scrollRef, sticky } = this.asProps;
109
- const SHeadWrapper = Box;
110
-
111
- this.columns = flattenColumns(columnsChildren);
112
-
113
- const [offsetLeftSum, offsetRightSum] = getScrollOffsetValue(this.columns);
114
-
115
- logger.warn(
116
- sticky,
117
- "'sticky' property is deprecated, use '<Sticky/>' wrapper",
118
- this.asProps['data-ui-name'] || Head.displayName,
119
- );
120
-
121
- return sstyled(styles)(
122
- <SHeadWrapper sticky={sticky}>
123
- <ScrollArea
124
- styles={scrollStyles}
125
- use:left={`${offsetLeftSum}px`}
126
- use:right={`${offsetRightSum}px`}
127
- shadow
128
- onResize={onResize}
129
- >
130
- <ScrollArea.Container ref={$scrollRef}>
131
- <SHead render={Box}>
132
- {this.renderColumns(columnsChildren, 100 / this.columns.length)}
133
- </SHead>
134
- </ScrollArea.Container>
135
- </ScrollArea>
136
- {Children.origin}
137
- </SHeadWrapper>,
138
- );
139
- }
140
- }
141
-
142
- export default Head;
package/src/index.ts DELETED
@@ -1,2 +0,0 @@
1
- export { default } from './DataTable';
2
- export * from './DataTable';
@@ -1,295 +0,0 @@
1
- @import '@semcore/utils/style/var.css';
2
-
3
- SDataTable {
4
- position: relative;
5
- }
6
-
7
- SHeadWrapper {
8
- position: relative;
9
- }
10
-
11
- SHeadWrapper[sticky] {
12
- position: sticky;
13
- top: 0;
14
- z-index: 2;
15
- }
16
-
17
- SHead {
18
- display: flex;
19
- position: relative;
20
- flex-direction: row;
21
- min-width: fit-content;
22
- z-index: 0;
23
- }
24
-
25
- SColumn {
26
- display: flex;
27
- align-items: center;
28
- flex-grow: 1;
29
- font-size: var(--fs-100);
30
- color: var(--gray-800);
31
- box-sizing: border-box;
32
- position: relative;
33
-
34
- &:focus {
35
- outline: none;
36
- box-shadow: var(--keyboard-focus);
37
- }
38
- }
39
-
40
- SColumn[hidden] {
41
- height: 0 !important;
42
- padding: 0 !important;
43
- overflow: hidden !important;
44
- border: none !important;
45
- }
46
-
47
- SColumn[use='primary'] {
48
- padding: 12px;
49
- border-right: 1px solid var(--gray-100);
50
- border-bottom: 1px solid var(--gray-100);
51
- background-color: var(--gray-50);
52
- }
53
-
54
- SColumn[use='secondary'] {
55
- padding: 8px;
56
- border-bottom: 1px solid var(--gray-300);
57
- background-color: var(--white);
58
- }
59
-
60
- SColumn[use]:last-child {
61
- border-right: none;
62
- }
63
-
64
- SColumn[group][use] {
65
- display: flex;
66
- flex-wrap: wrap;
67
- flex-direction: column;
68
- align-items: normal;
69
- border-bottom: none;
70
- padding: 0;
71
- }
72
-
73
- SColumn[groupHead][use] {
74
- justify-content: center;
75
- border-right: none;
76
- /* for resizable */
77
- z-index: 1;
78
- }
79
-
80
- SColumn[groupHead][use='primary'] {
81
- border-bottom: 1px solid var(--gray-100);
82
- }
83
-
84
- SColumn[groupHead][use='secondary'] {
85
- border-bottom: 1px solid var(--gray-100);
86
- }
87
-
88
- SColumn[sortable] {
89
- cursor: pointer;
90
-
91
- &[use='primary']:hover {
92
- background-color: var(--gray-100);
93
- }
94
- }
95
-
96
- SColumn[active][use='primary'] {
97
- background-color: var(--gray-100);
98
- }
99
-
100
- SColumn[resizable] {
101
- &:hover:after {
102
- background: var(--gray-100);
103
- }
104
-
105
- &:after {
106
- content: '';
107
- position: absolute;
108
- bottom: 0;
109
- right: -1px;
110
- height: 100vh;
111
- width: 1px;
112
- background: transparent;
113
- cursor: col-resize;
114
- }
115
- }
116
-
117
- SColumn[fixed] {
118
- position: sticky;
119
- /* because up resizable */
120
- z-index: 2;
121
- }
122
-
123
- SSortIcon {
124
- fill: var(--gray-300);
125
- margin-left: 6px;
126
- }
127
-
128
- SSortIcon[active] {
129
- fill: var(--gray-400);
130
- }
131
-
132
- SBodyWrapper {
133
- position: relative;
134
- }
135
-
136
- SBody {
137
- display: flex;
138
- flex-direction: column;
139
- position: relative;
140
- min-width: fit-content;
141
- }
142
-
143
- SRow {
144
- display: flex;
145
- flex-direction: row;
146
- position: relative;
147
- }
148
-
149
- /* DEFAULT THEME */
150
- SRow[active] > SCell:not([theme]),
151
- SRow:hover > SCell:not([theme]),
152
- SRow SCell:hover + SGroupCell SCell:not([theme]) {
153
- background-color: color-mod(var(--gray-100) blend(var(--white) 50%));
154
- }
155
-
156
- /* MUTED THEME */
157
- SRow[theme='muted'] SCell:not([theme]) {
158
- background-color: #f2f3f4;
159
- }
160
-
161
- SRow:hover > SCell[theme='muted'],
162
- SRow[theme='muted'][active] > SCell:not([theme]),
163
- SRow[theme='muted']:hover > SCell:not([theme]),
164
- SRow[theme='muted'] SCell:hover + SGroupCell SCell:not([theme]) {
165
- background-color: #f6f7f7;
166
- }
167
-
168
- /* INFO THEME */
169
- SRow[theme='info'] SCell:not([theme]) {
170
- background-color: var(--blue-50);
171
- }
172
-
173
- SRow:hover > SCell[theme='info'],
174
- SRow[theme='info'][active] > SCell:not([theme]),
175
- SRow[theme='info']:hover > SCell:not([theme]),
176
- SRow[theme='info'] SCell:hover + SGroupCell SCell:not([theme]) {
177
- background-color: var(--blue-100);
178
- }
179
-
180
- /* SUCCESS THEME */
181
- SRow[theme='success'] SCell:not([theme]) {
182
- background-color: var(--green-50);
183
- }
184
-
185
- SRow:hover > SCell[theme='success'],
186
- SRow[theme='success'][active] > SCell:not([theme]),
187
- SRow[theme='success']:hover > SCell:not([theme]),
188
- SRow[theme='success'] SCell:hover + SGroupCell SCell:not([theme]) {
189
- background-color: var(--green-100);
190
- }
191
-
192
- /* WARNING THEME */
193
- SRow[theme='warning'] SCell:not([theme]) {
194
- background-color: var(--orange-50);
195
- }
196
-
197
- SRow:hover > SCell[theme='warning'],
198
- SRow[theme='warning'][active] > SCell:not([theme]),
199
- SRow[theme='warning']:hover > SCell:not([theme]),
200
- SRow[theme='warning'] SCell:hover + SGroupCell SCell:not([theme]) {
201
- background-color: var(--orange-100);
202
- }
203
-
204
- /* DANGER THEME */
205
- SRow[theme='danger'] SCell:not([theme]) {
206
- background-color: var(--red-50);
207
- }
208
-
209
- SRow:hover > SCell[theme='danger'],
210
- SRow[theme='danger'][active] > SCell:not([theme]),
211
- SRow[theme='danger']:hover > SCell:not([theme]),
212
- SRow[theme='danger'] SCell:hover + SGroupCell SCell:not([theme]) {
213
- background-color: var(--red-100);
214
- }
215
-
216
- SRow[positioned] {
217
- position: absolute;
218
- }
219
-
220
- SCell {
221
- display: flex;
222
- flex: 1;
223
- flex-basis: auto;
224
- font-size: var(--fs-200);
225
- line-height: var(--lh-200);
226
- color: var(--gray-800);
227
- box-sizing: border-box;
228
- border-bottom: 1px solid var(--gray-100);
229
- overflow: hidden;
230
- white-space: nowrap;
231
- }
232
-
233
- SCell[use='primary'] {
234
- padding: 12px;
235
- min-height: 45px;
236
- background-color: var(--white);
237
- }
238
-
239
- SCell[use='secondary'] {
240
- padding: 8px;
241
- min-height: 37px;
242
- background-color: var(--white);
243
- }
244
-
245
- SCell[fixed] {
246
- position: sticky;
247
- z-index: 1;
248
- }
249
-
250
- SCell[theme='muted'] {
251
- background-color: #f2f3f4;
252
- }
253
-
254
- SCell[theme='info'] {
255
- background-color: var(--blue-50);
256
- }
257
-
258
- SCell[theme='success'] {
259
- background-color: var(--green-50);
260
- }
261
-
262
- SCell[theme='warning'] {
263
- background-color: var(--orange-50);
264
- }
265
-
266
- SCell[theme='danger'] {
267
- background-color: var(--red-50);
268
- }
269
-
270
- SScrollAreaBar[orientation='horizontal'] {
271
- position: sticky;
272
- bottom: 0;
273
- left: 0;
274
- margin-top: -12px;
275
- z-index: 2;
276
- }
277
-
278
- SScrollAreaBar[orientation='vertical'] {
279
- width: 12px;
280
- }
281
-
282
- SScrollAreaBar[orientation='horizontal'] {
283
- margin-left: calc(var(--left) + 4px);
284
- margin-right: calc(var(--right) + 4px);
285
- width: calc(100% - var(--offsetSum) - 8px);
286
- }
287
-
288
- SHeightHold {
289
- position: absolute;
290
- top: 0;
291
- width: 100%;
292
- pointer-events: none;
293
- /* should be under other layers */
294
- z-index: -1;
295
- }
@@ -1,6 +0,0 @@
1
- SShadowHorizontal:before {
2
- left: var(--left) !important;
3
- }
4
- SShadowHorizontal:after {
5
- right: var(--right) !important;
6
- }
package/src/types.ts DELETED
@@ -1,53 +0,0 @@
1
- import React from 'react';
2
- import { ROW_GROUP } from './DataTable';
3
-
4
- export type PseudoChildPropsGetter = (
5
- props: { [propName: string]: unknown },
6
- rowData: { [columnName: string]: unknown },
7
- index: number,
8
- ) => { [propName: string]: unknown };
9
- export type PropsLayer = {
10
- childrenPropsGetter?: PseudoChildPropsGetter;
11
- [propName: string]: unknown;
12
- };
13
-
14
- export type SortDirection = 'asc' | 'desc';
15
- export type Column<
16
- Props extends { [propName: string]: unknown } = { [propName: string]: unknown },
17
- > = {
18
- name: string;
19
- active: boolean;
20
- width: number;
21
- fixed?: 'left' | 'right';
22
- resizable?: boolean;
23
- sortable?: boolean | SortDirection;
24
- sortDirection: SortDirection;
25
- cssVar: string | string[];
26
- data?: unknown;
27
- props: {
28
- name: string;
29
- } & Partial<{
30
- onClick: (event: React.MouseEvent) => void;
31
- onKeyDown: (event: React.KeyboardEvent) => void;
32
- ref: React.RefObject<HTMLElement>;
33
- style: React.CSSProperties;
34
- fixed: 'left' | 'right';
35
- children: React.ReactNode[];
36
- resizable: boolean;
37
- sortable: boolean | SortDirection;
38
- sortDirection: SortDirection;
39
- }> &
40
- Props;
41
- columns: Column[];
42
- };
43
- export type Cell = Pick<Column, 'name' | 'cssVar' | 'fixed' | 'data'> & {
44
- cellPropsLayers: PropsLayer[];
45
- };
46
- export type RowData<
47
- Data extends { [columnName: string]: unknown } = { [columnName: string]: unknown },
48
- > = Data &
49
- Partial<{
50
- name: string;
51
- [ROW_GROUP]: RowData[];
52
- }>;
53
- export type NestedCells = (Cell | NestedCells)[] & { flatRowData?: RowData };
package/src/utils.ts DELETED
@@ -1,55 +0,0 @@
1
- import type { Column } from './types';
2
-
3
- export const getScrollOffsetValue = (columns: Column[]) =>
4
- columns.reduce(
5
- (acc, column) => {
6
- if (column.fixed === 'left') {
7
- acc[0] += column.width;
8
- }
9
- if (column.fixed === 'right') {
10
- acc[1] += column.width;
11
- }
12
- return acc;
13
- },
14
- [0, 0] as [leftOffset: number, rightOffset: number],
15
- );
16
-
17
- export const flattenColumns = (columns: Column[]) =>
18
- columns.reduce((acc, column) => {
19
- const hasNestedColumns = 'columns' in column && column.columns.length > 0;
20
- const columns: Column[] = hasNestedColumns ? flattenColumns(column.columns) : [column];
21
- acc = acc.concat(columns);
22
- return acc;
23
- }, [] as Column[]);
24
-
25
- export const getFixedStyle = (
26
- cell: Pick<Column, 'name' | 'fixed'>,
27
- columns: Column[],
28
- ): [side: 'left' | 'right', style: string | number] | [side: undefined, style: undefined] => {
29
- const side = cell.fixed;
30
- if (!side) return [undefined, undefined];
31
- const names = cell.name.split('/');
32
- const nameSideMap = {
33
- left: names[0],
34
- right: names[names.length - 1],
35
- };
36
- const name = nameSideMap[side];
37
- const index = columns.findIndex((column) => column.name === name);
38
-
39
- if (index === -1) return [undefined, undefined];
40
-
41
- const startIndexSideMap = {
42
- left: 0,
43
- right: index,
44
- };
45
- const endIndexSideMap = {
46
- left: index,
47
- right: columns.length - 1,
48
- };
49
- const columnsFixed = columns.slice(startIndexSideMap[side], endIndexSideMap[side]);
50
-
51
- if (columnsFixed.length < 1) return [side, 0];
52
-
53
- const vars = columnsFixed.map((column) => `var(--${column.name}_width)`);
54
- return [side, vars.length === 1 ? vars[0] : `calc(${vars.join(' + ')})`];
55
- };