poe-svelte-ui-lib 1.2.7 → 1.2.9
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/dist/Input/Input.svelte +4 -4
- package/dist/Joystick/Joystick.svelte +283 -83
- package/dist/Joystick/Joystick.svelte.d.ts +2 -2
- package/dist/Switch/Switch.svelte +1 -0
- package/dist/Tabs/Tabs.svelte +5 -0
- package/dist/Tabs/TabsProps.svelte +16 -33
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -2
- package/dist/locales/translations.js +1 -0
- package/dist/types.d.ts +16 -1
- package/package.json +3 -3
package/dist/Input/Input.svelte
CHANGED
|
@@ -174,11 +174,11 @@
|
|
|
174
174
|
if (!number.maxNum || !number.step) return
|
|
175
175
|
if (Number(value) + number.step >= number.maxNum) {
|
|
176
176
|
value = number.maxNum
|
|
177
|
-
onUpdate
|
|
177
|
+
onUpdate(value as number)
|
|
178
178
|
return
|
|
179
179
|
}
|
|
180
180
|
value = Number(value) + (number.step ?? 1)
|
|
181
|
-
onUpdate
|
|
181
|
+
onUpdate(value as number)
|
|
182
182
|
}}
|
|
183
183
|
aria-label="Увеличить">+</button
|
|
184
184
|
>
|
|
@@ -189,11 +189,11 @@
|
|
|
189
189
|
if (number.minNum === null || number.minNum === undefined || !number.step) return
|
|
190
190
|
if (Number(value) - number.step <= number.minNum) {
|
|
191
191
|
value = number.minNum
|
|
192
|
-
onUpdate
|
|
192
|
+
onUpdate(value as number)
|
|
193
193
|
return
|
|
194
194
|
}
|
|
195
195
|
value = Number(value) - (number.step ?? 1)
|
|
196
|
-
onUpdate
|
|
196
|
+
onUpdate(value as number)
|
|
197
197
|
}}
|
|
198
198
|
aria-label="Уменьшить">−</button
|
|
199
199
|
>
|
|
@@ -1,125 +1,325 @@
|
|
|
1
|
-
<!-- $lib/ElementsUI/ProgressBar.svelte -->
|
|
2
1
|
<script lang="ts">
|
|
3
2
|
import { twMerge } from 'tailwind-merge'
|
|
4
|
-
import type {
|
|
3
|
+
import type { IJoystickProps } from '../types'
|
|
5
4
|
|
|
6
5
|
let {
|
|
7
6
|
id = crypto.randomUUID(),
|
|
8
7
|
wrapperClass = '',
|
|
9
8
|
label = { name: '', class: '' },
|
|
10
|
-
value = $bindable(0),
|
|
11
|
-
|
|
12
|
-
minNum:
|
|
13
|
-
maxNum: 100,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
value = $bindable([0, 0, 0]),
|
|
10
|
+
limits = [
|
|
11
|
+
{ minNum: -100, maxNum: 100 },
|
|
12
|
+
{ minNum: -100, maxNum: 100 },
|
|
13
|
+
{ minNum: -100, maxNum: 100 },
|
|
14
|
+
],
|
|
15
|
+
onUpdate = () => {},
|
|
16
|
+
}: IJoystickProps = $props()
|
|
17
17
|
|
|
18
18
|
const directions = [
|
|
19
|
-
{
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
{
|
|
20
|
+
id: 'right',
|
|
21
|
+
angle: 30.5,
|
|
22
|
+
content: true,
|
|
23
|
+
onClick: () => {
|
|
24
|
+
if (value[2] + sensitivity >= limits[2].maxNum) {
|
|
25
|
+
value[2] = limits[2].maxNum
|
|
26
|
+
onUpdate(value)
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
value[2] += sensitivity
|
|
31
|
+
onUpdate(value)
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: 'bottom-right',
|
|
36
|
+
angle: 58,
|
|
37
|
+
content: false,
|
|
38
|
+
onClick: () => {
|
|
39
|
+
if (value[2] + sensitivity >= limits[2].maxNum) {
|
|
40
|
+
value[2] = limits[2].maxNum
|
|
41
|
+
onUpdate(value)
|
|
42
|
+
} else {
|
|
43
|
+
value[2] += sensitivity
|
|
44
|
+
onUpdate(value)
|
|
45
|
+
}
|
|
46
|
+
if (value[1] - sensitivity <= limits[1].minNum) {
|
|
47
|
+
value[1] = limits[1].minNum
|
|
48
|
+
onUpdate(value)
|
|
49
|
+
} else {
|
|
50
|
+
value[1] -= sensitivity
|
|
51
|
+
onUpdate(value)
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
id: 'bottom',
|
|
57
|
+
angle: 122,
|
|
58
|
+
content: true,
|
|
59
|
+
onClick: () => {
|
|
60
|
+
if (value[1] - sensitivity <= limits[1].minNum) {
|
|
61
|
+
value[1] = limits[1].minNum
|
|
62
|
+
onUpdate(value)
|
|
63
|
+
return
|
|
64
|
+
}
|
|
65
|
+
value[1] -= sensitivity
|
|
66
|
+
onUpdate(value)
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
id: 'bottom-left',
|
|
71
|
+
angle: 149.5,
|
|
72
|
+
content: false,
|
|
73
|
+
onClick: () => {
|
|
74
|
+
if (value[2] - sensitivity <= limits[2].minNum) {
|
|
75
|
+
value[2] = limits[2].minNum
|
|
76
|
+
onUpdate(value)
|
|
77
|
+
} else {
|
|
78
|
+
value[2] -= sensitivity
|
|
79
|
+
onUpdate(value)
|
|
80
|
+
}
|
|
81
|
+
if (value[1] - sensitivity <= limits[1].minNum) {
|
|
82
|
+
value[1] = limits[1].minNum
|
|
83
|
+
onUpdate(value)
|
|
84
|
+
} else {
|
|
85
|
+
value[1] -= sensitivity
|
|
86
|
+
onUpdate(value)
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
id: 'left',
|
|
92
|
+
angle: 212,
|
|
93
|
+
content: true,
|
|
94
|
+
onClick: () => {
|
|
95
|
+
if (value[2] - sensitivity <= limits[2].minNum) {
|
|
96
|
+
value[2] = limits[2].minNum
|
|
97
|
+
onUpdate(value)
|
|
98
|
+
return
|
|
99
|
+
}
|
|
100
|
+
value[2] -= sensitivity
|
|
101
|
+
onUpdate(value)
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
id: 'top-left',
|
|
106
|
+
angle: 239,
|
|
107
|
+
content: false,
|
|
108
|
+
onClick: () => {
|
|
109
|
+
if (value[1] + sensitivity >= limits[1].maxNum) {
|
|
110
|
+
value[1] = limits[1].maxNum
|
|
111
|
+
onUpdate(value)
|
|
112
|
+
} else {
|
|
113
|
+
value[1] += sensitivity
|
|
114
|
+
onUpdate(value)
|
|
115
|
+
}
|
|
116
|
+
if (value[2] - sensitivity <= limits[2].minNum) {
|
|
117
|
+
value[2] = limits[2].minNum
|
|
118
|
+
onUpdate(value)
|
|
119
|
+
} else {
|
|
120
|
+
value[2] -= sensitivity
|
|
121
|
+
onUpdate(value)
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
id: 'top',
|
|
127
|
+
angle: 301,
|
|
128
|
+
content: true,
|
|
129
|
+
onClick: () => {
|
|
130
|
+
if (value[1] + sensitivity >= limits[1].maxNum) {
|
|
131
|
+
value[1] = limits[1].maxNum
|
|
132
|
+
onUpdate(value)
|
|
133
|
+
return
|
|
134
|
+
}
|
|
135
|
+
value[1] += sensitivity
|
|
136
|
+
onUpdate(value)
|
|
137
|
+
},
|
|
138
|
+
},
|
|
26
139
|
{
|
|
27
140
|
id: 'top-right',
|
|
28
141
|
angle: 328,
|
|
29
142
|
content: false,
|
|
143
|
+
onClick: () => {
|
|
144
|
+
if (value[1] + sensitivity >= limits[1].maxNum) {
|
|
145
|
+
value[1] = limits[1].maxNum
|
|
146
|
+
onUpdate(value)
|
|
147
|
+
} else {
|
|
148
|
+
value[1] += sensitivity
|
|
149
|
+
onUpdate(value)
|
|
150
|
+
}
|
|
151
|
+
if (value[2] + sensitivity >= limits[2].maxNum) {
|
|
152
|
+
value[2] = limits[2].maxNum
|
|
153
|
+
onUpdate(value)
|
|
154
|
+
} else {
|
|
155
|
+
value[2] += sensitivity
|
|
156
|
+
onUpdate(value)
|
|
157
|
+
}
|
|
158
|
+
},
|
|
30
159
|
},
|
|
31
160
|
]
|
|
32
161
|
|
|
33
|
-
|
|
162
|
+
const sensitivityOptions = [0.01, 0.1, 1.0, 10, 100]
|
|
163
|
+
let sensitivity = $state(1.0)
|
|
164
|
+
|
|
34
165
|
let clipPos = Math.cos(Math.PI / directions.length) * 100
|
|
35
166
|
let angle = 360 / directions.length
|
|
36
167
|
</script>
|
|
37
168
|
|
|
38
|
-
<div {id} class={twMerge(`bg-
|
|
169
|
+
<div {id} class={twMerge(`bg-blue relative flex w-full flex-col items-center`, wrapperClass)}>
|
|
39
170
|
{#if label.name}
|
|
40
171
|
<h5 class={twMerge(` w-full px-4 text-center`, label.class)}>{label.name}</h5>
|
|
41
172
|
{/if}
|
|
42
173
|
|
|
43
|
-
<div class="
|
|
44
|
-
<div class="
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
<
|
|
48
|
-
class="
|
|
49
|
-
|
|
50
|
-
|
|
174
|
+
<div class=" flex items-center justify-center">
|
|
175
|
+
<div class="relative z-10 flex size-40 items-center justify-center rounded-full bg-(--bg-color) shadow-[0_0_20px_rgb(0_0_0_/0.25)]">
|
|
176
|
+
<div class="absolute h-full w-full overflow-hidden rounded-full">
|
|
177
|
+
{#each directions as direction, index}
|
|
178
|
+
<button
|
|
179
|
+
class="pointer-events-none absolute top-1/2 left-1/2 block w-1/2 -translate-y-1/2 cursor-pointer"
|
|
180
|
+
onclick={direction.onClick}
|
|
181
|
+
title=""
|
|
182
|
+
>
|
|
183
|
+
<span
|
|
184
|
+
class="relative flex w-full origin-left items-center justify-center pl-[60%] h-[{direction.content
|
|
185
|
+
? 2 * 5 * Math.sin((Math.PI * 65) / 360)
|
|
186
|
+
: 2 * 5 * Math.sin((Math.PI * 25) / 360)}rem] pointer-events-auto
|
|
51
187
|
{direction.content ? 'bg-(--bg-color)' : ''}
|
|
52
188
|
"
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
189
|
+
style="transform: rotate({angle * index}deg); clip-path: polygon(100% 0, {clipPos}% 0, 0 50%, {clipPos}% 100%, 100% 100%)"
|
|
190
|
+
role="application"
|
|
191
|
+
onmouseenter={(e) => (e.currentTarget.style.backgroundColor = 'color-mix(in srgb, var(--bg-color), var(--shadow-color) 20%)')}
|
|
192
|
+
onmouseleave={(e) => (e.currentTarget.style.backgroundColor = 'var(--bg-color)')}
|
|
193
|
+
>
|
|
194
|
+
{#if direction.content}
|
|
195
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"
|
|
196
|
+
><path
|
|
197
|
+
fill="currentColor"
|
|
198
|
+
d="M12.6 12L8.7 8.1q-.275-.275-.275-.7t.275-.7t.7-.275t.7.275l4.6 4.6q.15.15.213.325t.062.375t-.062.375t-.213.325l-4.6 4.6q-.275.275-.7.275t-.7-.275t-.275-.7t.275-.7z"
|
|
199
|
+
/></svg
|
|
200
|
+
>
|
|
201
|
+
{:else}
|
|
202
|
+
•
|
|
203
|
+
{/if}
|
|
204
|
+
</span>
|
|
205
|
+
</button>
|
|
206
|
+
{/each}
|
|
207
|
+
</div>
|
|
208
|
+
<div class="pointer-events-none absolute h-full w-full overflow-hidden rounded-full">
|
|
209
|
+
{#each directions as direction, index}
|
|
210
|
+
<span
|
|
211
|
+
class=" absolute top-1/2 left-1/2 h-0 w-[52%] origin-left border-b border-(--bg-color) {index % 2 == 0
|
|
212
|
+
? 'shadow-[0_3px_5px_rgb(0_0_0_/0.5)] '
|
|
213
|
+
: 'shadow-[0_-3px_5px_rgb(0_0_0_/0.5)]'}"
|
|
214
|
+
style="transform: rotate({direction.angle}deg);"
|
|
57
215
|
>
|
|
58
|
-
{#if direction.content}
|
|
59
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"
|
|
60
|
-
><path
|
|
61
|
-
fill="currentColor"
|
|
62
|
-
d="M12.6 12L8.7 8.1q-.275-.275-.275-.7t.275-.7t.7-.275t.7.275l4.6 4.6q.15.15.213.325t.062.375t-.062.375t-.213.325l-4.6 4.6q-.275.275-.7.275t-.7-.275t-.275-.7t.275-.7z"
|
|
63
|
-
/></svg
|
|
64
|
-
>
|
|
65
|
-
{/if}
|
|
66
216
|
</span>
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
{#each directions as direction, index}
|
|
72
|
-
<span
|
|
73
|
-
class=" absolute top-1/2 left-1/2 h-0 w-[52%] origin-left border-b border-(--bg-color) {index % 2 == 0
|
|
74
|
-
? 'shadow-[0_3px_5px_rgb(0_0_0_/0.5)] '
|
|
75
|
-
: 'shadow-[0_-3px_5px_rgb(0_0_0_/0.5)]'}"
|
|
76
|
-
style="transform: rotate({direction.angle}deg);"
|
|
77
|
-
>
|
|
78
|
-
</span>
|
|
79
|
-
{/each}
|
|
80
|
-
</div>
|
|
81
|
-
<div class="z-10 flex size-20 items-center justify-center rounded-full bg-(--bg-color) shadow-[0_0_15px_rgb(0_0_0_/0.25)]">
|
|
82
|
-
<button class="flex size-18 cursor-pointer items-center justify-center rounded-full bg-(--bg-color)" title=""
|
|
83
|
-
><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"
|
|
84
|
-
><path
|
|
85
|
-
fill="currentColor"
|
|
86
|
-
d="M6 19h3v-5q0-.425.288-.712T10 13h4q.425 0 .713.288T15 14v5h3v-9l-6-4.5L6 10zm-2 0v-9q0-.475.213-.9t.587-.7l6-4.5q.525-.4 1.2-.4t1.2.4l6 4.5q.375.275.588.7T20 10v9q0 .825-.588 1.413T18 21h-4q-.425 0-.712-.288T13 20v-5h-2v5q0 .425-.288.713T10 21H6q-.825 0-1.412-.587T4 19m8-6.75"
|
|
87
|
-
/></svg
|
|
88
|
-
></button
|
|
217
|
+
{/each}
|
|
218
|
+
</div>
|
|
219
|
+
<div
|
|
220
|
+
class="z-20 flex size-20 items-center justify-center rounded-full bg-(--bg-color) shadow-[0_0_15px_rgb(0_0_0_/0.25)] transition hover:scale-103"
|
|
89
221
|
>
|
|
222
|
+
<button
|
|
223
|
+
class="flex size-18 cursor-pointer items-center justify-center rounded-full bg-(--bg-color)"
|
|
224
|
+
title=""
|
|
225
|
+
onclick={() => {
|
|
226
|
+
value = [0, 0, 0]
|
|
227
|
+
onUpdate(value)
|
|
228
|
+
}}
|
|
229
|
+
><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"
|
|
230
|
+
><path
|
|
231
|
+
fill="currentColor"
|
|
232
|
+
d="M6 19h3v-5q0-.425.288-.712T10 13h4q.425 0 .713.288T15 14v5h3v-9l-6-4.5L6 10zm-2 0v-9q0-.475.213-.9t.587-.7l6-4.5q.525-.4 1.2-.4t1.2.4l6 4.5q.375.275.588.7T20 10v9q0 .825-.588 1.413T18 21h-4q-.425 0-.712-.288T13 20v-5h-2v5q0 .425-.288.713T10 21H6q-.825 0-1.412-.587T4 19m8-6.75"
|
|
233
|
+
/></svg
|
|
234
|
+
></button
|
|
235
|
+
>
|
|
236
|
+
</div>
|
|
90
237
|
</div>
|
|
91
|
-
|
|
92
238
|
<div
|
|
93
|
-
class="absolute
|
|
94
|
-
style="background: color-mix(in srgb, var(--bg-color), var(--shadow-color)
|
|
239
|
+
class="absolute flex h-15 w-65 items-center justify-between rounded-full shadow-[0_0_15px_rgb(0_0_0_/0.25)]"
|
|
240
|
+
style="background: color-mix(in srgb, var(--bg-color), var(--shadow-color) 10%)"
|
|
95
241
|
>
|
|
96
|
-
<button
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
242
|
+
<button
|
|
243
|
+
class="h-full cursor-pointer rounded-l-full px-3.5"
|
|
244
|
+
title=""
|
|
245
|
+
onclick={() => {
|
|
246
|
+
if (value[0] - sensitivity <= limits[0].minNum) {
|
|
247
|
+
value[0] = limits[0].minNum
|
|
248
|
+
onUpdate(value)
|
|
249
|
+
return
|
|
250
|
+
}
|
|
251
|
+
value[0] -= sensitivity
|
|
252
|
+
onUpdate(value)
|
|
253
|
+
}}
|
|
254
|
+
onmouseenter={(e) => (e.currentTarget.style.backgroundColor = 'color-mix(in srgb, var(--bg-color), var(--shadow-color) 30%)')}
|
|
255
|
+
onmouseleave={(e) => (e.currentTarget.style.backgroundColor = 'background: color-mix(in srgb, var(--bg-color), var(--shadow-color) 10%)')}
|
|
256
|
+
><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
|
|
257
|
+
><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="1.5"
|
|
258
|
+
><path
|
|
259
|
+
stroke-miterlimit="10"
|
|
260
|
+
d="M6.395 7.705A7.9 7.9 0 0 1 12 5.382a7.93 7.93 0 0 1 7.929 7.929A7.94 7.94 0 0 1 12 21.25a7.94 7.94 0 0 1-7.929-7.94"
|
|
261
|
+
/><path stroke-linejoin="round" d="m7.12 2.75l-.95 3.858a1.33 1.33 0 0 0 .97 1.609l3.869.948" /></g
|
|
262
|
+
></svg
|
|
106
263
|
></button
|
|
107
264
|
>
|
|
108
|
-
<button
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
265
|
+
<button
|
|
266
|
+
class="h-full cursor-pointer rounded-r-full px-3.5"
|
|
267
|
+
title=""
|
|
268
|
+
onclick={() => {
|
|
269
|
+
if (value[0] + sensitivity >= limits[0].maxNum) {
|
|
270
|
+
value[0] = limits[0].maxNum
|
|
271
|
+
onUpdate(value)
|
|
272
|
+
return
|
|
273
|
+
}
|
|
274
|
+
value[0] += sensitivity
|
|
275
|
+
onUpdate(value)
|
|
276
|
+
}}
|
|
277
|
+
onmouseenter={(e) => (e.currentTarget.style.backgroundColor = 'color-mix(in srgb, var(--bg-color), var(--shadow-color) 30%)')}
|
|
278
|
+
onmouseleave={(e) => (e.currentTarget.style.backgroundColor = 'vabackground: color-mix(in srgb, var(--bg-color), var(--shadow-color) 10%)')}
|
|
279
|
+
><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
|
|
280
|
+
><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="1.5"
|
|
281
|
+
><path
|
|
282
|
+
stroke-miterlimit="10"
|
|
283
|
+
d="M17.605 7.705A7.9 7.9 0 0 0 12 5.382a7.93 7.93 0 0 0-7.929 7.929A7.94 7.94 0 0 0 12 21.25a7.94 7.94 0 0 0 7.929-7.94"
|
|
284
|
+
/><path stroke-linejoin="round" d="m16.88 2.75l.95 3.858a1.33 1.33 0 0 1-.97 1.609l-3.869.948" /></g
|
|
285
|
+
></svg
|
|
118
286
|
></button
|
|
119
287
|
>
|
|
120
288
|
</div>
|
|
121
289
|
</div>
|
|
122
290
|
|
|
291
|
+
<p>{value[0]}</p>
|
|
292
|
+
<p>{value[1]}</p>
|
|
293
|
+
<p>{value[2]}</p>
|
|
294
|
+
|
|
295
|
+
<div {id} class="flex h-full w-full flex-row justify-center rounded-full p-10">
|
|
296
|
+
{#each sensitivityOptions as option, index}
|
|
297
|
+
<button
|
|
298
|
+
id={crypto.randomUUID()}
|
|
299
|
+
class={twMerge(`m-0 inline-block min-w-0 flex-1 cursor-pointer items-center px-2 py-1 font-semibold shadow-sm transition-all duration-300
|
|
300
|
+
select-none hover:shadow-md
|
|
301
|
+
${
|
|
302
|
+
option === sensitivity && sensitivity !== null
|
|
303
|
+
? 'z-10 py-1 shadow-[0_0_10px_var(--shadow-color)] hover:shadow-[0_0_15px_var(--shadow-color)]'
|
|
304
|
+
: ''
|
|
305
|
+
}
|
|
306
|
+
${sensitivityOptions.length > 0 && index === 0 ? 'rounded-l-2xl' : ''} ${
|
|
307
|
+
index === sensitivityOptions.length - 1 ? 'rounded-r-2xl' : ''
|
|
308
|
+
} bg-(--back-color)`)}
|
|
309
|
+
onclick={() => {
|
|
310
|
+
sensitivity = option
|
|
311
|
+
}}
|
|
312
|
+
>
|
|
313
|
+
<span class="flex flex-row items-center justify-center gap-4">
|
|
314
|
+
{#if option}
|
|
315
|
+
<div class="flex-1">
|
|
316
|
+
{option}
|
|
317
|
+
</div>
|
|
318
|
+
{/if}
|
|
319
|
+
</span>
|
|
320
|
+
</button>
|
|
321
|
+
{/each}
|
|
322
|
+
</div>
|
|
123
323
|
<!-- {direction.content ? 2 * 6.25 * Math.sin((Math.PI * 65) / 360) : 2 * 6.25 * Math.sin((Math.PI * 25) / 360)} -->
|
|
124
324
|
<!-- angle / 2 + angle * index -->
|
|
125
325
|
<!-- ? 'shadow-[0_-2px_5px_rgb(254_202_202)] '
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
declare const Joystick: import("svelte").Component<
|
|
1
|
+
import type { IJoystickProps } from '../types';
|
|
2
|
+
declare const Joystick: import("svelte").Component<IJoystickProps, {}, "value">;
|
|
3
3
|
type Joystick = ReturnType<typeof Joystick>;
|
|
4
4
|
export default Joystick;
|
package/dist/Tabs/Tabs.svelte
CHANGED
|
@@ -38,6 +38,11 @@
|
|
|
38
38
|
item.class,
|
|
39
39
|
index === currentTabIndex ? twMerge('bg-(--back-color) text-blue-500', item.class) : 'bg-(--bg-color) text-gray-500',
|
|
40
40
|
)}
|
|
41
|
+
style="width: {item.class
|
|
42
|
+
?.split(' ')
|
|
43
|
+
.find((cls: string) => cls.startsWith('w-'))
|
|
44
|
+
?.replace('w-[', '')
|
|
45
|
+
.slice(0, -1)};"
|
|
41
46
|
onclick={() => (currentTabIndex = index)}
|
|
42
47
|
>
|
|
43
48
|
{#if item?.icon}
|
|
@@ -56,21 +56,6 @@
|
|
|
56
56
|
} else if (width.class.includes('w-auto')) return 1
|
|
57
57
|
else return 2
|
|
58
58
|
})
|
|
59
|
-
|
|
60
|
-
const handleImageUpload = (event: Event) => {
|
|
61
|
-
const input = event.target as HTMLInputElement
|
|
62
|
-
if (!input.files || input.files.length === 0) return
|
|
63
|
-
|
|
64
|
-
const file = input.files[0]
|
|
65
|
-
const reader = new FileReader()
|
|
66
|
-
reader.onload = (e) => {
|
|
67
|
-
const base64String = e.target?.result as string
|
|
68
|
-
updateProperty('image', base64String, component, onPropertyChange)
|
|
69
|
-
}
|
|
70
|
-
reader.readAsDataURL(file)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
let currentImage = $derived(component.properties.image ?? '')
|
|
74
59
|
</script>
|
|
75
60
|
|
|
76
61
|
{#if forConstructor}
|
|
@@ -123,19 +108,11 @@
|
|
|
123
108
|
}}
|
|
124
109
|
value={initialWidth()}
|
|
125
110
|
onChange={(value) => {
|
|
126
|
-
|
|
127
|
-
component.properties
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
})
|
|
132
|
-
} else {
|
|
133
|
-
component.properties.items.forEach((_item: any, index: number) => {
|
|
134
|
-
const items = [...(component.properties?.items || [])]
|
|
135
|
-
items[index]['class'] = twMerge(items[index].class, 'w-auto')
|
|
136
|
-
updateProperty('items', items, component, onPropertyChange)
|
|
137
|
-
})
|
|
138
|
-
}
|
|
111
|
+
component.properties.items.forEach((_item: any, index: number) => {
|
|
112
|
+
const items = [...(component.properties?.items || [])]
|
|
113
|
+
items[index]['class'] = twMerge(items[index].class, value === 2 ? `w-[${(1 / items.length) * 100}%]` : 'w-auto')
|
|
114
|
+
updateProperty('items', items, component, onPropertyChange)
|
|
115
|
+
})
|
|
139
116
|
}}
|
|
140
117
|
/>
|
|
141
118
|
</div>
|
|
@@ -143,19 +120,21 @@
|
|
|
143
120
|
|
|
144
121
|
<div class="space-y-4">
|
|
145
122
|
<div class="m-0 flex items-center justify-center gap-2">
|
|
146
|
-
<h4>{$t('constructor.props.
|
|
123
|
+
<h4>{$t('constructor.props.tabs.title')}</h4>
|
|
147
124
|
<UI.Button
|
|
148
125
|
wrapperClass="w-8"
|
|
149
126
|
content={{ icon: ButtonAdd }}
|
|
150
127
|
onClick={() => {
|
|
151
|
-
let tabWidth = Math.max(...Array.from(document.body.querySelectorAll('.tab')).map((item) => (item as HTMLElement).offsetWidth))
|
|
152
128
|
const newItem: { name: string; icon: string; class: string } = {
|
|
153
129
|
name: `Tab ${component.properties?.items.length + 1}`,
|
|
154
|
-
class: `
|
|
130
|
+
class: `text-${initialColor?.value.slice(3)}-500 ${initialPosition?.value}`,
|
|
155
131
|
icon: '',
|
|
156
132
|
}
|
|
157
133
|
const items = [...(component.properties?.items || []), newItem]
|
|
158
|
-
|
|
134
|
+
items.forEach((_item: any, index: number) => {
|
|
135
|
+
items[index]['class'] = twMerge(items[index].class, initialWidth() === 2 ? `w-[${(1 / items.length) * 100}%]` : 'w-auto')
|
|
136
|
+
updateProperty('items', items, component, onPropertyChange)
|
|
137
|
+
})
|
|
159
138
|
}}
|
|
160
139
|
/>
|
|
161
140
|
</div>
|
|
@@ -196,6 +175,10 @@
|
|
|
196
175
|
onClick={() => {
|
|
197
176
|
const items = [...(component.properties?.items || [])]
|
|
198
177
|
items.splice(index, 1)
|
|
178
|
+
items.forEach((_item: any, index: number) => {
|
|
179
|
+
items[index]['class'] = twMerge(items[index].class, initialWidth() === 2 ? `w-[${(1 / items.length) * 100}%]` : 'w-auto')
|
|
180
|
+
updateProperty('items', items, component, onPropertyChange)
|
|
181
|
+
})
|
|
199
182
|
updateProperty('items', items, component, onPropertyChange)
|
|
200
183
|
}}
|
|
201
184
|
/>
|
|
@@ -328,7 +311,7 @@
|
|
|
328
311
|
|
|
329
312
|
<div class="space-y-4">
|
|
330
313
|
<div class="m-0 flex items-center justify-center gap-2">
|
|
331
|
-
<h4>{$t('constructor.props.
|
|
314
|
+
<h4>{$t('constructor.props.tabs.title')}</h4>
|
|
332
315
|
<UI.Button
|
|
333
316
|
wrapperClass="w-8"
|
|
334
317
|
content={{ icon: ButtonAdd }}
|
package/dist/index.d.ts
CHANGED
|
@@ -9,6 +9,8 @@ export { default as Graph } from './Graph/Graph.svelte';
|
|
|
9
9
|
export { default as GraphProps } from './Graph/GraphProps.svelte';
|
|
10
10
|
export { default as Input } from './Input/Input.svelte';
|
|
11
11
|
export { default as InputProps } from './Input/InputProps.svelte';
|
|
12
|
+
export { default as Joystick } from './Joystick/Joystick.svelte';
|
|
13
|
+
export { default as JoystickProps } from './Joystick/JoystickProps.svelte';
|
|
12
14
|
export { default as Modal } from './Modal.svelte';
|
|
13
15
|
export { default as ProgressBar } from './ProgressBar/ProgressBar.svelte';
|
|
14
16
|
export { default as ProgressBarProps } from './ProgressBar/ProgressBarProps.svelte';
|
|
@@ -26,4 +28,4 @@ export { default as TextField } from './TextField/TextField.svelte';
|
|
|
26
28
|
export { default as TextFieldProps } from './TextField/TextFieldProps.svelte';
|
|
27
29
|
export * from './locales/i18n';
|
|
28
30
|
export * from './locales/translations';
|
|
29
|
-
export { type UIComponent, type Position, type IUIComponentHandler, type IButtonProps, type IAccordionProps, type IInputProps, type ISelectProps, type ISelectOption, type ISwitchProps, type IColorPickerProps, type ISliderProps, type ITextFieldProps, type IProgressBarProps, type IGraphProps, type IGraphDataObject, type ITableHeader, type ITableProps, type ITabsProps, } from './types';
|
|
31
|
+
export { type UIComponent, type Position, type IUIComponentHandler, type IButtonProps, type IAccordionProps, type IInputProps, type ISelectProps, type ISelectOption, type ISwitchProps, type IColorPickerProps, type ISliderProps, type ITextFieldProps, type IProgressBarProps, type IGraphProps, type IGraphDataObject, type ITableHeader, type ITableProps, type ITabsProps, type IJoystickProps, } from './types';
|
package/dist/index.js
CHANGED
|
@@ -10,8 +10,8 @@ export { default as Graph } from './Graph/Graph.svelte';
|
|
|
10
10
|
export { default as GraphProps } from './Graph/GraphProps.svelte';
|
|
11
11
|
export { default as Input } from './Input/Input.svelte';
|
|
12
12
|
export { default as InputProps } from './Input/InputProps.svelte';
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
export { default as Joystick } from './Joystick/Joystick.svelte';
|
|
14
|
+
export { default as JoystickProps } from './Joystick/JoystickProps.svelte';
|
|
15
15
|
export { default as Modal } from './Modal.svelte';
|
|
16
16
|
export { default as ProgressBar } from './ProgressBar/ProgressBar.svelte';
|
|
17
17
|
export { default as ProgressBarProps } from './ProgressBar/ProgressBarProps.svelte';
|
|
@@ -95,6 +95,7 @@ const translations = {
|
|
|
95
95
|
'constructor.props.widthMode': 'Ширина кнопок',
|
|
96
96
|
'constructor.props.graphdata.title': 'Начальные данные ',
|
|
97
97
|
'constructor.props.options.title': 'Опции компонента',
|
|
98
|
+
'constructor.props.tabs.title': 'Вкладки меню',
|
|
98
99
|
'constructor.props.valuetype': 'Тип значения',
|
|
99
100
|
'constructor.props.action': 'Действие при переключении',
|
|
100
101
|
'constructor.props.caption.left': 'Надпись слева',
|
package/dist/types.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export interface UIComponent {
|
|
|
8
8
|
id: string;
|
|
9
9
|
name?: string;
|
|
10
10
|
type: 'Button' | 'Accordion' | 'Input' | 'Select' | 'Switch' | 'ColorPicker' | 'Slider' | 'TextField' | 'Joystick' | 'ProgressBar' | 'Graph' | 'Table' | 'Tabs' | 'FileAttach';
|
|
11
|
-
properties: IAccordionProps | IButtonProps | IInputProps | ISelectProps | ISwitchProps | IColorPickerProps | ISliderProps | ITextFieldProps | IProgressBarProps | IGraphProps | ITableProps<object> | ITabsProps | IFileInputProps;
|
|
11
|
+
properties: IAccordionProps | IButtonProps | IInputProps | ISelectProps | ISwitchProps | IColorPickerProps | ISliderProps | ITextFieldProps | IProgressBarProps | IGraphProps | ITableProps<object> | ITabsProps | IFileInputProps | IJoystickProps;
|
|
12
12
|
position: Position;
|
|
13
13
|
parentId: string;
|
|
14
14
|
}
|
|
@@ -126,6 +126,7 @@ export interface ISwitchProps {
|
|
|
126
126
|
captionLeft?: string;
|
|
127
127
|
captionRight?: string;
|
|
128
128
|
};
|
|
129
|
+
type?: 'horizontal' | 'vertical' | 'checkbox';
|
|
129
130
|
value?: number;
|
|
130
131
|
eventHandler?: IUIComponentHandler;
|
|
131
132
|
onChange?: (value: number) => void;
|
|
@@ -272,3 +273,17 @@ export interface ITabsProps {
|
|
|
272
273
|
apiArray?: UIComponent[];
|
|
273
274
|
Components?: Snippet<[component: UIComponent, fixedHeight: boolean]>;
|
|
274
275
|
}
|
|
276
|
+
export interface IJoystickProps {
|
|
277
|
+
id?: string;
|
|
278
|
+
wrapperClass?: string;
|
|
279
|
+
label?: {
|
|
280
|
+
name?: string;
|
|
281
|
+
class?: string;
|
|
282
|
+
};
|
|
283
|
+
value?: number[];
|
|
284
|
+
limits?: {
|
|
285
|
+
minNum: number;
|
|
286
|
+
maxNum: number;
|
|
287
|
+
}[];
|
|
288
|
+
onUpdate?: (value: number[]) => void;
|
|
289
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "poe-svelte-ui-lib",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.9",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -46,9 +46,9 @@
|
|
|
46
46
|
"@sveltejs/kit": "^2.48.4",
|
|
47
47
|
"@sveltejs/package": "^2.5.4",
|
|
48
48
|
"@sveltejs/vite-plugin-svelte": "^6.2.1",
|
|
49
|
-
"@types/node": "^24.10.
|
|
49
|
+
"@types/node": "^24.10.1",
|
|
50
50
|
"publint": "^0.3.15",
|
|
51
|
-
"svelte": "^5.43.
|
|
51
|
+
"svelte": "^5.43.6",
|
|
52
52
|
"svelte-preprocess": "^6.0.3",
|
|
53
53
|
"vite": "^7.2.2",
|
|
54
54
|
"vite-plugin-compression": "^0.5.1"
|