wx-svelte-core 1.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.
Files changed (60) hide show
  1. package/license.txt +21 -0
  2. package/package.json +35 -0
  3. package/src/Locale.svelte +17 -0
  4. package/src/components/Area.svelte +70 -0
  5. package/src/components/Button.svelte +187 -0
  6. package/src/components/Calendar.svelte +42 -0
  7. package/src/components/Checkbox.svelte +132 -0
  8. package/src/components/CheckboxGroup.svelte +52 -0
  9. package/src/components/ColorBoard.svelte +311 -0
  10. package/src/components/ColorPicker.svelte +110 -0
  11. package/src/components/ColorSelect.svelte +204 -0
  12. package/src/components/Combo.svelte +228 -0
  13. package/src/components/Counter.svelte +178 -0
  14. package/src/components/DatePicker.svelte +115 -0
  15. package/src/components/DateRangePicker.svelte +138 -0
  16. package/src/components/Dropdown.svelte +125 -0
  17. package/src/components/Field.svelte +91 -0
  18. package/src/components/Globals.svelte +53 -0
  19. package/src/components/Icon.svelte +31 -0
  20. package/src/components/Modal.svelte +115 -0
  21. package/src/components/ModalArea.svelte +32 -0
  22. package/src/components/MultiCombo.svelte +279 -0
  23. package/src/components/Notice.svelte +145 -0
  24. package/src/components/Notices.svelte +20 -0
  25. package/src/components/Pager.svelte +131 -0
  26. package/src/components/Popup.svelte +53 -0
  27. package/src/components/Portal.svelte +42 -0
  28. package/src/components/RadioButton.svelte +129 -0
  29. package/src/components/RadioButtonGroup.svelte +50 -0
  30. package/src/components/RangeCalendar.svelte +134 -0
  31. package/src/components/RichSelect.svelte +149 -0
  32. package/src/components/Segmented.svelte +115 -0
  33. package/src/components/Select.svelte +124 -0
  34. package/src/components/SideArea.svelte +33 -0
  35. package/src/components/Slider.svelte +242 -0
  36. package/src/components/Switch.svelte +88 -0
  37. package/src/components/Tabs.svelte +163 -0
  38. package/src/components/Text.svelte +185 -0
  39. package/src/components/Timepicker.svelte +217 -0
  40. package/src/components/TwoState.svelte +60 -0
  41. package/src/components/calendar/Button.svelte +40 -0
  42. package/src/components/calendar/Duodecade.svelte +97 -0
  43. package/src/components/calendar/Header.svelte +105 -0
  44. package/src/components/calendar/Month.svelte +189 -0
  45. package/src/components/calendar/Panel.svelte +119 -0
  46. package/src/components/calendar/Year.svelte +89 -0
  47. package/src/components/calendar/helpers.js +56 -0
  48. package/src/components/helpers/SuggestDropdown.svelte +79 -0
  49. package/src/components/helpers/colorTransformator.js +146 -0
  50. package/src/components/helpers/colorValidation.js +21 -0
  51. package/src/components/helpers/listnav.js +85 -0
  52. package/src/components/helpers/sliderMove.js +42 -0
  53. package/src/components/helpers.js +6 -0
  54. package/src/index.js +50 -0
  55. package/src/themes/FontOpenSans.svelte +36 -0
  56. package/src/themes/FonttRoboto.svelte +19 -0
  57. package/src/themes/Material.svelte +321 -0
  58. package/src/themes/Willow.svelte +323 -0
  59. package/src/themes/WillowDark.svelte +320 -0
  60. package/whatsnew.md +97 -0
