@inglorious/web 2.0.0 → 2.0.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/package.json +2 -2
- package/src/index.js +1 -0
- package/src/list.js +35 -31
- package/src/mount.js +2 -3
- package/src/table.js +372 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inglorious/web",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "A new web framework that leverages the power of the Inglorious Store combined with the performance and simplicity of lit-html.",
|
|
5
5
|
"author": "IceOnFire <antony.mistretta@gmail.com> (https://ingloriouscoderz.it)",
|
|
6
6
|
"license": "MIT",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"lit-html": "^3.3.1",
|
|
39
|
-
"@inglorious/store": "7.
|
|
39
|
+
"@inglorious/store": "7.1.0",
|
|
40
40
|
"@inglorious/utils": "3.7.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
package/src/index.js
CHANGED
|
@@ -2,6 +2,7 @@ export { form, getFieldError, getFieldValue, isFieldTouched } from "./form.js"
|
|
|
2
2
|
export { list } from "./list.js"
|
|
3
3
|
export { mount } from "./mount.js"
|
|
4
4
|
export { router } from "./router.js"
|
|
5
|
+
export { getPaginationInfo, getRows, getSortDirection, table } from "./table.js"
|
|
5
6
|
export { createStore } from "@inglorious/store"
|
|
6
7
|
export { createDevtools } from "@inglorious/store/client/devtools.js"
|
|
7
8
|
export { createSelector } from "@inglorious/store/select.js"
|
package/src/list.js
CHANGED
|
@@ -2,6 +2,7 @@ import { html } from "lit-html"
|
|
|
2
2
|
import { ref } from "lit-html/directives/ref.js"
|
|
3
3
|
|
|
4
4
|
const LIST_START = 0
|
|
5
|
+
const PRETTY_INDEX = 1
|
|
5
6
|
|
|
6
7
|
export const list = {
|
|
7
8
|
init(entity) {
|
|
@@ -12,11 +13,41 @@ export const list = {
|
|
|
12
13
|
resetList(entity)
|
|
13
14
|
},
|
|
14
15
|
|
|
16
|
+
scroll(entity, containerEl) {
|
|
17
|
+
const scrollTop = containerEl.scrollTop
|
|
18
|
+
const { items, bufferSize, itemHeight, estimatedHeight, viewportHeight } =
|
|
19
|
+
entity
|
|
20
|
+
const height = itemHeight || estimatedHeight
|
|
21
|
+
|
|
22
|
+
const start = Math.max(
|
|
23
|
+
LIST_START,
|
|
24
|
+
Math.floor(scrollTop / height) - bufferSize,
|
|
25
|
+
)
|
|
26
|
+
const visibleCount = Math.ceil(viewportHeight / height)
|
|
27
|
+
const end = Math.min(start + visibleCount + bufferSize, items.length)
|
|
28
|
+
|
|
29
|
+
if (
|
|
30
|
+
entity.visibleRange.start === start &&
|
|
31
|
+
entity.visibleRange.end === end
|
|
32
|
+
) {
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
entity.scrollTop = scrollTop
|
|
37
|
+
entity.visibleRange = { start, end }
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
measureHeight(entity, containerEl) {
|
|
41
|
+
const firstItem = containerEl.querySelector("[data-index]")
|
|
42
|
+
if (!firstItem) return
|
|
43
|
+
|
|
44
|
+
entity.itemHeight = firstItem.offsetHeight
|
|
45
|
+
},
|
|
46
|
+
|
|
15
47
|
render(entity, api) {
|
|
16
48
|
const { items, visibleRange, viewportHeight, itemHeight, estimatedHeight } =
|
|
17
49
|
entity
|
|
18
|
-
const
|
|
19
|
-
const type = types[entity.type]
|
|
50
|
+
const type = api.getType(entity.type)
|
|
20
51
|
|
|
21
52
|
if (!items) {
|
|
22
53
|
console.warn(`list entity ${entity.id} needs 'items'`)
|
|
@@ -63,35 +94,8 @@ export const list = {
|
|
|
63
94
|
`
|
|
64
95
|
},
|
|
65
96
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const { items, bufferSize, itemHeight, estimatedHeight, viewportHeight } =
|
|
69
|
-
entity
|
|
70
|
-
const height = itemHeight || estimatedHeight
|
|
71
|
-
|
|
72
|
-
const start = Math.max(
|
|
73
|
-
LIST_START,
|
|
74
|
-
Math.floor(scrollTop / height) - bufferSize,
|
|
75
|
-
)
|
|
76
|
-
const visibleCount = Math.ceil(viewportHeight / height)
|
|
77
|
-
const end = Math.min(start + visibleCount + bufferSize, items.length)
|
|
78
|
-
|
|
79
|
-
if (
|
|
80
|
-
entity.visibleRange.start === start &&
|
|
81
|
-
entity.visibleRange.end === end
|
|
82
|
-
) {
|
|
83
|
-
return
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
entity.scrollTop = scrollTop
|
|
87
|
-
entity.visibleRange = { start, end }
|
|
88
|
-
},
|
|
89
|
-
|
|
90
|
-
measureHeight(entity, containerEl) {
|
|
91
|
-
const firstItem = containerEl.querySelector("[data-index]")
|
|
92
|
-
if (!firstItem) return
|
|
93
|
-
|
|
94
|
-
entity.itemHeight = firstItem.offsetHeight
|
|
97
|
+
renderItem(item, index) {
|
|
98
|
+
return html`<div>${index + PRETTY_INDEX}. ${JSON.stringify(item)}</div>`
|
|
95
99
|
},
|
|
96
100
|
}
|
|
97
101
|
|
package/src/mount.js
CHANGED
|
@@ -14,7 +14,6 @@ export function mount(store, renderFn, element) {
|
|
|
14
14
|
/** @param {string} id */
|
|
15
15
|
render(id, options = {}) {
|
|
16
16
|
const entity = api.getEntity(id)
|
|
17
|
-
const types = api.getTypes()
|
|
18
17
|
|
|
19
18
|
if (!entity) {
|
|
20
19
|
const { allowType } = options
|
|
@@ -23,7 +22,7 @@ export function mount(store, renderFn, element) {
|
|
|
23
22
|
}
|
|
24
23
|
|
|
25
24
|
// No entity with this ID, try static type
|
|
26
|
-
const type =
|
|
25
|
+
const type = api.getType(id)
|
|
27
26
|
if (!type?.render) {
|
|
28
27
|
console.warn(`No entity or type found: ${id}`)
|
|
29
28
|
return html`<div>Not found: ${id}</div>`
|
|
@@ -32,7 +31,7 @@ export function mount(store, renderFn, element) {
|
|
|
32
31
|
}
|
|
33
32
|
|
|
34
33
|
// Entity exists, render it
|
|
35
|
-
const type =
|
|
34
|
+
const type = api.getType(entity.type)
|
|
36
35
|
if (!type?.render) {
|
|
37
36
|
console.warn(`No render function for type: ${entity.type}`)
|
|
38
37
|
return html`<div>No renderer for ${entity.type}</div>`
|
package/src/table.js
ADDED
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
/* eslint-disable no-magic-numbers */
|
|
2
|
+
|
|
3
|
+
export const table = {
|
|
4
|
+
init(entity) {
|
|
5
|
+
initTable(entity)
|
|
6
|
+
},
|
|
7
|
+
|
|
8
|
+
create(entity) {
|
|
9
|
+
initTable(entity)
|
|
10
|
+
},
|
|
11
|
+
|
|
12
|
+
sortChange(entity, columnId) {
|
|
13
|
+
const column = entity.columns.find((c) => c.id === columnId)
|
|
14
|
+
if (!column?.isSortable) return
|
|
15
|
+
|
|
16
|
+
const existingIndex = entity.sorts.findIndex((s) => s.column === columnId)
|
|
17
|
+
|
|
18
|
+
if (existingIndex !== -1) {
|
|
19
|
+
// Toggle direction
|
|
20
|
+
const existing = entity.sorts[existingIndex]
|
|
21
|
+
if (existing.direction === "asc") {
|
|
22
|
+
existing.direction = "desc"
|
|
23
|
+
} else {
|
|
24
|
+
// Remove from sort if going from desc back to nothing
|
|
25
|
+
entity.sorts.splice(existingIndex, 1)
|
|
26
|
+
}
|
|
27
|
+
} else {
|
|
28
|
+
// Add new sort
|
|
29
|
+
entity.sorts.push({ column: columnId, direction: "asc" })
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (entity.pagination) {
|
|
33
|
+
entity.pagination.page = 0
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
sortsClear(entity) {
|
|
38
|
+
entity.sorts = []
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
filter(entity, { columnId, value }) {
|
|
42
|
+
if (value === null || value === undefined || value === "") {
|
|
43
|
+
delete entity.filters[columnId]
|
|
44
|
+
} else {
|
|
45
|
+
entity.filters[columnId] = value
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Reset to first page when filtering
|
|
49
|
+
if (entity.pagination) {
|
|
50
|
+
entity.pagination.page = 0
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
filtersClear(entity) {
|
|
55
|
+
entity.filters = {}
|
|
56
|
+
if (entity.pagination) {
|
|
57
|
+
entity.pagination.page = 0
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
pageChange(entity, page) {
|
|
62
|
+
if (!entity.pagination) return
|
|
63
|
+
|
|
64
|
+
const totalPages = Math.ceil(
|
|
65
|
+
getTotalRows(entity) / entity.pagination.pageSize,
|
|
66
|
+
)
|
|
67
|
+
entity.pagination.page = Math.max(0, Math.min(page, totalPages - 1))
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
pageNext(entity) {
|
|
71
|
+
if (!entity.pagination) return
|
|
72
|
+
const totalPages = Math.ceil(
|
|
73
|
+
getTotalRows(entity) / entity.pagination.pageSize,
|
|
74
|
+
)
|
|
75
|
+
entity.pagination.page = Math.min(
|
|
76
|
+
entity.pagination.page + 1,
|
|
77
|
+
totalPages - 1,
|
|
78
|
+
)
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
pagePrev(entity) {
|
|
82
|
+
if (!entity.pagination) return
|
|
83
|
+
entity.pagination.page = Math.max(entity.pagination.page - 1, 0)
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
pageSizeChange(entity, pageSize) {
|
|
87
|
+
if (!entity.pagination) return
|
|
88
|
+
|
|
89
|
+
entity.pagination.pageSize = pageSize
|
|
90
|
+
entity.pagination.page = 0
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
rowSelect(entity, rowId) {
|
|
94
|
+
if (!entity.selection.includes(rowId)) {
|
|
95
|
+
entity.selection.push(rowId)
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
|
|
99
|
+
rowDeselect(entity, rowId) {
|
|
100
|
+
const index = entity.selection.indexOf(rowId)
|
|
101
|
+
if (index !== -1) {
|
|
102
|
+
entity.selection.splice(index, 1)
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
rowToggle(entity, rowId) {
|
|
107
|
+
const index = entity.selection.indexOf(rowId)
|
|
108
|
+
if (index === -1) {
|
|
109
|
+
entity.selection.push(rowId)
|
|
110
|
+
} else {
|
|
111
|
+
entity.selection.splice(index, 1)
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
rowsToggleAll(entity) {
|
|
116
|
+
const rows = getRows(entity)
|
|
117
|
+
const allSelected = rows.every((row) => entity.selection.includes(row.id))
|
|
118
|
+
|
|
119
|
+
if (allSelected) {
|
|
120
|
+
// Deselect all visible
|
|
121
|
+
rows.forEach((row) => {
|
|
122
|
+
const index = entity.selection.indexOf(row.id)
|
|
123
|
+
if (index !== -1) entity.selection.splice(index, 1)
|
|
124
|
+
})
|
|
125
|
+
} else {
|
|
126
|
+
// Select all visible
|
|
127
|
+
rows.forEach((row) => {
|
|
128
|
+
if (!entity.selection.includes(row.id)) {
|
|
129
|
+
entity.selection.push(row.id)
|
|
130
|
+
}
|
|
131
|
+
})
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
|
|
135
|
+
rowsSelectAll(entity) {
|
|
136
|
+
const rows = getRows(entity)
|
|
137
|
+
rows.forEach((row) => {
|
|
138
|
+
if (!entity.selection.includes(row.id)) {
|
|
139
|
+
entity.selection.push(row.id)
|
|
140
|
+
}
|
|
141
|
+
})
|
|
142
|
+
},
|
|
143
|
+
|
|
144
|
+
selectionClear(entity) {
|
|
145
|
+
entity.selection.length = 0
|
|
146
|
+
},
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Helper functions outside the type (like form helpers)
|
|
150
|
+
|
|
151
|
+
export function getRows(entity) {
|
|
152
|
+
let rows = entity.data || []
|
|
153
|
+
|
|
154
|
+
// Filtering
|
|
155
|
+
if (Object.keys(entity.filters).length > 0) {
|
|
156
|
+
rows = rows.filter((row) => {
|
|
157
|
+
return Object.entries(entity.filters).every(([columnId, filterValue]) => {
|
|
158
|
+
const column = entity.columns.find((c) => c.id === columnId)
|
|
159
|
+
if (!column) return true
|
|
160
|
+
|
|
161
|
+
// Custom filter function
|
|
162
|
+
if (column.filterFn) {
|
|
163
|
+
return column.filterFn(row, filterValue)
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Default filters by type
|
|
167
|
+
const value = row[columnId]
|
|
168
|
+
|
|
169
|
+
if (column.type === "number") {
|
|
170
|
+
if (typeof filterValue === "object") {
|
|
171
|
+
const { min, max } = filterValue
|
|
172
|
+
if (min !== undefined && value < min) return false
|
|
173
|
+
if (max !== undefined && value > max) return false
|
|
174
|
+
return true
|
|
175
|
+
}
|
|
176
|
+
return value === filterValue
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (column.type === "boolean") {
|
|
180
|
+
return value === filterValue
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// String filtering (case-insensitive contains)
|
|
184
|
+
return String(value)
|
|
185
|
+
.toLowerCase()
|
|
186
|
+
.includes(String(filterValue).toLowerCase())
|
|
187
|
+
})
|
|
188
|
+
})
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Sorting
|
|
192
|
+
if (entity.sorts.length) {
|
|
193
|
+
rows = [...rows].sort((a, b) => {
|
|
194
|
+
for (const { column: columnId, direction } of entity.sorts) {
|
|
195
|
+
const column = entity.columns.find((c) => c.id === columnId)
|
|
196
|
+
let aVal = a[columnId]
|
|
197
|
+
let bVal = b[columnId]
|
|
198
|
+
|
|
199
|
+
// Custom sort function
|
|
200
|
+
if (column?.sortFn) {
|
|
201
|
+
const result =
|
|
202
|
+
direction === "asc" ? column.sortFn(a, b) : column.sortFn(b, a)
|
|
203
|
+
if (result !== 0) return result
|
|
204
|
+
continue
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Default sorting
|
|
208
|
+
if (aVal === bVal) continue
|
|
209
|
+
if (aVal == null) return 1
|
|
210
|
+
if (bVal == null) return -1
|
|
211
|
+
|
|
212
|
+
const comparison = aVal < bVal ? -1 : 1
|
|
213
|
+
return direction === "asc" ? comparison : -comparison
|
|
214
|
+
}
|
|
215
|
+
return 0
|
|
216
|
+
})
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Pagination
|
|
220
|
+
if (entity.pagination) {
|
|
221
|
+
const { page, pageSize } = entity.pagination
|
|
222
|
+
const start = page * pageSize
|
|
223
|
+
rows = rows.slice(start, start + pageSize)
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return rows
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export function getTotalRows(entity) {
|
|
230
|
+
if (!entity.data) return 0
|
|
231
|
+
|
|
232
|
+
// If no filters, return total data length
|
|
233
|
+
if (Object.keys(entity.filters).length === 0) {
|
|
234
|
+
return entity.data.length
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Count filtered rows
|
|
238
|
+
return entity.data.filter((row) => {
|
|
239
|
+
return Object.entries(entity.filters).every(([columnId, filterValue]) => {
|
|
240
|
+
const column = entity.columns.find((c) => c.id === columnId)
|
|
241
|
+
if (!column) return true
|
|
242
|
+
|
|
243
|
+
// Custom filter function
|
|
244
|
+
if (column.filterFn) {
|
|
245
|
+
return column.filterFn(row, filterValue)
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Default filters by type
|
|
249
|
+
const value = row[columnId]
|
|
250
|
+
|
|
251
|
+
if (column.type === "number") {
|
|
252
|
+
if (typeof filterValue === "object") {
|
|
253
|
+
const { min, max } = filterValue
|
|
254
|
+
if (min !== undefined && value < min) return false
|
|
255
|
+
if (max !== undefined && value > max) return false
|
|
256
|
+
return true
|
|
257
|
+
}
|
|
258
|
+
return value === filterValue
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if (column.type === "boolean") {
|
|
262
|
+
return value === filterValue
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// String filtering (case-insensitive contains)
|
|
266
|
+
return String(value)
|
|
267
|
+
.toLowerCase()
|
|
268
|
+
.includes(String(filterValue).toLowerCase())
|
|
269
|
+
})
|
|
270
|
+
}).length
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
export function getPaginationInfo(entity) {
|
|
274
|
+
if (!entity.pagination) return null
|
|
275
|
+
|
|
276
|
+
const totalRows = getTotalRows(entity)
|
|
277
|
+
const { page, pageSize } = entity.pagination
|
|
278
|
+
const totalPages = Math.ceil(totalRows / pageSize)
|
|
279
|
+
const start = page * pageSize
|
|
280
|
+
const end = Math.min((page + 1) * pageSize, totalRows)
|
|
281
|
+
|
|
282
|
+
return {
|
|
283
|
+
page,
|
|
284
|
+
pageSize,
|
|
285
|
+
totalPages,
|
|
286
|
+
totalRows,
|
|
287
|
+
start,
|
|
288
|
+
end,
|
|
289
|
+
hasNextPage: page < totalPages - 1,
|
|
290
|
+
hasPrevPage: page > 0,
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
export function getSortDirection(entity, columnId) {
|
|
295
|
+
const sort = entity.sorts.find((s) => s.column === columnId)
|
|
296
|
+
return sort?.direction || null
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
export function getSortIndex(entity, columnId) {
|
|
300
|
+
return entity.sorts.findIndex((s) => s.column === columnId)
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
export function getFilter(entity, columnId) {
|
|
304
|
+
return entity.filters[columnId]
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
export function isRowSelected(entity, rowId) {
|
|
308
|
+
return entity.selection.includes(rowId)
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
export function isAllSelected(entity) {
|
|
312
|
+
const rows = getRows(entity)
|
|
313
|
+
return rows.length && rows.every((row) => entity.selection.includes(row.id))
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
export function isSomeSelected(entity) {
|
|
317
|
+
const rows = getRows(entity)
|
|
318
|
+
const selectedCount = rows.filter((row) =>
|
|
319
|
+
entity.selection.includes(row.id),
|
|
320
|
+
).length
|
|
321
|
+
return selectedCount && selectedCount < rows.length
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
function initTable(entity) {
|
|
325
|
+
// Auto-generate columns from first data item if not provided
|
|
326
|
+
if (!entity.columns && entity.data?.length) {
|
|
327
|
+
const [firstRow] = entity.data
|
|
328
|
+
|
|
329
|
+
entity.columns = Object.keys(firstRow).map((key) => {
|
|
330
|
+
const value = firstRow[key]
|
|
331
|
+
const type = getDefaultColumnType(value)
|
|
332
|
+
const [firstChar, ...rest] = key
|
|
333
|
+
|
|
334
|
+
return {
|
|
335
|
+
id: key,
|
|
336
|
+
title: [firstChar.toUpperCase(), ...rest].join(""),
|
|
337
|
+
isSortable: true,
|
|
338
|
+
isFilterable: type !== "boolean",
|
|
339
|
+
type,
|
|
340
|
+
width: getDefaultColumnWidth(type),
|
|
341
|
+
}
|
|
342
|
+
})
|
|
343
|
+
} else {
|
|
344
|
+
entity.columns ??= []
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// State
|
|
348
|
+
entity.sorts ??= []
|
|
349
|
+
entity.filters ??= {}
|
|
350
|
+
entity.selection ??= []
|
|
351
|
+
|
|
352
|
+
// Pagination (null = disabled)
|
|
353
|
+
entity.pagination ??= null
|
|
354
|
+
|
|
355
|
+
if (entity.pagination) {
|
|
356
|
+
entity.pagination.page ??= 0
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
function getDefaultColumnType(value) {
|
|
361
|
+
if (typeof value === "number") return "number"
|
|
362
|
+
if (typeof value === "boolean") return "boolean"
|
|
363
|
+
if (value instanceof Date) return "date"
|
|
364
|
+
return "string"
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
function getDefaultColumnWidth(type) {
|
|
368
|
+
if (type === "number") return 100
|
|
369
|
+
if (type === "boolean") return 80
|
|
370
|
+
if (type === "date") return 120
|
|
371
|
+
return 200
|
|
372
|
+
}
|