@neovici/cosmoz-omnitable 14.2.0 → 14.3.0
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/cosmoz-omnitable-styles.js +3 -9
- package/cosmoz-omnitable.js +2 -2
- package/grouped-list/cosmoz-grouped-list-row.js +41 -0
- package/grouped-list/cosmoz-grouped-list.js +13 -0
- package/grouped-list/index.js +1 -0
- package/grouped-list/use-collapsible-items.js +32 -0
- package/grouped-list/use-cosmoz-grouped-list.js +115 -0
- package/grouped-list/use-selected-items.js +141 -0
- package/grouped-list/use-weak-state.js +21 -0
- package/grouped-list/utils.js +87 -0
- package/lib/render-list.js +9 -8
- package/package.json +5 -5
|
@@ -307,21 +307,15 @@ export default css`
|
|
|
307
307
|
}
|
|
308
308
|
|
|
309
309
|
/* End of empty data set styling */
|
|
310
|
-
|
|
311
310
|
.tableContent-scroller {
|
|
312
311
|
flex: auto;
|
|
313
312
|
position: relative;
|
|
314
313
|
overflow: auto;
|
|
315
314
|
overflow-x: hidden;
|
|
316
315
|
will-change: transform;
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
position: absolute !important;
|
|
321
|
-
top: 0;
|
|
322
|
-
right: 0;
|
|
323
|
-
bottom: 0;
|
|
324
|
-
left: 0;
|
|
316
|
+
flex-basis: 0.000001px;
|
|
317
|
+
display: flex;
|
|
318
|
+
flex-direction: column;
|
|
325
319
|
}
|
|
326
320
|
|
|
327
321
|
.itemRow {
|
package/cosmoz-omnitable.js
CHANGED
|
@@ -4,7 +4,6 @@ import '@polymer/iron-icons/iron-icons';
|
|
|
4
4
|
import '@polymer/iron-icon/iron-icon';
|
|
5
5
|
import '@polymer/paper-spinner/paper-spinner-lite';
|
|
6
6
|
|
|
7
|
-
import '@neovici/cosmoz-grouped-list';
|
|
8
7
|
import '@neovici/cosmoz-bottom-bar';
|
|
9
8
|
|
|
10
9
|
import './cosmoz-omnitable-column';
|
|
@@ -18,13 +17,14 @@ import styles from './cosmoz-omnitable-styles';
|
|
|
18
17
|
import { html as polymerHtml } from '@polymer/polymer/lib/utils/html-tag';
|
|
19
18
|
import { html } from 'lit-html';
|
|
20
19
|
import { guard } from 'lit-html/directives/guard.js';
|
|
20
|
+
import { notifyProperty } from '@neovici/cosmoz-utils/hooks/use-notify-property';
|
|
21
21
|
|
|
22
22
|
import { useOmnitable } from './lib/use-omnitable';
|
|
23
23
|
import { component } from '@pionjs/pion';
|
|
24
24
|
import { renderHeader } from './lib/render-header';
|
|
25
25
|
import { renderFooter } from './lib/render-footer';
|
|
26
26
|
import { renderList } from './lib/render-list';
|
|
27
|
-
import
|
|
27
|
+
import './grouped-list/index.js';
|
|
28
28
|
|
|
29
29
|
const shimCSS = (s) => window.ShadyCSS?.ApplyShim?.transformCssText?.(s) || s;
|
|
30
30
|
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { render } from 'lit-html';
|
|
2
|
+
|
|
3
|
+
customElements.define(
|
|
4
|
+
'cosmoz-grouped-list-row',
|
|
5
|
+
class Element extends HTMLElement {
|
|
6
|
+
get item() {
|
|
7
|
+
return this._item;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
set item(item) {
|
|
11
|
+
this._item = item;
|
|
12
|
+
this._render();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
get index() {
|
|
16
|
+
return this._index;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
set index(index) {
|
|
20
|
+
this._index = index;
|
|
21
|
+
this._render();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
get renderFn() {
|
|
25
|
+
return this._renderFn;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
set renderFn(renderFn) {
|
|
29
|
+
this._renderFn = renderFn;
|
|
30
|
+
this._render();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
_render() {
|
|
34
|
+
if (this._item == null || this._index == null || this._renderFn == null) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
render(this._renderFn(this._item, this._index), this);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
renderCosmozGroupedList,
|
|
3
|
+
useCosmozGroupedList,
|
|
4
|
+
} from './use-cosmoz-grouped-list.js';
|
|
5
|
+
import { component } from '@pionjs/pion';
|
|
6
|
+
|
|
7
|
+
const CosmozGroupedList = (host) =>
|
|
8
|
+
renderCosmozGroupedList(useCosmozGroupedList(host));
|
|
9
|
+
|
|
10
|
+
customElements.define(
|
|
11
|
+
'cosmoz-grouped-list',
|
|
12
|
+
component(CosmozGroupedList, { useShadowDOM: false }),
|
|
13
|
+
);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import './cosmoz-grouped-list.js';
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { useCallback } from '@pionjs/pion';
|
|
2
|
+
import { useWeakState } from './use-weak-state';
|
|
3
|
+
import { isGroup } from './utils';
|
|
4
|
+
|
|
5
|
+
export const useCollapsibleItems = () => {
|
|
6
|
+
const { setItemState, state, signal } = useWeakState(),
|
|
7
|
+
toggleFold = useCallback((item, folded) => {
|
|
8
|
+
if (!isGroup(item)) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
setItemState(item, (state) => ({
|
|
13
|
+
folded: folded !== undefined ? folded : !state.folded,
|
|
14
|
+
}));
|
|
15
|
+
}, []),
|
|
16
|
+
toggleCollapse = useCallback((item, collapsed) => {
|
|
17
|
+
if (isGroup(item)) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
setItemState(item, (state) => ({
|
|
22
|
+
expanded: collapsed !== undefined ? !collapsed : !state.expanded,
|
|
23
|
+
}));
|
|
24
|
+
}, []);
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
state,
|
|
28
|
+
signal,
|
|
29
|
+
toggleFold,
|
|
30
|
+
toggleCollapse,
|
|
31
|
+
};
|
|
32
|
+
};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { useImperativeApi } from '@neovici/cosmoz-utils/hooks/use-imperative-api';
|
|
2
|
+
import { useNotifyProperty } from '@neovici/cosmoz-utils/hooks/use-notify-property';
|
|
3
|
+
import { useCallback, useLayoutEffect, useMemo } from '@pionjs/pion';
|
|
4
|
+
import { html } from 'lit-html';
|
|
5
|
+
import './cosmoz-grouped-list-row';
|
|
6
|
+
import { useCollapsibleItems } from './use-collapsible-items';
|
|
7
|
+
import { useSelectedItems } from './use-selected-items';
|
|
8
|
+
import { byReference, isExpanded, isFolded, prepareData } from './utils';
|
|
9
|
+
import { virtualize } from '@lit-labs/virtualizer/virtualize.js';
|
|
10
|
+
|
|
11
|
+
const styles = {
|
|
12
|
+
host: {
|
|
13
|
+
position: 'relative',
|
|
14
|
+
display: 'flex',
|
|
15
|
+
flexDirection: 'column',
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
// eslint-disable-next-line max-lines-per-function
|
|
19
|
+
useCosmozGroupedList = (host) => {
|
|
20
|
+
const {
|
|
21
|
+
data,
|
|
22
|
+
renderItem,
|
|
23
|
+
renderGroup,
|
|
24
|
+
displayEmptyGroups,
|
|
25
|
+
compareItemsFn = byReference,
|
|
26
|
+
} = host,
|
|
27
|
+
{ toggleFold, toggleCollapse, state, signal } = useCollapsibleItems(),
|
|
28
|
+
// TODO: state changes trigger recalculation, which is slow (200ms with 10k items)
|
|
29
|
+
// it only makes sense to do it when a group is folded
|
|
30
|
+
// suggested fix: separate signal for item collapse and group fold
|
|
31
|
+
flatData = useMemo(
|
|
32
|
+
() => prepareData(data, displayEmptyGroups, state),
|
|
33
|
+
[data, displayEmptyGroups, signal]
|
|
34
|
+
),
|
|
35
|
+
{
|
|
36
|
+
selectedItems,
|
|
37
|
+
isItemSelected,
|
|
38
|
+
isGroupSelected,
|
|
39
|
+
isSelected,
|
|
40
|
+
select,
|
|
41
|
+
deselect,
|
|
42
|
+
selectOnly,
|
|
43
|
+
selectAll,
|
|
44
|
+
deselectAll,
|
|
45
|
+
toggleSelect,
|
|
46
|
+
toggleSelectTo,
|
|
47
|
+
} = useSelectedItems({
|
|
48
|
+
initial: [],
|
|
49
|
+
compareItemsFn,
|
|
50
|
+
data,
|
|
51
|
+
flatData,
|
|
52
|
+
}),
|
|
53
|
+
renderRow = useCallback(
|
|
54
|
+
(item, index) =>
|
|
55
|
+
// eslint-disable-next-line no-nested-ternary
|
|
56
|
+
Array.isArray(item.items)
|
|
57
|
+
? renderGroup(item, index, {
|
|
58
|
+
selected: isGroupSelected(item, selectedItems),
|
|
59
|
+
folded: isFolded(item, state),
|
|
60
|
+
toggleSelect: (selected) =>
|
|
61
|
+
toggleSelect(
|
|
62
|
+
item,
|
|
63
|
+
typeof selected === 'boolean' ? selected : undefined
|
|
64
|
+
),
|
|
65
|
+
toggleFold: () => toggleFold(item),
|
|
66
|
+
})
|
|
67
|
+
: renderItem(item, index, {
|
|
68
|
+
selected: selectedItems.includes(item),
|
|
69
|
+
expanded: isExpanded(item, state),
|
|
70
|
+
toggleSelect: (selected) =>
|
|
71
|
+
toggleSelect(
|
|
72
|
+
item,
|
|
73
|
+
typeof selected === 'boolean' ? selected : undefined
|
|
74
|
+
),
|
|
75
|
+
toggleCollapse: () => toggleCollapse(item),
|
|
76
|
+
}),
|
|
77
|
+
[renderItem, renderGroup, selectedItems, toggleSelect, signal]
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
useLayoutEffect(() => Object.assign(host.style, styles.host), []);
|
|
81
|
+
|
|
82
|
+
useNotifyProperty('selectedItems', selectedItems);
|
|
83
|
+
const api = {
|
|
84
|
+
toggleFold,
|
|
85
|
+
toggleCollapse,
|
|
86
|
+
isItemSelected,
|
|
87
|
+
isGroupSelected,
|
|
88
|
+
isSelected,
|
|
89
|
+
select,
|
|
90
|
+
deselect,
|
|
91
|
+
selectOnly,
|
|
92
|
+
selectAll,
|
|
93
|
+
deselectAll,
|
|
94
|
+
toggleSelect,
|
|
95
|
+
toggleSelectTo,
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
useImperativeApi(api, Object.values(api));
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
renderRow,
|
|
102
|
+
flatData,
|
|
103
|
+
};
|
|
104
|
+
},
|
|
105
|
+
renderCosmozGroupedList = ({ renderRow, flatData }) =>
|
|
106
|
+
virtualize({
|
|
107
|
+
items: flatData,
|
|
108
|
+
renderItem: (item, index) => html`<cosmoz-grouped-list-row
|
|
109
|
+
.item=${item}
|
|
110
|
+
.index=${index}
|
|
111
|
+
.renderFn=${renderRow}
|
|
112
|
+
></cosmoz-grouped-list-row>`,
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
export { renderCosmozGroupedList, useCosmozGroupedList };
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { useCallback, useEffect, useState } from '@pionjs/pion';
|
|
2
|
+
import { isGroup } from './utils';
|
|
3
|
+
|
|
4
|
+
// eslint-disable-next-line max-lines-per-function
|
|
5
|
+
export const useSelectedItems = ({
|
|
6
|
+
initial,
|
|
7
|
+
compareItemsFn,
|
|
8
|
+
data,
|
|
9
|
+
flatData
|
|
10
|
+
}) => {
|
|
11
|
+
const [selectedItems, setSelectedItems] = useState(initial),
|
|
12
|
+
[lastSelection, setLastSelection] = useState(),
|
|
13
|
+
/**
|
|
14
|
+
* Check if item is selected.
|
|
15
|
+
* @param {object} item Item.
|
|
16
|
+
* @returns {boolean} Whether item is selected.
|
|
17
|
+
*/
|
|
18
|
+
isItemSelected = useCallback(
|
|
19
|
+
item => selectedItems.includes(item),
|
|
20
|
+
[selectedItems]
|
|
21
|
+
),
|
|
22
|
+
/**
|
|
23
|
+
* Check if group is selected.
|
|
24
|
+
* @param {object} group Group.
|
|
25
|
+
* @returns {boolean} Whether group is selected.
|
|
26
|
+
*/
|
|
27
|
+
isGroupSelected = useCallback(
|
|
28
|
+
group => group?.items?.every(isItemSelected),
|
|
29
|
+
[isItemSelected]
|
|
30
|
+
),
|
|
31
|
+
/**
|
|
32
|
+
* Check if item.group is selected.
|
|
33
|
+
* @param {object} item Item.
|
|
34
|
+
* @returns {boolean} Whether item is selected.
|
|
35
|
+
*/
|
|
36
|
+
isSelected = useCallback(
|
|
37
|
+
item => isItemSelected(item) || isGroupSelected(item),
|
|
38
|
+
[isItemSelected, isGroupSelected]
|
|
39
|
+
),
|
|
40
|
+
/**
|
|
41
|
+
* Add an item/group to the list of selected items.
|
|
42
|
+
* @param {object} item Item to select.
|
|
43
|
+
* @returns {void}
|
|
44
|
+
*/
|
|
45
|
+
select = useCallback(item => {
|
|
46
|
+
const items = item.items ?? [item];
|
|
47
|
+
setSelectedItems(selection => [
|
|
48
|
+
...selection,
|
|
49
|
+
...items.filter(i => !selection.includes(i))
|
|
50
|
+
]);
|
|
51
|
+
setLastSelection(item);
|
|
52
|
+
}, []),
|
|
53
|
+
/**
|
|
54
|
+
* Removes an item/group from the list of selected items.
|
|
55
|
+
* @param {object} item Item to select.
|
|
56
|
+
* @returns {void}
|
|
57
|
+
*/
|
|
58
|
+
deselect = useCallback(item => {
|
|
59
|
+
const items = item.items ?? [item];
|
|
60
|
+
setSelectedItems(selection =>
|
|
61
|
+
selection.filter(i => !items.includes(i))
|
|
62
|
+
);
|
|
63
|
+
setLastSelection(item);
|
|
64
|
+
}, []),
|
|
65
|
+
selectOnly = useCallback(item => {
|
|
66
|
+
setSelectedItems(item.items?.slice() || [item]);
|
|
67
|
+
setLastSelection(item);
|
|
68
|
+
}, []),
|
|
69
|
+
/**
|
|
70
|
+
* Select all items.
|
|
71
|
+
* @returns {void}
|
|
72
|
+
*/
|
|
73
|
+
selectAll = useCallback(() => {
|
|
74
|
+
setSelectedItems(data.flatMap(item => item.items || item));
|
|
75
|
+
setLastSelection(undefined);
|
|
76
|
+
}, [data]),
|
|
77
|
+
/**
|
|
78
|
+
* Deselect all selected items.
|
|
79
|
+
* @returns {void}
|
|
80
|
+
*/
|
|
81
|
+
deselectAll = useCallback(() => {
|
|
82
|
+
setSelectedItems([]);
|
|
83
|
+
setLastSelection(undefined);
|
|
84
|
+
}, []),
|
|
85
|
+
/**
|
|
86
|
+
* Toggles the selection of an item/group.
|
|
87
|
+
* @param {object} item Item to select.
|
|
88
|
+
* @param {boolean=} selected Select or deselect, fallback to toggling.
|
|
89
|
+
* @returns {void}
|
|
90
|
+
*/
|
|
91
|
+
toggleSelect = useCallback(
|
|
92
|
+
(item, selected = !isSelected(item)) =>
|
|
93
|
+
selected ? select(item) : deselect(item),
|
|
94
|
+
[isSelected]
|
|
95
|
+
),
|
|
96
|
+
toggleSelectTo = useCallback(
|
|
97
|
+
(item, selected) => {
|
|
98
|
+
const last = lastSelection
|
|
99
|
+
? flatData.findIndex(i => compareItemsFn(i, lastSelection))
|
|
100
|
+
: -1;
|
|
101
|
+
if (last < 0) {
|
|
102
|
+
return toggleSelect(item, selected);
|
|
103
|
+
}
|
|
104
|
+
const [from, to] = [last, flatData.indexOf(item)].sort((a, b) => a - b);
|
|
105
|
+
flatData.slice(from, to + 1).forEach((item, i, items) => {
|
|
106
|
+
if (i > 0 && i < items.length - 1 && isGroup(item)) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
toggleSelect(item, selected);
|
|
110
|
+
});
|
|
111
|
+
setLastSelection(item);
|
|
112
|
+
},
|
|
113
|
+
[flatData, compareItemsFn, toggleSelect]
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
// keep selected items across data updates
|
|
117
|
+
useEffect(
|
|
118
|
+
() =>
|
|
119
|
+
setSelectedItems(selectedItems =>
|
|
120
|
+
selectedItems.length > 0
|
|
121
|
+
? flatData.filter(i =>
|
|
122
|
+
selectedItems.find(item => compareItemsFn(i, item))
|
|
123
|
+
)
|
|
124
|
+
: selectedItems
|
|
125
|
+
),
|
|
126
|
+
[flatData]
|
|
127
|
+
);
|
|
128
|
+
return {
|
|
129
|
+
selectedItems,
|
|
130
|
+
isItemSelected,
|
|
131
|
+
isGroupSelected,
|
|
132
|
+
isSelected,
|
|
133
|
+
select,
|
|
134
|
+
deselect,
|
|
135
|
+
selectOnly,
|
|
136
|
+
selectAll,
|
|
137
|
+
deselectAll,
|
|
138
|
+
toggleSelect,
|
|
139
|
+
toggleSelectTo
|
|
140
|
+
};
|
|
141
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useCallback, useState } from '@pionjs/pion';
|
|
2
|
+
import { callFn, getItemState } from './utils';
|
|
3
|
+
|
|
4
|
+
export const useWeakState = () => {
|
|
5
|
+
const [wrapper, setState] = useState(() => [new WeakMap()]),
|
|
6
|
+
setItemState = useCallback(
|
|
7
|
+
(item, newItemState) =>
|
|
8
|
+
setState(([state]) => {
|
|
9
|
+
const itemState = getItemState(item, state);
|
|
10
|
+
Object.assign(itemState, callFn(newItemState, itemState));
|
|
11
|
+
return [state];
|
|
12
|
+
}),
|
|
13
|
+
[]
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
setItemState,
|
|
18
|
+
state: wrapper[0],
|
|
19
|
+
signal: wrapper
|
|
20
|
+
};
|
|
21
|
+
};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
const symbols = {
|
|
2
|
+
group: Symbol('group')
|
|
3
|
+
},
|
|
4
|
+
getItemState = (item, itemsState) => {
|
|
5
|
+
if (!itemsState.has(item)) {
|
|
6
|
+
itemsState.set(item, {});
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
return itemsState.get(item);
|
|
10
|
+
},
|
|
11
|
+
isExpanded = (item, itemsState) => Boolean(getItemState(item, itemsState).expanded),
|
|
12
|
+
isFolded = (group, itemsState) => Boolean(getItemState(group, itemsState).folded),
|
|
13
|
+
isGroup = item => item ? item.items instanceof Array : false,
|
|
14
|
+
/**
|
|
15
|
+
* Asserts that data is either all items or all groups, never mixed.
|
|
16
|
+
* @param {Array} data the data
|
|
17
|
+
* @return {void}
|
|
18
|
+
*/
|
|
19
|
+
_assertDataIsHomogeneous = data => {
|
|
20
|
+
if (!Array.isArray(data) || data.length === 0) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const firstItemIsAGroup = Array.isArray(data[0].items),
|
|
25
|
+
isHomogeneous = data.every(
|
|
26
|
+
group => Array.isArray(group.items) === firstItemIsAGroup
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
if (!isHomogeneous) {
|
|
30
|
+
throw new Error('Data must be homogeneous.');
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
/**
|
|
34
|
+
* Prepare data.
|
|
35
|
+
* @param {array} data Data.
|
|
36
|
+
* @param {boolean} displayEmptyGroups Flag.
|
|
37
|
+
* @param {WeakMap} itemsState State.
|
|
38
|
+
* @returns {void|array} Prepared data.
|
|
39
|
+
*/
|
|
40
|
+
prepareData = (data, displayEmptyGroups, itemsState) => {
|
|
41
|
+
if (!Array.isArray(data)) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// data should be either all items or all grouped items, never mixed
|
|
46
|
+
_assertDataIsHomogeneous(data);
|
|
47
|
+
|
|
48
|
+
const flatData = data.reduce((acc, item) => {
|
|
49
|
+
// simple items
|
|
50
|
+
if (!item.items) {
|
|
51
|
+
return acc.concat(item);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// groups with items
|
|
55
|
+
if (item.items.length) {
|
|
56
|
+
if (getItemState(item, itemsState).folded) {
|
|
57
|
+
return acc.concat(item);
|
|
58
|
+
}
|
|
59
|
+
return acc.concat(
|
|
60
|
+
item,
|
|
61
|
+
item.items.map(i => Object.assign(i, { [symbols.group]: item }))
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// groups without items
|
|
66
|
+
if (displayEmptyGroups) {
|
|
67
|
+
return acc.concat(item);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return acc;
|
|
71
|
+
}, []);
|
|
72
|
+
|
|
73
|
+
return flatData;
|
|
74
|
+
},
|
|
75
|
+
callFn = (fn, ...args) => typeof fn === 'function' ? fn(...args) : fn,
|
|
76
|
+
byReference = (a, b) => a === b;
|
|
77
|
+
|
|
78
|
+
export {
|
|
79
|
+
symbols,
|
|
80
|
+
prepareData,
|
|
81
|
+
getItemState,
|
|
82
|
+
isExpanded,
|
|
83
|
+
isFolded,
|
|
84
|
+
isGroup,
|
|
85
|
+
callFn,
|
|
86
|
+
byReference
|
|
87
|
+
};
|
package/lib/render-list.js
CHANGED
|
@@ -63,15 +63,16 @@ export const renderList = ({
|
|
|
63
63
|
<div class="tableContent-scroller" id="scroller" part="scroller">
|
|
64
64
|
<cosmoz-grouped-list
|
|
65
65
|
id="groupedList"
|
|
66
|
-
.data
|
|
67
|
-
@selected-items-changed
|
|
68
|
-
setSelectedItems(event.detail.value)}
|
|
69
|
-
.displayEmptyGroups
|
|
66
|
+
.data="${processedItems}"
|
|
67
|
+
@selected-items-changed="${(event) =>
|
|
68
|
+
setSelectedItems(event.detail.value)}"
|
|
69
|
+
.displayEmptyGroups="${
|
|
70
70
|
displayEmptyGroups /* TODO: check if still works */
|
|
71
|
-
}
|
|
72
|
-
.compareItemsFn
|
|
73
|
-
.renderItem
|
|
74
|
-
.renderGroup
|
|
71
|
+
}"
|
|
72
|
+
.compareItemsFn="${compareItemsFn}"
|
|
73
|
+
.renderItem="${renderItem}"
|
|
74
|
+
.renderGroup="${renderGroup}"
|
|
75
75
|
></cosmoz-grouped-list>
|
|
76
|
+
<slot name="extraContent"></slot>
|
|
76
77
|
</div>`;
|
|
77
78
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neovici/cosmoz-omnitable",
|
|
3
|
-
"version": "14.
|
|
3
|
+
"version": "14.3.0",
|
|
4
4
|
"description": "[](https://travis-ci.org/Neovici/cosmoz-omnitable)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"web-components"
|
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
},
|
|
22
22
|
"files": [
|
|
23
23
|
"cosmoz-*.js",
|
|
24
|
-
"get-effective-children-legacy-mixin.js",
|
|
25
24
|
"ui-helpers",
|
|
26
|
-
"lib/**/*.js"
|
|
25
|
+
"lib/**/*.js",
|
|
26
|
+
"grouped-list/*.js"
|
|
27
27
|
],
|
|
28
28
|
"scripts": {
|
|
29
29
|
"lint": "eslint --cache --ext .js .",
|
|
@@ -59,12 +59,12 @@
|
|
|
59
59
|
}
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
|
+
"@lit-labs/virtualizer": "^2.1.0",
|
|
62
63
|
"@neovici/cosmoz-autocomplete": "^10.0.0",
|
|
63
64
|
"@neovici/cosmoz-bottom-bar": "^9.0.3",
|
|
64
65
|
"@neovici/cosmoz-collapse": "^1.1.0",
|
|
65
66
|
"@neovici/cosmoz-datetime-input": "^4.0.1",
|
|
66
67
|
"@neovici/cosmoz-dropdown": "^5.0.0",
|
|
67
|
-
"@neovici/cosmoz-grouped-list": "^8.0.0",
|
|
68
68
|
"@neovici/cosmoz-i18next": "^3.1.1",
|
|
69
69
|
"@neovici/cosmoz-input": "^5.0.0",
|
|
70
70
|
"@neovici/cosmoz-router": "^11.0.0",
|
|
@@ -94,6 +94,6 @@
|
|
|
94
94
|
"@semantic-release/git": "^10.0.0",
|
|
95
95
|
"husky": "^9.0.0",
|
|
96
96
|
"semantic-release": "^24.0.0",
|
|
97
|
-
"sinon": "^
|
|
97
|
+
"sinon": "^20.0.0"
|
|
98
98
|
}
|
|
99
99
|
}
|