@@ -0,0 +1,279 @@
1
+ <script>
2
+ import { createEventDispatcher } from "svelte";
3
+ import List from "./helpers/SuggestDropdown.svelte";
4
+ import Checkbox from "./Checkbox.svelte";
5
+
6
+ export let value;
7
+ export let options = [];
8
+ export let textField = "label";
9
+ export let placeholder = "";
10
+ export let title = "";
11
+ export let disabled = false;
12
+ export let error = false;
13
+ export let checkboxes = false;
14
+
15
+ const dispatch = createEventDispatcher();
16
+
17
+ let text = "";
18
+ let selected = [];
19
+ let filterOptions;
20
+ let focus = false;
21
+
22
+ $: filterOptions = options;
23
+
24
+ let navigate;
25
+ let keydown;
26
+ function ready(ev) {
27
+ navigate = ev.detail.navigate;
28
+ keydown = ev.detail.keydown;
29
+ }
30
+
31
+ $: selected = value ? options.filter(i => value.includes(i.id)) : [];
32
+
33
+ function input() {
34
+ filterOptions = text
35
+ ? options.filter(i =>
36
+ i[textField].toLowerCase().includes(text.toLowerCase())
37
+ )
38
+ : options;
39
+ if (filterOptions.length) navigate(0);
40
+ else navigate(null);
41
+ }
42
+ function select(ev) {
43
+ const { id } = ev.detail;
44
+
45
+ if (id) {
46
+ let next;
47
+ if (value) {
48
+ if (value.includes(id)) {
49
+ next = value.filter(i => i !== id);
50
+ } else {
51
+ next = [...value, id];
52
+ }
53
+ } else {
54
+ next = [id];
55
+ }
56
+
57
+ value = next;
58
+ selected = options.filter(i => value.includes(i.id));
59
+
60
+ dispatch("select", { selected });
61
+ dispatch("change", { value });
62
+ }
63
+ }
64
+
65
+ function remove(id) {
66
+ value = value.filter(i => i !== id);
67
+ dispatch("change", { value });
68
+ }
69
+
70
+ const index = () =>
71
+ value && value.length
72
+ ? filterOptions.findIndex(i => i.id === value[0])
73
+ : 0;
74
+ </script>
75
+
76
+ <div
77
+ {title}
78
+ class="wx-multicombo"
79
+ class:wx-error={error}
80
+ class:wx-disabled={disabled}
81
+ class:wx-not-empty={selected.length}
82
+ class:wx-focus={focus && !disabled}
83
+ on:click={() => !disabled && navigate(index())}
84
+ on:keydown={ev => keydown(ev, index())}
85
+ >
86
+ <div class="wx-wrapper">
87
+ <div class="wx-tags">
88
+ {#each selected as tag (tag.id)}
89
+ <div class="wx-tag">
90
+ <slot option={tag}>{tag[textField]}</slot>
91
+ {#if !disabled}
92
+ <!-- svelte-ignore a11y-click-events-have-key-events -->
93
+ <i
94
+ class="wxi-close"
95
+ on:click|stopPropagation={() => remove(tag.id)}
96
+ />
97
+ {/if}
98
+ </div>
99
+ {/each}
100
+ </div>
101
+ <div class="wx-select">
102
+ <input
103
+ type="text"
104
+ bind:value={text}
105
+ on:input={input}
106
+ {placeholder}
107
+ {disabled}
108
+ />
109
+ <i class="wx-icon wxi-angle-down" />
110
+ </div>
111
+ </div>
112
+
113
+ {#if !disabled}
114
+ <List
115
+ let:option
116
+ items={filterOptions}
117
+ on:ready={ready}
118
+ on:select={select}
119
+ >
120
+ {#if checkboxes}
121
+ <Checkbox
122
+ style="margin-right: 8px; pointer-events: none;"
123
+ name={option.id}
124
+ value={value && value.includes(option.id)}
125
+ />
126
+ {/if}
127
+ <slot {option}>{option.name}</slot>
128
+ </List>
129
+ {/if}
130
+ </div>
131
+
132
+ <style>
133
+ .wx-multicombo {
134
+ position: relative;
135
+ width: var(--wx-input-width);
136
+ }
137
+ .wx-multicombo.wx-focus .wx-wrapper {
138
+ border: var(--wx-input-border-focus);
139
+ }
140
+ .wx-multicombo.wx-disabled .wx-wrapper {
141
+ border: var(--wx-input-border-disabled);
142
+ background: var(--wx-input-background-disabled);
143
+ }
144
+ .wx-multicombo.wx-disabled .wx-tag {
145
+ background: var(--wx-color-disabled);
146
+ color: var(--wx-color-font-disabled);
147
+ }
148
+ .wx-multicombo:not(.wx-disabled) .wx-tag {
149
+ padding-right: calc(
150
+ var(--wx-input-icon-size) + var(--wx-input-icon-indent) * 2
151
+ );
152
+ }
153
+ .wx-multicombo.wx-disabled input {
154
+ cursor: not-allowed;
155
+ color: var(--wx-color-font-disabled);
156
+ }
157
+ .wx-multicombo.wx-disabled .wx-icon {
158
+ color: var(--wx-color-font-disabled);
159
+ }
160
+ .wx-multicombo.wx-error .wx-wrapper {
161
+ border-color: var(--wx-color-danger);
162
+ }
163
+ .wx-multicombo.wx-error input {
164
+ color: var(--wx-color-danger);
165
+ }
166
+ .wx-multicombo.wx-error .wx-icon {
167
+ color: var(--wx-color-danger);
168
+ }
169
+ .wx-multicombo.wx-not-empty .wx-tags {
170
+ gap: var(--wx-multicombo-tag-gap);
171
+ padding: var(--wx-multicombo-tag-gap);
172
+ }
173
+ .wx-multicombo.wx-not-empty input {
174
+ border-top: var(--wx-input-border);
175
+ }
176
+ .wx-multicombo.wx-not-empty.wx-focus input {
177
+ border-top: var(--wx-input-border-focus);
178
+ }
179
+ .wx-multicombo.wx-not-empty.wx-disabled input {
180
+ border-top: var(--wx-input-border-disabled);
181
+ }
182
+ .wx-multicombo.wx-not-empty.wx-error input {
183
+ border-top-color: var(--wx-color-danger);
184
+ }
185
+
186
+ .wx-wrapper {
187
+ border: var(--wx-input-border);
188
+ border-radius: var(--wx-input-border-radius);
189
+ background: var(--wx-input-background);
190
+ }
191
+
192
+ .wx-tags {
193
+ display: flex;
194
+ flex-wrap: wrap;
195
+ align-items: flex-start;
196
+ overflow: hidden;
197
+ }
198
+
199
+ .wx-tag {
200
+ position: relative;
201
+ font-family: var(--wx-input-font-family);
202
+ font-size: var(--wx-input-font-size);
203
+ line-height: var(--wx-input-line-height);
204
+ font-weight: var(--wx-input-font-weight);
205
+ text-align: var(--wx-input-text-align);
206
+ color: var(--wx-input-font-color);
207
+ border: var(--wx-multicombo-tag-border);
208
+ border-radius: var(--wx-multicombo-tag-border-radius);
209
+ background: var(--wx-multicombo-tag-background);
210
+ padding: var(--wx-multicombo-tag-pading);
211
+ }
212
+
213
+ .wxi-close {
214
+ position: absolute;
215
+ right: var(--wx-input-icon-indent);
216
+ top: 50%;
217
+ transform: translateY(-50%);
218
+ font-size: var(--wx-input-icon-size);
219
+ line-height: 1;
220
+ display: flex;
221
+ justify-content: center;
222
+ align-items: center;
223
+ width: var(--wx-input-icon-size);
224
+ height: var(--wx-input-icon-size);
225
+ border-radius: var(--wx-input-border-radius);
226
+ color: var(--wx-input-icon-color);
227
+ cursor: pointer;
228
+ }
229
+ .wxi-close:hover {
230
+ color: var(--wx-color-primary);
231
+ }
232
+
233
+ .wx-select {
234
+ position: relative;
235
+ }
236
+
237
+ input {
238
+ display: block;
239
+ width: 100%;
240
+ height: var(--wx-input-height);
241
+ outline: none;
242
+ background: transparent;
243
+ border: none;
244
+ border-radius: 0;
245
+ font-family: var(--wx-input-font-family);
246
+ font-size: var(--wx-input-font-size);
247
+ line-height: var(--wx-input-line-height);
248
+ font-weight: var(--wx-input-font-weight);
249
+ text-align: var(--wx-input-text-align);
250
+ color: var(--wx-input-font-color);
251
+ padding: var(--wx-input-padding);
252
+ padding-right: calc(
253
+ var(--wx-input-icon-size) + var(--wx-input-icon-indent) * 2
254
+ );
255
+ overflow: hidden;
256
+ text-overflow: ellipsis;
257
+ cursor: pointer;
258
+ }
259
+
260
+ .wx-icon {
261
+ position: absolute;
262
+ right: var(--wx-input-icon-indent);
263
+ top: 50%;
264
+ transform: translateY(-50%);
265
+ font-size: var(--wx-input-icon-size);
266
+ line-height: 1;
267
+ width: var(--wx-input-icon-size);
268
+ height: var(--wx-input-icon-size);
269
+ display: flex;
270
+ justify-content: center;
271
+ align-items: center;
272
+ pointer-events: none;
273
+ user-select: none;
274
+ color: var(--wx-input-icon-color);
275
+ }
276
+ .wx-icon:before {
277
+ display: block;
278
+ }
279
+ </style>
@@ -0,0 +1,145 @@
1
+ <script>
2
+ import { fade } from "svelte/transition";
3
+ export let notice = {};
4
+
5
+ function onRemove() {
6
+ if (notice.remove) notice.remove();
7
+ }
8
+ </script>
9
+
10
+ <div
11
+ class="wx-notice wx-{notice.type ? notice.type : ''}"
12
+ role="status"
13
+ aria-live="polite"
14
+ transition:fade
15
+ >
16
+ <div class="wx-text">{notice.text}</div>
17
+ <!-- svelte-ignore a11y-click-events-have-key-events -->
18
+ <div class="wx-button">
19
+ <i class="wx-close wxi-close" on:click={onRemove} />
20
+ </div>
21
+ </div>
22
+
23
+ <style>
24
+ .wx-notice {
25
+ position: relative;
26
+ background: var(--wx-notice-background);
27
+ box-shadow: var(--wx-notice-shadow);
28
+ border: var(--wx-notice-border);
29
+ border-radius: var(--wx-notice-border-radius);
30
+ margin: var(--wx-notice-margin);
31
+ display: flex;
32
+ flex-wrap: nowrap;
33
+ align-items: center;
34
+ justify-content: space-between;
35
+ overflow: hidden;
36
+ font-family: var(--wx-notice-font-family);
37
+ font-size: var(--wx-notice-font-size);
38
+ line-height: var(--wx-notice-line-height);
39
+ font-weight: var(--wx-notice-font-weight);
40
+ color: var(--wx-notice-font-color);
41
+ width: var(--wx-notice-width);
42
+ }
43
+ .wx-notice:before {
44
+ content: "";
45
+ display: block;
46
+ position: absolute;
47
+ z-index: 1;
48
+ left: 0;
49
+ top: 0;
50
+ width: var(--wx-notice-type-border-width);
51
+ height: 100%;
52
+ border-top-right-radius: var(--wx-notice-type-border-width);
53
+ border-bottom-right-radius: var(--wx-notice-type-border-width);
54
+ background: var(--wx-notice-type-border-color);
55
+ }
56
+ .wx-notice:after {
57
+ content: "";
58
+ display: block;
59
+ position: absolute;
60
+ left: 0;
61
+ top: 0;
62
+ width: 100%;
63
+ height: 100%;
64
+ opacity: var(--wx-notice-type-background-opacity);
65
+ background: transparent;
66
+ }
67
+
68
+ .wx-text,
69
+ .wx-button {
70
+ position: relative;
71
+ z-index: 2;
72
+ padding: var(--wx-notice-padding);
73
+ }
74
+
75
+ .wx-text {
76
+ flex-shrink: 0;
77
+ word-wrap: break-word;
78
+ max-width: calc(
79
+ var(--wx-notice-width) - var(--wx-notice-padding) * 2 -
80
+ var(--wx-notice-icon-size)
81
+ );
82
+ }
83
+
84
+ .wx-close {
85
+ position: relative;
86
+ display: flex;
87
+ justify-content: center;
88
+ align-items: center;
89
+ font-size: var(--wx-notice-icon-size);
90
+ line-height: 1;
91
+ width: var(--wx-notice-icon-size);
92
+ height: var(--wx-notice-icon-size);
93
+ color: var(--wx-notice-type-icon-color);
94
+ cursor: pointer;
95
+ }
96
+ .wx-close:before {
97
+ display: block;
98
+ z-index: 1;
99
+ }
100
+ .wx-close:after {
101
+ content: "";
102
+ display: block;
103
+ position: absolute;
104
+ left: 50%;
105
+ top: 50%;
106
+ transform: translate(-50%, -50%);
107
+ width: calc(100% + 4px);
108
+ height: calc(100% + 4px);
109
+ border-radius: 50%;
110
+ }
111
+ .wx-close:hover:after {
112
+ background: var(--wx-background-hover);
113
+ }
114
+
115
+ .wx-notice.wx-info,
116
+ .wx-notice.wx-warning,
117
+ .wx-notice.wx-success,
118
+ .wx-notice.wx-danger {
119
+ color: var(--wx-notice-type-font-color);
120
+ }
121
+
122
+ .wx-notice.wx-info:before,
123
+ .wx-notice.wx-info:after {
124
+ background: var(--wx-color-info);
125
+ }
126
+ .wx-notice.wx-warning:before,
127
+ .wx-notice.wx-warning:after {
128
+ background: var(--wx-color-warning);
129
+ }
130
+ .wx-notice.wx-success:before,
131
+ .wx-notice.wx-success:after {
132
+ background: var(--wx-color-success);
133
+ }
134
+ .wx-notice.wx-danger:before,
135
+ .wx-notice.wx-danger:after {
136
+ background: var(--wx-color-danger);
137
+ }
138
+
139
+ .wx-notice.wx-info .wx-close:after,
140
+ .wx-notice.wx-warning .wx-close:after,
141
+ .wx-notice.wx-success .wx-close:after,
142
+ .wx-notice.wx-danger .wx-close:after {
143
+ opacity: var(--wx-notice-type-close-hover-opacity);
144
+ }
145
+ </style>
@@ -0,0 +1,20 @@
1
+ <script>
2
+ import Notice from "./Notice.svelte";
3
+
4
+ export let data;
5
+ </script>
6
+
7
+ <div class="wx-notices">
8
+ {#each data as notice (notice.id)}
9
+ <Notice {notice} />
10
+ {/each}
11
+ </div>
12
+
13
+ <style>
14
+ .wx-notices {
15
+ position: fixed;
16
+ z-index: var(--wx-notice-z-index);
17
+ top: 0;
18
+ right: 0;
19
+ }
20
+ </style>
@@ -0,0 +1,131 @@
1
+ <script>
2
+ import { createEventDispatcher } from "svelte";
3
+ const dispatch = createEventDispatcher();
4
+
5
+ export let pageSize = 20;
6
+ export let total = 0;
7
+ export let value = 1;
8
+
9
+ let pageCount = 0,
10
+ from = 0,
11
+ to = 0;
12
+ $: pageCount = Math.ceil(total / pageSize);
13
+ $: {
14
+ from = (value - 1) * pageSize;
15
+ to = Math.min(value * pageSize, total);
16
+ setTimeout(() => {
17
+ dispatch("change", { value, from, to });
18
+ }, 1);
19
+ }
20
+
21
+ function setActivePage(id) {
22
+ switch (id) {
23
+ case "first":
24
+ value = 1;
25
+ break;
26
+
27
+ case "prev":
28
+ value = Math.max(1, value - 1);
29
+ break;
30
+
31
+ case "next":
32
+ value = Math.min(+value + 1, pageCount);
33
+ break;
34
+
35
+ case "last":
36
+ value = pageCount;
37
+ break;
38
+
39
+ default:
40
+ break;
41
+ }
42
+ }
43
+ </script>
44
+
45
+ <div class="wx-pager">
46
+ <div class="wx-left">
47
+ <span>Rows per page: </span>
48
+ <input type="text" bind:value={pageSize} />
49
+ </div>
50
+
51
+ <div class="wx-center">
52
+ <!-- svelte-ignore a11y-click-events-have-key-events -->
53
+ <i
54
+ class="wx-icon wxi-angle-dbl-left"
55
+ on:click={() => setActivePage("first")}
56
+ />
57
+ <!-- svelte-ignore a11y-click-events-have-key-events -->
58
+ <i
59
+ class="wx-icon wxi-angle-left"
60
+ on:click={() => setActivePage("prev")}
61
+ />
62
+ <input type="text" bind:value />
63
+ <!-- svelte-ignore a11y-click-events-have-key-events -->
64
+ <i
65
+ class="wx-icon wxi-angle-right"
66
+ on:click={() => setActivePage("next")}
67
+ />
68
+ <!-- svelte-ignore a11y-click-events-have-key-events -->
69
+ <i
70
+ class="wx-icon wxi-angle-dbl-right"
71
+ on:click={() => setActivePage("last")}
72
+ />
73
+ </div>
74
+
75
+ <div class="wx-right">Total pages: {pageCount}</div>
76
+ </div>
77
+
78
+ <style>
79
+ .wx-pager {
80
+ display: flex;
81
+ gap: var(--wx-padding);
82
+ align-items: center;
83
+ padding: var(--wx-padding);
84
+ }
85
+
86
+ input {
87
+ display: block;
88
+ width: 50px;
89
+ height: var(--wx-input-height);
90
+ padding: var(--wx-input-padding);
91
+ outline: none;
92
+ font-family: var(--wx-input-font-family);
93
+ font-size: var(--wx-input-font-size);
94
+ line-height: var(--wx-input-line-height);
95
+ font-weight: var(--wx-input-font-weight);
96
+ text-align: var(--wx-input-text-align);
97
+ color: var(--wx-input-font-color);
98
+ border: var(--wx-input-border);
99
+ border-radius: var(--wx-input-border-radius);
100
+ background: var(--wx-input-background);
101
+ }
102
+ input:focus {
103
+ border: var(--wx-input-border-focus);
104
+ }
105
+ input::placeholder {
106
+ color: var(--wx-input-placeholder-color);
107
+ }
108
+
109
+ .wx-icon {
110
+ cursor: pointer;
111
+ padding: var(--wx-input-padding);
112
+ border-radius: var(--wx-input-border-radius);
113
+ font-size: var(--wx-icon-size);
114
+ line-height: 1;
115
+ color: var(--wx-color-link);
116
+ }
117
+ .wx-icon:before {
118
+ display: block;
119
+ }
120
+ .wx-icon:hover {
121
+ background-color: var(--wx-background-hover);
122
+ }
123
+
124
+ .wx-left,
125
+ .wx-center,
126
+ .wx-right {
127
+ display: flex;
128
+ align-items: center;
129
+ gap: var(--wx-padding);
130
+ }
131
+ </style>
@@ -0,0 +1,53 @@
1
+ <script>
2
+ import { clickOutside, calculatePosition } from "wx-lib-dom";
3
+ import { onMount } from "svelte";
4
+
5
+ export let left = 0;
6
+ export let top = 0;
7
+ export let at = "bottom";
8
+ export let parent = null;
9
+ export let cancel;
10
+ export let mount;
11
+
12
+ let self;
13
+
14
+ let x = 0;
15
+ let y = 0;
16
+ let width;
17
+
18
+ function updatePosition() {
19
+ const result = calculatePosition(self, parent, at, left, top);
20
+ x = result.x || x;
21
+ y = result.y || y;
22
+ width = result.width || width;
23
+ }
24
+
25
+ if (mount) mount(updatePosition);
26
+ onMount(updatePosition);
27
+ $: updatePosition(parent);
28
+
29
+ function down(e) {
30
+ if (cancel) cancel(e);
31
+ }
32
+ </script>
33
+
34
+ <div
35
+ use:clickOutside={down}
36
+ bind:this={self}
37
+ class="wx-popup"
38
+ style="top:{y}px;left:{x}px;width:{width};"
39
+ >
40
+ <slot />
41
+ </div>
42
+
43
+ <style>
44
+ .wx-popup {
45
+ position: fixed;
46
+ z-index: var(--wx-popup-z-index);
47
+ background: var(--wx-popup-background);
48
+ box-shadow: var(--wx-popup-shadow);
49
+ border: var(--wx-popup-border);
50
+ border-radius: var(--wx-popup-border-radius);
51
+ overflow: hidden;
52
+ }
53
+ </style>
@@ -0,0 +1,42 @@
1
+ <script>
2
+ import { onMount, getContext, onDestroy } from "svelte";
3
+
4
+ let portal;
5
+ export let theme = "";
6
+ export let target = undefined;
7
+
8
+ let handlers = [];
9
+ export const mount = h => {
10
+ if (handlers) handlers.push(h);
11
+ };
12
+
13
+ if (theme === "") theme = getContext("wx-theme");
14
+
15
+ function getParentRoot(p) {
16
+ while (p !== document.body && !p.getAttribute("data-wx-portal-root")) {
17
+ p = p.parentNode;
18
+ }
19
+ return p;
20
+ }
21
+ onMount(() => {
22
+ let currentTarget = target || getParentRoot(portal);
23
+ currentTarget.appendChild(portal);
24
+ if (handlers) handlers.forEach(h => h());
25
+ });
26
+
27
+ onDestroy(() => {
28
+ if (portal && portal.parentNode) portal.parentNode.removeChild(portal);
29
+ });
30
+ </script>
31
+
32
+ <div class="wx-portal">
33
+ <div class="wx-{theme}-theme" bind:this={portal}>
34
+ <slot {mount} />
35
+ </div>
36
+ </div>
37
+
38
+ <style>
39
+ .wx-portal {
40
+ display: none;
41
+ }
42
+ </style>