ywana-core8 0.1.103 → 0.2.1
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/index.css +4941 -324
- package/dist/index.js +42338 -0
- package/dist/index.js.map +1 -0
- package/dist/index.modern.js +37458 -31678
- package/dist/index.modern.js.map +1 -1
- package/dist/index.umd.js +39634 -34010
- package/dist/index.umd.js.map +1 -1
- package/package.json +26 -29
- package/src/Test.stories.jsx +28 -0
- package/src/desktop/Desktop.stories.jsx +110 -0
- package/src/desktop/WindowContext.js +135 -0
- package/src/desktop/WindowManager.js +355 -0
- package/src/desktop/desktop.css +55 -4
- package/src/desktop/desktop.js +312 -6
- package/src/desktop/index.js +7 -0
- package/src/desktop/window.css +229 -36
- package/src/desktop/window.js +254 -20
- package/src/desktop.backup/desktop.css +6 -0
- package/src/desktop.backup/desktop.js +13 -0
- package/src/desktop.backup/window.css +58 -0
- package/src/desktop.backup/window.js +27 -0
- package/src/html/Accordion.stories.jsx +178 -0
- package/src/html/Button.stories.jsx +175 -0
- package/src/html/Checkbox.stories.jsx +131 -0
- package/src/html/Chip.stories.jsx +189 -0
- package/src/html/Color.stories.jsx +234 -0
- package/src/html/Form.stories.jsx +271 -0
- package/src/html/Icon.stories.jsx +233 -0
- package/src/html/Progress.stories.jsx +247 -0
- package/src/html/Radio.stories.jsx +289 -0
- package/src/html/StyleTest.stories.jsx +81 -0
- package/src/html/Switch.stories.jsx +329 -0
- package/src/html/Tab.stories.jsx +239 -0
- package/src/html/Table.stories.jsx +188 -0
- package/src/html/Table2.stories.jsx +238 -0
- package/src/html/TextField2.stories.jsx +337 -0
- package/src/html/Tree.stories.jsx +285 -0
- package/src/html/accordion.example.js +0 -74
- package/src/html/accordion.js +1 -6
- package/src/html/button.js +2 -13
- package/src/html/checkbox.js +1 -9
- package/src/html/chip.js +2 -19
- package/src/html/color.js +1 -14
- package/src/html/form.js +4 -15
- package/src/html/header2.js +1 -12
- package/src/html/icon.js +1 -7
- package/src/html/index.js +1 -1
- package/src/html/list.js +1 -19
- package/src/html/menu.js +9 -5
- package/src/html/progress.js +5 -53
- package/src/html/property.js +9 -25
- package/src/html/radio.js +2 -16
- package/src/html/section.js +1 -6
- package/src/html/selector.js +2 -19
- package/src/html/switch.css +134 -100
- package/src/html/switch.example.js +46 -36
- package/src/html/switch.js +43 -192
- package/src/html/tab.js +3 -24
- package/src/html/text.js +1 -12
- package/src/html/textfield2.js +5 -42
- package/src/html/thumbnail.js +1 -12
- package/src/html/tokenfield.js +2 -21
- package/src/html/tree.js +3 -35
- package/src/index.js +1 -0
- package/__previewjs__/Wrapper.tsx +0 -14
- package/build-doc.sh +0 -10
- package/db/db.json +0 -89
- package/db/routes.json +0 -0
- package/dist/index.cjs +0 -36722
- package/dist/index.cjs.map +0 -1
- package/dist/index.css.map +0 -1
- package/doc/README.md +0 -196
- package/doc/evalulations/ACCORDION_EVALUATION.md +0 -583
- package/doc/evalulations/CHECKBOX_EVALUATION.md +0 -273
- package/doc/evalulations/CHIP_EVALUATION.md +0 -542
- package/doc/evalulations/COLOR_EVALUATION.md +0 -524
- package/doc/evalulations/COMPONENTS_EVALUATION.md +0 -477
- package/doc/evalulations/FORM_EVALUATION.md +0 -459
- package/doc/evalulations/HEADER_EVALUATION.md +0 -436
- package/doc/evalulations/ICON_EVALUATION.md +0 -254
- package/doc/evalulations/LIST_EVALUATION.md +0 -574
- package/doc/evalulations/PROGRESS_EVALUATION.md +0 -450
- package/doc/evalulations/RADIO_EVALUATION.md +0 -439
- package/doc/evalulations/RADIO_VISUAL_FIX.md +0 -183
- package/doc/evalulations/SECTION_IMPROVEMENTS.md +0 -153
- package/doc/evalulations/SWITCH_EVALUATION.md +0 -335
- package/doc/evalulations/SWITCH_VISUAL_FIX.md +0 -232
- package/doc/evalulations/TAB_EVALUATION.md +0 -626
- package/doc/evalulations/TEXTFIELD_EVALUATION.md +0 -747
- package/doc/evalulations/TOOLTIP_FIX.md +0 -157
- package/doc/evalulations/TREE_EVALUATION.md +0 -708
- package/doc/index.html +0 -0
- package/doc/package-lock.json +0 -17298
- package/doc/package.json +0 -34
- package/doc/public/index.html +0 -24
- package/doc/scripts/generate-examples.js +0 -129
- package/doc/src/App.css +0 -171
- package/doc/src/App.js +0 -114
- package/doc/src/components/ExamplePage.js +0 -129
- package/doc/src/components/WelcomePage.js +0 -84
- package/doc/src/index.css +0 -246
- package/doc/src/index.js +0 -17
- package/doc/src/theme.css +0 -256
- package/jest.config.js +0 -24
- package/preview.config.js +0 -38
- package/publish.sh +0 -6
- package/src/desktop/dektop.test.js +0 -11
- package/src/domain/CollectionAPI.test.js +0 -19
- package/src/domain/ContentEditor.test.js +0 -52
- package/src/domain2/CollectionAPI.test.js +0 -19
- package/src/domain2/CollectionContext.test.js +0 -71
- package/src/domain2/CollectionPage.test.js +0 -112
- package/src/domain2/DynamicForm.test.js +0 -47
- package/src/html/accordion.test.js +0 -37
- package/src/html/accordion.unit.test.js +0 -334
- package/src/html/button.example.new.js +0 -416
- package/src/html/button.test.js +0 -422
- package/src/html/checkbox.test.js +0 -285
- package/src/html/chip.test.js +0 -425
- package/src/html/color.example.js.backup +0 -527
- package/src/html/color.test.js +0 -377
- package/src/html/components.example.js.backup +0 -492
- package/src/html/components_enhanced.test.js +0 -581
- package/src/html/form.example.js.backup +0 -385
- package/src/html/form.test.js +0 -369
- package/src/html/header2.example.js.backup +0 -411
- package/src/html/header2.test.js +0 -377
- package/src/html/icon.example.js.backup +0 -268
- package/src/html/icon.test.js +0 -231
- package/src/html/label.test.js +0 -0
- package/src/html/list.example.js.backup +0 -404
- package/src/html/list.test.js +0 -383
- package/src/html/progress.example.js.backup +0 -424
- package/src/html/progress.test.js +0 -313
- package/src/html/property.example.js.backup +0 -553
- package/src/html/property.test.js +0 -371
- package/src/html/radio.example.js.backup +0 -389
- package/src/html/radio.test.js +0 -318
- package/src/html/section.example.js.backup +0 -99
- package/src/html/section.test.js +0 -131
- package/src/html/selector.test.js +0 -20
- package/src/html/switch.example.js.backup +0 -461
- package/src/html/switch.test.js +0 -355
- package/src/html/tab.example.js.backup +0 -446
- package/src/html/tab.test.js +0 -25
- package/src/html/tab_enhanced.test.js +0 -504
- package/src/html/table.test.js +0 -70
- package/src/html/table2.test.js +0 -582
- package/src/html/text.test.js +0 -15
- package/src/html/textfield.test.js +0 -51
- package/src/html/textfield2.example.js.backup +0 -1370
- package/src/html/textfield2.test.js +0 -950
- package/src/html/tokenfield.example.js.backup +0 -503
- package/src/html/tokenfield.test.js +0 -423
- package/src/html/tree.example.js.backup +0 -475
- package/src/html/tree.test.js +0 -43
- package/src/html/tree_enhanced.test.js +0 -495
- package/src/http/token.test.js +0 -50
- package/src/incubator/pdfViewer.js +0 -33
- package/src/incubator/wizard.test.js +0 -127
- package/src/site/site.test.js +0 -230
- package/src/site/view.test.js +0 -41
- package/src/widgets/calendar/Calendar.test.js +0 -28
- package/src/widgets/explorer/Explorer.test.js +0 -121
- package/src/widgets/ide/editor.test.js +0 -33
- package/src/widgets/kanban/Kanban.test.js +0 -78
- package/src/widgets/login/LoginBox.test.js +0 -12
- package/src/widgets/login/ResetPasswordBox.test.js +0 -34
- package/src/widgets/login/validations.test.js +0 -51
- package/src/widgets/planner/Planner.test.js +0 -60
- package/src/widgets/upload/Upload.test.js +0 -32
- package/table2.test.js +0 -454
package/src/html/table2.test.js
DELETED
@@ -1,582 +0,0 @@
|
|
1
|
-
import React from 'react'
|
2
|
-
import { DataTable2 } from './table2'
|
3
|
-
|
4
|
-
// Pruebas unitarias para el componente DataTable2 mejorado
|
5
|
-
describe('Enhanced DataTable2 Component', () => {
|
6
|
-
// Mock de los componentes dependientes
|
7
|
-
const mockIcon = jest.fn()
|
8
|
-
const mockText = jest.fn()
|
9
|
-
const mockCheckBox = jest.fn()
|
10
|
-
const mockTextField = jest.fn()
|
11
|
-
const mockDropDown = jest.fn()
|
12
|
-
const mockEmptyMessage = jest.fn()
|
13
|
-
|
14
|
-
beforeEach(() => {
|
15
|
-
jest.clearAllMocks()
|
16
|
-
|
17
|
-
// Mock de componentes
|
18
|
-
jest.doMock('./icon', () => ({ Icon: mockIcon }))
|
19
|
-
jest.doMock('./text', () => ({ Text: mockText }))
|
20
|
-
jest.doMock('./checkbox', () => ({ CheckBox: mockCheckBox }))
|
21
|
-
jest.doMock('./textfield', () => ({ TextField: mockTextField, DropDown: mockDropDown }))
|
22
|
-
jest.doMock('../widgets/empty/EmptyMessage', () => ({ EmptyMessage: mockEmptyMessage }))
|
23
|
-
|
24
|
-
// Mock de console.warn
|
25
|
-
jest.spyOn(console, 'warn').mockImplementation(() => {})
|
26
|
-
|
27
|
-
// Mock de navigator.clipboard
|
28
|
-
global.navigator = {
|
29
|
-
clipboard: {
|
30
|
-
writeText: jest.fn().mockResolvedValue(undefined)
|
31
|
-
},
|
32
|
-
userLanguage: 'en-US',
|
33
|
-
language: 'en-US'
|
34
|
-
}
|
35
|
-
|
36
|
-
// Mock de URL.createObjectURL
|
37
|
-
global.URL = {
|
38
|
-
createObjectURL: jest.fn().mockReturnValue('mock-url'),
|
39
|
-
revokeObjectURL: jest.fn()
|
40
|
-
}
|
41
|
-
|
42
|
-
// Mock de Blob
|
43
|
-
global.Blob = jest.fn().mockImplementation((content, options) => ({
|
44
|
-
content,
|
45
|
-
options
|
46
|
-
}))
|
47
|
-
|
48
|
-
// Mock de document.createElement
|
49
|
-
global.document = {
|
50
|
-
createElement: jest.fn().mockReturnValue({
|
51
|
-
href: '',
|
52
|
-
download: '',
|
53
|
-
click: jest.fn()
|
54
|
-
})
|
55
|
-
}
|
56
|
-
})
|
57
|
-
|
58
|
-
afterEach(() => {
|
59
|
-
console.warn.mockRestore()
|
60
|
-
if (global.document && global.document.createElement.mockRestore) {
|
61
|
-
global.document.createElement.mockRestore()
|
62
|
-
}
|
63
|
-
})
|
64
|
-
|
65
|
-
// DataTable2 Component Tests
|
66
|
-
describe('DataTable2 Component', () => {
|
67
|
-
const mockColumns = [
|
68
|
-
{ id: 'name', label: 'Name', type: 'String', sortable: true },
|
69
|
-
{ id: 'age', label: 'Age', type: 'Number', sortable: true },
|
70
|
-
{ id: 'email', label: 'Email', type: 'String', filterable: true }
|
71
|
-
]
|
72
|
-
|
73
|
-
const mockRows = [
|
74
|
-
{ id: 1, name: 'John Doe', age: 30, email: 'john@example.com' },
|
75
|
-
{ id: 2, name: 'Jane Smith', age: 25, email: 'jane@example.com' },
|
76
|
-
{ id: 3, name: 'Bob Johnson', age: 35, email: 'bob@example.com' }
|
77
|
-
]
|
78
|
-
|
79
|
-
test('component exports correctly', () => {
|
80
|
-
expect(DataTable2).toBeDefined()
|
81
|
-
expect(typeof DataTable2).toBe('function')
|
82
|
-
})
|
83
|
-
|
84
|
-
test('component has correct PropTypes', () => {
|
85
|
-
expect(DataTable2.propTypes).toBeDefined()
|
86
|
-
expect(DataTable2.propTypes.columns).toBeDefined()
|
87
|
-
expect(DataTable2.propTypes.rows).toBeDefined()
|
88
|
-
expect(DataTable2.propTypes.onRowSelection).toBeDefined()
|
89
|
-
expect(DataTable2.propTypes.onSort).toBeDefined()
|
90
|
-
expect(DataTable2.propTypes.onCheckAll).toBeDefined()
|
91
|
-
expect(DataTable2.propTypes.editable).toBeDefined()
|
92
|
-
expect(DataTable2.propTypes.outlined).toBeDefined()
|
93
|
-
expect(DataTable2.propTypes.expanded).toBeDefined()
|
94
|
-
expect(DataTable2.propTypes.multisort).toBeDefined()
|
95
|
-
expect(DataTable2.propTypes.filterable).toBeDefined()
|
96
|
-
// New props
|
97
|
-
expect(DataTable2.propTypes.loading).toBeDefined()
|
98
|
-
expect(DataTable2.propTypes.skeleton).toBeDefined()
|
99
|
-
expect(DataTable2.propTypes.searchable).toBeDefined()
|
100
|
-
expect(DataTable2.propTypes.exportable).toBeDefined()
|
101
|
-
expect(DataTable2.propTypes.virtualScrolling).toBeDefined()
|
102
|
-
})
|
103
|
-
|
104
|
-
test('component has correct defaultProps', () => {
|
105
|
-
expect(DataTable2.defaultProps).toBeDefined()
|
106
|
-
expect(DataTable2.defaultProps.columns).toEqual([])
|
107
|
-
expect(DataTable2.defaultProps.rows).toEqual([])
|
108
|
-
expect(DataTable2.defaultProps.expanded).toBe(false)
|
109
|
-
expect(DataTable2.defaultProps.emptyMessage).toBe("No Results Found")
|
110
|
-
expect(DataTable2.defaultProps.emptyIcon).toBe("search_off")
|
111
|
-
expect(DataTable2.defaultProps.multisort).toBe(false)
|
112
|
-
expect(DataTable2.defaultProps.filterable).toBe(false)
|
113
|
-
// New defaults
|
114
|
-
expect(DataTable2.defaultProps.loading).toBe(false)
|
115
|
-
expect(DataTable2.defaultProps.skeleton).toBe(false)
|
116
|
-
expect(DataTable2.defaultProps.striped).toBe(false)
|
117
|
-
expect(DataTable2.defaultProps.hover).toBe(true)
|
118
|
-
expect(DataTable2.defaultProps.responsive).toBe(true)
|
119
|
-
expect(DataTable2.defaultProps.stickyHeader).toBe(true)
|
120
|
-
expect(DataTable2.defaultProps.selectionMode).toBe('single')
|
121
|
-
expect(DataTable2.defaultProps.sortMode).toBe('single')
|
122
|
-
})
|
123
|
-
|
124
|
-
test('validates props correctly', () => {
|
125
|
-
const validateProps = (columns, rows, virtualScrolling, pageSize) => {
|
126
|
-
if (!Array.isArray(columns)) {
|
127
|
-
console.warn('DataTable2: columns prop must be an array')
|
128
|
-
}
|
129
|
-
if (!Array.isArray(rows)) {
|
130
|
-
console.warn('DataTable2: rows prop must be an array')
|
131
|
-
}
|
132
|
-
if (virtualScrolling && !pageSize) {
|
133
|
-
console.warn('DataTable2: pageSize is required when virtualScrolling is enabled')
|
134
|
-
}
|
135
|
-
}
|
136
|
-
|
137
|
-
// Invalid columns prop
|
138
|
-
validateProps('not an array', [], false, null)
|
139
|
-
expect(console.warn).toHaveBeenCalledWith('DataTable2: columns prop must be an array')
|
140
|
-
|
141
|
-
console.warn.mockClear()
|
142
|
-
|
143
|
-
// Invalid rows prop
|
144
|
-
validateProps([], 'not an array', false, null)
|
145
|
-
expect(console.warn).toHaveBeenCalledWith('DataTable2: rows prop must be an array')
|
146
|
-
|
147
|
-
console.warn.mockClear()
|
148
|
-
|
149
|
-
// Virtual scrolling without pageSize
|
150
|
-
validateProps([], [], true, null)
|
151
|
-
expect(console.warn).toHaveBeenCalledWith('DataTable2: pageSize is required when virtualScrolling is enabled')
|
152
|
-
|
153
|
-
console.warn.mockClear()
|
154
|
-
|
155
|
-
// Valid props
|
156
|
-
validateProps(mockColumns, mockRows, false, null)
|
157
|
-
expect(console.warn).not.toHaveBeenCalled()
|
158
|
-
})
|
159
|
-
|
160
|
-
test('handles sort correctly (maintaining original behavior)', () => {
|
161
|
-
const changeSort = (id, sortDir, sortMode, multisort, setSortDir) => {
|
162
|
-
if (sortMode === 'none') return
|
163
|
-
|
164
|
-
if (sortMode === 'multiple' || multisort) {
|
165
|
-
const nextDir = sortDir[id] ? sortDir[id] * -1 : 1
|
166
|
-
const next = Object.assign({}, sortDir, { [id]: nextDir })
|
167
|
-
setSortDir(next)
|
168
|
-
} else {
|
169
|
-
const nextDir = sortDir[id] ? sortDir[id] * -1 : 1
|
170
|
-
setSortDir({ [id]: nextDir })
|
171
|
-
}
|
172
|
-
}
|
173
|
-
|
174
|
-
const mockSetSortDir = jest.fn()
|
175
|
-
|
176
|
-
// Single sort mode
|
177
|
-
changeSort('name', {}, 'single', false, mockSetSortDir)
|
178
|
-
expect(mockSetSortDir).toHaveBeenCalledWith({ name: 1 })
|
179
|
-
|
180
|
-
mockSetSortDir.mockClear()
|
181
|
-
|
182
|
-
// Multiple sort mode
|
183
|
-
changeSort('age', { name: 1 }, 'multiple', false, mockSetSortDir)
|
184
|
-
expect(mockSetSortDir).toHaveBeenCalledWith({ name: 1, age: 1 })
|
185
|
-
|
186
|
-
mockSetSortDir.mockClear()
|
187
|
-
|
188
|
-
// Reverse sort
|
189
|
-
changeSort('name', { name: 1 }, 'single', false, mockSetSortDir)
|
190
|
-
expect(mockSetSortDir).toHaveBeenCalledWith({ name: -1 })
|
191
|
-
|
192
|
-
mockSetSortDir.mockClear()
|
193
|
-
|
194
|
-
// No sort mode
|
195
|
-
changeSort('name', {}, 'none', false, mockSetSortDir)
|
196
|
-
expect(mockSetSortDir).not.toHaveBeenCalled()
|
197
|
-
})
|
198
|
-
|
199
|
-
test('handles multiSort correctly (maintaining original logic)', () => {
|
200
|
-
const multiSort = (array, sortObject = {}) => {
|
201
|
-
const sortKeys = Object.keys(sortObject);
|
202
|
-
|
203
|
-
if (!sortKeys.length) {
|
204
|
-
return array;
|
205
|
-
}
|
206
|
-
|
207
|
-
const keySort = (a, b, direction) => {
|
208
|
-
direction = direction !== null ? direction : 1;
|
209
|
-
|
210
|
-
// check if a and b are numbers and compare as numbers
|
211
|
-
if (!isNaN(a) && !isNaN(b)) {
|
212
|
-
a = Number(a);
|
213
|
-
b = Number(b);
|
214
|
-
}
|
215
|
-
|
216
|
-
// If b > a, multiply by -1 to get the reverse direction.
|
217
|
-
return a > b ? direction : -1 * direction;
|
218
|
-
};
|
219
|
-
|
220
|
-
return array.sort((a, b) => {
|
221
|
-
let sorted = 0;
|
222
|
-
let index = 0;
|
223
|
-
|
224
|
-
// Loop until sorted (-1 or 1) or until the sort keys have been processed.
|
225
|
-
while (sorted === 0 && index < sortKeys.length) {
|
226
|
-
const key = sortKeys[index];
|
227
|
-
if (key) {
|
228
|
-
const direction = sortObject[key];
|
229
|
-
sorted = keySort(a[key], b[key], direction);
|
230
|
-
index++;
|
231
|
-
}
|
232
|
-
}
|
233
|
-
|
234
|
-
return sorted;
|
235
|
-
});
|
236
|
-
};
|
237
|
-
|
238
|
-
const testData = [
|
239
|
-
{ name: 'Charlie', age: 30 },
|
240
|
-
{ name: 'Alice', age: 25 },
|
241
|
-
{ name: 'Bob', age: 35 }
|
242
|
-
]
|
243
|
-
|
244
|
-
// No sort
|
245
|
-
expect(multiSort([...testData], {})).toEqual(testData)
|
246
|
-
|
247
|
-
// Sort by name ascending
|
248
|
-
const sortedByName = multiSort([...testData], { name: 1 })
|
249
|
-
expect(sortedByName[0].name).toBe('Alice')
|
250
|
-
expect(sortedByName[1].name).toBe('Bob')
|
251
|
-
expect(sortedByName[2].name).toBe('Charlie')
|
252
|
-
|
253
|
-
// Sort by age descending
|
254
|
-
const sortedByAge = multiSort([...testData], { age: -1 })
|
255
|
-
expect(sortedByAge[0].age).toBe(35)
|
256
|
-
expect(sortedByAge[1].age).toBe(30)
|
257
|
-
expect(sortedByAge[2].age).toBe(25)
|
258
|
-
|
259
|
-
// Multi-sort: name asc, then age desc
|
260
|
-
const multiSorted = multiSort([...testData], { name: 1, age: -1 })
|
261
|
-
expect(multiSorted[0].name).toBe('Alice')
|
262
|
-
})
|
263
|
-
|
264
|
-
test('handles row selection correctly (maintaining original behavior)', () => {
|
265
|
-
const mockOnRowSelection = jest.fn()
|
266
|
-
const mockOnRowClick = jest.fn()
|
267
|
-
|
268
|
-
const select = (row, event, selectedRows, selectionMode, setSelectedRows, onRowSelection, onRowClick) => {
|
269
|
-
if (event.target.id !== "checked") {
|
270
|
-
// Enhanced selection logic
|
271
|
-
if (selectionMode === 'multiple') {
|
272
|
-
const newSelected = new Set(selectedRows)
|
273
|
-
if (newSelected.has(row.id)) {
|
274
|
-
newSelected.delete(row.id)
|
275
|
-
} else {
|
276
|
-
newSelected.add(row.id)
|
277
|
-
}
|
278
|
-
setSelectedRows(newSelected)
|
279
|
-
} else if (selectionMode === 'single') {
|
280
|
-
setSelectedRows(new Set([row.id]))
|
281
|
-
}
|
282
|
-
|
283
|
-
// Call original callback
|
284
|
-
if (onRowSelection) onRowSelection(row, event)
|
285
|
-
if (onRowClick) onRowClick(row, event)
|
286
|
-
}
|
287
|
-
}
|
288
|
-
|
289
|
-
const mockSetSelectedRows = jest.fn()
|
290
|
-
const mockEvent = { target: { id: 'not-checked' } }
|
291
|
-
const mockRow = { id: 1, name: 'Test' }
|
292
|
-
|
293
|
-
// Single selection
|
294
|
-
select(mockRow, mockEvent, new Set(), 'single', mockSetSelectedRows, mockOnRowSelection, mockOnRowClick)
|
295
|
-
expect(mockSetSelectedRows).toHaveBeenCalledWith(new Set([1]))
|
296
|
-
expect(mockOnRowSelection).toHaveBeenCalledWith(mockRow, mockEvent)
|
297
|
-
expect(mockOnRowClick).toHaveBeenCalledWith(mockRow, mockEvent)
|
298
|
-
|
299
|
-
mockSetSelectedRows.mockClear()
|
300
|
-
mockOnRowSelection.mockClear()
|
301
|
-
mockOnRowClick.mockClear()
|
302
|
-
|
303
|
-
// Multiple selection - add
|
304
|
-
select(mockRow, mockEvent, new Set(), 'multiple', mockSetSelectedRows, mockOnRowSelection, mockOnRowClick)
|
305
|
-
expect(mockSetSelectedRows).toHaveBeenCalledWith(new Set([1]))
|
306
|
-
|
307
|
-
// Multiple selection - remove
|
308
|
-
select(mockRow, mockEvent, new Set([1]), 'multiple', mockSetSelectedRows, mockOnRowSelection, mockOnRowClick)
|
309
|
-
expect(mockSetSelectedRows).toHaveBeenCalledWith(new Set())
|
310
|
-
|
311
|
-
// Reset mocks before checkbox test
|
312
|
-
mockOnRowSelection.mockClear()
|
313
|
-
mockOnRowClick.mockClear()
|
314
|
-
mockSetSelectedRows.mockClear()
|
315
|
-
|
316
|
-
// Checkbox click (should not trigger selection)
|
317
|
-
const checkboxEvent = { target: { id: 'checked' } }
|
318
|
-
select(mockRow, checkboxEvent, new Set(), 'single', mockSetSelectedRows, mockOnRowSelection, mockOnRowClick)
|
319
|
-
expect(mockOnRowSelection).not.toHaveBeenCalled()
|
320
|
-
expect(mockOnRowClick).not.toHaveBeenCalled()
|
321
|
-
})
|
322
|
-
|
323
|
-
test('handles check all correctly (maintaining original behavior)', () => {
|
324
|
-
const mockOnCheckAll = jest.fn()
|
325
|
-
|
326
|
-
const checkAll = (id, value, rows, selectionMode, setAllChecked, setSelectedRows, onCheckAll) => {
|
327
|
-
const ids = rows.map(row => row.id)
|
328
|
-
setAllChecked(value)
|
329
|
-
|
330
|
-
if (selectionMode === 'multiple') {
|
331
|
-
if (value) {
|
332
|
-
setSelectedRows(new Set(ids))
|
333
|
-
} else {
|
334
|
-
setSelectedRows(new Set())
|
335
|
-
}
|
336
|
-
}
|
337
|
-
|
338
|
-
if (onCheckAll) onCheckAll(ids, value)
|
339
|
-
}
|
340
|
-
|
341
|
-
const mockSetAllChecked = jest.fn()
|
342
|
-
const mockSetSelectedRows = jest.fn()
|
343
|
-
|
344
|
-
// Check all
|
345
|
-
checkAll('checked', true, mockRows, 'multiple', mockSetAllChecked, mockSetSelectedRows, mockOnCheckAll)
|
346
|
-
expect(mockSetAllChecked).toHaveBeenCalledWith(true)
|
347
|
-
expect(mockSetSelectedRows).toHaveBeenCalledWith(new Set([1, 2, 3]))
|
348
|
-
expect(mockOnCheckAll).toHaveBeenCalledWith([1, 2, 3], true)
|
349
|
-
|
350
|
-
mockSetAllChecked.mockClear()
|
351
|
-
mockSetSelectedRows.mockClear()
|
352
|
-
mockOnCheckAll.mockClear()
|
353
|
-
|
354
|
-
// Uncheck all
|
355
|
-
checkAll('checked', false, mockRows, 'multiple', mockSetAllChecked, mockSetSelectedRows, mockOnCheckAll)
|
356
|
-
expect(mockSetAllChecked).toHaveBeenCalledWith(false)
|
357
|
-
expect(mockSetSelectedRows).toHaveBeenCalledWith(new Set())
|
358
|
-
expect(mockOnCheckAll).toHaveBeenCalledWith([1, 2, 3], false)
|
359
|
-
})
|
360
|
-
|
361
|
-
test('handles search functionality', () => {
|
362
|
-
const searchRows = (rows, searchTerm, searchable, columns) => {
|
363
|
-
if (!searchTerm || !searchable) return rows
|
364
|
-
|
365
|
-
return rows.filter(row => {
|
366
|
-
return columns.some(column => {
|
367
|
-
const value = row[column.id]
|
368
|
-
if (value == null) return false
|
369
|
-
return String(value).toLowerCase().includes(searchTerm.toLowerCase())
|
370
|
-
})
|
371
|
-
})
|
372
|
-
}
|
373
|
-
|
374
|
-
// No search term
|
375
|
-
expect(searchRows(mockRows, '', true, mockColumns)).toEqual(mockRows)
|
376
|
-
|
377
|
-
// Search disabled
|
378
|
-
expect(searchRows(mockRows, 'john', false, mockColumns)).toEqual(mockRows)
|
379
|
-
|
380
|
-
// Search for 'john'
|
381
|
-
const johnResults = searchRows(mockRows, 'john', true, mockColumns)
|
382
|
-
expect(johnResults).toHaveLength(2) // John Doe and Bob Johnson
|
383
|
-
expect(johnResults.map(r => r.name)).toEqual(['John Doe', 'Bob Johnson'])
|
384
|
-
|
385
|
-
// Search for email
|
386
|
-
const emailResults = searchRows(mockRows, 'jane@', true, mockColumns)
|
387
|
-
expect(emailResults).toHaveLength(1)
|
388
|
-
expect(emailResults[0].name).toBe('Jane Smith')
|
389
|
-
|
390
|
-
// No results
|
391
|
-
const noResults = searchRows(mockRows, 'xyz', true, mockColumns)
|
392
|
-
expect(noResults).toHaveLength(0)
|
393
|
-
})
|
394
|
-
|
395
|
-
test('handles export functionality', () => {
|
396
|
-
const handleExport = (processedRows, columns, onExport) => {
|
397
|
-
if (onExport) {
|
398
|
-
onExport(processedRows, columns)
|
399
|
-
} else {
|
400
|
-
// Default CSV export
|
401
|
-
const csvContent = [
|
402
|
-
columns.map(col => col.label || col.id).join(','),
|
403
|
-
...processedRows.map(row =>
|
404
|
-
columns.map(col => {
|
405
|
-
const value = row[col.id]
|
406
|
-
return typeof value === 'string' ? `"${value}"` : value
|
407
|
-
}).join(',')
|
408
|
-
)
|
409
|
-
].join('\n')
|
410
|
-
|
411
|
-
const blob = new Blob([csvContent], { type: 'text/csv' })
|
412
|
-
const url = URL.createObjectURL(blob)
|
413
|
-
const a = document.createElement('a')
|
414
|
-
a.href = url
|
415
|
-
a.download = 'table-export.csv'
|
416
|
-
a.click()
|
417
|
-
URL.revokeObjectURL(url)
|
418
|
-
}
|
419
|
-
}
|
420
|
-
|
421
|
-
const mockOnExport = jest.fn()
|
422
|
-
|
423
|
-
// Custom export
|
424
|
-
handleExport(mockRows, mockColumns, mockOnExport)
|
425
|
-
expect(mockOnExport).toHaveBeenCalledWith(mockRows, mockColumns)
|
426
|
-
|
427
|
-
mockOnExport.mockClear()
|
428
|
-
|
429
|
-
// Default CSV export
|
430
|
-
handleExport(mockRows, mockColumns, null)
|
431
|
-
expect(Blob).toHaveBeenCalledWith([expect.stringContaining('Name,Age,Email')], { type: 'text/csv' })
|
432
|
-
expect(URL.createObjectURL).toHaveBeenCalled()
|
433
|
-
expect(global.document.createElement).toHaveBeenCalledWith('a')
|
434
|
-
})
|
435
|
-
|
436
|
-
test('handles virtual scrolling pagination', () => {
|
437
|
-
const paginateRows = (filteredRows, virtualScrolling, currentPage, pageSize) => {
|
438
|
-
if (!virtualScrolling) return filteredRows
|
439
|
-
|
440
|
-
const start = currentPage * pageSize
|
441
|
-
const end = start + pageSize
|
442
|
-
return filteredRows.slice(start, end)
|
443
|
-
}
|
444
|
-
|
445
|
-
const largeDataset = Array.from({ length: 100 }, (_, i) => ({
|
446
|
-
id: i + 1,
|
447
|
-
name: `User ${i + 1}`,
|
448
|
-
age: 20 + (i % 50),
|
449
|
-
email: `user${i + 1}@example.com`
|
450
|
-
}))
|
451
|
-
|
452
|
-
// Virtual scrolling disabled
|
453
|
-
expect(paginateRows(largeDataset, false, 0, 10)).toEqual(largeDataset)
|
454
|
-
|
455
|
-
// First page
|
456
|
-
const firstPage = paginateRows(largeDataset, true, 0, 10)
|
457
|
-
expect(firstPage).toHaveLength(10)
|
458
|
-
expect(firstPage[0].id).toBe(1)
|
459
|
-
expect(firstPage[9].id).toBe(10)
|
460
|
-
|
461
|
-
// Second page
|
462
|
-
const secondPage = paginateRows(largeDataset, true, 1, 10)
|
463
|
-
expect(secondPage).toHaveLength(10)
|
464
|
-
expect(secondPage[0].id).toBe(11)
|
465
|
-
expect(secondPage[9].id).toBe(20)
|
466
|
-
|
467
|
-
// Last page (partial)
|
468
|
-
const lastPage = paginateRows(largeDataset, true, 9, 10)
|
469
|
-
expect(lastPage).toHaveLength(10)
|
470
|
-
expect(lastPage[0].id).toBe(91)
|
471
|
-
expect(lastPage[9].id).toBe(100)
|
472
|
-
})
|
473
|
-
|
474
|
-
test('generates CSS classes correctly', () => {
|
475
|
-
const generateClasses = (outlined, striped, compact, bordered, hover, rowHeight, density, theme, responsive, isLoading, skeleton, className) => {
|
476
|
-
return [
|
477
|
-
'datatable8', // Maintain original class for compatibility
|
478
|
-
'datatable2', // New class for v2 features
|
479
|
-
outlined && 'outlined',
|
480
|
-
striped && 'datatable2--striped',
|
481
|
-
compact && 'datatable2--compact',
|
482
|
-
bordered && 'datatable2--bordered',
|
483
|
-
!hover && 'datatable2--no-hover',
|
484
|
-
`datatable2--${rowHeight}`,
|
485
|
-
`datatable2--${density}`,
|
486
|
-
`datatable2--${theme}`,
|
487
|
-
responsive && 'datatable2--responsive',
|
488
|
-
isLoading && 'datatable2--loading',
|
489
|
-
skeleton && 'datatable2--skeleton',
|
490
|
-
className
|
491
|
-
].filter(Boolean).join(' ')
|
492
|
-
}
|
493
|
-
|
494
|
-
expect(generateClasses(false, false, false, false, true, 'medium', 'normal', 'default', true, false, false, ''))
|
495
|
-
.toBe('datatable8 datatable2 datatable2--medium datatable2--normal datatable2--default datatable2--responsive')
|
496
|
-
|
497
|
-
expect(generateClasses(true, true, true, true, false, 'large', 'comfortable', 'dark', false, true, true, 'custom'))
|
498
|
-
.toBe('datatable8 datatable2 outlined datatable2--striped datatable2--compact datatable2--bordered datatable2--no-hover datatable2--large datatable2--comfortable datatable2--dark datatable2--loading datatable2--skeleton custom')
|
499
|
-
})
|
500
|
-
|
501
|
-
test('maintains 100% compatibility with original DataTable', () => {
|
502
|
-
// Test that all original props work exactly the same
|
503
|
-
const originalProps = {
|
504
|
-
columns: mockColumns,
|
505
|
-
rows: mockRows,
|
506
|
-
onRowSelection: jest.fn(),
|
507
|
-
onSort: jest.fn(),
|
508
|
-
onCheckAll: jest.fn(),
|
509
|
-
editable: true,
|
510
|
-
outlined: true,
|
511
|
-
expanded: false,
|
512
|
-
className: 'test-table',
|
513
|
-
emptyMessage: "Custom empty message",
|
514
|
-
emptyIcon: "custom_icon",
|
515
|
-
multisort: true,
|
516
|
-
filterable: true,
|
517
|
-
onClearFilters: jest.fn()
|
518
|
-
}
|
519
|
-
|
520
|
-
// These should all work without any changes
|
521
|
-
expect(() => {
|
522
|
-
// Simulate component creation with original props
|
523
|
-
const component = { props: originalProps }
|
524
|
-
expect(component.props.columns).toEqual(mockColumns)
|
525
|
-
expect(component.props.rows).toEqual(mockRows)
|
526
|
-
expect(component.props.editable).toBe(true)
|
527
|
-
expect(component.props.outlined).toBe(true)
|
528
|
-
expect(component.props.multisort).toBe(true)
|
529
|
-
expect(component.props.filterable).toBe(true)
|
530
|
-
}).not.toThrow()
|
531
|
-
|
532
|
-
// Verify callbacks maintain same signature
|
533
|
-
expect(typeof originalProps.onRowSelection).toBe('function')
|
534
|
-
expect(typeof originalProps.onSort).toBe('function')
|
535
|
-
expect(typeof originalProps.onCheckAll).toBe('function')
|
536
|
-
expect(typeof originalProps.onClearFilters).toBe('function')
|
537
|
-
})
|
538
|
-
|
539
|
-
test('new features are optional and do not break existing code', () => {
|
540
|
-
// Test that new props have sensible defaults
|
541
|
-
const newFeatures = {
|
542
|
-
loading: false,
|
543
|
-
skeleton: false,
|
544
|
-
striped: false,
|
545
|
-
hover: true,
|
546
|
-
compact: false,
|
547
|
-
bordered: false,
|
548
|
-
responsive: true,
|
549
|
-
stickyHeader: true,
|
550
|
-
virtualScrolling: false,
|
551
|
-
pageSize: 50,
|
552
|
-
selectionMode: 'single',
|
553
|
-
sortMode: 'single',
|
554
|
-
resizable: false,
|
555
|
-
reorderable: false,
|
556
|
-
exportable: false,
|
557
|
-
searchable: false,
|
558
|
-
accessibility: true,
|
559
|
-
showRowNumbers: false,
|
560
|
-
showSelectAll: true
|
561
|
-
}
|
562
|
-
|
563
|
-
// All new features should have safe defaults
|
564
|
-
Object.entries(newFeatures).forEach(([key, expectedDefault]) => {
|
565
|
-
expect(DataTable2.defaultProps[key]).toBe(expectedDefault)
|
566
|
-
})
|
567
|
-
|
568
|
-
// Test that omitting new props doesn't break anything
|
569
|
-
const minimalProps = {
|
570
|
-
columns: mockColumns,
|
571
|
-
rows: mockRows
|
572
|
-
}
|
573
|
-
|
574
|
-
expect(() => {
|
575
|
-
// Simulate component with minimal props
|
576
|
-
const component = { props: { ...DataTable2.defaultProps, ...minimalProps } }
|
577
|
-
expect(component.props.columns).toEqual(mockColumns)
|
578
|
-
expect(component.props.rows).toEqual(mockRows)
|
579
|
-
}).not.toThrow()
|
580
|
-
})
|
581
|
-
})
|
582
|
-
})
|
package/src/html/text.test.js
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
import React, { useState } from 'react'
|
2
|
-
import { useEffect } from 'react/cjs/react.production.min'
|
3
|
-
import { Text, TEXTFORMATS } from './text'
|
4
|
-
|
5
|
-
const TextTest = (prop) => {
|
6
|
-
|
7
|
-
|
8
|
-
return (
|
9
|
-
<>
|
10
|
-
<Text format={TEXTFORMATS.NUMERIC}>846964.4199142859</Text>
|
11
|
-
<Text format={TEXTFORMATS.NUMERIC}>{"345356345.345"}</Text>
|
12
|
-
<Text format={TEXTFORMATS.STRING}>Lorem Ipsum dolro sit amet....</Text>
|
13
|
-
</>
|
14
|
-
)
|
15
|
-
}
|
@@ -1,51 +0,0 @@
|
|
1
|
-
import React, { useState } from 'react'
|
2
|
-
import { DropDown, TextField, TextArea, TokenField } from '.'
|
3
|
-
import { DateRange } from './textfield'
|
4
|
-
|
5
|
-
const TextFieldTest = (prop) => {
|
6
|
-
|
7
|
-
const [form, setForm] = useState({
|
8
|
-
gender3: "3",
|
9
|
-
labelLeft: "xxxxx"
|
10
|
-
})
|
11
|
-
|
12
|
-
function change(id, value) {
|
13
|
-
console.log('2', id, value)
|
14
|
-
const next = Object.assign({}, form, { [id]: value })
|
15
|
-
setForm(next)
|
16
|
-
}
|
17
|
-
|
18
|
-
const options = [
|
19
|
-
{ label: "", value: "" },
|
20
|
-
{ label: "One", value: "1" },
|
21
|
-
{ label: "Two", value: "2" },
|
22
|
-
{ label: "Three", value: "3" },
|
23
|
-
{ label: "Four", value: "4" },
|
24
|
-
{ label: "Five", value: "5" },
|
25
|
-
]
|
26
|
-
|
27
|
-
const options2 = [
|
28
|
-
{ label: "YES", value: "true" },
|
29
|
-
{ label: "NO", value: "false" },
|
30
|
-
]
|
31
|
-
|
32
|
-
return (
|
33
|
-
<>
|
34
|
-
<TextField id="labelLeft" labelPosition="left" label="Label Left" value={form.labelLeft} onChange={change}/>
|
35
|
-
<TextField id="name" label="Name" value={form.name} onChange={change} outlined/>
|
36
|
-
<br/>
|
37
|
-
<DropDown id="b1" label="Boolean1" labelPosition="left" onChange={change} options={options2} value={form.b1} />
|
38
|
-
<br/>
|
39
|
-
<DropDown id="gender1" label="Dropdown 1" value={form.gender1} onChange={change} options={options} predictive={false} position="top"/>
|
40
|
-
<DropDown id="gender2" label="Dropdown 2" value={form.gender2} onChange={change} options={options} predictive={true}/>
|
41
|
-
<DropDown id="gender3" label="Dropdown 3" value={form.gender3} onChange={change} options={options} predictive={false} editable={true}/>
|
42
|
-
<TokenField id="token1" label="Tokens" onChange={change} />
|
43
|
-
<TokenField id="token2" label="Tokens DropDown" onChange={change} options={options} tokens={form.token2}/>
|
44
|
-
<br/>
|
45
|
-
<br/>
|
46
|
-
<TextArea id="text1" label="Text 1" value={form.text1} onChange={change} placeholder="loremitsum"/>
|
47
|
-
<TextField id="date1" type="DATE" label="Date" value={form.date1} onChange={change} />
|
48
|
-
<DateRange id="range1" value={form.range1} onChange={change}/>
|
49
|
-
</>
|
50
|
-
)
|
51
|
-
}
|