wx-svelte-core 2.2.1 → 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 +6 -5
- package/readme.md +15 -15
- package/src/Locale.svelte +8 -6
- package/src/components/Calendar.svelte +4 -5
- package/src/components/Checkbox.svelte +1 -1
- package/src/components/ColorBoard.svelte +303 -6
- package/src/components/ColorPicker.svelte +1 -1
- package/src/components/ColorSelect.svelte +1 -1
- package/src/components/Combo.svelte +1 -1
- package/src/components/Counter.svelte +1 -1
- package/src/components/DatePicker.svelte +108 -6
- package/src/components/DateRangePicker.svelte +130 -6
- package/src/components/Dropdown.svelte +3 -3
- package/src/components/Field.svelte +1 -1
- package/src/components/Globals.svelte +1 -1
- package/src/components/Modal.svelte +129 -6
- package/src/components/MultiCombo.svelte +4 -4
- package/src/components/Pager.svelte +157 -6
- package/src/components/Popup.svelte +1 -1
- package/src/components/Portal.svelte +1 -1
- package/src/components/RadioButton.svelte +1 -1
- package/src/components/RadioButtonGroup.svelte +1 -1
- package/src/components/Segmented.svelte +1 -1
- package/src/components/Select.svelte +1 -1
- package/src/components/SideArea.svelte +1 -1
- package/src/components/Slider.svelte +11 -11
- package/src/components/Switch.svelte +1 -1
- package/src/components/Tabs.svelte +1 -0
- package/src/components/Text.svelte +9 -9
- package/src/components/TextArea.svelte +1 -1
- package/src/components/TimePicker.svelte +223 -6
- package/src/components/TwoState.svelte +3 -3
- package/src/components/calendar/Duodecade.svelte +1 -1
- package/src/components/calendar/Header.svelte +1 -1
- package/src/components/calendar/Month.svelte +3 -2
- package/src/components/calendar/Year.svelte +1 -1
- package/src/components/helpers/SuggestDropdown.svelte +85 -6
- package/src/components/helpers/listnav.js +1 -1
- package/src/components/helpers/locale.js +6 -0
- package/src/components/helpers.js +1 -1
- package/src/index.js +5 -5
- package/whatsnew.md +12 -0
- package/src/components/Month.svelte +0 -10
- package/src/components/colorboard/Layout.svelte +0 -306
- package/src/components/datepicker/Layout.svelte +0 -110
- package/src/components/daterangepicker/Layout.svelte +0 -131
- package/src/components/helpers/suggestDropdown/Layout.svelte +0 -88
- package/src/components/modal/Layout.svelte +0 -132
- package/src/components/pager/Layout.svelte +0 -160
- package/src/components/timepicker/Layout.svelte +0 -227
package/license.txt
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wx-svelte-core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "SVAR Svelte Core - Svelte UI library of 20+ components and form controls",
|
|
5
5
|
"productTag": "core",
|
|
6
6
|
"productTrial": false,
|
|
@@ -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,9 +33,9 @@
|
|
|
32
33
|
},
|
|
33
34
|
"homepage": "https://svar.dev/svelte/core/",
|
|
34
35
|
"dependencies": {
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
36
|
+
"@svar-ui/core-locales": "2.3.0",
|
|
37
|
+
"@svar-ui/lib-dom": "0.9.2",
|
|
38
|
+
"@svar-ui/lib-svelte": "0.5.2"
|
|
38
39
|
},
|
|
39
40
|
"files": [
|
|
40
41
|
"src",
|
package/readme.md
CHANGED
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
|
|
13
13
|
<div align="center">
|
|
14
14
|
|
|
15
|
-
[](https://www.npmjs.com/package/@svar-ui/svelte-core)
|
|
16
16
|
[](https://github.com/svar-widgets/core/blob/main/license.txt)
|
|
17
|
-
[](https://www.npmjs.com/package/@svar-ui/svelte-core)
|
|
18
18
|
|
|
19
19
|
</div>
|
|
20
20
|
|
|
@@ -24,20 +24,20 @@
|
|
|
24
24
|
|
|
25
25
|
SVAR Core library includes the following components:
|
|
26
26
|
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
32
|
-
-
|
|
27
|
+
- buttons & form controls,
|
|
28
|
+
- calendar (datepicker),
|
|
29
|
+
- popups,
|
|
30
|
+
- notifications,
|
|
31
|
+
- sliding sidebar,
|
|
32
|
+
- tabs, and more.
|
|
33
33
|
|
|
34
34
|
Additionally, you can use these SVAR Svelte components to build unified app interfaces:
|
|
35
35
|
|
|
36
|
-
- [Menu](https://www.npmjs.com/package/
|
|
37
|
-
- [Toolbar](https://www.npmjs.com/package/
|
|
38
|
-
- [File uploader](https://www.npmjs.com/package/
|
|
39
|
-
- [Comments](https://www.npmjs.com/package/
|
|
40
|
-
- [Tasklist](https://www.npmjs.com/package/
|
|
36
|
+
- [Menu](https://www.npmjs.com/package/@svar-ui/svelte-menu)
|
|
37
|
+
- [Toolbar](https://www.npmjs.com/package/@svar-ui/svelte-toolbar)
|
|
38
|
+
- [File uploader](https://www.npmjs.com/package/@svar-ui/svelte-uploader)
|
|
39
|
+
- [Comments](https://www.npmjs.com/package/@svar-ui/svelte-comments)
|
|
40
|
+
- [Tasklist](https://www.npmjs.com/package/@svar-ui/svelte-tasklist)
|
|
41
41
|
|
|
42
42
|
### :gear: Svelte 4 and Svelte 5 versions
|
|
43
43
|
|
|
@@ -46,7 +46,7 @@ There are two versions of the library: the 1.x version - designed to work with S
|
|
|
46
46
|
To use the SVAR Core for Svelte 5, install it as follows:
|
|
47
47
|
|
|
48
48
|
```
|
|
49
|
-
npm install
|
|
49
|
+
npm install @svar-ui/svelte-core
|
|
50
50
|
```
|
|
51
51
|
|
|
52
52
|
To use the SVAR Core for Svelte 4:
|
|
@@ -61,7 +61,7 @@ To use any of the Core components, simply import the package and include the des
|
|
|
61
61
|
|
|
62
62
|
```svelte
|
|
63
63
|
<script>
|
|
64
|
-
import { Button } from "
|
|
64
|
+
import { Button } from "@svar-ui/svelte-core";
|
|
65
65
|
</script>
|
|
66
66
|
|
|
67
67
|
<Button>Click me</Button>
|
package/src/Locale.svelte
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { getContext, setContext } from "svelte";
|
|
3
|
-
import { locale } from "
|
|
4
|
-
import { en } from "
|
|
3
|
+
import { locale } from "@svar-ui/lib-dom";
|
|
4
|
+
import { en } from "@svar-ui/core-locales";
|
|
5
5
|
|
|
6
6
|
let { words = null, optional = false, children } = $props();
|
|
7
7
|
|
|
8
8
|
let l = getContext("wx-i18n");
|
|
9
|
-
if (!l) {
|
|
10
|
-
|
|
9
|
+
if (!l || words !== null) {
|
|
10
|
+
if (!l) {
|
|
11
|
+
l = locale(en);
|
|
12
|
+
}
|
|
13
|
+
l = l.extend(words, optional);
|
|
14
|
+
setContext("wx-i18n", l);
|
|
11
15
|
}
|
|
12
|
-
l = l.extend(words, optional);
|
|
13
|
-
setContext("wx-i18n", l);
|
|
14
16
|
</script>
|
|
15
17
|
|
|
16
18
|
{@render children?.()}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import Panel from "./calendar/Panel.svelte";
|
|
3
|
-
|
|
4
3
|
import Locale from "../Locale.svelte";
|
|
5
4
|
|
|
6
5
|
let {
|
|
@@ -8,7 +7,7 @@
|
|
|
8
7
|
current = $bindable(),
|
|
9
8
|
markers = null,
|
|
10
9
|
buttons = ["clear", "today"],
|
|
11
|
-
onchange
|
|
10
|
+
onchange,
|
|
12
11
|
} = $props();
|
|
13
12
|
|
|
14
13
|
function fixCurrent(force) {
|
|
@@ -17,7 +16,7 @@
|
|
|
17
16
|
}
|
|
18
17
|
fixCurrent(value);
|
|
19
18
|
|
|
20
|
-
function
|
|
19
|
+
function change(v) {
|
|
21
20
|
const x = v.value;
|
|
22
21
|
if (x) {
|
|
23
22
|
value = new Date(x);
|
|
@@ -26,10 +25,10 @@
|
|
|
26
25
|
value = null;
|
|
27
26
|
}
|
|
28
27
|
|
|
29
|
-
|
|
28
|
+
onchange && onchange({ value });
|
|
30
29
|
}
|
|
31
30
|
</script>
|
|
32
31
|
|
|
33
32
|
<Locale>
|
|
34
|
-
<Panel {value} bind:current {markers} {buttons} {
|
|
33
|
+
<Panel {value} bind:current {markers} {buttons} onchange={change} />
|
|
35
34
|
</Locale>
|
|
@@ -1,10 +1,307 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import
|
|
3
|
-
import
|
|
2
|
+
import { onMount, getContext } from "svelte";
|
|
3
|
+
import Button from "./Button.svelte";
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
//helpers
|
|
6
|
+
import { sliderMove } from "./helpers/sliderMove";
|
|
7
|
+
import colorTransformator from "./helpers/colorTransformator";
|
|
8
|
+
import { parseColor } from "./helpers/colorValidation.js";
|
|
9
|
+
import { defaultLocale } from "./helpers/locale";
|
|
10
|
+
|
|
11
|
+
let { value = $bindable("#65D3B3"), button = false, onchange } = $props();
|
|
12
|
+
|
|
13
|
+
let block;
|
|
14
|
+
|
|
15
|
+
const _ = (getContext("wx-i18n") || defaultLocale()).getGroup("core");
|
|
16
|
+
|
|
17
|
+
const BLOCK = "Block";
|
|
18
|
+
const LINE = "Line";
|
|
19
|
+
|
|
20
|
+
let blockTop = $state();
|
|
21
|
+
let blockLeft = $state();
|
|
22
|
+
let hueColor = $state();
|
|
23
|
+
let colorLine = $state();
|
|
24
|
+
let lineLeft = $state();
|
|
25
|
+
|
|
26
|
+
let color = $derived(parseColor(value) || "#65D3B3");
|
|
27
|
+
let blockColor = $derived(colorTransformator.hvsToHex(hueColor, 1, 1));
|
|
28
|
+
|
|
29
|
+
function moveBlockSlider(dx, dy) {
|
|
30
|
+
const { width, height } = block.getBoundingClientRect();
|
|
31
|
+
|
|
32
|
+
if (dy < 0) dy = 0;
|
|
33
|
+
else if (dy > height) dy = height;
|
|
34
|
+
|
|
35
|
+
if (dx < 0) dx = 0;
|
|
36
|
+
else if (dx > width) dx = width;
|
|
37
|
+
|
|
38
|
+
blockTop = dy;
|
|
39
|
+
blockLeft = dx;
|
|
40
|
+
|
|
41
|
+
setCurrentColor();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function setCurrentColor(lineSliderMove) {
|
|
45
|
+
let _sValue, _vValue;
|
|
46
|
+
|
|
47
|
+
if (lineSliderMove) {
|
|
48
|
+
[, _sValue, _vValue] = colorTransformator.hexToHvs(color);
|
|
49
|
+
} else {
|
|
50
|
+
const { width, height } = block.getBoundingClientRect();
|
|
51
|
+
|
|
52
|
+
const pxX = width / 100;
|
|
53
|
+
const pxY = height / 100;
|
|
54
|
+
|
|
55
|
+
_sValue = Math.ceil(blockLeft / pxX) / 100;
|
|
56
|
+
_vValue = Math.ceil(Math.abs(blockTop / pxY - 100)) / 100;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
value = colorTransformator.hvsToHex(hueColor, _sValue, _vValue);
|
|
60
|
+
onchange && onchange({ value, input: true });
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function moveLineSlider(dx) {
|
|
64
|
+
const width = colorLine.getBoundingClientRect().width;
|
|
65
|
+
|
|
66
|
+
if (dx < 0) dx = 0;
|
|
67
|
+
else if (dx > width) dx = width;
|
|
68
|
+
|
|
69
|
+
toggleLineColor(dx, width);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function toggleLineColor(dx, width) {
|
|
73
|
+
width = width || colorLine.getBoundingClientRect().width;
|
|
74
|
+
|
|
75
|
+
lineLeft = dx;
|
|
76
|
+
|
|
77
|
+
const h = Math.round((lineLeft * 359) / width);
|
|
78
|
+
hueColor = Math.max(Math.min(h, 359), 0);
|
|
79
|
+
|
|
80
|
+
setCurrentColor(true);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
onMount(() => setSlidersPosition());
|
|
84
|
+
|
|
85
|
+
function setSlidersPosition() {
|
|
86
|
+
const [h, s, v] = colorTransformator.hexToHvs(color);
|
|
87
|
+
const { width, height } = block.getBoundingClientRect();
|
|
88
|
+
hueColor = h;
|
|
89
|
+
|
|
90
|
+
lineLeft = (h * colorLine.getBoundingClientRect().width) / 359;
|
|
91
|
+
blockLeft = s * width;
|
|
92
|
+
blockTop = Math.abs(height * (v - 1));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function handleChange({ target }) {
|
|
96
|
+
const newColor = parseColor(target.value);
|
|
97
|
+
|
|
98
|
+
value = newColor;
|
|
99
|
+
onchange && onchange({ value, input: true });
|
|
100
|
+
if (newColor) {
|
|
101
|
+
setSlidersPosition();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function handleSelect(ev) {
|
|
106
|
+
ev.stopPropagation();
|
|
107
|
+
onchange && onchange({ value: color });
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function keydown(ev) {
|
|
111
|
+
const slider = ev.target;
|
|
112
|
+
const isSliderBlock = slider === BLOCK;
|
|
113
|
+
const isSliderLine = slider === LINE;
|
|
114
|
+
|
|
115
|
+
let css = window.getComputedStyle(slider);
|
|
116
|
+
let left = parseFloat(css.left);
|
|
117
|
+
let top = parseFloat(css.top);
|
|
118
|
+
const code = ev.code;
|
|
119
|
+
|
|
120
|
+
if (isSliderBlock) {
|
|
121
|
+
switch (code) {
|
|
122
|
+
case "ArrowLeft": {
|
|
123
|
+
left--;
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
case "ArrowRight": {
|
|
127
|
+
left++;
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
case "ArrowDown": {
|
|
131
|
+
top++;
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
case "ArrowUp": {
|
|
135
|
+
top--;
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
default:
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
moveBlockSlider(left, top);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (isSliderLine) {
|
|
146
|
+
if (code === "ArrowLeft" || code === "ArrowDown") left--;
|
|
147
|
+
else if (code === "ArrowRight" || code === "ArrowUp") left++;
|
|
148
|
+
else return;
|
|
149
|
+
moveLineSlider(left);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
ev.preventDefault();
|
|
153
|
+
}
|
|
6
154
|
</script>
|
|
7
155
|
|
|
8
|
-
<
|
|
9
|
-
<
|
|
10
|
-
|
|
156
|
+
<div class="wx-colorboard">
|
|
157
|
+
<div
|
|
158
|
+
class="wx-color-block"
|
|
159
|
+
style="background: {blockColor};"
|
|
160
|
+
bind:this={block}
|
|
161
|
+
use:sliderMove={{ moveBlockSlider }}
|
|
162
|
+
>
|
|
163
|
+
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
|
|
164
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
165
|
+
<div
|
|
166
|
+
class="wx-color-block-slider wx-slider"
|
|
167
|
+
style="background: {color}; top: {blockTop}px; left:{blockLeft}px;"
|
|
168
|
+
tabindex="0"
|
|
169
|
+
data-slider={BLOCK}
|
|
170
|
+
onkeydown={keydown}
|
|
171
|
+
></div>
|
|
172
|
+
</div>
|
|
173
|
+
<div
|
|
174
|
+
class="wx-color-line"
|
|
175
|
+
bind:this={colorLine}
|
|
176
|
+
use:sliderMove={{ moveLineSlider }}
|
|
177
|
+
>
|
|
178
|
+
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
|
|
179
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
180
|
+
<div
|
|
181
|
+
class="wx-color-line-slider wx-slider"
|
|
182
|
+
style="background: {blockColor}; left: {lineLeft}px;"
|
|
183
|
+
tabindex="0"
|
|
184
|
+
data-slider={LINE}
|
|
185
|
+
onkeydown={keydown}
|
|
186
|
+
></div>
|
|
187
|
+
</div>
|
|
188
|
+
<div class="wx-color-controls">
|
|
189
|
+
<div class="wx-color" style="background: {color}"></div>
|
|
190
|
+
<input type="text" class="wx-text" bind:value onchange={handleChange} />
|
|
191
|
+
</div>
|
|
192
|
+
{#if button}
|
|
193
|
+
<Button onclick={handleSelect} type="secondary">{_("select")}</Button>
|
|
194
|
+
{/if}
|
|
195
|
+
</div>
|
|
196
|
+
|
|
197
|
+
<style>
|
|
198
|
+
.wx-colorboard {
|
|
199
|
+
display: flex;
|
|
200
|
+
flex-direction: column;
|
|
201
|
+
gap: 12px;
|
|
202
|
+
padding: 8px;
|
|
203
|
+
width: 100%;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
.wx-color-block {
|
|
207
|
+
height: 140px;
|
|
208
|
+
width: 100%;
|
|
209
|
+
position: relative;
|
|
210
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.wx-color-block::before,
|
|
214
|
+
.wx-color-block::after {
|
|
215
|
+
content: "";
|
|
216
|
+
width: 100%;
|
|
217
|
+
height: 100%;
|
|
218
|
+
position: absolute;
|
|
219
|
+
}
|
|
220
|
+
.wx-color-block:before {
|
|
221
|
+
background-image: linear-gradient(0deg, #000, hsla(0, 0%, 100%, 0));
|
|
222
|
+
z-index: 2;
|
|
223
|
+
}
|
|
224
|
+
.wx-color-block::after {
|
|
225
|
+
background-image: linear-gradient(90deg, #fff, hsla(20, 42%, 65%, 0));
|
|
226
|
+
z-index: 1;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
.wx-color-block-slider {
|
|
230
|
+
height: 16px;
|
|
231
|
+
width: 16px;
|
|
232
|
+
margin: -8px 0 0 -8px;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.wx-slider {
|
|
236
|
+
border: 2px solid white;
|
|
237
|
+
border-radius: 50%;
|
|
238
|
+
position: absolute;
|
|
239
|
+
z-index: 3;
|
|
240
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.wx-slider:focus,
|
|
244
|
+
.wx-slider:hover {
|
|
245
|
+
outline: none;
|
|
246
|
+
box-shadow:
|
|
247
|
+
0 1px 3px rgba(0, 0, 0, 0.2),
|
|
248
|
+
inset 0 0 4px #ffffff;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
.wx-color-line {
|
|
252
|
+
width: 100%;
|
|
253
|
+
height: 8px;
|
|
254
|
+
background-image: linear-gradient(
|
|
255
|
+
90deg,
|
|
256
|
+
red,
|
|
257
|
+
#ff0 17%,
|
|
258
|
+
#0f0 33%,
|
|
259
|
+
#0ff 50%,
|
|
260
|
+
#00f 67%,
|
|
261
|
+
#f0f 83%,
|
|
262
|
+
red
|
|
263
|
+
);
|
|
264
|
+
position: relative;
|
|
265
|
+
border-radius: 6px;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.wx-color-line-slider {
|
|
269
|
+
height: 14px;
|
|
270
|
+
width: 14px;
|
|
271
|
+
margin: 0 0 0 -7px;
|
|
272
|
+
top: -4px;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
.wx-color-controls {
|
|
276
|
+
display: flex;
|
|
277
|
+
flex-wrap: wrap;
|
|
278
|
+
justify-content: space-between;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.wx-color,
|
|
282
|
+
.wx-text {
|
|
283
|
+
width: calc(50% - 4px);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
.wx-color {
|
|
287
|
+
height: 32px;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
.wx-text {
|
|
291
|
+
outline: none;
|
|
292
|
+
background: var(--wx-input-background);
|
|
293
|
+
border: var(--wx-input-border);
|
|
294
|
+
border-radius: var(--wx-input-border-radius);
|
|
295
|
+
font-family: var(--wx-input-font-family);
|
|
296
|
+
font-size: var(--wx-input-font-size);
|
|
297
|
+
line-height: var(--wx-input-line-height);
|
|
298
|
+
font-weight: var(--wx-input-font-weight);
|
|
299
|
+
text-align: var(--wx-input-text-align);
|
|
300
|
+
color: var(--wx-input-font-color);
|
|
301
|
+
padding: var(--wx-input-padding);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
.wx-text:focus {
|
|
305
|
+
border: var(--wx-input-border-focus);
|
|
306
|
+
}
|
|
307
|
+
</style>
|
|
@@ -1,10 +1,112 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import
|
|
3
|
-
import
|
|
2
|
+
import { getContext } from "svelte";
|
|
3
|
+
import { uid, dateToString } from "@svar-ui/lib-dom";
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
import Text from "./Text.svelte";
|
|
6
|
+
import Dropdown from "./Dropdown.svelte";
|
|
7
|
+
import Calendar from "./Calendar.svelte";
|
|
8
|
+
import { defaultLocale } from "./helpers/locale";
|
|
9
|
+
|
|
10
|
+
let {
|
|
11
|
+
value = $bindable(),
|
|
12
|
+
id = uid(),
|
|
13
|
+
disabled = false,
|
|
14
|
+
error = false,
|
|
15
|
+
width = "unset",
|
|
16
|
+
align = "start",
|
|
17
|
+
placeholder = "",
|
|
18
|
+
format = "",
|
|
19
|
+
buttons = ["clear", "today"],
|
|
20
|
+
css = "",
|
|
21
|
+
title = "",
|
|
22
|
+
editable = false,
|
|
23
|
+
clear = false,
|
|
24
|
+
onchange,
|
|
25
|
+
} = $props();
|
|
26
|
+
|
|
27
|
+
const { calendar: calendarLocale, formats } = (
|
|
28
|
+
getContext("wx-i18n") || defaultLocale()
|
|
29
|
+
).getRaw();
|
|
30
|
+
const f = format || formats.dateFormat;
|
|
31
|
+
let dateFormat =
|
|
32
|
+
typeof f === "function" ? f : dateToString(f, calendarLocale);
|
|
33
|
+
|
|
34
|
+
let popup = $state();
|
|
35
|
+
|
|
36
|
+
function oncancel() {
|
|
37
|
+
popup = false;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function doChange(v) {
|
|
41
|
+
// skip "select" event if the same value
|
|
42
|
+
// or different objects with the same value
|
|
43
|
+
const skipEvent =
|
|
44
|
+
v === value ||
|
|
45
|
+
(v && value && v.valueOf() === value.valueOf()) ||
|
|
46
|
+
(!v && !value);
|
|
47
|
+
|
|
48
|
+
value = v;
|
|
49
|
+
if (!skipEvent) {
|
|
50
|
+
onchange && onchange({ value });
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// fire after on-click finished
|
|
54
|
+
setTimeout(oncancel, 1);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const formattedValue = $derived(value ? dateFormat(value) : "");
|
|
58
|
+
|
|
59
|
+
function change({ value: v, input }) {
|
|
60
|
+
if (!editable && !clear) return;
|
|
61
|
+
if (input) return;
|
|
62
|
+
|
|
63
|
+
// convert to date, but ignore empty string input
|
|
64
|
+
let date =
|
|
65
|
+
typeof editable === "function"
|
|
66
|
+
? editable(v)
|
|
67
|
+
: v
|
|
68
|
+
? new Date(v)
|
|
69
|
+
: null;
|
|
70
|
+
|
|
71
|
+
// if date is invalid ( incorrect text input ) then use old value
|
|
72
|
+
// else use the entered date
|
|
73
|
+
// in any case fallback to null, to prevent undefined as value
|
|
74
|
+
date = isNaN(date) ? value || null : date || null;
|
|
75
|
+
doChange(date);
|
|
76
|
+
}
|
|
6
77
|
</script>
|
|
7
78
|
|
|
8
|
-
<
|
|
9
|
-
|
|
10
|
-
|
|
79
|
+
<svelte:window onscroll={oncancel} />
|
|
80
|
+
|
|
81
|
+
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
82
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
83
|
+
<div class="wx-datepicker" onclick={() => (popup = true)}>
|
|
84
|
+
<Text
|
|
85
|
+
{css}
|
|
86
|
+
{title}
|
|
87
|
+
value={formattedValue}
|
|
88
|
+
{id}
|
|
89
|
+
readonly={!editable}
|
|
90
|
+
{disabled}
|
|
91
|
+
{error}
|
|
92
|
+
{placeholder}
|
|
93
|
+
oninput={oncancel}
|
|
94
|
+
onchange={change}
|
|
95
|
+
icon="wxi-calendar"
|
|
96
|
+
inputStyle="cursor: pointer; width: 100%; padding-right: calc(var(--wx-input-icon-size) + var(--wx-input-icon-indent) * 2);"
|
|
97
|
+
{clear}
|
|
98
|
+
/>
|
|
99
|
+
|
|
100
|
+
{#if popup && !disabled}
|
|
101
|
+
<Dropdown {oncancel} {width} {align} autoFit={!!align}>
|
|
102
|
+
<Calendar {buttons} {value} onchange={e => doChange(e.value)} />
|
|
103
|
+
</Dropdown>
|
|
104
|
+
{/if}
|
|
105
|
+
</div>
|
|
106
|
+
|
|
107
|
+
<style>
|
|
108
|
+
.wx-datepicker {
|
|
109
|
+
position: relative;
|
|
110
|
+
width: var(--wx-input-width);
|
|
111
|
+
}
|
|
112
|
+
</style>
|