wx-svelte-grid 2.5.1 → 2.6.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 +10 -10
- package/readme.md +20 -12
- package/src/components/Grid.svelte +7 -2
- package/src/components/Layout.svelte +2 -3
- package/src/components/inlineEditors/Combo.svelte +16 -5
- package/src/components/inlineEditors/Datepicker.svelte +19 -9
- package/src/components/inlineEditors/Editor.svelte +11 -5
- package/src/components/inlineEditors/MultiSelect.svelte +121 -0
- package/src/components/inlineEditors/Richselect.svelte +15 -6
- package/src/components/inlineEditors/Text.svelte +5 -3
- package/src/components/inlineEditors/editors.js +6 -0
- package/src/components/inlineFilters/DatePicker.svelte +27 -0
- package/src/components/inlineFilters/filters.js +2 -0
- package/src/helpers/columnWidth.js +6 -1
- package/src/index.js +2 -0
- package/types/index.d.ts +15 -0
- package/whatsnew.md +27 -0
- package/src/components/editor/Editor.svelte +0 -56
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wx-svelte-grid",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.1",
|
|
4
4
|
"description": "A fast, feature-rich Svelte DataGrid component",
|
|
5
5
|
"productTag": "grid",
|
|
6
6
|
"productTrial": false,
|
|
@@ -33,19 +33,19 @@
|
|
|
33
33
|
},
|
|
34
34
|
"homepage": "https://svar.dev/svelte/datagrid/",
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@svar-ui/lib-dom": "0.12.
|
|
36
|
+
"@svar-ui/lib-dom": "0.12.1",
|
|
37
37
|
"@svar-ui/lib-state": "1.9.6",
|
|
38
38
|
"@svar-ui/lib-svelte": "0.5.2",
|
|
39
|
-
"@svar-ui/svelte-menu": "2.
|
|
40
|
-
"@svar-ui/svelte-core": "2.
|
|
41
|
-
"@svar-ui/svelte-toolbar": "2.
|
|
42
|
-
"@svar-ui/grid-data-provider": "2.
|
|
43
|
-
"@svar-ui/grid-locales": "2.
|
|
44
|
-
"@svar-ui/grid-store": "2.
|
|
39
|
+
"@svar-ui/svelte-menu": "2.5.1",
|
|
40
|
+
"@svar-ui/svelte-core": "2.5.1",
|
|
41
|
+
"@svar-ui/svelte-toolbar": "2.5.1",
|
|
42
|
+
"@svar-ui/grid-data-provider": "2.6.1",
|
|
43
|
+
"@svar-ui/grid-locales": "2.6.1",
|
|
44
|
+
"@svar-ui/grid-store": "2.6.1"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@svar-ui/svelte-editor": "2.
|
|
48
|
-
"@svar-ui/svelte-filter": "2.
|
|
47
|
+
"@svar-ui/svelte-editor": "2.5.1",
|
|
48
|
+
"@svar-ui/svelte-filter": "2.5.0"
|
|
49
49
|
},
|
|
50
50
|
"files": [
|
|
51
51
|
"src",
|
package/readme.md
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
</div>
|
|
21
21
|
|
|
22
|
-
[SVAR Svelte DataGrid](https://svar.dev/svelte/datagrid/) is a high-performance Svelte component for building feature-rich, accessible data tables
|
|
22
|
+
[SVAR Svelte DataGrid](https://svar.dev/svelte/datagrid/) is a high-performance Svelte component for building feature-rich, accessible data tables. It supports sorting, advanced filtering, paging, in-cell editing, and virtual scrolling out of the box. Comes with full TypeScript support and a flexible, developer-friendly API. Suitable for dashboards, admin panels, and data-heavy SaaS applications.
|
|
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">
|
|
@@ -29,26 +29,30 @@
|
|
|
29
29
|
|
|
30
30
|
Here is a quick overview of what SVAR Svelte DataGrid offers:
|
|
31
31
|
|
|
32
|
-
- High performance (virtual scrolling
|
|
32
|
+
- High performance (virtual scrolling and dynamic loading)
|
|
33
33
|
- In-cell editing with different cell editors (datepicker, combo, select, rich select, etc.)
|
|
34
|
+
- External editor for grid data
|
|
34
35
|
- Custom HTML for cells
|
|
35
36
|
- Sorting by multiple columns
|
|
36
|
-
-
|
|
37
|
+
- Advanced filtering (including natural language)
|
|
37
38
|
- Paging
|
|
38
|
-
-
|
|
39
|
+
- Frozen columns
|
|
39
40
|
- Expandable/collapsible columns
|
|
41
|
+
- Row reordering with drag-and-drop
|
|
40
42
|
- Customizable tooltips for grid cells
|
|
41
43
|
- Context menu
|
|
42
|
-
-
|
|
44
|
+
- Built-in toolbar
|
|
43
45
|
- Tree-like structure
|
|
44
|
-
- Print support
|
|
45
|
-
-
|
|
46
|
-
- Accessibility: compatible with [WAI-ARIA](https://www.w3.org/WAI/standards-guidelines/aria/) standard
|
|
46
|
+
- Print support, export to CSV
|
|
47
|
+
- Undo/redo
|
|
47
48
|
- Keyboard navigation
|
|
49
|
+
- Accessibility: compatibility with [WAI-ARIA](https://www.w3.org/WAI/standards-guidelines/aria/) standard
|
|
48
50
|
- RestDataProvider for easy backend data binding
|
|
49
|
-
- Dark and light skins
|
|
51
|
+
- Dark and light skins, customizable with CSS (no Tailwind dependency)
|
|
50
52
|
- Full TypeScript support
|
|
51
53
|
|
|
54
|
+
[Check the demos](https://docs.svar.dev/svelte/grid/samples/#/base/willow) to see how these features work.
|
|
55
|
+
|
|
52
56
|
### :hammer_and_wrench: How to Use
|
|
53
57
|
|
|
54
58
|
To use SVAR Svelte DataGrid, simply import the package and include the component in your Svelte file:
|
|
@@ -87,14 +91,14 @@ To use SVAR Svelte DataGrid, simply import the package and include the component
|
|
|
87
91
|
|
|
88
92
|
For further instructions, see the detailed [how-to-start guide](https://docs.svar.dev/svelte/grid/getting_started).
|
|
89
93
|
|
|
90
|
-
###
|
|
94
|
+
### How to Modify
|
|
91
95
|
|
|
92
96
|
Typically, you don't need to modify the code. However, if you wish to do so, follow these steps:
|
|
93
97
|
|
|
94
98
|
1. Run `yarn` to install dependencies. Note that this project is a monorepo using `yarn` workspaces, so npm will not work
|
|
95
99
|
2. Start the project in development mode with `yarn start`
|
|
96
100
|
|
|
97
|
-
###
|
|
101
|
+
### Run Tests
|
|
98
102
|
|
|
99
103
|
To run the test:
|
|
100
104
|
|
|
@@ -107,6 +111,10 @@ To run the test:
|
|
|
107
111
|
yarn test:cypress
|
|
108
112
|
```
|
|
109
113
|
|
|
110
|
-
###
|
|
114
|
+
### Need Help?
|
|
111
115
|
|
|
112
116
|
Join our [community forum](https://forum.svar.dev) to get help or post feature requests.
|
|
117
|
+
|
|
118
|
+
### ⭐ Show Your Support
|
|
119
|
+
|
|
120
|
+
If SVAR Svelte DataGrid helps your project, [give us a star on GitHub](https://github.com/svar-widgets/grid)! It helps more developers discover this component and keeps our team motivated to ship new features.
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
sortMarks = {},
|
|
40
40
|
undo = false,
|
|
41
41
|
hotkeys = null,
|
|
42
|
+
filterValues = {},
|
|
42
43
|
...restProps
|
|
43
44
|
} = $props();
|
|
44
45
|
|
|
@@ -147,7 +148,7 @@
|
|
|
147
148
|
let _skin = $derived(getContext("wx-theme"));
|
|
148
149
|
let init_once = true;
|
|
149
150
|
|
|
150
|
-
|
|
151
|
+
const reinitStore = () => {
|
|
151
152
|
dataStore.init({
|
|
152
153
|
data,
|
|
153
154
|
columns: finalColumns,
|
|
@@ -157,6 +158,7 @@
|
|
|
157
158
|
dynamic,
|
|
158
159
|
tree,
|
|
159
160
|
sortMarks,
|
|
161
|
+
filterValues,
|
|
160
162
|
select,
|
|
161
163
|
undo,
|
|
162
164
|
reorder,
|
|
@@ -167,7 +169,10 @@
|
|
|
167
169
|
init(api);
|
|
168
170
|
init_once = false;
|
|
169
171
|
}
|
|
170
|
-
}
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
reinitStore();
|
|
175
|
+
$effect(reinitStore);
|
|
171
176
|
</script>
|
|
172
177
|
|
|
173
178
|
<Locale words={en} optional={true}>
|
|
@@ -120,12 +120,11 @@
|
|
|
120
120
|
.filter(c => !c.hidden)
|
|
121
121
|
.map(a => ({ ...a }));
|
|
122
122
|
columns.forEach(a => {
|
|
123
|
-
a.fixed = { left: 1 };
|
|
123
|
+
a.fixed = { left: 1, leftSize: $split.left };
|
|
124
124
|
a.left = width;
|
|
125
125
|
width += a.width;
|
|
126
126
|
});
|
|
127
|
-
if (columns.length)
|
|
128
|
-
columns[columns.length - 1].fixed = { left: -1 };
|
|
127
|
+
if (columns.length) columns[columns.length - 1].fixed.left = -1;
|
|
129
128
|
}
|
|
130
129
|
|
|
131
130
|
return { columns, width };
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { onMount } from "svelte";
|
|
3
3
|
import { SuggestDropdown } from "@svar-ui/svelte-core";
|
|
4
|
+
import { clickOutside } from "@svar-ui/lib-dom";
|
|
4
5
|
|
|
5
|
-
let {
|
|
6
|
+
let { editor, onaction, onsave, onapply, oncancel } = $props();
|
|
6
7
|
|
|
7
8
|
let { value, renderedValue: text, options: filterOptions } = $state(editor);
|
|
8
|
-
|
|
9
|
+
|
|
10
|
+
let { template, cell, dropdown = {} } = $state(editor?.config || {});
|
|
11
|
+
|
|
12
|
+
const dropdownOptions = $derived({ trackScroll: true, ...dropdown });
|
|
9
13
|
|
|
10
14
|
let index = $derived(filterOptions.findIndex(a => a.id === value));
|
|
11
15
|
|
|
12
16
|
function updateValue({ id }) {
|
|
13
|
-
|
|
14
|
-
|
|
17
|
+
onapply(id);
|
|
18
|
+
onsave();
|
|
15
19
|
}
|
|
16
20
|
|
|
17
21
|
let navigate;
|
|
@@ -46,8 +50,15 @@
|
|
|
46
50
|
bind:value={text}
|
|
47
51
|
oninput={input}
|
|
48
52
|
onkeydown={e => keydown(e, index)}
|
|
53
|
+
use:clickOutside={() => onsave(true)}
|
|
49
54
|
/>
|
|
50
|
-
<SuggestDropdown
|
|
55
|
+
<SuggestDropdown
|
|
56
|
+
items={filterOptions}
|
|
57
|
+
onready={ready}
|
|
58
|
+
onselect={updateValue}
|
|
59
|
+
{...dropdownOptions}
|
|
60
|
+
{oncancel}
|
|
61
|
+
>
|
|
51
62
|
{#snippet children({ option })}
|
|
52
63
|
{#if template}
|
|
53
64
|
{template(option)}
|
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { onMount } from "svelte";
|
|
3
|
+
import { clickOutside } from "@svar-ui/lib-dom";
|
|
3
4
|
|
|
4
5
|
import { Calendar, Dropdown } from "@svar-ui/svelte-core";
|
|
5
6
|
|
|
6
|
-
let {
|
|
7
|
+
let { editor, onaction, onsave, onapply, oncancel } = $props();
|
|
7
8
|
|
|
8
9
|
let value = $state(editor.value || new Date());
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
let { template, cell, dropdown = {} } = $state(editor?.config || {});
|
|
11
|
+
const dropdownOptions = $derived({
|
|
12
|
+
trackScroll: true,
|
|
13
|
+
width: "auto",
|
|
14
|
+
...dropdown,
|
|
15
|
+
});
|
|
12
16
|
|
|
13
17
|
function updateValue({ value }) {
|
|
14
|
-
|
|
15
|
-
|
|
18
|
+
onapply(value);
|
|
19
|
+
onsave();
|
|
16
20
|
}
|
|
17
21
|
|
|
18
22
|
let node;
|
|
@@ -31,7 +35,7 @@
|
|
|
31
35
|
class="wx-value"
|
|
32
36
|
bind:this={node}
|
|
33
37
|
tabindex="0"
|
|
34
|
-
onclick={
|
|
38
|
+
onclick={oncancel}
|
|
35
39
|
onkeydown={ev => ev.preventDefault()}
|
|
36
40
|
>
|
|
37
41
|
{#if template}
|
|
@@ -41,8 +45,14 @@
|
|
|
41
45
|
<SvelteComponent data={editor.value} {onaction} />
|
|
42
46
|
{:else}<span class="wx-text">{editor.renderedValue}</span>{/if}
|
|
43
47
|
</div>
|
|
44
|
-
<Dropdown
|
|
45
|
-
<
|
|
48
|
+
<Dropdown {...dropdownOptions} {oncancel}>
|
|
49
|
+
<div use:clickOutside={() => onsave(true)}>
|
|
50
|
+
<Calendar
|
|
51
|
+
{value}
|
|
52
|
+
onchange={updateValue}
|
|
53
|
+
buttons={editor.config?.buttons}
|
|
54
|
+
/>
|
|
55
|
+
</div>
|
|
46
56
|
</Dropdown>
|
|
47
57
|
|
|
48
58
|
<style>
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { getContext } from "svelte";
|
|
3
3
|
import { getStyle } from "../../helpers/columnWidth";
|
|
4
|
-
import { clickOutside } from "@svar-ui/lib-dom";
|
|
5
4
|
import { editors } from "./editors";
|
|
6
5
|
|
|
7
6
|
let { column, row } = $props();
|
|
@@ -35,7 +34,13 @@
|
|
|
35
34
|
}
|
|
36
35
|
|
|
37
36
|
function keyHandler(ev) {
|
|
38
|
-
if (ev.key === "Enter" && $editor)
|
|
37
|
+
if (ev.key === "Enter" && $editor) {
|
|
38
|
+
if (column.editor.type === "multiselect") {
|
|
39
|
+
updateValue($editor.value);
|
|
40
|
+
} else {
|
|
41
|
+
cancel();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
39
44
|
}
|
|
40
45
|
|
|
41
46
|
let style = $derived(
|
|
@@ -71,11 +76,12 @@
|
|
|
71
76
|
onclick={ev => ev.stopPropagation()}
|
|
72
77
|
ondblclick={ev => ev.stopPropagation()}
|
|
73
78
|
onkeydown={keyHandler}
|
|
74
|
-
use:clickOutside={() => save(true)}
|
|
75
79
|
>
|
|
76
80
|
<SvelteComponent
|
|
77
81
|
editor={$editor}
|
|
78
|
-
|
|
82
|
+
onsave={save}
|
|
83
|
+
onapply={updateValue}
|
|
84
|
+
oncancel={cancel}
|
|
79
85
|
onaction={({ action, data }) => api.exec(action, data)}
|
|
80
86
|
/>
|
|
81
87
|
</div>
|
|
@@ -87,7 +93,7 @@
|
|
|
87
93
|
background-color: var(--wx-background);
|
|
88
94
|
color: var(--wx-color-font);
|
|
89
95
|
position: relative;
|
|
90
|
-
z-index:
|
|
96
|
+
z-index: 2;
|
|
91
97
|
}
|
|
92
98
|
.wx-cell :global(.wx-dropdown) {
|
|
93
99
|
border: var(--wx-table-editor-dropdown-border);
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { SuggestDropdown } from "@svar-ui/svelte-core";
|
|
3
|
+
import { clickOutside } from "@svar-ui/lib-dom";
|
|
4
|
+
import { onMount } from "svelte";
|
|
5
|
+
|
|
6
|
+
let { editor, onaction, onsave, onapply, oncancel } = $props();
|
|
7
|
+
let { config } = $state(editor);
|
|
8
|
+
|
|
9
|
+
const options = $derived(editor?.options ?? []);
|
|
10
|
+
let value = $derived(editor?.value || []);
|
|
11
|
+
let renderedValue = $derived(editor?.renderedValue);
|
|
12
|
+
|
|
13
|
+
let index = $derived.by(() => {
|
|
14
|
+
const firstSelected = options.find(opt => value.includes(opt.id));
|
|
15
|
+
return firstSelected ? options.indexOf(firstSelected) : -1;
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const dropdownOptions = $derived.by(() => {
|
|
19
|
+
const dropdown = config?.dropdown || {};
|
|
20
|
+
return { trackScroll: true, ...dropdown };
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
function updateValue({ id }) {
|
|
24
|
+
onapply(id);
|
|
25
|
+
node.focus();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
let navigate;
|
|
29
|
+
let keydown = $state();
|
|
30
|
+
|
|
31
|
+
function ready(ev) {
|
|
32
|
+
navigate = ev.navigate;
|
|
33
|
+
keydown = ev.keydown;
|
|
34
|
+
navigate(index);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
let node = $state();
|
|
38
|
+
onMount(() => {
|
|
39
|
+
node.focus();
|
|
40
|
+
if (window && window.getSelection) {
|
|
41
|
+
window.getSelection().removeAllRanges();
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
</script>
|
|
45
|
+
|
|
46
|
+
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
47
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
48
|
+
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
|
|
49
|
+
<div
|
|
50
|
+
bind:this={node}
|
|
51
|
+
class="wx-value"
|
|
52
|
+
tabindex="0"
|
|
53
|
+
onclick={oncancel}
|
|
54
|
+
onkeydown={ev => {
|
|
55
|
+
keydown(ev, index);
|
|
56
|
+
ev.preventDefault();
|
|
57
|
+
}}
|
|
58
|
+
use:clickOutside={() => onsave(true)}
|
|
59
|
+
>
|
|
60
|
+
{#if config?.template}
|
|
61
|
+
{config.template(value?.map(id => options.find(opt => opt.id === id)))}
|
|
62
|
+
{:else if config?.cell}
|
|
63
|
+
{@const SvelteComponent = config.cell}
|
|
64
|
+
<SvelteComponent
|
|
65
|
+
data={value.map(id => options.find(opt => opt.id === id))}
|
|
66
|
+
/>
|
|
67
|
+
{:else}
|
|
68
|
+
<span class="wx-text">{renderedValue}</span>
|
|
69
|
+
{/if}
|
|
70
|
+
</div>
|
|
71
|
+
|
|
72
|
+
<SuggestDropdown
|
|
73
|
+
items={options}
|
|
74
|
+
onready={ready}
|
|
75
|
+
onselect={updateValue}
|
|
76
|
+
checkboxes={true}
|
|
77
|
+
multiselect={true}
|
|
78
|
+
{...dropdownOptions}
|
|
79
|
+
{oncancel}
|
|
80
|
+
{value}
|
|
81
|
+
>
|
|
82
|
+
{#snippet children({ option })}
|
|
83
|
+
<div class="wx-option">
|
|
84
|
+
{#if config?.template}
|
|
85
|
+
{config.template(option)}
|
|
86
|
+
{:else if config?.cell}
|
|
87
|
+
{@const SvelteComponent = config.cell}
|
|
88
|
+
<SvelteComponent data={option} {onaction} />
|
|
89
|
+
{:else}
|
|
90
|
+
{option.label}
|
|
91
|
+
{/if}
|
|
92
|
+
</div>
|
|
93
|
+
{/snippet}
|
|
94
|
+
</SuggestDropdown>
|
|
95
|
+
|
|
96
|
+
<style>
|
|
97
|
+
.wx-option {
|
|
98
|
+
display: flex;
|
|
99
|
+
direction: row;
|
|
100
|
+
align-items: center;
|
|
101
|
+
justify-content: flex-start;
|
|
102
|
+
gap: 8px;
|
|
103
|
+
}
|
|
104
|
+
.wx-text {
|
|
105
|
+
width: 100%;
|
|
106
|
+
white-space: nowrap;
|
|
107
|
+
overflow: hidden;
|
|
108
|
+
text-overflow: ellipsis;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.wx-value {
|
|
112
|
+
width: 100%;
|
|
113
|
+
height: 100%;
|
|
114
|
+
padding: 8px;
|
|
115
|
+
overflow: hidden;
|
|
116
|
+
outline: none;
|
|
117
|
+
border: 1px solid var(--wx-color-primary);
|
|
118
|
+
text-overflow: ellipsis;
|
|
119
|
+
white-space: nowrap;
|
|
120
|
+
}
|
|
121
|
+
</style>
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { onMount } from "svelte";
|
|
3
3
|
import { SuggestDropdown } from "@svar-ui/svelte-core";
|
|
4
|
+
import { clickOutside } from "@svar-ui/lib-dom";
|
|
4
5
|
|
|
5
|
-
let {
|
|
6
|
+
let { editor, onaction, onsave, onapply, oncancel } = $props();
|
|
6
7
|
|
|
7
8
|
let data = $state(editor.options.find(opt => opt.id === editor.value));
|
|
8
9
|
let { value, options } = $state(editor);
|
|
9
|
-
let { template, cell } = $state(editor?.config || {});
|
|
10
|
+
let { template, cell, dropdown = {} } = $state(editor?.config || {});
|
|
11
|
+
const dropdownOptions = $derived({ trackScroll: true, ...dropdown });
|
|
10
12
|
|
|
11
13
|
let index = $derived(options.findIndex(a => a.id === value));
|
|
12
14
|
|
|
13
15
|
function updateValue({ id }) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
onapply(id);
|
|
17
|
+
onsave();
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
let navigate;
|
|
@@ -40,11 +42,12 @@
|
|
|
40
42
|
bind:this={node}
|
|
41
43
|
class="wx-value"
|
|
42
44
|
tabindex="0"
|
|
43
|
-
onclick={
|
|
45
|
+
onclick={oncancel}
|
|
44
46
|
onkeydown={ev => {
|
|
45
47
|
keydown(ev, index);
|
|
46
48
|
ev.preventDefault();
|
|
47
49
|
}}
|
|
50
|
+
use:clickOutside={() => onsave(true)}
|
|
48
51
|
>
|
|
49
52
|
{#if template}
|
|
50
53
|
{template(data)}
|
|
@@ -53,7 +56,13 @@
|
|
|
53
56
|
<SvelteComponent {data} {onaction} />
|
|
54
57
|
{:else}<span class="wx-text">{editor.renderedValue}</span>{/if}
|
|
55
58
|
</div>
|
|
56
|
-
<SuggestDropdown
|
|
59
|
+
<SuggestDropdown
|
|
60
|
+
items={options}
|
|
61
|
+
onready={ready}
|
|
62
|
+
onselect={updateValue}
|
|
63
|
+
{...dropdownOptions}
|
|
64
|
+
{oncancel}
|
|
65
|
+
>
|
|
57
66
|
{#snippet children({ option })}
|
|
58
67
|
{#if template}
|
|
59
68
|
{template(option)}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { onMount } from "svelte";
|
|
3
|
+
import { clickOutside } from "@svar-ui/lib-dom";
|
|
3
4
|
|
|
4
|
-
let {
|
|
5
|
+
let { editor, onsave, onapply } = $props();
|
|
5
6
|
|
|
6
7
|
let value = $state(editor.value || "");
|
|
7
8
|
|
|
@@ -10,15 +11,16 @@
|
|
|
10
11
|
|
|
11
12
|
function updateValue() {
|
|
12
13
|
value = node.value;
|
|
13
|
-
|
|
14
|
+
onapply(node.value);
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
function closeAndSave({ key }) {
|
|
17
|
-
if (key === "Enter")
|
|
18
|
+
if (key === "Enter") onsave();
|
|
18
19
|
}
|
|
19
20
|
</script>
|
|
20
21
|
|
|
21
22
|
<input
|
|
23
|
+
use:clickOutside={() => onsave(true)}
|
|
22
24
|
class="wx-text"
|
|
23
25
|
oninput={updateValue}
|
|
24
26
|
onkeydown={closeAndSave}
|
|
@@ -2,10 +2,16 @@ import Text from "./Text.svelte";
|
|
|
2
2
|
import Combo from "./Combo.svelte";
|
|
3
3
|
import Datepicker from "./Datepicker.svelte";
|
|
4
4
|
import Richselect from "./Richselect.svelte";
|
|
5
|
+
import Multiselect from "./MultiSelect.svelte";
|
|
5
6
|
|
|
6
7
|
export const editors = {
|
|
7
8
|
text: Text,
|
|
8
9
|
combo: Combo,
|
|
9
10
|
datepicker: Datepicker,
|
|
10
11
|
richselect: Richselect,
|
|
12
|
+
multiselect: Multiselect,
|
|
11
13
|
};
|
|
14
|
+
|
|
15
|
+
export function registerInlineEditor(type, component) {
|
|
16
|
+
editors[type] = component;
|
|
17
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { DatePicker } from "@svar-ui/svelte-core";
|
|
3
|
+
|
|
4
|
+
let { filter, column, action, filterValue } = $props();
|
|
5
|
+
|
|
6
|
+
function filterRows({ value }) {
|
|
7
|
+
action({ value, key: column.id });
|
|
8
|
+
}
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
12
|
+
<div style="width:100%;">
|
|
13
|
+
<DatePicker
|
|
14
|
+
placeholder={""}
|
|
15
|
+
clear={true}
|
|
16
|
+
{...filter.config ?? {}}
|
|
17
|
+
value={filterValue}
|
|
18
|
+
onchange={filterRows}
|
|
19
|
+
/>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
<style>
|
|
23
|
+
:global(.wx-cell.wx-filter div.wx-datepicker input) {
|
|
24
|
+
height: 28px;
|
|
25
|
+
padding: 4px 8px;
|
|
26
|
+
}
|
|
27
|
+
</style>
|
|
@@ -18,7 +18,12 @@ export function getCssName(column, cell, columnStyle) {
|
|
|
18
18
|
|
|
19
19
|
if (column.fixed) {
|
|
20
20
|
for (const pos in column.fixed) {
|
|
21
|
-
|
|
21
|
+
let isShadow = column.fixed[pos] === -1;
|
|
22
|
+
if (!isShadow && column.fixed.leftSize && cell.colspan) {
|
|
23
|
+
const spanIndex = cell.colspan + column._colindex - 1;
|
|
24
|
+
isShadow = spanIndex === column.fixed.leftSize;
|
|
25
|
+
}
|
|
26
|
+
css += isShadow ? "wx-shadow " : "wx-fixed ";
|
|
22
27
|
}
|
|
23
28
|
}
|
|
24
29
|
css += cell.rowspan > 1 ? "wx-rowspan " : "";
|
package/src/index.js
CHANGED
package/types/index.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ import type {
|
|
|
10
10
|
TMethodsConfig,
|
|
11
11
|
IConfig,
|
|
12
12
|
TEditorType,
|
|
13
|
+
TEditorConfig,
|
|
13
14
|
IColumnEditor,
|
|
14
15
|
IHeaderCell,
|
|
15
16
|
} from "@svar-ui/grid-store";
|
|
@@ -131,6 +132,20 @@ export declare const WillowDark: Component<{
|
|
|
131
132
|
children?: () => any;
|
|
132
133
|
}>;
|
|
133
134
|
|
|
135
|
+
export declare function registerInlineEditor(
|
|
136
|
+
type: string,
|
|
137
|
+
component: Component<{
|
|
138
|
+
editor: TEditorConfig;
|
|
139
|
+
onsave?: (ignoreFocus: boolean) => void;
|
|
140
|
+
oncancel?: () => void;
|
|
141
|
+
onapply?: (value: any) => void;
|
|
142
|
+
onaction?: (ev: {
|
|
143
|
+
action: string;
|
|
144
|
+
data?: { [key: string]: any };
|
|
145
|
+
}) => void;
|
|
146
|
+
}>
|
|
147
|
+
): void;
|
|
148
|
+
|
|
134
149
|
/* get component events from store actions*/
|
|
135
150
|
type RemoveHyphen<S extends string> = S extends `${infer Head}-${infer Tail}`
|
|
136
151
|
? `${Head}${RemoveHyphen<Tail>}`
|
package/whatsnew.md
CHANGED
|
@@ -1,3 +1,30 @@
|
|
|
1
|
+
## 2.6.1
|
|
2
|
+
|
|
3
|
+
### Fixes
|
|
4
|
+
|
|
5
|
+
- Impossible to configure inline editor dropdown
|
|
6
|
+
- Inline editor dropdown is detached during scroll
|
|
7
|
+
- Editor state object is mutated instead of being reset
|
|
8
|
+
- DataProvider adds trailing slash to getData url
|
|
9
|
+
- Incorrect height of sidebar Editor
|
|
10
|
+
|
|
11
|
+
## 2.6.0
|
|
12
|
+
|
|
13
|
+
### New features
|
|
14
|
+
|
|
15
|
+
- Multiselect inline editor
|
|
16
|
+
- Ability to register custom inline editors
|
|
17
|
+
|
|
18
|
+
### Updates
|
|
19
|
+
|
|
20
|
+
- Integration with FilterQuery
|
|
21
|
+
|
|
22
|
+
### Fixes
|
|
23
|
+
|
|
24
|
+
- Dropdown editors are cut off in small tables
|
|
25
|
+
- DataGrid fails to initialize in SvelteKit with serverside rendering
|
|
26
|
+
- Error in fetching Typescript definitions from store
|
|
27
|
+
|
|
1
28
|
## 2.5.1
|
|
2
29
|
|
|
3
30
|
### Fixes
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import {
|
|
3
|
-
Field,
|
|
4
|
-
Text,
|
|
5
|
-
RichSelect,
|
|
6
|
-
MultiCombo,
|
|
7
|
-
DatePicker,
|
|
8
|
-
Area,
|
|
9
|
-
Checkbox,
|
|
10
|
-
Switch,
|
|
11
|
-
} from "@svar-ui/svelte-core";
|
|
12
|
-
|
|
13
|
-
let { editors, data = null } = $props();
|
|
14
|
-
</script>
|
|
15
|
-
|
|
16
|
-
{#if data}
|
|
17
|
-
{#each editors as editor}
|
|
18
|
-
{#if editor.type === "combo"}
|
|
19
|
-
<Field label={editor.label}>
|
|
20
|
-
<RichSelect
|
|
21
|
-
options={editor.options || []}
|
|
22
|
-
bind:value={$data[editor.id]}
|
|
23
|
-
/>
|
|
24
|
-
</Field>
|
|
25
|
-
{:else if editor.type === "multicombo"}
|
|
26
|
-
<Field label={editor.label}>
|
|
27
|
-
<MultiCombo
|
|
28
|
-
textField="name"
|
|
29
|
-
checkboxes={false}
|
|
30
|
-
options={editor.options || []}
|
|
31
|
-
bind:value={$data[editor.id]}
|
|
32
|
-
/>
|
|
33
|
-
</Field>
|
|
34
|
-
{:else if editor.type === "datepicker"}
|
|
35
|
-
<Field label={editor.label}>
|
|
36
|
-
<DatePicker bind:value={$data[editor.id]} />
|
|
37
|
-
</Field>
|
|
38
|
-
{:else if editor.type === "textarea"}
|
|
39
|
-
<Field label={editor.label}>
|
|
40
|
-
<Area bind:value={$data[editor.id]} />
|
|
41
|
-
</Field>
|
|
42
|
-
{:else if editor.type === "switch"}
|
|
43
|
-
<Field label={editor.label}>
|
|
44
|
-
<Switch bind:value={$data[editor.id]} />
|
|
45
|
-
</Field>
|
|
46
|
-
{:else if editor.type === "checkbox"}
|
|
47
|
-
<Field label={editor.label}>
|
|
48
|
-
<Checkbox bind:value={$data[editor.id]} />
|
|
49
|
-
</Field>
|
|
50
|
-
{:else}
|
|
51
|
-
<Field label={editor.label}>
|
|
52
|
-
<Text bind:value={$data[editor.id]} />
|
|
53
|
-
</Field>
|
|
54
|
-
{/if}
|
|
55
|
-
{/each}
|
|
56
|
-
{/if}
|