wca-designsystem 0.0.55 → 0.0.56

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,5 +1,5 @@
1
1
  {
2
- "version": "0.0.55",
2
+ "version": "0.0.56",
3
3
  "license": "MIT",
4
4
  "main": "dist/index.js",
5
5
  "typings": "dist/index.d.ts",
@@ -14,11 +14,11 @@ function SkeletonTable<T extends { id: number | string }>({
14
14
  }: SkeletonTableProps<T>) {
15
15
  return (
16
16
  <S.TabelaBody>
17
- {columns?.map(row => {
17
+ {data?.map(row => {
18
18
  return (
19
- <tr key={row.header}>
20
- {data.map(cell => (
21
- <td key={cell.id}>
19
+ <tr key={row.id}>
20
+ {columns.map(cell => (
21
+ <td key={cell.header}>
22
22
  <Skeleton height={19} radius="xl" animate={true} />
23
23
  </td>
24
24
  ))}
@@ -9,156 +9,41 @@ export default {
9
9
  component: Tabela,
10
10
  } as Meta;
11
11
 
12
- const data: any[] = [
13
- {
14
- id: 1,
15
- name: 'Produto 1',
16
- price: '$10',
17
- exemplo: 'opa',
18
- exemplo2: 'opa2',
19
- children: [
20
- {
21
- id: '1-1',
22
- name: 'Task 1',
23
- price: '$10',
24
- exemplo: 'opa',
25
- exemplo2: 'opa2',
26
- children: [
27
- {
28
- id: '1-10',
29
- name: 'Task 10',
30
- price: '$10',
31
- exemplo: 'opa',
32
- exemplo2: 'opa2',
33
- },
34
- ],
35
- },
36
- {
37
- id: '1-2',
38
- name: 'Task 2',
39
- price: '$10',
40
- exemplo: 'opa',
41
- exemplo2: 'opa2',
42
- },
43
- ],
44
- },
45
- {
46
- id: 2,
47
- name: 'Produto 2',
48
- price: '$15',
49
- exemplo: 'opa',
50
- exemplo2: 'opa2',
51
- children: [
52
- {
53
- id: '2-1',
54
- name: 'Task 1',
55
- price: '$10',
56
- exemplo: 'opa',
57
- exemplo2: 'opa2',
58
- },
59
- {
60
- id: '2-2',
61
- name: 'Task 2',
62
- price: '$10',
63
- exemplo: 'opa',
64
- exemplo2: 'opa2',
65
- },
66
- ],
67
- },
68
- {
69
- id: 3,
70
- name: 'Produto 3',
71
- price: '$20',
72
- exemplo: 'opa',
73
- exemplo2: 'opa2',
74
- children: [
75
- {
76
- id: '3-1',
77
- name: 'Task 1',
78
- price: '$10',
79
- exemplo: 'opa',
80
- exemplo2: 'opa2',
81
- },
82
- {
83
- id: '3-2',
84
- name: 'Task 2',
85
- price: '$10',
86
- exemplo: 'opa',
87
- exemplo2: 'opa2',
88
- },
89
- ],
90
- },
91
- {
92
- id: 4,
93
- name: 'Produto 3',
94
- price: '$20',
95
- exemplo: 'opa',
96
- exemplo2: 'opa2',
97
- children: [
98
- {
99
- id: '4-1',
100
- name: 'Task 1',
101
- price: '$10',
102
- exemplo: 'opa',
103
- exemplo2: 'opa2',
104
- },
105
- {
106
- id: '4-2',
107
- name: 'Task 2',
108
- price: '$10',
109
- exemplo: 'opa',
110
- exemplo2: 'opa2',
111
- },
112
- ],
113
- },
114
- {
115
- id: 5,
116
- name: 'Produto 3',
117
- price: '$20',
118
- exemplo: 'opa',
119
- exemplo2: 'opa2',
120
- children: [
121
- {
122
- id: '5-1',
123
- name: 'Task 1',
124
- price: '$10',
125
- exemplo: 'opa',
126
- exemplo2: 'opa2',
127
- },
128
- {
129
- id: '5-2',
130
- name: 'Task 2',
131
- price: '$10',
132
- exemplo: 'opa',
133
- exemplo2: 'opa2',
134
- },
135
- ],
136
- },
137
- {
138
- id: 6,
139
- name: 'Produto 3',
140
- price: '$20',
141
- exemplo: 'opa',
142
- exemplo2: 'opa2',
143
- children: [
12
+ const generateData = () => {
13
+ const data = [];
14
+
15
+ for (let i = 1; i <= 101; i++) {
16
+ const children = [
144
17
  {
145
- id: '6-1',
146
- name: 'Task 1',
18
+ id: `${i}-1`,
19
+ name: `Task ${i}-1`,
147
20
  price: '$10',
148
21
  exemplo: 'opa',
149
22
  exemplo2: 'opa2',
150
23
  },
151
24
  {
152
- id: '6-2',
153
- name: 'Task 2',
25
+ id: `${i}-2`,
26
+ name: `Task ${i}-2`,
154
27
  price: '$10',
155
28
  exemplo: 'opa',
156
29
  exemplo2: 'opa2',
157
30
  },
158
- ],
159
- },
160
- ];
31
+ ];
161
32
 
33
+ data.push({
34
+ id: i,
35
+ name: `Produto ${i}`,
36
+ price: '$20',
37
+ exemplo: 'opa',
38
+ exemplo2: 'opa2',
39
+ children,
40
+ });
41
+ }
42
+
43
+ return data;
44
+ };
45
+
46
+ const data = generateData();
162
47
  const columns: any = [
163
48
  {
164
49
  key: 'expand',
@@ -190,6 +75,7 @@ TabelaProps.args = {
190
75
  columns: columns,
191
76
  color: theme.colors.blue,
192
77
  hasFiltersButtons: true,
78
+
193
79
  ordenarPor: {
194
80
  label: 'Ordenar por: Maior',
195
81
  value: 'Maior',
@@ -201,6 +87,9 @@ TabelaProps.args = {
201
87
  rowSelection: [],
202
88
  setRowSelection: () => console.log('selecionou'),
203
89
  setFiltrosPor: () => console.log('aqui'),
90
+ fetchMoreData: () => console.log('fetchMoreData'),
91
+ hasInfinitScrool: true,
92
+ hasMoreData: true,
204
93
  setGlobalFilter: () => console.log('aqui'),
205
94
  setPagination: () => console.log('aqui'),
206
95
  quantidadeDeRegistros: 10,
@@ -1,4 +1,4 @@
1
- import React, { useState, useCallback } from 'react';
1
+ import React, { useState, useCallback, useRef, useEffect } from 'react';
2
2
  import { Checkbox } from '@mantine/core';
3
3
  import { Column } from '.';
4
4
  import * as S from './styles';
@@ -18,6 +18,9 @@ export interface BodyTableProps<
18
18
  hasSelect?: boolean;
19
19
  rowSelection?: Array<T>;
20
20
  setRowSelection?: React.Dispatch<React.SetStateAction<Array<T>>> | undefined;
21
+ hasInfinitScrool?: boolean;
22
+ hasMoreData?: boolean;
23
+ fetchMoreData?: () => void;
21
24
  }
22
25
 
23
26
  function BodyTable<T extends { id: string | number; children: Array<T> }>(
@@ -29,10 +32,15 @@ function BodyTable<T extends { id: string | number; children: Array<T> }>(
29
32
  acoesChildren,
30
33
  hasSelect,
31
34
  rowSelection,
35
+ fetchMoreData,
36
+ hasMoreData,
37
+ hasInfinitScrool,
32
38
  setRowSelection,
33
39
  color,
34
40
  } = props;
35
41
 
42
+ const tableBodyRef = useRef<HTMLTableSectionElement | null>(null);
43
+
36
44
  const [expandedRows, setExpandedRows] = useState<Set<number | string>>(
37
45
  new Set()
38
46
  );
@@ -62,6 +70,30 @@ function BodyTable<T extends { id: string | number; children: Array<T> }>(
62
70
  });
63
71
  }, []);
64
72
 
73
+ useEffect(() => {
74
+ if (!fetchMoreData || !hasInfinitScrool || !tableBodyRef.current) return;
75
+
76
+ const handleScroll = () => {
77
+ debugger;
78
+ const element = tableBodyRef.current;
79
+ if (element) {
80
+ const atBottom =
81
+ element.scrollHeight - element.scrollTop === element.clientHeight;
82
+ if (atBottom) {
83
+ debugger;
84
+ fetchMoreData(); // Dispara a função ao atingir o final do scroll
85
+ }
86
+ }
87
+ };
88
+
89
+ const currentRef = tableBodyRef.current;
90
+ currentRef?.addEventListener('scroll', handleScroll);
91
+
92
+ return () => {
93
+ currentRef?.removeEventListener('scroll', handleScroll);
94
+ };
95
+ }, [fetchMoreData, hasInfinitScrool]);
96
+
65
97
  function renderRows(
66
98
  item: T,
67
99
  columns: Column<T>[],
@@ -79,7 +111,6 @@ function BodyTable<T extends { id: string | number; children: Array<T> }>(
79
111
 
80
112
  return [
81
113
  <tr key={`row-${item.id}`}>
82
- {/* Checkbox para seleção */}
83
114
  {hasSelect && (
84
115
  <td className="select">
85
116
  <Checkbox
@@ -96,8 +127,6 @@ function BodyTable<T extends { id: string | number; children: Array<T> }>(
96
127
  />
97
128
  </td>
98
129
  )}
99
-
100
- {/* Colunas dinâmicas */}
101
130
  {columns.map((column, colIndex) => {
102
131
  if (column.key === 'expand') {
103
132
  return (
@@ -137,12 +166,10 @@ function BodyTable<T extends { id: string | number; children: Array<T> }>(
137
166
  );
138
167
  }
139
168
 
140
- // Verifica se existe a prop 'cell'
141
169
  if (column.cell) {
142
170
  return <td key={`cell-${colIndex}`}>{column.cell(item)}</td>;
143
171
  }
144
172
 
145
- // Render padrão
146
173
  return column.render ? (
147
174
  <td
148
175
  key={`column-${colIndex}`}
@@ -168,8 +195,6 @@ function BodyTable<T extends { id: string | number; children: Array<T> }>(
168
195
  );
169
196
  })}
170
197
  </tr>,
171
-
172
- // Renderiza os filhos recursivamente, caso existam
173
198
  ...(expandedRows.has(item.id)
174
199
  ? item.children.flatMap(child =>
175
200
  renderRows(
@@ -186,11 +211,12 @@ function BodyTable<T extends { id: string | number; children: Array<T> }>(
186
211
  : []),
187
212
  ];
188
213
  }
214
+
189
215
  return (
190
216
  <S.TabelaBody
217
+ ref={tableBodyRef}
191
218
  color={color}
192
219
  hasselect={hasSelect ? 'true' : 'false'}
193
- // style={{ left: hasSelect ? '52px' : '17px' }}
194
220
  >
195
221
  {data.flatMap(item =>
196
222
  renderRows(
@@ -204,6 +230,13 @@ function BodyTable<T extends { id: string | number; children: Array<T> }>(
204
230
  color
205
231
  )
206
232
  )}
233
+ {hasInfinitScrool && hasMoreData && (
234
+ <tr>
235
+ <td colSpan={columns.length + (hasSelect ? 1 : 0)}>
236
+ <div className="load-more" style={{ height: '1px' }} />
237
+ </td>
238
+ </tr>
239
+ )}
207
240
  </S.TabelaBody>
208
241
  );
209
242
  }
@@ -1,13 +1,11 @@
1
- import React from 'react';
1
+ import React, { useEffect, useRef, useState } from 'react';
2
2
  import BodyTable from './body';
3
3
  import HeaderTabela from './header';
4
4
  import Paginacao from './pagination';
5
5
  import SkeletonTable from './SkeletonTable';
6
6
  import * as S from './styles';
7
- import { useState } from 'react';
8
7
  import TabelaHeader from '../../molecules/TabelaHeader';
9
8
 
10
- // Tipo genérico para as colunas
11
9
  export type Column<T> = {
12
10
  key: keyof T;
13
11
  header: string;
@@ -63,6 +61,8 @@ export type CustomTableProps<
63
61
  };
64
62
  quantidadeRegistros?: number | undefined;
65
63
  tamanhoPaginacao?: number | undefined;
64
+ fetchMoreData?: (() => void) | undefined;
65
+ hasInfinitScrool?: boolean;
66
66
  };
67
67
 
68
68
  const Tabela = <T extends { id: string | number; children: Array<T> }>({
@@ -85,6 +85,7 @@ const Tabela = <T extends { id: string | number; children: Array<T> }>({
85
85
  setGlobalFilter,
86
86
  hasOrder,
87
87
  headerSelection,
88
+ fetchMoreData,
88
89
  setOrdenarPor,
89
90
  setSimples,
90
91
  handleAdicionar,
@@ -92,22 +93,52 @@ const Tabela = <T extends { id: string | number; children: Array<T> }>({
92
93
  quantidadeRegistros,
93
94
  tamanhoPaginacao,
94
95
  fixedPosition,
96
+ hasInfinitScrool,
95
97
  }: CustomTableProps<T>) => {
96
98
  const [toogleFiltros, setToogleFiltros] = useState(false);
97
-
98
99
  const [formatedColumns, setFormatedColumns] = useState(
99
- columns.map(column => {
100
- return {
101
- ...column,
102
- active: true,
103
- };
104
- })
100
+ columns.map(column => ({
101
+ ...column,
102
+ active: true,
103
+ }))
105
104
  );
106
105
 
106
+ const [tamScroll, setTamScroll] = useState<number>(0);
107
107
  const columnsToShow = formatedColumns.filter(
108
108
  column => column.active === true
109
109
  );
110
110
 
111
+ const topScrollRef = useRef<HTMLDivElement>(null);
112
+ const bottomScrollRef = useRef<HTMLDivElement>(null);
113
+
114
+ // Sincroniza o scroll horizontal entre os dois scrollbars
115
+ useEffect(() => {
116
+ const topScroll = topScrollRef.current;
117
+ const bottomScroll = bottomScrollRef.current;
118
+
119
+ if (topScroll && bottomScroll) {
120
+ const syncScroll = (source: HTMLDivElement, target: HTMLDivElement) => {
121
+ target.scrollLeft = source.scrollLeft;
122
+ };
123
+
124
+ setTamScroll(bottomScroll.scrollWidth);
125
+ const onTopScroll = () =>
126
+ topScroll && bottomScroll && syncScroll(topScroll, bottomScroll);
127
+ const onBottomScroll = () =>
128
+ topScroll && bottomScroll && syncScroll(bottomScroll, topScroll);
129
+
130
+ topScroll.addEventListener('scroll', onTopScroll);
131
+ bottomScroll.addEventListener('scroll', onBottomScroll);
132
+
133
+ return () => {
134
+ topScroll.removeEventListener('scroll', onTopScroll);
135
+ bottomScroll.removeEventListener('scroll', onBottomScroll);
136
+ };
137
+ }
138
+
139
+ return;
140
+ }, []);
141
+
111
142
  return (
112
143
  <S.TableWrapper>
113
144
  <TabelaHeader
@@ -125,7 +156,11 @@ const Tabela = <T extends { id: string | number; children: Array<T> }>({
125
156
  ordenarPor={ordenarPor}
126
157
  setOrdenarPor={setOrdenarPor}
127
158
  />
128
- <S.TableContainer>
159
+ {/* Scroll horizontal no topo */}
160
+ <S.ScrollWrapper ref={topScrollRef}>
161
+ <S.FakeTable columnswidth={tamScroll} />
162
+ </S.ScrollWrapper>
163
+ <S.TableContainer ref={bottomScrollRef}>
129
164
  <S.StyledTable>
130
165
  {data?.length == 0 ? (
131
166
  <></>
@@ -156,7 +191,10 @@ const Tabela = <T extends { id: string | number; children: Array<T> }>({
156
191
  ) : (
157
192
  <BodyTable
158
193
  color={color}
194
+ fetchMoreData={fetchMoreData}
195
+ hasInfinitScrool={hasInfinitScrool}
159
196
  hasSelect={hasSelect}
197
+ hasMoreData={quantidadeRegistros !== data.length}
160
198
  rowSelection={rowSelection}
161
199
  setRowSelection={setRowSelection}
162
200
  acoesChildren={acoesChildren}
@@ -70,7 +70,7 @@ const Paginacao = ({
70
70
  <SelectCustomizado
71
71
  tipo="round"
72
72
  onChange={e => changeLinhas(e!)}
73
- defaultValue={'10'}
73
+ defaultValue={tabelaPaginacao.pageSize.toString() ?? '10'}
74
74
  data={['10', '20', '30']}
75
75
  comboboxProps={{
76
76
  position: 'bottom',
@@ -12,6 +12,9 @@ export const TableWrapper = styled.div`
12
12
  ${() => css`
13
13
  max-width: 1500px;
14
14
  overflow-x: hidden;
15
+ display: flex;
16
+ flex-direction: column;
17
+ gap: 1rem;
15
18
  `}
16
19
  `;
17
20
 
@@ -231,3 +234,14 @@ export const PaginationButtons = styled.div<ColorsProp>`
231
234
  }
232
235
  `}
233
236
  `;
237
+
238
+ export const ScrollWrapper = styled.div`
239
+ overflow-x: auto;
240
+ width: 100%;
241
+ margin-bottom: -15px;
242
+ `;
243
+
244
+ export const FakeTable = styled.div<{ columnswidth: number }>`
245
+ width: ${({ columnswidth }) => columnswidth}px;
246
+ height: 1px; /* Apenas para criar a barra de rolagem */
247
+ `;