wx-svelte-grid 2.1.5 → 2.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/license.txt +1 -1
- package/package.json +17 -14
- package/readme.md +14 -11
- package/src/components/Cell.svelte +4 -6
- package/src/components/Grid.svelte +50 -16
- package/src/components/HeaderCell.svelte +20 -8
- package/src/components/HeaderFooter.svelte +2 -1
- package/src/components/Layout.svelte +17 -15
- package/src/components/Tooltip.svelte +1 -1
- package/src/components/editor/Editor.svelte +1 -1
- package/src/components/inlineEditors/Combo.svelte +1 -1
- package/src/components/inlineEditors/Datepicker.svelte +4 -4
- package/src/components/inlineEditors/Editor.svelte +12 -2
- package/src/components/inlineEditors/Richselect.svelte +1 -1
- package/src/components/inlineFilters/Richselect.svelte +2 -2
- package/src/components/inlineFilters/Text.svelte +1 -1
- package/src/components/menus/ContextMenu.svelte +5 -4
- package/src/components/menus/HeaderMenu.svelte +1 -1
- package/src/components/print/Grid.svelte +1 -1
- package/src/components/print/HeaderFooter.svelte +1 -1
- package/src/components/print/Print.svelte +1 -1
- package/src/helpers/actions/reorder.js +1 -1
- package/src/helpers/actions/resize.js +1 -1
- package/src/helpers/hotkeys.js +19 -15
- package/src/index.js +4 -14
- package/src/themes/Material.svelte +1 -1
- package/src/themes/Willow.svelte +1 -1
- package/src/themes/WillowDark.svelte +1 -1
- package/types/index.d.ts +137 -0
- package/whatsnew.md +34 -0
- package/src/helpers/menuOptions.js +0 -15
package/license.txt
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wx-svelte-grid",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "A
|
|
3
|
+
"version": "2.3.0",
|
|
4
|
+
"description": "A fast, feature-rich Svelte DataGrid component",
|
|
5
5
|
"productTag": "grid",
|
|
6
6
|
"productTrial": false,
|
|
7
7
|
"type": "module",
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
"svelte": "src/index.js",
|
|
19
19
|
"exports": {
|
|
20
20
|
".": {
|
|
21
|
-
"svelte": "./src/index.js"
|
|
21
|
+
"svelte": "./src/index.js",
|
|
22
|
+
"types": "./types/index.d.ts"
|
|
22
23
|
},
|
|
23
24
|
"./package.json": "./package.json"
|
|
24
25
|
},
|
|
@@ -32,22 +33,24 @@
|
|
|
32
33
|
},
|
|
33
34
|
"homepage": "https://svar.dev/svelte/datagrid/",
|
|
34
35
|
"dependencies": {
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
36
|
+
"@svar-ui/lib-dom": "0.9.2",
|
|
37
|
+
"@svar-ui/lib-state": "1.9.6",
|
|
38
|
+
"@svar-ui/lib-svelte": "0.5.2",
|
|
39
|
+
"@svar-ui/svelte-menu": "2.3.0",
|
|
40
|
+
"@svar-ui/svelte-core": "2.3.1",
|
|
41
|
+
"@svar-ui/grid-data-provider": "2.3.0",
|
|
42
|
+
"@svar-ui/grid-locales": "2.3.0",
|
|
43
|
+
"@svar-ui/grid-store": "2.3.0"
|
|
43
44
|
},
|
|
44
45
|
"devDependencies": {
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
46
|
+
"@svar-ui/svelte-editor": "2.3.0",
|
|
47
|
+
"@svar-ui/svelte-comments": "2.3.0",
|
|
48
|
+
"@svar-ui/svelte-tasklist": "2.3.0",
|
|
49
|
+
"@svar-ui/svelte-filter": "2.3.0"
|
|
48
50
|
},
|
|
49
51
|
"files": [
|
|
50
52
|
"src",
|
|
53
|
+
"types",
|
|
51
54
|
"readme.md",
|
|
52
55
|
"whatsnew.md",
|
|
53
56
|
"license.txt"
|
package/readme.md
CHANGED
|
@@ -12,44 +12,47 @@
|
|
|
12
12
|
|
|
13
13
|
<div align="center">
|
|
14
14
|
|
|
15
|
-
[](https://www.npmjs.com/package/@svar-ui/svelte-grid)
|
|
16
16
|
[](https://github.com/svar-widgets/grid/blob/main/license.txt)
|
|
17
|
-
[](https://www.npmjs.com/package/@svar-ui/svelte-grid)
|
|
18
18
|
[](https://github.com/svar-widgets/grid)
|
|
19
19
|
|
|
20
20
|
</div>
|
|
21
21
|
|
|
22
|
-
[SVAR DataGrid](https://svar.dev/svelte/datagrid/) is an advanced Svelte component that enhances standard data tables, enabling you to create high-performance, feature-rich data grids that efficiently handle large data sets. Fully customizable, it supports inline editing
|
|
22
|
+
[SVAR DataGrid](https://svar.dev/svelte/datagrid/) is an advanced Svelte component that enhances standard data tables, enabling you to create high-performance, feature-rich data grids that efficiently handle large data sets. Fully customizable, it supports inline editing, sorting, filtering, and virtual scrolling for optimal performance.
|
|
23
23
|
|
|
24
24
|
<div align="center">
|
|
25
25
|
<img src="https://cdn.svar.dev/public/react-grid.png" alt="SVAR Svelte DataGrid - Screenshot" width="700">
|
|
26
26
|
</div>
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
### :sparkles: Key Features
|
|
29
29
|
|
|
30
|
-
- High performance (virtual scrolling and
|
|
30
|
+
- High performance (virtual scrolling for rows and columns)
|
|
31
31
|
- In-cell editing with different cell editors (datepicker, combo, select, rich select, etc.)
|
|
32
|
+
- Custom HTML for cells
|
|
32
33
|
- Sorting by multiple columns
|
|
33
|
-
-
|
|
34
|
-
-
|
|
34
|
+
- Filtering
|
|
35
|
+
- Paging
|
|
35
36
|
- Fixed columns
|
|
36
37
|
- Expandable/collapsible columns
|
|
37
38
|
- Customizable tooltips for grid cells
|
|
38
39
|
- Context menu
|
|
40
|
+
- External editor for grid data
|
|
39
41
|
- Tree-like structure
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
+
- Print support
|
|
43
|
+
- Responsive design to adapt to different screen/container sizes
|
|
44
|
+
- Accessibility: compatibile with [WAI-ARIA](https://www.w3.org/WAI/standards-guidelines/aria/) standard
|
|
42
45
|
- Keyboard navigation
|
|
43
46
|
- RestDataProvider for easy backend data binding
|
|
44
47
|
- Dark and light skins
|
|
45
48
|
|
|
46
|
-
|
|
49
|
+
### :hammer_and_wrench: How to Use
|
|
47
50
|
|
|
48
51
|
To use SVAR DataGrid, simply import the package and include the component in your Svelte file:
|
|
49
52
|
|
|
50
53
|
```svelte
|
|
51
54
|
<script>
|
|
52
|
-
import { Grid } from "
|
|
55
|
+
import { Grid } from "@svar-ui/svelte-grid";
|
|
53
56
|
|
|
54
57
|
const data = [
|
|
55
58
|
{
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { onDestroy, getContext } from "svelte";
|
|
3
3
|
import { getStyle } from "../helpers/columnWidth";
|
|
4
|
-
import { getRenderValue } from "
|
|
4
|
+
import { getRenderValue } from "@svar-ui/grid-store";
|
|
5
5
|
|
|
6
6
|
let {
|
|
7
7
|
row,
|
|
@@ -35,11 +35,9 @@
|
|
|
35
35
|
|
|
36
36
|
let cellEl;
|
|
37
37
|
$effect(() => {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
cellEl.blur();
|
|
42
|
-
}
|
|
38
|
+
const needFocus =
|
|
39
|
+
$focusCell?.row === row.id && $focusCell?.column === column.id;
|
|
40
|
+
if (cellEl && focusable && needFocus) cellEl.focus();
|
|
43
41
|
});
|
|
44
42
|
|
|
45
43
|
function buildCellCss(columnStyle, cellStyle) {
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
import { writable } from "svelte/store";
|
|
5
5
|
|
|
6
6
|
// core widgets lib
|
|
7
|
-
import { Locale } from "
|
|
8
|
-
import { en } from "
|
|
7
|
+
import { Locale } from "@svar-ui/svelte-core";
|
|
8
|
+
import { en } from "@svar-ui/grid-locales";
|
|
9
9
|
|
|
10
10
|
// stores
|
|
11
|
-
import { EventBusRouter } from "
|
|
12
|
-
import { DataStore, isCommunity } from "
|
|
11
|
+
import { EventBusRouter } from "@svar-ui/lib-state";
|
|
12
|
+
import { DataStore, isCommunity } from "@svar-ui/grid-store";
|
|
13
13
|
|
|
14
14
|
// ui
|
|
15
15
|
import Layout from "./Layout.svelte";
|
|
@@ -26,7 +26,6 @@
|
|
|
26
26
|
header = true,
|
|
27
27
|
footer = false,
|
|
28
28
|
dynamic = null,
|
|
29
|
-
filter = null,
|
|
30
29
|
overlay = null,
|
|
31
30
|
reorder = false,
|
|
32
31
|
onreorder = null,
|
|
@@ -36,9 +35,17 @@
|
|
|
36
35
|
tree = false,
|
|
37
36
|
autoConfig = false,
|
|
38
37
|
init = null,
|
|
38
|
+
responsive = null,
|
|
39
|
+
sortMarks = {},
|
|
40
|
+
undo = false,
|
|
39
41
|
...restProps
|
|
40
42
|
} = $props();
|
|
41
43
|
|
|
44
|
+
let clientWidth = $state(0);
|
|
45
|
+
let clientHeight = $state(0);
|
|
46
|
+
let responsiveLevel = $state(null);
|
|
47
|
+
let responsiveConfig = $state(null);
|
|
48
|
+
|
|
42
49
|
// init stores
|
|
43
50
|
const dataStore = new DataStore(writable);
|
|
44
51
|
|
|
@@ -92,27 +99,50 @@
|
|
|
92
99
|
});
|
|
93
100
|
// auto config columns
|
|
94
101
|
const finalColumns = $derived.by(() => {
|
|
95
|
-
|
|
96
|
-
if (autoConfig && !res.length && data.length) {
|
|
102
|
+
if (autoConfig && !columns.length && data.length) {
|
|
97
103
|
const test = data[0];
|
|
104
|
+
const autoCols = [];
|
|
98
105
|
|
|
99
106
|
for (let key in test) {
|
|
100
|
-
if (key
|
|
107
|
+
if (key !== "id" && key[0] !== "$") {
|
|
101
108
|
let col = {
|
|
102
109
|
id: key,
|
|
103
|
-
header: key[0].toUpperCase() + key.
|
|
110
|
+
header: key[0].toUpperCase() + key.slice(1),
|
|
104
111
|
};
|
|
105
112
|
|
|
106
|
-
if (typeof autoConfig === "object")
|
|
113
|
+
if (typeof autoConfig === "object") {
|
|
107
114
|
col = { ...col, ...autoConfig };
|
|
108
|
-
|
|
115
|
+
}
|
|
116
|
+
autoCols.push(col);
|
|
109
117
|
}
|
|
110
118
|
}
|
|
119
|
+
|
|
120
|
+
return autoCols;
|
|
111
121
|
}
|
|
112
122
|
|
|
113
|
-
return columns;
|
|
123
|
+
return responsiveConfig?.columns ?? columns;
|
|
114
124
|
});
|
|
115
125
|
|
|
126
|
+
const finalSizes = $derived(responsiveConfig?.sizes ?? sizes);
|
|
127
|
+
|
|
128
|
+
function resize(rect) {
|
|
129
|
+
clientWidth = rect.width;
|
|
130
|
+
clientHeight = rect.height;
|
|
131
|
+
|
|
132
|
+
if (responsive) {
|
|
133
|
+
const levels = Object.keys(responsive)
|
|
134
|
+
.map(Number)
|
|
135
|
+
.sort((a, b) => a - b);
|
|
136
|
+
|
|
137
|
+
const newLevel = levels.find(level => clientWidth <= level) ?? null;
|
|
138
|
+
|
|
139
|
+
if (newLevel !== responsiveLevel) {
|
|
140
|
+
responsiveConfig = responsive[newLevel];
|
|
141
|
+
responsiveLevel = newLevel;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
116
146
|
const isReorderAvailable = $derived.by(() => {
|
|
117
147
|
let available = !tree;
|
|
118
148
|
if (!isCommunity()) available = true;
|
|
@@ -121,20 +151,20 @@
|
|
|
121
151
|
});
|
|
122
152
|
|
|
123
153
|
let _skin = $derived(getContext("wx-theme"));
|
|
124
|
-
|
|
125
154
|
let init_once = true;
|
|
126
155
|
const reinitStore = () => {
|
|
127
156
|
dataStore.init({
|
|
128
157
|
data,
|
|
129
158
|
columns: finalColumns,
|
|
130
159
|
split,
|
|
131
|
-
sizes,
|
|
160
|
+
sizes: finalSizes,
|
|
132
161
|
selectedRows,
|
|
133
162
|
dynamic,
|
|
134
|
-
filter,
|
|
135
163
|
tree,
|
|
164
|
+
sortMarks,
|
|
165
|
+
select,
|
|
166
|
+
undo,
|
|
136
167
|
_skin,
|
|
137
|
-
_select: select,
|
|
138
168
|
});
|
|
139
169
|
|
|
140
170
|
if (init_once && init) {
|
|
@@ -159,5 +189,9 @@
|
|
|
159
189
|
{onreorder}
|
|
160
190
|
{multiselect}
|
|
161
191
|
{autoRowHeight}
|
|
192
|
+
{clientWidth}
|
|
193
|
+
{clientHeight}
|
|
194
|
+
{responsiveLevel}
|
|
195
|
+
{resize}
|
|
162
196
|
/>
|
|
163
197
|
</Locale>
|
|
@@ -16,17 +16,29 @@
|
|
|
16
16
|
} = $props();
|
|
17
17
|
|
|
18
18
|
const api = getContext("grid-store");
|
|
19
|
+
const { sortMarks } = api.getReactiveState();
|
|
19
20
|
|
|
20
21
|
let start;
|
|
21
22
|
|
|
23
|
+
let sortMark = $derived($sortMarks[column.id]);
|
|
24
|
+
|
|
22
25
|
function down(node) {
|
|
23
26
|
start = cell.flexgrow ? node.parentNode.clientWidth : cell.width;
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
function move(dx) {
|
|
30
|
+
resizeColumn(dx, true);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function up(dx) {
|
|
34
|
+
resizeColumn(dx, false);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function resizeColumn(dx, inProgress) {
|
|
27
38
|
api.exec("resize-column", {
|
|
28
39
|
id: cell.id,
|
|
29
40
|
width: Math.max(1, start + dx),
|
|
41
|
+
inProgress,
|
|
30
42
|
});
|
|
31
43
|
}
|
|
32
44
|
|
|
@@ -110,9 +122,9 @@
|
|
|
110
122
|
aria-colindex={cell._colindex}
|
|
111
123
|
aria-colspan={cell.colspan > 1 ? cell.colspan : undefined}
|
|
112
124
|
aria-rowspan={cell.rowspan > 1 ? cell.rowspan : undefined}
|
|
113
|
-
aria-sort={!
|
|
125
|
+
aria-sort={!sortMark?.order || cell.filter
|
|
114
126
|
? "none"
|
|
115
|
-
:
|
|
127
|
+
: sortMark?.order === "asc"
|
|
116
128
|
? "ascending"
|
|
117
129
|
: "descending"}
|
|
118
130
|
onkeydown={toggleSortColumn}
|
|
@@ -154,23 +166,23 @@
|
|
|
154
166
|
class="wx-grip"
|
|
155
167
|
role="presentation"
|
|
156
168
|
aria-label="Resize column"
|
|
157
|
-
use:resize={{ down, move }}
|
|
169
|
+
use:resize={{ down, move, up }}
|
|
158
170
|
onclick={ev => ev.stopPropagation()}
|
|
159
171
|
>
|
|
160
172
|
<div></div>
|
|
161
173
|
</div>
|
|
162
174
|
{/if}
|
|
163
175
|
|
|
164
|
-
{#if
|
|
176
|
+
{#if sortRow}
|
|
165
177
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
166
178
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
167
179
|
<div class="wx-sort">
|
|
168
|
-
{#if
|
|
169
|
-
{#if
|
|
170
|
-
<div class="wx-order">{
|
|
180
|
+
{#if sortMark}
|
|
181
|
+
{#if typeof sortMark.index !== "undefined"}
|
|
182
|
+
<div class="wx-order">{sortMark.index + 1}</div>
|
|
171
183
|
{/if}
|
|
172
184
|
<i
|
|
173
|
-
class="wxi-arrow-{
|
|
185
|
+
class="wxi-arrow-{sortMark.order === 'asc'
|
|
174
186
|
? 'up'
|
|
175
187
|
: 'down'}"
|
|
176
188
|
></i>
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { getContext } from "svelte";
|
|
3
3
|
import HeaderCell from "./HeaderCell.svelte";
|
|
4
4
|
import FooterCell from "./FooterCell.svelte";
|
|
5
|
-
import { isCommunity } from "
|
|
5
|
+
import { isCommunity } from "@svar-ui/grid-store";
|
|
6
6
|
|
|
7
7
|
let {
|
|
8
8
|
deltaLeft,
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
function isSort(cell, ind, column) {
|
|
65
|
+
if (!column.sort) return false;
|
|
65
66
|
for (let i = renderedHeader.length - 1; i >= 0; i--) {
|
|
66
67
|
const cell = column.header[i];
|
|
67
68
|
if (!cell.filter && !cell._hidden) return ind === i;
|
|
@@ -12,11 +12,11 @@
|
|
|
12
12
|
locateAttr,
|
|
13
13
|
locate,
|
|
14
14
|
id,
|
|
15
|
-
} from "
|
|
15
|
+
} from "@svar-ui/lib-dom";
|
|
16
16
|
|
|
17
|
-
import { hotkeys } from "
|
|
18
|
-
import {
|
|
19
|
-
import { scrollTo } from "
|
|
17
|
+
import { hotkeys } from "@svar-ui/grid-store";
|
|
18
|
+
import { getKeys } from "../helpers/hotkeys";
|
|
19
|
+
import { scrollTo } from "@svar-ui/grid-store";
|
|
20
20
|
|
|
21
21
|
import Cell from "./Cell.svelte";
|
|
22
22
|
import HeaderFooter from "./HeaderFooter.svelte";
|
|
@@ -35,6 +35,10 @@
|
|
|
35
35
|
columnStyle,
|
|
36
36
|
cellStyle,
|
|
37
37
|
autoRowHeight,
|
|
38
|
+
resize,
|
|
39
|
+
clientWidth,
|
|
40
|
+
clientHeight,
|
|
41
|
+
responsiveLevel,
|
|
38
42
|
} = $props();
|
|
39
43
|
|
|
40
44
|
const api = getContext("grid-store");
|
|
@@ -46,12 +50,13 @@
|
|
|
46
50
|
split,
|
|
47
51
|
_sizes,
|
|
48
52
|
selectedRows,
|
|
49
|
-
|
|
53
|
+
select,
|
|
50
54
|
editor,
|
|
51
55
|
scroll,
|
|
52
56
|
tree,
|
|
53
57
|
focusCell,
|
|
54
58
|
_print,
|
|
59
|
+
undo,
|
|
55
60
|
} = api.getReactiveState();
|
|
56
61
|
|
|
57
62
|
// will be calculated once, after rendering
|
|
@@ -65,9 +70,7 @@
|
|
|
65
70
|
});
|
|
66
71
|
|
|
67
72
|
const defaultRowHeight = $derived($_sizes.rowHeight);
|
|
68
|
-
let
|
|
69
|
-
clientHeight = $state(0),
|
|
70
|
-
tableNode;
|
|
73
|
+
let tableNode;
|
|
71
74
|
|
|
72
75
|
// reorder
|
|
73
76
|
let dragItem = $state(null),
|
|
@@ -346,11 +349,6 @@
|
|
|
346
349
|
scrollLeft = ev.target.scrollLeft;
|
|
347
350
|
}
|
|
348
351
|
|
|
349
|
-
function resize(rect) {
|
|
350
|
-
clientWidth = rect.width;
|
|
351
|
-
clientHeight = rect.height;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
352
|
function lockSelection(ev) {
|
|
355
353
|
// we prevent default on mousedown reaction to stop the unwanted text selection
|
|
356
354
|
// in the same time we need to have focus-in, so trigger it manually
|
|
@@ -638,7 +636,7 @@
|
|
|
638
636
|
</script>
|
|
639
637
|
|
|
640
638
|
<div
|
|
641
|
-
class=
|
|
639
|
+
class={`wx-grid ${responsiveLevel ? `wx-responsive-${responsiveLevel}` : ""}`}
|
|
642
640
|
style="--header-height:{headerHeight}px; --footer-height:{footerHeight}px;--split-left-width:{leftColumns.width}px;
|
|
643
641
|
--split-right-width:{rightColumns.width}px;"
|
|
644
642
|
>
|
|
@@ -655,7 +653,10 @@
|
|
|
655
653
|
getReorder: () => reorder,
|
|
656
654
|
getDraggableInfo: () => ({ hasDraggable: checkDraggable() }),
|
|
657
655
|
}}
|
|
658
|
-
use:hotkeys={{
|
|
656
|
+
use:hotkeys={{
|
|
657
|
+
keys: getKeys({ undo: $undo }),
|
|
658
|
+
exec: v => api.exec("hotkey", v),
|
|
659
|
+
}}
|
|
659
660
|
{style}
|
|
660
661
|
role={$tree ? "treegrid" : "grid"}
|
|
661
662
|
aria-colcount={renderColumns.data.length}
|
|
@@ -772,6 +773,7 @@
|
|
|
772
773
|
.wx-grid {
|
|
773
774
|
height: 100%;
|
|
774
775
|
}
|
|
776
|
+
|
|
775
777
|
.wx-table-box {
|
|
776
778
|
outline: none;
|
|
777
779
|
position: relative;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { onMount } from "svelte";
|
|
3
3
|
|
|
4
|
-
import { Calendar, Dropdown } from "
|
|
4
|
+
import { Calendar, Dropdown } from "@svar-ui/svelte-core";
|
|
5
5
|
|
|
6
6
|
let { actions, editor, onaction } = $props();
|
|
7
7
|
|
|
8
8
|
let value = $state(editor.value || new Date());
|
|
9
9
|
|
|
10
|
-
let template = $state(editor
|
|
11
|
-
let cell = $state(editor
|
|
10
|
+
let template = $state(editor.config?.template);
|
|
11
|
+
let cell = $state(editor.config?.cell);
|
|
12
12
|
|
|
13
13
|
function updateValue({ value }) {
|
|
14
14
|
actions.updateValue(value);
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
{:else}<span class="wx-text">{editor.renderedValue}</span>{/if}
|
|
43
43
|
</div>
|
|
44
44
|
<Dropdown width={"auto"}>
|
|
45
|
-
<Calendar {value} onchange={updateValue} />
|
|
45
|
+
<Calendar {value} onchange={updateValue} buttons={editor.config?.buttons} />
|
|
46
46
|
</Dropdown>
|
|
47
47
|
|
|
48
48
|
<style>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { getContext } from "svelte";
|
|
3
3
|
import { getStyle } from "../../helpers/columnWidth";
|
|
4
|
-
import { clickOutside } from "
|
|
4
|
+
import { clickOutside } from "@svar-ui/lib-dom";
|
|
5
5
|
import { editors } from "./editors";
|
|
6
6
|
|
|
7
7
|
let { column, row } = $props();
|
|
@@ -34,6 +34,10 @@
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
function keyHandler(ev) {
|
|
38
|
+
if (ev.key === "Enter" && $editor) cancel();
|
|
39
|
+
}
|
|
40
|
+
|
|
37
41
|
let style = $derived(
|
|
38
42
|
getStyle(
|
|
39
43
|
column.width,
|
|
@@ -44,7 +48,12 @@
|
|
|
44
48
|
)
|
|
45
49
|
);
|
|
46
50
|
|
|
47
|
-
const SvelteComponent = $derived(
|
|
51
|
+
const SvelteComponent = $derived.by(() => {
|
|
52
|
+
let editor = column.editor;
|
|
53
|
+
if (typeof editor === "function") editor = editor(row, column);
|
|
54
|
+
let type = typeof editor === "string" ? editor : editor.type;
|
|
55
|
+
return editors[type];
|
|
56
|
+
});
|
|
48
57
|
</script>
|
|
49
58
|
|
|
50
59
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
@@ -61,6 +70,7 @@
|
|
|
61
70
|
tabindex="-1"
|
|
62
71
|
onclick={ev => ev.stopPropagation()}
|
|
63
72
|
ondblclick={ev => ev.stopPropagation()}
|
|
73
|
+
onkeydown={keyHandler}
|
|
64
74
|
use:clickOutside={() => save(true)}
|
|
65
75
|
>
|
|
66
76
|
<SvelteComponent
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { getContext } from "svelte";
|
|
3
|
-
import { RichSelect } from "
|
|
4
|
-
import { getValue } from "
|
|
3
|
+
import { RichSelect } from "@svar-ui/svelte-core";
|
|
4
|
+
import { getValue } from "@svar-ui/grid-store";
|
|
5
5
|
|
|
6
6
|
let { filter, column, action, filterValue } = $props();
|
|
7
7
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import { ContextMenu } from "
|
|
2
|
+
import { ContextMenu } from "@svar-ui/svelte-menu";
|
|
3
3
|
import { getContext } from "svelte";
|
|
4
4
|
import { defaultMenuOptions } from "../../../src";
|
|
5
|
+
import { locale } from "@svar-ui/lib-dom";
|
|
6
|
+
import { en } from "@svar-ui/grid-locales";
|
|
5
7
|
|
|
6
8
|
let {
|
|
7
9
|
api,
|
|
8
|
-
handler,
|
|
9
10
|
options = defaultMenuOptions,
|
|
10
11
|
at = "point",
|
|
11
12
|
resolver = getItem,
|
|
@@ -16,7 +17,8 @@
|
|
|
16
17
|
onclick,
|
|
17
18
|
} = $props();
|
|
18
19
|
|
|
19
|
-
const _ =
|
|
20
|
+
const _ =
|
|
21
|
+
getContext("wx-i18n")?.getGroup("grid") || locale(en).getGroup("grid");
|
|
20
22
|
|
|
21
23
|
const localize = options => {
|
|
22
24
|
return options.map(o => {
|
|
@@ -62,7 +64,6 @@
|
|
|
62
64
|
{at}
|
|
63
65
|
{dataKey}
|
|
64
66
|
options={localize(options)}
|
|
65
|
-
{handler}
|
|
66
67
|
{resolver}
|
|
67
68
|
{filter}
|
|
68
69
|
onclick={handleClicks}
|
|
@@ -27,7 +27,7 @@ export function resize(node, config) {
|
|
|
27
27
|
document.body.style.cursor = "";
|
|
28
28
|
document.body.style.userSelect = "";
|
|
29
29
|
|
|
30
|
-
if (config && config.up) config.up();
|
|
30
|
+
if (config && config.up) config.up(dx);
|
|
31
31
|
|
|
32
32
|
window.removeEventListener("mousemove", move);
|
|
33
33
|
window.removeEventListener("mouseup", up);
|
package/src/helpers/hotkeys.js
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
1
|
+
export function getKeys(config) {
|
|
2
|
+
return {
|
|
3
|
+
tab: true,
|
|
4
|
+
"shift+tab": true,
|
|
5
|
+
arrowup: true,
|
|
6
|
+
arrowdown: true,
|
|
7
|
+
arrowright: true,
|
|
8
|
+
arrowleft: true,
|
|
9
|
+
enter: true,
|
|
10
|
+
escape: true,
|
|
11
|
+
f2: true,
|
|
12
|
+
home: true,
|
|
13
|
+
end: true,
|
|
14
|
+
"ctrl+home": true,
|
|
15
|
+
"ctrl+end": true,
|
|
16
|
+
"ctrl+z": config.undo,
|
|
17
|
+
"ctrl+y": config.undo,
|
|
18
|
+
};
|
|
19
|
+
}
|
package/src/index.js
CHANGED
|
@@ -2,25 +2,15 @@ import Grid from "./components/Grid.svelte";
|
|
|
2
2
|
import HeaderMenu from "./components/menus/HeaderMenu.svelte";
|
|
3
3
|
import Tooltip from "./components/Tooltip.svelte";
|
|
4
4
|
import ContextMenu from "./components/menus/ContextMenu.svelte";
|
|
5
|
-
import { defaultMenuOptions } from "./helpers/menuOptions";
|
|
6
5
|
|
|
7
6
|
import Material from "./themes/Material.svelte";
|
|
8
7
|
import Willow from "./themes/Willow.svelte";
|
|
9
8
|
import WillowDark from "./themes/WillowDark.svelte";
|
|
10
9
|
|
|
11
|
-
export { getEditorConfig } from "
|
|
10
|
+
export { getEditorConfig, defaultMenuOptions } from "@svar-ui/grid-store";
|
|
12
11
|
|
|
13
|
-
import { setEnv } from "
|
|
14
|
-
import { env } from "
|
|
12
|
+
import { setEnv } from "@svar-ui/lib-dom";
|
|
13
|
+
import { env } from "@svar-ui/lib-svelte";
|
|
15
14
|
setEnv(env);
|
|
16
15
|
|
|
17
|
-
export {
|
|
18
|
-
Grid,
|
|
19
|
-
HeaderMenu,
|
|
20
|
-
Tooltip,
|
|
21
|
-
ContextMenu,
|
|
22
|
-
defaultMenuOptions,
|
|
23
|
-
Material,
|
|
24
|
-
Willow,
|
|
25
|
-
WillowDark,
|
|
26
|
-
};
|
|
16
|
+
export { Grid, HeaderMenu, Tooltip, ContextMenu, Material, Willow, WillowDark };
|
package/src/themes/Willow.svelte
CHANGED
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import type { Component, ComponentProps } from "svelte";
|
|
2
|
+
import { ContextMenu as BaseContextMenu } from "@svar-ui/svelte-menu";
|
|
3
|
+
|
|
4
|
+
import type {
|
|
5
|
+
IColumn,
|
|
6
|
+
IRow,
|
|
7
|
+
IApi,
|
|
8
|
+
ISizeConfig,
|
|
9
|
+
TMethodsConfig,
|
|
10
|
+
IConfig,
|
|
11
|
+
TEditorType,
|
|
12
|
+
IColumnEditor,
|
|
13
|
+
IHeaderCell,
|
|
14
|
+
} from "@svar-ui/grid-store";
|
|
15
|
+
|
|
16
|
+
export * from "@svar-ui/grid-store";
|
|
17
|
+
|
|
18
|
+
export interface IColumnEditorConfig extends IColumnEditor {
|
|
19
|
+
config?: IColumnEditor["config"] & {
|
|
20
|
+
cell?: Component<{
|
|
21
|
+
data: any;
|
|
22
|
+
onaction: (ev: {
|
|
23
|
+
action?: any;
|
|
24
|
+
data?: { [key: string]: any };
|
|
25
|
+
}) => void;
|
|
26
|
+
}>;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type TEditorHandlerConfig = (
|
|
31
|
+
row?: IRow,
|
|
32
|
+
column?: IColumn
|
|
33
|
+
) => TEditorType | IColumnEditorConfig | null;
|
|
34
|
+
|
|
35
|
+
export interface ICellProps {
|
|
36
|
+
api: IApi;
|
|
37
|
+
row: IRow;
|
|
38
|
+
column: IColumn;
|
|
39
|
+
onaction: (ev: { action?: any; data?: { [key: string]: any } }) => void;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface IHeaderCellConfig extends IHeaderCell {
|
|
43
|
+
cell?: Component<
|
|
44
|
+
ICellProps & {
|
|
45
|
+
cell: Omit<IHeaderCell, "cell">;
|
|
46
|
+
}
|
|
47
|
+
>;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export type TColumnHeaderConfig =
|
|
51
|
+
| string
|
|
52
|
+
| IHeaderCellConfig
|
|
53
|
+
| (string | IHeaderCellConfig)[];
|
|
54
|
+
|
|
55
|
+
export interface IColumnConfig
|
|
56
|
+
extends Omit<
|
|
57
|
+
IColumn,
|
|
58
|
+
"left" | "right" | "fixed" | "optionsMap" | "header" | "footer"
|
|
59
|
+
> {
|
|
60
|
+
cell?: Component<ICellProps>;
|
|
61
|
+
editor?: TEditorType | IColumnEditorConfig | TEditorHandlerConfig;
|
|
62
|
+
header?: TColumnHeaderConfig;
|
|
63
|
+
footer?: TColumnHeaderConfig;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export declare const Grid: Component<
|
|
67
|
+
{
|
|
68
|
+
rowStyle?: (row: any) => string;
|
|
69
|
+
columnStyle?: (column: IColumn) => string;
|
|
70
|
+
cellStyle?: (row: any, column: IColumn) => string;
|
|
71
|
+
multiselect?: boolean;
|
|
72
|
+
autoConfig?: boolean | IColumnConfig;
|
|
73
|
+
header?: boolean;
|
|
74
|
+
footer?: boolean;
|
|
75
|
+
reorder?: boolean;
|
|
76
|
+
autoRowHeight?: boolean;
|
|
77
|
+
responsive?: {
|
|
78
|
+
[key: string]: {
|
|
79
|
+
sizes?: ISizeConfig;
|
|
80
|
+
columns?: IColumnConfig[];
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
init?: (api: IApi) => void;
|
|
84
|
+
|
|
85
|
+
overlay?: string | Component;
|
|
86
|
+
columns: IColumnConfig[];
|
|
87
|
+
} & IConfig &
|
|
88
|
+
GridActions<TMethodsConfig>
|
|
89
|
+
>;
|
|
90
|
+
|
|
91
|
+
export declare const HeaderMenu: Component<{
|
|
92
|
+
columns?: { [key: string]: boolean };
|
|
93
|
+
api?: IApi;
|
|
94
|
+
children?: () => any;
|
|
95
|
+
}>;
|
|
96
|
+
|
|
97
|
+
export declare const ContextMenu: Component<
|
|
98
|
+
ComponentProps<typeof BaseContextMenu> & {
|
|
99
|
+
api?: IApi;
|
|
100
|
+
}
|
|
101
|
+
>;
|
|
102
|
+
|
|
103
|
+
export declare const Tooltip: Component<{
|
|
104
|
+
content?: Component;
|
|
105
|
+
api?: IApi;
|
|
106
|
+
children?: () => any;
|
|
107
|
+
}>;
|
|
108
|
+
|
|
109
|
+
export declare const Material: Component<{
|
|
110
|
+
fonts?: boolean;
|
|
111
|
+
children?: () => any;
|
|
112
|
+
}>;
|
|
113
|
+
|
|
114
|
+
export declare const Willow: Component<{
|
|
115
|
+
fonts?: boolean;
|
|
116
|
+
children?: () => any;
|
|
117
|
+
}>;
|
|
118
|
+
|
|
119
|
+
export declare const WillowDark: Component<{
|
|
120
|
+
fonts?: boolean;
|
|
121
|
+
children?: () => any;
|
|
122
|
+
}>;
|
|
123
|
+
|
|
124
|
+
/* get component events from store actions*/
|
|
125
|
+
type RemoveHyphen<S extends string> = S extends `${infer Head}-${infer Tail}`
|
|
126
|
+
? `${Head}${RemoveHyphen<Tail>}`
|
|
127
|
+
: S;
|
|
128
|
+
|
|
129
|
+
type EventName<K extends string> = `on${RemoveHyphen<K>}`;
|
|
130
|
+
|
|
131
|
+
export type GridActions<TMethodsConfig extends Record<string, any>> = {
|
|
132
|
+
[K in keyof TMethodsConfig as EventName<K & string>]?: (
|
|
133
|
+
ev: TMethodsConfig[K]
|
|
134
|
+
) => void;
|
|
135
|
+
} & {
|
|
136
|
+
[key: `on${string}`]: (ev?: any) => void;
|
|
137
|
+
};
|
package/whatsnew.md
CHANGED
|
@@ -1,3 +1,37 @@
|
|
|
1
|
+
## 2.3.0
|
|
2
|
+
|
|
3
|
+
### New features
|
|
4
|
+
|
|
5
|
+
- TypeScript definitions
|
|
6
|
+
|
|
7
|
+
### Fixes
|
|
8
|
+
|
|
9
|
+
- Default locale is not applied to ContextMenu
|
|
10
|
+
|
|
11
|
+
## 2.2.0
|
|
12
|
+
|
|
13
|
+
### New features
|
|
14
|
+
|
|
15
|
+
- Undo/redo for data and column actions
|
|
16
|
+
- Ability to tune responsive behaviour
|
|
17
|
+
- Dynamic inline editors for column cells
|
|
18
|
+
- Integration with SVAR Filter
|
|
19
|
+
|
|
20
|
+
### Updates
|
|
21
|
+
|
|
22
|
+
- Non-persistent filtering: table is not re-filtered on data changes
|
|
23
|
+
|
|
24
|
+
### Fixes
|
|
25
|
+
|
|
26
|
+
- Inline "date" editor is not closed on Enter key
|
|
27
|
+
- Shift+tab hotkey makes extra step with inline editors
|
|
28
|
+
- Enter hotkey calls "open-row" action for non-branches in `tree` mode
|
|
29
|
+
- Changing any property reverts data in `tree` mode
|
|
30
|
+
|
|
31
|
+
### Breaking changes
|
|
32
|
+
|
|
33
|
+
- `sort` state property renamed to `sortMarks`
|
|
34
|
+
|
|
1
35
|
## 2.1.5
|
|
2
36
|
|
|
3
37
|
### Fixes
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export const defaultMenuOptions = [
|
|
2
|
-
{
|
|
3
|
-
id: "add:before",
|
|
4
|
-
text: "Add before",
|
|
5
|
-
icon: "wxi-table-row-plus-before",
|
|
6
|
-
},
|
|
7
|
-
{
|
|
8
|
-
id: "add:after",
|
|
9
|
-
text: "Add after",
|
|
10
|
-
icon: "wxi-table-row-plus-after",
|
|
11
|
-
},
|
|
12
|
-
{ id: "copy", text: "Copy", icon: "wxi-content-copy" },
|
|
13
|
-
{ type: "separator" },
|
|
14
|
-
{ id: "delete", text: "Delete", icon: "wxi-delete-outline" },
|
|
15
|
-
];
|