poe-svelte-ui-lib 1.2.20 → 1.2.22
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/Accordion/Accordion.svelte +1 -1
- package/dist/Accordion/AccordionProps.svelte +3 -2
- package/dist/Button/Button.svelte +1 -1
- package/dist/Button/ButtonProps.svelte +3 -2
- package/dist/ColorPicker/ColorPicker.svelte +1 -1
- package/dist/FileAttach/FileAttach.svelte +9 -2
- package/dist/Graph/Graph.svelte +1 -1
- package/dist/Graph/GraphProps.svelte +3 -2
- package/dist/Input/Input.svelte +2 -2
- package/dist/Input/InputProps.svelte +15 -10
- package/dist/Joystick/Joystick.svelte +44 -30
- package/dist/ProgressBar/ProgressBar.svelte +1 -1
- package/dist/Select/Select.svelte +3 -3
- package/dist/Select/SelectProps.svelte +3 -2
- package/dist/Slider/Slider.svelte +4 -1
- package/dist/Slider/SliderProps.svelte +3 -2
- package/dist/Switch/Switch.svelte +80 -63
- package/dist/Switch/SwitchProps.svelte +242 -28
- package/dist/Table/Table.svelte +1 -1
- package/dist/Table/TableProps.svelte +21 -14
- package/dist/Tabs/Tabs.svelte +2 -2
- package/dist/Tabs/TabsProps.svelte +9 -7
- package/dist/TextField/TextField.svelte +4 -1
- package/dist/TextField/TextFieldProps.svelte +18 -17
- package/dist/locales/translations.js +5 -0
- package/dist/options.d.ts +5 -0
- package/dist/options.js +5 -0
- package/dist/types.d.ts +3 -0
- package/package.json +2 -2
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
</script>
|
|
19
19
|
|
|
20
20
|
<div
|
|
21
|
-
{id}
|
|
21
|
+
id={`${id}-${crypto.randomUUID().slice(0, 6)}`}
|
|
22
22
|
class={twMerge(
|
|
23
23
|
`${outline ? 'border-none' : 'rounded-xl hover:shadow-md'} w-full
|
|
24
24
|
border border-(--border-color) bg-(--container-color) p-0 transition-shadow duration-250`,
|
|
@@ -163,8 +163,9 @@
|
|
|
163
163
|
|
|
164
164
|
<UI.Switch
|
|
165
165
|
label={{ name: $t('constructor.props.open') }}
|
|
166
|
-
value={component.properties.isOpen
|
|
167
|
-
|
|
166
|
+
value={component.properties.isOpen}
|
|
167
|
+
options={[{ id: crypto.randomUUID(), value: 0, class: '' }]}
|
|
168
|
+
onChange={(value) => updateProperty('isOpen', value, component, onPropertyChange)}
|
|
168
169
|
/>
|
|
169
170
|
</div>
|
|
170
171
|
<div class="flex w-1/3 flex-col items-center px-2">
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
|
|
68
68
|
<div class={twMerge(`relative flex w-full flex-col items-center `, wrapperClass)}>
|
|
69
69
|
<button
|
|
70
|
-
{id}
|
|
70
|
+
id={`${id}-${crypto.randomUUID().slice(0, 6)}`}
|
|
71
71
|
class="{twMerge(
|
|
72
72
|
`relative m-0 inline-block w-full items-center rounded-2xl
|
|
73
73
|
px-2 py-1 font-semibold transition duration-200 select-none
|
|
@@ -141,8 +141,9 @@
|
|
|
141
141
|
<UI.Switch
|
|
142
142
|
wrapperClass="bg-blue"
|
|
143
143
|
label={{ name: $t('constructor.props.disabled') }}
|
|
144
|
-
value={component.properties.disabled
|
|
145
|
-
|
|
144
|
+
value={component.properties.disabled}
|
|
145
|
+
options={[{ id: crypto.randomUUID(), value: 0, class: '' }]}
|
|
146
|
+
onChange={(value) => updateProperty('disabled', value, component, onPropertyChange)}
|
|
146
147
|
/>
|
|
147
148
|
</div>
|
|
148
149
|
<div class="flex w-1/3 flex-col px-2">
|
|
@@ -129,7 +129,7 @@
|
|
|
129
129
|
})
|
|
130
130
|
</script>
|
|
131
131
|
|
|
132
|
-
<div {id} class={twMerge(`relative flex w-full flex-col items-center`, wrapperClass)}>
|
|
132
|
+
<div id={`${id}-${crypto.randomUUID().slice(0, 6)}`} class={twMerge(`relative flex w-full flex-col items-center`, wrapperClass)}>
|
|
133
133
|
{#if label.name}
|
|
134
134
|
<h5 class={twMerge(`w-full px-4 text-center`, label.class)}>{label.name}</h5>
|
|
135
135
|
{/if}
|
|
@@ -77,12 +77,19 @@
|
|
|
77
77
|
<span class="text-sm text-gray-500">Image</span>
|
|
78
78
|
{/if}
|
|
79
79
|
</button>
|
|
80
|
-
<input
|
|
80
|
+
<input
|
|
81
|
+
id={`${id}-${crypto.randomUUID().slice(0, 6)}`}
|
|
82
|
+
type="file"
|
|
83
|
+
class="absolute -z-10 h-0 w-0 overflow-hidden opacity-0"
|
|
84
|
+
{accept}
|
|
85
|
+
{disabled}
|
|
86
|
+
onchange={handleFileChange}
|
|
87
|
+
/>
|
|
81
88
|
</div>
|
|
82
89
|
{:else}
|
|
83
90
|
<label class="relative inline-block w-full">
|
|
84
91
|
<input
|
|
85
|
-
{id}
|
|
92
|
+
id={`${id}-${crypto.randomUUID().slice(0, 6)}`}
|
|
86
93
|
type="file"
|
|
87
94
|
class={`h-8.5 w-full rounded-2xl bg-(--back-color) font-semibold shadow-sm transition duration-250 hover:shadow-md
|
|
88
95
|
${disabled ? 'cursor-not-allowed opacity-50' : 'cursor-pointer'} invalid:shadow-[0_0_6px(--red-color) file:h-full file:w-1/3
|
package/dist/Graph/Graph.svelte
CHANGED
|
@@ -218,7 +218,7 @@
|
|
|
218
218
|
}
|
|
219
219
|
</script>
|
|
220
220
|
|
|
221
|
-
<div {id} class={`relative flex w-full flex-col items-center justify-center ${wrapperClass}`}>
|
|
221
|
+
<div id={`${id}-${crypto.randomUUID().slice(0, 6)}`} class={`relative flex w-full flex-col items-center justify-center ${wrapperClass}`}>
|
|
222
222
|
{#if label.name}
|
|
223
223
|
<h5 class={`w-full px-4 text-center ${label.class}`}>{label.name}</h5>
|
|
224
224
|
{/if}
|
|
@@ -67,8 +67,9 @@
|
|
|
67
67
|
<UI.Switch
|
|
68
68
|
wrapperClass="bg-blue"
|
|
69
69
|
label={{ name: $t('constructor.props.istest') }}
|
|
70
|
-
value={component.properties.isTest
|
|
71
|
-
|
|
70
|
+
value={component.properties.isTest}
|
|
71
|
+
options={[{ id: crypto.randomUUID(), value: 0, class: '' }]}
|
|
72
|
+
onChange={(value) => updateProperty('isTest', value, component, onPropertyChange)}
|
|
72
73
|
/>
|
|
73
74
|
</div>
|
|
74
75
|
</div>
|
package/dist/Input/Input.svelte
CHANGED
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
componentClass,
|
|
75
75
|
)}
|
|
76
76
|
style="background: color-mix(in srgb, var(--bg-color), var(--back-color) 70%);"
|
|
77
|
-
{id}
|
|
77
|
+
id={`${id}-${crypto.randomUUID().slice(0, 6)}`}
|
|
78
78
|
{placeholder}
|
|
79
79
|
{disabled}
|
|
80
80
|
autocomplete={help?.autocomplete}
|
|
@@ -99,7 +99,7 @@
|
|
|
99
99
|
componentClass,
|
|
100
100
|
)}
|
|
101
101
|
style="background: color-mix(in srgb, var(--bg-color), var(--back-color) 70%);"
|
|
102
|
-
{id}
|
|
102
|
+
id={`${id}-${crypto.randomUUID().slice(0, 6)}`}
|
|
103
103
|
{disabled}
|
|
104
104
|
{maxlength}
|
|
105
105
|
rows={textareaRows}
|
|
@@ -161,13 +161,15 @@
|
|
|
161
161
|
/>
|
|
162
162
|
<UI.Switch
|
|
163
163
|
label={{ name: $t('constructor.props.readonly') }}
|
|
164
|
-
value={component.properties.readonly
|
|
165
|
-
|
|
164
|
+
value={component.properties.readonly}
|
|
165
|
+
options={[{ id: crypto.randomUUID(), value: 0, class: '' }]}
|
|
166
|
+
onChange={(value) => updateProperty('readonly', value)}
|
|
166
167
|
/>
|
|
167
168
|
<UI.Switch
|
|
168
169
|
label={{ name: $t('constructor.props.copy') }}
|
|
169
|
-
value={component.properties.help.copyButton
|
|
170
|
-
|
|
170
|
+
value={component.properties.help.copyButton}
|
|
171
|
+
options={[{ id: crypto.randomUUID(), value: 0, class: '' }]}
|
|
172
|
+
onChange={(value) => updateProperty('help.copyButton', value)}
|
|
171
173
|
/>
|
|
172
174
|
</div>
|
|
173
175
|
<div class="flex w-1/3 flex-col px-2">
|
|
@@ -320,18 +322,21 @@
|
|
|
320
322
|
|
|
321
323
|
<UI.Switch
|
|
322
324
|
label={{ name: $t('constructor.props.readonly') }}
|
|
323
|
-
value={component.properties.readonly
|
|
324
|
-
|
|
325
|
+
value={component.properties.readonly}
|
|
326
|
+
options={[{ id: crypto.randomUUID(), value: 0, class: '' }]}
|
|
327
|
+
onChange={(value) => updateProperty('readonly', value)}
|
|
325
328
|
/>
|
|
326
329
|
<UI.Switch
|
|
327
330
|
label={{ name: $t('constructor.props.copy') }}
|
|
328
|
-
value={component.properties.help.copyButton
|
|
329
|
-
|
|
331
|
+
value={component.properties.help.copyButton}
|
|
332
|
+
options={[{ id: crypto.randomUUID(), value: 0, class: '' }]}
|
|
333
|
+
onChange={(value) => updateProperty('help.copyButton', value)}
|
|
330
334
|
/>
|
|
331
335
|
<UI.Switch
|
|
332
336
|
label={{ name: $t('constructor.props.disabled') }}
|
|
333
|
-
value={component.properties.disabled
|
|
334
|
-
|
|
337
|
+
value={component.properties.disabled}
|
|
338
|
+
options={[{ id: crypto.randomUUID(), value: 0, class: '' }]}
|
|
339
|
+
onChange={(value) => updateProperty('disabled', value)}
|
|
335
340
|
/>
|
|
336
341
|
</div>
|
|
337
342
|
</div>
|
|
@@ -166,13 +166,14 @@
|
|
|
166
166
|
let angle = 360 / directions.length
|
|
167
167
|
</script>
|
|
168
168
|
|
|
169
|
-
<div {id} class={twMerge(`bg-
|
|
169
|
+
<div id={`${id}-${crypto.randomUUID().slice(0, 6)}`} class={twMerge(`bg-red relative flex w-full flex-col items-center`, wrapperClass)}>
|
|
170
170
|
{#if label.name}
|
|
171
171
|
<h5 class={twMerge(` w-full px-4 text-center`, label.class)}>{label.name}</h5>
|
|
172
172
|
{/if}
|
|
173
173
|
|
|
174
|
-
<div class=" flex items-center justify-center">
|
|
174
|
+
<div class=" flex w-1/2 items-center justify-center">
|
|
175
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
|
+
<!-- Основные кнопки (оси pitch и yaw) -->
|
|
176
177
|
<div class="absolute h-full w-full overflow-hidden rounded-full">
|
|
177
178
|
{#each directions as direction, index}
|
|
178
179
|
<button
|
|
@@ -205,6 +206,7 @@
|
|
|
205
206
|
</button>
|
|
206
207
|
{/each}
|
|
207
208
|
</div>
|
|
209
|
+
<!-- Линии для разделения на сектора -->
|
|
208
210
|
<div class="pointer-events-none absolute h-full w-full overflow-hidden rounded-full">
|
|
209
211
|
{#each directions as direction, index}
|
|
210
212
|
<span
|
|
@@ -216,6 +218,7 @@
|
|
|
216
218
|
</span>
|
|
217
219
|
{/each}
|
|
218
220
|
</div>
|
|
221
|
+
<!-- Кнопка домой -->
|
|
219
222
|
<div
|
|
220
223
|
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"
|
|
221
224
|
>
|
|
@@ -235,6 +238,7 @@
|
|
|
235
238
|
>
|
|
236
239
|
</div>
|
|
237
240
|
</div>
|
|
241
|
+
<!-- Боковые кнопки (ось roll) -->
|
|
238
242
|
<div
|
|
239
243
|
class="absolute flex h-15 w-65 items-center justify-between rounded-full shadow-[0_0_15px_rgb(0_0_0_/0.25)]"
|
|
240
244
|
style="background: color-mix(in srgb, var(--bg-color), var(--shadow-color) 10%)"
|
|
@@ -288,40 +292,50 @@
|
|
|
288
292
|
</div>
|
|
289
293
|
</div>
|
|
290
294
|
|
|
291
|
-
<
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
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
|
|
295
|
+
<div class="absolute right-10 flex items-center">
|
|
296
|
+
<div id={`${id}-${crypto.randomUUID().slice(0, 6)}`} class="flex h-full flex-col justify-center rounded-full p-10">
|
|
297
|
+
{#each sensitivityOptions as option, index}
|
|
298
|
+
<button
|
|
299
|
+
id={crypto.randomUUID()}
|
|
300
|
+
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
301
|
select-none hover:shadow-md
|
|
301
302
|
${
|
|
302
303
|
option === sensitivity && sensitivity !== null
|
|
303
304
|
? 'z-10 py-1 shadow-[0_0_10px_var(--shadow-color)] hover:shadow-[0_0_15px_var(--shadow-color)]'
|
|
304
305
|
: ''
|
|
305
306
|
}
|
|
306
|
-
${sensitivityOptions.length > 0 && index === 0 ? 'rounded-
|
|
307
|
-
index === sensitivityOptions.length - 1 ? 'rounded-
|
|
307
|
+
${sensitivityOptions.length > 0 && index === 0 ? 'rounded-t-2xl' : ''} ${
|
|
308
|
+
index === sensitivityOptions.length - 1 ? 'rounded-b-2xl' : ''
|
|
308
309
|
} bg-(--back-color)`)}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
310
|
+
onclick={() => {
|
|
311
|
+
sensitivity = option
|
|
312
|
+
}}
|
|
313
|
+
>
|
|
314
|
+
<span class="flex flex-row items-center justify-center gap-4">
|
|
315
|
+
{#if option}
|
|
316
|
+
<div class="flex-1">
|
|
317
|
+
{option}
|
|
318
|
+
</div>
|
|
319
|
+
{/if}
|
|
320
|
+
</span>
|
|
321
|
+
</button>
|
|
322
|
+
{/each}
|
|
323
|
+
</div>
|
|
324
|
+
|
|
325
|
+
<div>
|
|
326
|
+
{#each [0, 1, 2] as num}
|
|
327
|
+
<h5 class={twMerge(` w-full px-4 text-center`, label.class)}>{num == 0 ? 'Roll' : num == 1 ? 'Pitch' : 'Yaw'}</h5>
|
|
328
|
+
<input
|
|
329
|
+
class={`w-20 rounded-2xl border border-(--border-color) px-4 py-1 text-center transition-all duration-300 outline-none
|
|
330
|
+
hover:shadow-md
|
|
331
|
+
[&::-webkit-inner-spin-button]:hidden
|
|
332
|
+
[&::-webkit-outer-spin-button]:hidden`}
|
|
333
|
+
style="background: color-mix(in srgb, var(--bg-color), var(--back-color) 70%);"
|
|
334
|
+
value={sensitivity == 0.01 ? value[num].toFixed(2) : sensitivity == 0.1 ? value[num].toFixed(1) : value[num].toFixed(0)}
|
|
335
|
+
id={`${id}-${crypto.randomUUID().slice(0, 6)}`}
|
|
336
|
+
readonly
|
|
337
|
+
/>
|
|
338
|
+
{/each}
|
|
339
|
+
</div>
|
|
322
340
|
</div>
|
|
323
|
-
<!-- {direction.content ? 2 * 6.25 * Math.sin((Math.PI * 65) / 360) : 2 * 6.25 * Math.sin((Math.PI * 25) / 360)} -->
|
|
324
|
-
<!-- angle / 2 + angle * index -->
|
|
325
|
-
<!-- ? 'shadow-[0_-2px_5px_rgb(254_202_202)] '
|
|
326
|
-
: 'shadow-[0_2px_5px_rgb(254_202_202)]'}" -->
|
|
327
341
|
</div>
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
})
|
|
41
41
|
</script>
|
|
42
42
|
|
|
43
|
-
<div {id} class={twMerge(`relative flex w-full flex-col items-center`, wrapperClass)}>
|
|
43
|
+
<div id={`${id}-${crypto.randomUUID().slice(0, 6)}`} class={twMerge(`relative flex w-full flex-col items-center`, wrapperClass)}>
|
|
44
44
|
{#if label.name}
|
|
45
45
|
<h5 class={twMerge(` w-full px-4 text-center`, label.class)}>{label.name}</h5>
|
|
46
46
|
{/if}
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
{/if}
|
|
93
93
|
{#if type === 'select'}
|
|
94
94
|
<button
|
|
95
|
-
{id}
|
|
95
|
+
id={`${id}-${crypto.randomUUID().slice(0, 6)}`}
|
|
96
96
|
value={value?.value ? String(value.value) : ''}
|
|
97
97
|
class={twMerge(
|
|
98
98
|
`w-full rounded-2xl border border-(--border-color) p-1 text-center duration-250
|
|
@@ -133,7 +133,7 @@
|
|
|
133
133
|
</div>
|
|
134
134
|
{/if}
|
|
135
135
|
{:else if type === 'buttons'}
|
|
136
|
-
<div {id} class="flex h-full w-full flex-row justify-center rounded-full border border-(--bg-color)">
|
|
136
|
+
<div id={`${id}-${crypto.randomUUID().slice(0, 6)}`} class="flex h-full w-full flex-row justify-center rounded-full border border-(--bg-color)">
|
|
137
137
|
{#each options as option, index (option.id)}
|
|
138
138
|
<button
|
|
139
139
|
id={option.id}
|
|
@@ -165,7 +165,7 @@
|
|
|
165
165
|
[&::-webkit-inner-spin-button]:hidden [&::-webkit-outer-spin-button]:hidden
|
|
166
166
|
{disabled ? 'cursor-not-allowed opacity-50' : 'cursor-text'} border-(--border-color)"
|
|
167
167
|
style="background: color-mix(in srgb, var(--bg-color), var(--back-color) 70%);"
|
|
168
|
-
{id}
|
|
168
|
+
id={`${id}-${crypto.randomUUID().slice(0, 6)}`}
|
|
169
169
|
{disabled}
|
|
170
170
|
oninput={(e) => handleSearch((e.currentTarget as HTMLInputElement).value)}
|
|
171
171
|
onclick={(e) => {
|
|
@@ -232,8 +232,9 @@
|
|
|
232
232
|
<UI.Switch
|
|
233
233
|
wrapperClass="bg-blue"
|
|
234
234
|
label={{ name: $t('constructor.props.disabled') }}
|
|
235
|
-
value={component.properties.disabled
|
|
236
|
-
|
|
235
|
+
value={component.properties.disabled }
|
|
236
|
+
options={[{ id: crypto.randomUUID(), value: 0, class: '' }]}
|
|
237
|
+
onChange={(value) => updateProperty('disabled', value , component, onPropertyChange)}
|
|
237
238
|
/>
|
|
238
239
|
</div>
|
|
239
240
|
<div class="flex w-1/3 flex-col items-center px-2">
|
|
@@ -98,7 +98,10 @@
|
|
|
98
98
|
{/if}
|
|
99
99
|
|
|
100
100
|
<!-- Слайдер -->
|
|
101
|
-
<div
|
|
101
|
+
<div
|
|
102
|
+
id={`${id}-${crypto.randomUUID().slice(0, 6)}`}
|
|
103
|
+
class="relative flex h-7 w-full justify-center rounded-full {disabled ? 'cursor-not-allowed opacity-50' : ''}"
|
|
104
|
+
>
|
|
102
105
|
{#if isRange}
|
|
103
106
|
<!-- Трек и активная зона -->
|
|
104
107
|
<div
|
|
@@ -138,8 +138,9 @@
|
|
|
138
138
|
<UI.Switch
|
|
139
139
|
wrapperClass="bg-blue"
|
|
140
140
|
label={{ name: $t('constructor.props.disabled') }}
|
|
141
|
-
value={component.properties.disabled
|
|
142
|
-
|
|
141
|
+
value={component.properties.disabled}
|
|
142
|
+
options={[{ id: crypto.randomUUID(), value: 0, class: '' }]}
|
|
143
|
+
onChange={(value) => updateProperty('disabled', value, component, onPropertyChange)}
|
|
143
144
|
/>
|
|
144
145
|
</div>
|
|
145
146
|
<div class="flex w-1/3 flex-col px-2">
|
|
@@ -5,39 +5,42 @@
|
|
|
5
5
|
|
|
6
6
|
let {
|
|
7
7
|
id = crypto.randomUUID(),
|
|
8
|
-
disabled = false,
|
|
9
8
|
wrapperClass = '',
|
|
10
9
|
label = { name: '', class: '', captionLeft: '', captionRight: '' },
|
|
11
10
|
height = '2rem',
|
|
12
11
|
type = 'horizontal',
|
|
12
|
+
options = [],
|
|
13
|
+
bitMode = false,
|
|
13
14
|
value = $bindable(),
|
|
14
15
|
onChange = () => {},
|
|
15
16
|
}: ISwitchProps = $props()
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
let checked = $derived(value === options[1])
|
|
18
|
+
let localOptions = $derived(bitMode ? options : options.slice(0, 1))
|
|
19
19
|
|
|
20
|
-
let
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
let checkedOptions: boolean[] = $derived(
|
|
21
|
+
(() => {
|
|
22
|
+
if (bitMode) {
|
|
23
|
+
return localOptions.map((option) => ((value ?? 0) & (1 << (option?.value ?? 0))) == Math.pow(2, option.value ?? 0))
|
|
24
|
+
} else {
|
|
25
|
+
return [value == 1]
|
|
26
|
+
}
|
|
27
|
+
})(),
|
|
24
28
|
)
|
|
29
|
+
let ID = $derived(`${id}-${crypto.randomUUID().slice(0, 6)}`)
|
|
25
30
|
|
|
26
31
|
$effect(() => {
|
|
27
|
-
if (value === undefined || value === null) value =
|
|
32
|
+
if (value === undefined || value === null) value = 0
|
|
28
33
|
})
|
|
29
34
|
|
|
30
|
-
const handleToggle = () => {
|
|
31
|
-
if (disabled) return
|
|
32
|
-
|
|
35
|
+
const handleToggle = (index: number) => {
|
|
36
|
+
if (localOptions[index].disabled) return
|
|
37
|
+
value = (value ?? 0) ^ (1 << (localOptions[index].value ?? 0))
|
|
33
38
|
|
|
34
|
-
value
|
|
35
|
-
|
|
36
|
-
onChange(newValue)
|
|
39
|
+
onChange(value)
|
|
37
40
|
}
|
|
38
41
|
|
|
39
42
|
const handleCaptionClick = (newValue: number) => {
|
|
40
|
-
if (disabled || value === newValue) return
|
|
43
|
+
if (localOptions[0].disabled || value === newValue) return
|
|
41
44
|
value = newValue
|
|
42
45
|
onChange(newValue)
|
|
43
46
|
}
|
|
@@ -50,67 +53,81 @@
|
|
|
50
53
|
</script>
|
|
51
54
|
|
|
52
55
|
{#if type !== 'checkbox'}
|
|
53
|
-
<div class={twMerge(`
|
|
56
|
+
<div class={twMerge(`relative flex w-full flex-col items-center justify-center`, wrapperClass)}>
|
|
54
57
|
{#if label.name}
|
|
55
58
|
<h5 class={twMerge(`w-full px-4 text-center`, label.class)}>{label.name}</h5>
|
|
56
59
|
{/if}
|
|
60
|
+
<div class="flex w-full flex-wrap justify-center gap-5">
|
|
61
|
+
{#each localOptions as option, index}
|
|
62
|
+
<div class={twMerge(`bg-blue flex flex-col`, option.class)}>
|
|
63
|
+
{#if option.name}
|
|
64
|
+
<span>{option.name}</span>
|
|
65
|
+
{/if}
|
|
66
|
+
|
|
67
|
+
<div class="relative flex w-full grow items-center justify-center bg-transparent">
|
|
68
|
+
{#if type === 'horizontal' && label.captionLeft}
|
|
69
|
+
<button
|
|
70
|
+
class="mr-2 {option.disabled ? 'opacity-60' : 'cursor-pointer'}"
|
|
71
|
+
style="width: {maxCaptionWidth}; text-align: end;"
|
|
72
|
+
onclick={() => handleCaptionClick(0)}>{label.captionLeft}</button
|
|
73
|
+
>
|
|
74
|
+
{/if}
|
|
57
75
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
76
|
+
<label
|
|
77
|
+
class="relative flex items-center justify-between rounded-full border
|
|
78
|
+
{checkedOptions[index] ? 'border-(--bg-color)' : 'border-(--gray-color)'}
|
|
79
|
+
{option.disabled ? 'opacity-60' : ''}"
|
|
80
|
+
>
|
|
81
|
+
<input
|
|
82
|
+
id={`${id}-${crypto.randomUUID().slice(0, 6)}`}
|
|
83
|
+
type="checkbox"
|
|
84
|
+
class="absolute left-1/2 h-full w-full -translate-x-1/2 cursor-pointer appearance-none rounded-md"
|
|
85
|
+
checked={checkedOptions[index]}
|
|
86
|
+
disabled={option.disabled}
|
|
87
|
+
onchange={() => handleToggle(index)}
|
|
88
|
+
/>
|
|
89
|
+
<span
|
|
90
|
+
class="relative flex items-center rounded-full transition-all duration-250
|
|
91
|
+
{checkedOptions[index] ? 'bg-(--bg-color)' : 'bg-(--gray-color)'}
|
|
92
|
+
{option.disabled ? '' : 'cursor-pointer'}"
|
|
93
|
+
style="{type === 'horizontal' ? 'width' : 'height'}: {`calc(${height} * 2)`}; {type === 'horizontal' ? 'height' : 'width'}: {height};"
|
|
94
|
+
>
|
|
95
|
+
<span
|
|
96
|
+
class="absolute rounded-full bg-(--back-color) transition-all duration-250
|
|
97
|
+
{option.disabled ? 'opacity-60' : 'cursor-pointer'}"
|
|
98
|
+
style="width: {`calc(${height} * 0.8)`}; height: {`calc(${height} * 0.8)`}; margin: 0 {`calc(${height} * 0.1)`}; transform: {checkedOptions[
|
|
99
|
+
index
|
|
100
|
+
]
|
|
101
|
+
? `${type === 'horizontal' ? `translateX(calc(${height}))` : `translateY(calc(-${height}/2))`}`
|
|
102
|
+
: `${type === 'horizontal' ? 'translateX(0)' : `translateY(calc(${height}/2))`}`};"
|
|
103
|
+
></span>
|
|
104
|
+
</span>
|
|
105
|
+
</label>
|
|
66
106
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
{disabled}
|
|
78
|
-
onchange={handleToggle}
|
|
79
|
-
/>
|
|
80
|
-
<span
|
|
81
|
-
class="relative flex items-center rounded-full transition-all duration-250
|
|
82
|
-
{checked ? 'bg-(--bg-color)' : 'bg-(--gray-color)'}
|
|
83
|
-
{disabled ? '' : 'cursor-pointer'}"
|
|
84
|
-
style="{type === 'horizontal' ? 'width' : 'height'}: {`calc(${height} * 2)`}; {type === 'horizontal' ? 'height' : 'width'}: {height};"
|
|
85
|
-
>
|
|
86
|
-
<span
|
|
87
|
-
class="absolute rounded-full bg-(--back-color) transition-all duration-250
|
|
88
|
-
{disabled ? 'opacity-60' : 'cursor-pointer'}"
|
|
89
|
-
style="width: {`calc(${height} * 0.8)`}; height: {`calc(${height} * 0.8)`}; margin: 0 {`calc(${height} * 0.1)`}; transform: {knobTransform};"
|
|
90
|
-
></span>
|
|
91
|
-
</span>
|
|
92
|
-
</label>
|
|
93
|
-
{#if type === 'horizontal'}
|
|
94
|
-
<button
|
|
95
|
-
class="ml-2 {disabled ? 'opacity-60' : 'cursor-pointer'}"
|
|
96
|
-
style="width: {maxCaptionWidth}; text-align: start;"
|
|
97
|
-
onclick={() => handleCaptionClick(2)}>{label.captionRight}</button
|
|
98
|
-
>
|
|
99
|
-
{/if}
|
|
107
|
+
{#if type === 'horizontal' && label.captionRight}
|
|
108
|
+
<button
|
|
109
|
+
class="ml-2 {option.disabled ? 'opacity-60' : 'cursor-pointer'}"
|
|
110
|
+
style="width: {maxCaptionWidth}; text-align: start;"
|
|
111
|
+
onclick={() => handleCaptionClick(1)}>{label.captionRight}</button
|
|
112
|
+
>
|
|
113
|
+
{/if}
|
|
114
|
+
</div>
|
|
115
|
+
</div>
|
|
116
|
+
{/each}
|
|
100
117
|
</div>
|
|
101
118
|
</div>
|
|
102
119
|
{:else}
|
|
103
120
|
<div class={twMerge('bg-blue m-1 flex items-center justify-center gap-2', wrapperClass)}>
|
|
104
121
|
<input
|
|
105
|
-
{
|
|
122
|
+
id={ID}
|
|
106
123
|
type="checkbox"
|
|
107
|
-
bind:checked
|
|
108
|
-
{disabled}
|
|
124
|
+
bind:checked={checkedOptions[0]}
|
|
125
|
+
disabled={localOptions[0].disabled}
|
|
109
126
|
class="
|
|
110
127
|
relative size-8 cursor-pointer appearance-none rounded-2xl border border-(--bg-color)
|
|
111
128
|
bg-white transition duration-300 after:origin-bottom-left after:opacity-0
|
|
112
129
|
checked:border-(--bg-color)
|
|
113
|
-
checked:bg-(--bg-color) checked:after:absolute checked:after:left-[5.5px]
|
|
130
|
+
checked:bg-(--bg-color) checked:after:absolute checked:after:-top-px checked:after:left-[5.5px]
|
|
114
131
|
checked:after:h-[13.5px] checked:after:w-[7.5px] checked:after:rotate-43
|
|
115
132
|
checked:after:border-2 checked:after:border-t-0
|
|
116
133
|
checked:after:border-l-0 checked:after:border-solid
|
|
@@ -118,9 +135,9 @@
|
|
|
118
135
|
checked:after:content-[''] hover:shadow-md
|
|
119
136
|
disabled:cursor-not-allowed disabled:opacity-70
|
|
120
137
|
"
|
|
121
|
-
onchange={handleToggle}
|
|
138
|
+
onchange={() => handleToggle(0)}
|
|
122
139
|
/>
|
|
123
|
-
<label for={
|
|
140
|
+
<label for={ID} class={twMerge("{disabled ? 'cursor-not-allowed opacity-70' : 'cursor-pointer'} ml-1 select-none", label.class)}>
|
|
124
141
|
{label.name}
|
|
125
142
|
</label>
|
|
126
143
|
</div>
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
import * as UI from '..'
|
|
6
6
|
import { optionsStore } from '../options'
|
|
7
7
|
import { twMerge } from 'tailwind-merge'
|
|
8
|
+
import ButtonDelete from '../libIcons/ButtonDelete.svelte'
|
|
9
|
+
import ButtonAdd from '../libIcons/ButtonAdd.svelte'
|
|
8
10
|
|
|
9
11
|
const {
|
|
10
12
|
component,
|
|
@@ -47,41 +49,160 @@
|
|
|
47
49
|
updateProperty('eventHandler.Argument', option.value as string, component, onPropertyChange)
|
|
48
50
|
}}
|
|
49
51
|
/>
|
|
52
|
+
{#if !component.properties.bitMode}
|
|
53
|
+
<UI.Select
|
|
54
|
+
wrapperClass="!h-14"
|
|
55
|
+
label={{ name: $t('constructor.props.type') }}
|
|
56
|
+
type="buttons"
|
|
57
|
+
options={$optionsStore.SWITCH_OPTIONS}
|
|
58
|
+
value={$optionsStore.SWITCH_OPTIONS.find((option) => option.value == component.properties.type)}
|
|
59
|
+
onUpdate={(option) => updateProperty('type', option.value as string, component, onPropertyChange)}
|
|
60
|
+
/>
|
|
61
|
+
{/if}
|
|
50
62
|
</div>
|
|
51
|
-
|
|
52
|
-
<
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
63
|
+
{#if !component.properties.bitMode}
|
|
64
|
+
<div class="flex w-1/3 flex-col px-2">
|
|
65
|
+
<UI.Input
|
|
66
|
+
label={{ name: $t('constructor.props.caption.left') }}
|
|
67
|
+
value={component.properties.label.captionLeft}
|
|
68
|
+
onUpdate={(value) => updateProperty('label.captionLeft', value as string, component, onPropertyChange)}
|
|
69
|
+
/>
|
|
70
|
+
<UI.Input
|
|
71
|
+
label={{ name: $t('constructor.props.caption.right') }}
|
|
72
|
+
value={component.properties.label.captionRight}
|
|
73
|
+
onUpdate={(value) => updateProperty('label.captionRight', value as string, component, onPropertyChange)}
|
|
74
|
+
/>
|
|
75
|
+
|
|
76
|
+
<UI.Switch
|
|
77
|
+
wrapperClass="bg-blue"
|
|
78
|
+
label={{ name: $t('constructor.props.disabled') }}
|
|
79
|
+
value={component.properties.options[0].disabled}
|
|
80
|
+
options={[{ id: crypto.randomUUID(), value: 0, class: '' }]}
|
|
81
|
+
onChange={(value) => {
|
|
82
|
+
const options = [...(component.properties?.options || [])]
|
|
83
|
+
options[0]['disabled'] = value
|
|
84
|
+
updateProperty('options', options, component, onPropertyChange)
|
|
85
|
+
}}
|
|
86
|
+
/>
|
|
87
|
+
</div>
|
|
88
|
+
{/if}
|
|
69
89
|
<div class="flex w-1/3 flex-col px-2">
|
|
70
90
|
<UI.Input
|
|
71
91
|
label={{ name: $t('constructor.props.label') }}
|
|
72
92
|
value={component.properties.label.name}
|
|
73
93
|
onUpdate={(value) => updateProperty('label.name', value as string, component, onPropertyChange)}
|
|
74
94
|
/>
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
95
|
+
{#if !component.properties.bitMode}
|
|
96
|
+
<UI.Select
|
|
97
|
+
wrapperClass="!h-14"
|
|
98
|
+
label={{ name: $t('constructor.props.colors') }}
|
|
99
|
+
type="buttons"
|
|
100
|
+
options={$optionsStore.COLOR_OPTIONS.filter((option) => option.value !== 'bg-max' && option.value !== 'bg-gray')}
|
|
101
|
+
value={initialColor}
|
|
102
|
+
onUpdate={(option) => {
|
|
103
|
+
const options = [...(component.properties?.options || [])]
|
|
104
|
+
options[0]['class'] = option.value
|
|
105
|
+
updateProperty('options', options, component, onPropertyChange)
|
|
106
|
+
}}
|
|
107
|
+
/>
|
|
108
|
+
{/if}
|
|
109
|
+
<UI.Switch
|
|
110
|
+
wrapperClass="bg-blue"
|
|
111
|
+
label={{ name: $t('constructor.props.bitmode') }}
|
|
112
|
+
value={component.properties.bitMode}
|
|
113
|
+
options={[{ id: crypto.randomUUID(), value: 0, class: '' }]}
|
|
114
|
+
onChange={(value) => {
|
|
115
|
+
updateProperty('bitMode', value, component, onPropertyChange)
|
|
116
|
+
updateProperty('value', 1, component, onPropertyChange)
|
|
117
|
+
}}
|
|
82
118
|
/>
|
|
83
119
|
</div>
|
|
84
120
|
</div>
|
|
121
|
+
{#if component.properties.bitMode}
|
|
122
|
+
<hr class="border-gray-400" />
|
|
123
|
+
|
|
124
|
+
<!-- Настройки опций -->
|
|
125
|
+
<div class="space-y-4">
|
|
126
|
+
<div class="m-0 flex items-center justify-center gap-2">
|
|
127
|
+
<h4>{$t('constructor.props.bits.title')}</h4>
|
|
128
|
+
<UI.Button
|
|
129
|
+
wrapperClass="w-8"
|
|
130
|
+
content={{ icon: ButtonAdd }}
|
|
131
|
+
onClick={() => {
|
|
132
|
+
const newOption: ISelectOption = {
|
|
133
|
+
id: crypto.randomUUID(),
|
|
134
|
+
name: `Option ${component.properties?.options.length + 1}`,
|
|
135
|
+
value: component.properties?.options.length,
|
|
136
|
+
class: 'bg-blue',
|
|
137
|
+
}
|
|
138
|
+
const options = [...(component.properties?.options || []), newOption]
|
|
139
|
+
updateProperty('options', options, component, onPropertyChange)
|
|
140
|
+
}}
|
|
141
|
+
/>
|
|
142
|
+
</div>
|
|
143
|
+
|
|
144
|
+
{#each component.properties.options || [] as option, index (option.id)}
|
|
145
|
+
<div class="m-0 flex items-end justify-around gap-2 border-gray-400">
|
|
146
|
+
<UI.Input
|
|
147
|
+
label={{ name: $t('constructor.props.optionname') }}
|
|
148
|
+
wrapperClass="!w-3/10"
|
|
149
|
+
value={option.name}
|
|
150
|
+
onUpdate={(value) => {
|
|
151
|
+
const options = [...(component.properties?.options || [])]
|
|
152
|
+
options[index]['name'] = value
|
|
153
|
+
updateProperty('options', options, component, onPropertyChange)
|
|
154
|
+
}}
|
|
155
|
+
/>
|
|
156
|
+
<UI.Input
|
|
157
|
+
label={{ name: $t('constructor.props.optionvalue') }}
|
|
158
|
+
wrapperClass="!w-3/10"
|
|
159
|
+
value={option.value}
|
|
160
|
+
type="number"
|
|
161
|
+
number={{ minNum: 0, maxNum: 31, step: 1 }}
|
|
162
|
+
onUpdate={(value) => {
|
|
163
|
+
const options = [...(component.properties?.options || [])]
|
|
164
|
+
options[index]['value'] = value
|
|
165
|
+
updateProperty('options', options, component, onPropertyChange)
|
|
166
|
+
}}
|
|
167
|
+
/>
|
|
168
|
+
<UI.Select
|
|
169
|
+
wrapperClass="w-80 h-14.5"
|
|
170
|
+
label={{ name: $t('constructor.props.colors') }}
|
|
171
|
+
type="buttons"
|
|
172
|
+
options={$optionsStore.COLOR_OPTIONS.filter((option) => option.value !== 'bg-max' && option.value !== 'bg-gray')}
|
|
173
|
+
value={$optionsStore.COLOR_OPTIONS.find((c) =>
|
|
174
|
+
(c.value as string).includes(option.class.split(' ').find((cls: string) => cls.startsWith('bg-'))),
|
|
175
|
+
)}
|
|
176
|
+
onUpdate={(option) => {
|
|
177
|
+
const options = [...(component.properties?.options || [])]
|
|
178
|
+
options[index]['class'] = option.value
|
|
179
|
+
updateProperty('options', options, component, onPropertyChange)
|
|
180
|
+
}}
|
|
181
|
+
/>
|
|
182
|
+
<UI.Switch
|
|
183
|
+
wrapperClass=" w-1/10 bg-blue"
|
|
184
|
+
label={{ name: $t('constructor.props.disabled') }}
|
|
185
|
+
value={option.disabled}
|
|
186
|
+
options={[{ id: crypto.randomUUID(), value: 0, class: '' }]}
|
|
187
|
+
onChange={(value) => {
|
|
188
|
+
const options = [...(component.properties?.options || [])]
|
|
189
|
+
options[index]['disabled'] = value
|
|
190
|
+
updateProperty('options', options, component, onPropertyChange)
|
|
191
|
+
}}
|
|
192
|
+
/>
|
|
193
|
+
<UI.Button
|
|
194
|
+
wrapperClass="w-8"
|
|
195
|
+
content={{ icon: ButtonDelete }}
|
|
196
|
+
onClick={() => {
|
|
197
|
+
const options = [...(component.properties?.options || [])]
|
|
198
|
+
options.splice(index, 1)
|
|
199
|
+
updateProperty('options', options, component, onPropertyChange)
|
|
200
|
+
}}
|
|
201
|
+
/>
|
|
202
|
+
</div>
|
|
203
|
+
{/each}
|
|
204
|
+
</div>
|
|
205
|
+
{/if}
|
|
85
206
|
{:else}
|
|
86
207
|
<div class="relative flex flex-row items-start justify-center">
|
|
87
208
|
<!-- Сообщение для отправки в ws по нажатию кнопки -->
|
|
@@ -128,6 +249,14 @@
|
|
|
128
249
|
value={component.properties.label.captionRight}
|
|
129
250
|
onUpdate={(value) => updateProperty('label.captionRight', value as string, component, onPropertyChange)}
|
|
130
251
|
/>
|
|
252
|
+
<UI.Select
|
|
253
|
+
wrapperClass="!h-14"
|
|
254
|
+
label={{ name: $t('constructor.props.type') }}
|
|
255
|
+
type="buttons"
|
|
256
|
+
options={$optionsStore.SWITCH_OPTIONS}
|
|
257
|
+
value={$optionsStore.SWITCH_OPTIONS.find((option) => option.value == component.properties.type)}
|
|
258
|
+
onUpdate={(option) => updateProperty('type', option.value as string, component, onPropertyChange)}
|
|
259
|
+
/>
|
|
131
260
|
</div>
|
|
132
261
|
<div class="flex w-1/3 flex-col px-2">
|
|
133
262
|
<UI.Input
|
|
@@ -139,15 +268,100 @@
|
|
|
139
268
|
label={{ name: $t('constructor.props.value') }}
|
|
140
269
|
value={component.properties.value}
|
|
141
270
|
type="number"
|
|
142
|
-
number={{ minNum:
|
|
271
|
+
number={{ minNum: 0, maxNum: component.properties.bitMode ? Math.pow(2, 32) : 1, step: 1 }}
|
|
143
272
|
onUpdate={(value) => updateProperty('value', value as number, component, onPropertyChange)}
|
|
144
273
|
/>
|
|
145
274
|
<UI.Switch
|
|
146
275
|
wrapperClass="bg-blue"
|
|
147
276
|
label={{ name: $t('constructor.props.disabled') }}
|
|
148
|
-
value={component.properties.disabled
|
|
149
|
-
|
|
277
|
+
value={component.properties.disabled}
|
|
278
|
+
options={[{ id: crypto.randomUUID(), value: 0, class: '' }]}
|
|
279
|
+
onChange={(value) => updateProperty('disabled', value, component, onPropertyChange)}
|
|
280
|
+
/>
|
|
281
|
+
<UI.Switch
|
|
282
|
+
wrapperClass="bg-blue"
|
|
283
|
+
label={{ name: $t('constructor.props.bitmode') }}
|
|
284
|
+
value={component.properties.bitMode}
|
|
285
|
+
options={[{ id: crypto.randomUUID(), value: 0, class: '' }]}
|
|
286
|
+
onChange={(value) => {
|
|
287
|
+
updateProperty('bitMode', value, component, onPropertyChange)
|
|
288
|
+
updateProperty('value', 1, component, onPropertyChange)
|
|
289
|
+
}}
|
|
150
290
|
/>
|
|
151
291
|
</div>
|
|
152
292
|
</div>
|
|
293
|
+
{#if component.properties.bitMode}
|
|
294
|
+
<hr class="border-gray-400" />
|
|
295
|
+
|
|
296
|
+
<!-- Настройки опций -->
|
|
297
|
+
<div class="space-y-4">
|
|
298
|
+
<div class="m-0 flex items-center justify-center gap-2">
|
|
299
|
+
<h4>{$t('constructor.props.bits.title')}</h4>
|
|
300
|
+
<UI.Button
|
|
301
|
+
wrapperClass="w-8"
|
|
302
|
+
content={{ icon: ButtonAdd }}
|
|
303
|
+
onClick={() => {
|
|
304
|
+
const newOption: ISelectOption = {
|
|
305
|
+
id: crypto.randomUUID(),
|
|
306
|
+
name: `Option ${component.properties?.options.length + 1}`,
|
|
307
|
+
value: component.properties?.options.length,
|
|
308
|
+
class: 'bg-blue',
|
|
309
|
+
}
|
|
310
|
+
const options = [...(component.properties?.options || []), newOption]
|
|
311
|
+
updateProperty('options', options, component, onPropertyChange)
|
|
312
|
+
}}
|
|
313
|
+
/>
|
|
314
|
+
</div>
|
|
315
|
+
|
|
316
|
+
{#each component.properties.options || [] as option, index (option.id)}
|
|
317
|
+
<div class="m-0 flex items-end justify-around gap-2 border-gray-400">
|
|
318
|
+
<UI.Input
|
|
319
|
+
label={{ name: $t('constructor.props.optionname') }}
|
|
320
|
+
wrapperClass="!w-3/10"
|
|
321
|
+
value={option.name}
|
|
322
|
+
onUpdate={(value) => {
|
|
323
|
+
const options = [...(component.properties?.options || [])]
|
|
324
|
+
options[index]['name'] = value
|
|
325
|
+
updateProperty('options', options, component, onPropertyChange)
|
|
326
|
+
}}
|
|
327
|
+
/>
|
|
328
|
+
<UI.Input
|
|
329
|
+
label={{ name: $t('constructor.props.optionvalue') }}
|
|
330
|
+
wrapperClass="!w-3/10"
|
|
331
|
+
value={option.value}
|
|
332
|
+
type="number"
|
|
333
|
+
number={{ minNum: 0, maxNum: 31, step: 1 }}
|
|
334
|
+
onUpdate={(value) => {
|
|
335
|
+
const options = [...(component.properties?.options || [])]
|
|
336
|
+
options[index]['value'] = value
|
|
337
|
+
updateProperty('options', options, component, onPropertyChange)
|
|
338
|
+
}}
|
|
339
|
+
/>
|
|
340
|
+
<UI.Select
|
|
341
|
+
wrapperClass="w-80 h-14.5"
|
|
342
|
+
label={{ name: $t('constructor.props.colors') }}
|
|
343
|
+
type="buttons"
|
|
344
|
+
options={$optionsStore.COLOR_OPTIONS.filter((option) => option.value !== 'bg-max' && option.value !== 'bg-gray')}
|
|
345
|
+
value={$optionsStore.COLOR_OPTIONS.find((c) =>
|
|
346
|
+
(c.value as string).includes(option.class.split(' ').find((cls: string) => cls.startsWith('bg-'))),
|
|
347
|
+
)}
|
|
348
|
+
onUpdate={(option) => {
|
|
349
|
+
const options = [...(component.properties?.options || [])]
|
|
350
|
+
options[index]['class'] = option.value
|
|
351
|
+
updateProperty('options', options, component, onPropertyChange)
|
|
352
|
+
}}
|
|
353
|
+
/>
|
|
354
|
+
<UI.Button
|
|
355
|
+
wrapperClass="w-8"
|
|
356
|
+
content={{ icon: ButtonDelete }}
|
|
357
|
+
onClick={() => {
|
|
358
|
+
const options = [...(component.properties?.options || [])]
|
|
359
|
+
options.splice(index, 1)
|
|
360
|
+
updateProperty('options', options, component, onPropertyChange)
|
|
361
|
+
}}
|
|
362
|
+
/>
|
|
363
|
+
</div>
|
|
364
|
+
{/each}
|
|
365
|
+
</div>
|
|
366
|
+
{/if}
|
|
153
367
|
{/if}
|
package/dist/Table/Table.svelte
CHANGED
|
@@ -155,7 +155,7 @@
|
|
|
155
155
|
})
|
|
156
156
|
</script>
|
|
157
157
|
|
|
158
|
-
<div {id} class={twMerge(`bg-blue flex h-full w-full flex-col overflow-hidden`, wrapperClass)}>
|
|
158
|
+
<div id={`${id}-${crypto.randomUUID().slice(0, 6)}`} class={twMerge(`bg-blue flex h-full w-full flex-col overflow-hidden`, wrapperClass)}>
|
|
159
159
|
{#if label.name}
|
|
160
160
|
<h5 class={twMerge(`w-full px-4 text-center`, label.class)}>{label.name}</h5>
|
|
161
161
|
{/if}
|
|
@@ -97,8 +97,9 @@
|
|
|
97
97
|
/>
|
|
98
98
|
<UI.Switch
|
|
99
99
|
label={{ name: $t('constructor.props.outline') }}
|
|
100
|
-
value={component.properties.outline
|
|
101
|
-
|
|
100
|
+
value={component.properties.outline}
|
|
101
|
+
options={[{ id: crypto.randomUUID(), value: 0, class: '' }]}
|
|
102
|
+
onChange={(value) => updateProperty('outline', value, component, onPropertyChange)}
|
|
102
103
|
/>
|
|
103
104
|
</div>
|
|
104
105
|
<div class="flex w-1/3 flex-col px-2">
|
|
@@ -168,14 +169,16 @@
|
|
|
168
169
|
<UI.Switch
|
|
169
170
|
wrapperClass="w-2/10"
|
|
170
171
|
label={{ name: $t('constructor.props.table.columns.sortable') }}
|
|
171
|
-
|
|
172
|
-
|
|
172
|
+
options={[{ id: crypto.randomUUID(), value: 0, class: '' }]}
|
|
173
|
+
value={column.sortable}
|
|
174
|
+
onChange={(value) => updateTableHeader(columnIndex, 'sortable', value)}
|
|
173
175
|
/>
|
|
174
176
|
<UI.Switch
|
|
175
177
|
wrapperClass="w-2/10"
|
|
176
178
|
label={{ name: $t('constructor.props.copy') }}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
+
options={[{ id: crypto.randomUUID(), value: 0, class: '' }]}
|
|
180
|
+
value={column.overflow?.copy}
|
|
181
|
+
onChange={(value) => updateTableHeader(columnIndex, 'overflow', { copy: value })}
|
|
179
182
|
/>
|
|
180
183
|
<UI.Button
|
|
181
184
|
wrapperClass="w-8"
|
|
@@ -302,8 +305,9 @@
|
|
|
302
305
|
/>
|
|
303
306
|
<UI.Switch
|
|
304
307
|
label={{ name: $t('constructor.props.outline') }}
|
|
305
|
-
value={component.properties.outline
|
|
306
|
-
|
|
308
|
+
value={component.properties.outline}
|
|
309
|
+
options={[{ id: crypto.randomUUID(), value: 0, class: '' }]}
|
|
310
|
+
onChange={(value) => updateProperty('outline', value, component, onPropertyChange)}
|
|
307
311
|
/>
|
|
308
312
|
</div>
|
|
309
313
|
</div>
|
|
@@ -370,14 +374,16 @@
|
|
|
370
374
|
<UI.Switch
|
|
371
375
|
label={{ name: $t('constructor.props.table.columns.sortable'), class: 'px-0' }}
|
|
372
376
|
wrapperClass="w-30"
|
|
373
|
-
|
|
374
|
-
|
|
377
|
+
options={[{ id: crypto.randomUUID(), value: 0, class: '' }]}
|
|
378
|
+
value={column.sortable}
|
|
379
|
+
onChange={(value) => updateTableHeader(columnIndex, 'sortable', value)}
|
|
375
380
|
/>
|
|
376
381
|
<UI.Switch
|
|
377
382
|
label={{ name: $t('constructor.props.copy'), class: 'px-0' }}
|
|
378
383
|
wrapperClass="w-30"
|
|
379
|
-
|
|
380
|
-
|
|
384
|
+
options={[{ id: crypto.randomUUID(), value: 0, class: '' }]}
|
|
385
|
+
value={column.overflow?.copy}
|
|
386
|
+
onChange={(value) => updateTableHeader(columnIndex, 'overflow', { copy: value, truncated: column.overflow?.truncated })}
|
|
381
387
|
/>
|
|
382
388
|
<UI.Button
|
|
383
389
|
wrapperClass="w-8"
|
|
@@ -414,8 +420,9 @@
|
|
|
414
420
|
<UI.Switch
|
|
415
421
|
wrapperClass="w-2/10"
|
|
416
422
|
label={{ name: $t('constructor.props.table.columns.truncated') }}
|
|
417
|
-
|
|
418
|
-
|
|
423
|
+
options={[{ id: crypto.randomUUID(), value: 0, class: '' }]}
|
|
424
|
+
value={column.overflow?.truncated}
|
|
425
|
+
onChange={(value) => updateTableHeader(columnIndex, 'overflow', { truncated: value, copy: column.overflow?.copy })}
|
|
419
426
|
/>
|
|
420
427
|
<div class="relative mt-6 flex w-full gap-2">
|
|
421
428
|
<UI.Button
|
package/dist/Tabs/Tabs.svelte
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
let currentTabIndex: number = $state(activeTab)
|
|
27
27
|
</script>
|
|
28
28
|
|
|
29
|
-
<div {id} class="w-full rounded-2xl bg-(--back-color)">
|
|
29
|
+
<div id={`${id}-${crypto.randomUUID().slice(0, 6)}`} class="w-full rounded-2xl bg-(--back-color)">
|
|
30
30
|
<!-- Вкладки -->
|
|
31
31
|
<div
|
|
32
32
|
class="{twMerge('bg-blue sticky top-0 z-50 flex h-fit items-center overflow-x-auto rounded-t-2xl px-1', wrapperClass)}
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
{@render Components(comp, false)}
|
|
76
76
|
{/each}
|
|
77
77
|
{:else if children}
|
|
78
|
-
{@render children(items[
|
|
78
|
+
{@render children(items[currentTabIndex])}
|
|
79
79
|
{:else}
|
|
80
80
|
{@render items[currentTabIndex]?.children?.()}
|
|
81
81
|
{/if}
|
|
@@ -52,9 +52,9 @@
|
|
|
52
52
|
const initialWidth = $derived(() => {
|
|
53
53
|
let width = component.properties.items.find((item: ISelectOption) => item.class?.split(' ').find((cls: string) => cls.startsWith('w-')))
|
|
54
54
|
if (!width) {
|
|
55
|
-
return
|
|
56
|
-
} else if (width.class.includes('w-auto')) return
|
|
57
|
-
else return
|
|
55
|
+
return 0
|
|
56
|
+
} else if (width.class.includes('w-auto')) return 0
|
|
57
|
+
else return 1
|
|
58
58
|
})
|
|
59
59
|
</script>
|
|
60
60
|
|
|
@@ -107,10 +107,11 @@
|
|
|
107
107
|
captionRight: $t('constructor.props.equal'),
|
|
108
108
|
}}
|
|
109
109
|
value={initialWidth()}
|
|
110
|
+
options={[{ id: crypto.randomUUID(), value: 0, class: '' }]}
|
|
110
111
|
onChange={(value) => {
|
|
111
112
|
component.properties.items.forEach((_item: any, index: number) => {
|
|
112
113
|
const items = [...(component.properties?.items || [])]
|
|
113
|
-
items[index]['class'] = twMerge(items[index].class, value
|
|
114
|
+
items[index]['class'] = twMerge(items[index].class, value ? `w-[${(1 / items.length) * 100}%]` : 'w-auto')
|
|
114
115
|
updateProperty('items', items, component, onPropertyChange)
|
|
115
116
|
})
|
|
116
117
|
}}
|
|
@@ -132,7 +133,7 @@
|
|
|
132
133
|
}
|
|
133
134
|
const items = [...(component.properties?.items || []), newItem]
|
|
134
135
|
items.forEach((_item: any, index: number) => {
|
|
135
|
-
items[index]['class'] = twMerge(items[index].class, initialWidth()
|
|
136
|
+
items[index]['class'] = twMerge(items[index].class, initialWidth() ? `w-[${(1 / items.length) * 100}%]` : 'w-auto')
|
|
136
137
|
updateProperty('items', items, component, onPropertyChange)
|
|
137
138
|
})
|
|
138
139
|
}}
|
|
@@ -176,7 +177,7 @@
|
|
|
176
177
|
const items = [...(component.properties?.items || [])]
|
|
177
178
|
items.splice(index, 1)
|
|
178
179
|
items.forEach((_item: any, index: number) => {
|
|
179
|
-
items[index]['class'] = twMerge(items[index].class, initialWidth()
|
|
180
|
+
items[index]['class'] = twMerge(items[index].class, initialWidth() ? `w-[${(1 / items.length) * 100}%]` : 'w-auto')
|
|
180
181
|
updateProperty('items', items, component, onPropertyChange)
|
|
181
182
|
})
|
|
182
183
|
updateProperty('items', items, component, onPropertyChange)
|
|
@@ -289,6 +290,7 @@
|
|
|
289
290
|
captionRight: $t('constructor.props.equal'),
|
|
290
291
|
}}
|
|
291
292
|
value={initialWidth()}
|
|
293
|
+
options={[{ id: crypto.randomUUID(), value: 0, class: '' }]}
|
|
292
294
|
onChange={(value) => {
|
|
293
295
|
if (value === 2) {
|
|
294
296
|
component.properties.items.forEach((_item: any, index: number) => {
|
|
@@ -319,7 +321,7 @@
|
|
|
319
321
|
let tabWidth = Math.max(...Array.from(document.body.querySelectorAll('.tab')).map((item) => (item as HTMLElement).offsetWidth))
|
|
320
322
|
const newItem: { name: string; icon: string; class: string } = {
|
|
321
323
|
name: `Tab ${component.properties?.items.length + 1}`,
|
|
322
|
-
class: `w-${initialWidth()
|
|
324
|
+
class: `w-${initialWidth() ? `[${tabWidth}px]` : 'auto'} text-${initialColor?.value.slice(3)}-500 ${initialPosition?.value}`,
|
|
323
325
|
icon: '',
|
|
324
326
|
}
|
|
325
327
|
const items = [...(component.properties?.items || []), newItem]
|
|
@@ -13,7 +13,10 @@
|
|
|
13
13
|
} as const
|
|
14
14
|
</script>
|
|
15
15
|
|
|
16
|
-
<div
|
|
16
|
+
<div
|
|
17
|
+
id={`${id}-${crypto.randomUUID().slice(0, 6)}`}
|
|
18
|
+
class={twMerge(`relative flex w-full flex-col items-center ${background ? 'rounded-2xl bg-(--back-color) px-6 py-2' : ''}`, wrapperClass)}
|
|
19
|
+
>
|
|
17
20
|
<p class={twMerge(`w-full text-center ${textSize[content.size ?? 'base']}`, content.class)}>
|
|
18
21
|
{content.name}
|
|
19
22
|
</p>
|
|
@@ -79,30 +79,28 @@
|
|
|
79
79
|
<div class="flex w-1/3 flex-col px-2">
|
|
80
80
|
<UI.Switch
|
|
81
81
|
label={{ name: $t('constructor.props.bold') }}
|
|
82
|
-
value={initialBold
|
|
82
|
+
value={initialBold}
|
|
83
|
+
options={[{ id: crypto.randomUUID(), value: 0, class: '' }]}
|
|
83
84
|
onChange={(value) =>
|
|
84
85
|
updateProperty(
|
|
85
86
|
'content.class',
|
|
86
|
-
`${component.properties.content.class} ${value
|
|
87
|
+
`${component.properties.content.class} ${value ? 'font-bold' : 'font-normal'}`,
|
|
87
88
|
component,
|
|
88
89
|
onPropertyChange,
|
|
89
90
|
)}
|
|
90
91
|
/>
|
|
91
92
|
<UI.Switch
|
|
92
93
|
label={{ name: $t('constructor.props.italic') }}
|
|
93
|
-
value={initialItalic
|
|
94
|
+
value={initialItalic}
|
|
95
|
+
options={[{ id: crypto.randomUUID(), value: 0, class: '' }]}
|
|
94
96
|
onChange={(value) =>
|
|
95
|
-
updateProperty(
|
|
96
|
-
'content.class',
|
|
97
|
-
`${component.properties.content.class} ${value === 2 ? 'italic' : 'not-italic'}`,
|
|
98
|
-
component,
|
|
99
|
-
onPropertyChange,
|
|
100
|
-
)}
|
|
97
|
+
updateProperty('content.class', `${component.properties.content.class} ${value ? 'italic' : 'not-italic'}`, component, onPropertyChange)}
|
|
101
98
|
/>
|
|
102
99
|
<UI.Switch
|
|
103
100
|
label={{ name: $t('constructor.props.background') }}
|
|
104
|
-
value={component.properties.background
|
|
105
|
-
|
|
101
|
+
value={component.properties.background}
|
|
102
|
+
options={[{ id: crypto.randomUUID(), value: 0, class: '' }]}
|
|
103
|
+
onChange={(value) => updateProperty('background', value, component, onPropertyChange)}
|
|
106
104
|
/>
|
|
107
105
|
</div>
|
|
108
106
|
</div>
|
|
@@ -152,30 +150,33 @@
|
|
|
152
150
|
<div class="flex w-1/3 flex-col px-2">
|
|
153
151
|
<UI.Switch
|
|
154
152
|
label={{ name: $t('constructor.props.bold') }}
|
|
155
|
-
value={initialBold
|
|
153
|
+
value={initialBold}
|
|
154
|
+
options={[{ id: crypto.randomUUID(), value: 0, class: '' }]}
|
|
156
155
|
onChange={(value) =>
|
|
157
156
|
updateProperty(
|
|
158
157
|
'content.class',
|
|
159
|
-
twMerge(`${component.properties.content.class} ${value
|
|
158
|
+
twMerge(`${component.properties.content.class} ${value ? 'font-bold' : 'font-normal'}`),
|
|
160
159
|
component,
|
|
161
160
|
onPropertyChange,
|
|
162
161
|
)}
|
|
163
162
|
/>
|
|
164
163
|
<UI.Switch
|
|
165
164
|
label={{ name: $t('constructor.props.italic') }}
|
|
166
|
-
value={initialItalic
|
|
165
|
+
value={initialItalic}
|
|
166
|
+
options={[{ id: crypto.randomUUID(), value: 0, class: '' }]}
|
|
167
167
|
onChange={(value) =>
|
|
168
168
|
updateProperty(
|
|
169
169
|
'content.class',
|
|
170
|
-
twMerge(`${component.properties.content.class} ${value
|
|
170
|
+
twMerge(`${component.properties.content.class} ${value ? 'italic' : 'not-italic'}`),
|
|
171
171
|
component,
|
|
172
172
|
onPropertyChange,
|
|
173
173
|
)}
|
|
174
174
|
/>
|
|
175
175
|
<UI.Switch
|
|
176
176
|
label={{ name: $t('constructor.props.background') }}
|
|
177
|
-
value={component.properties.background
|
|
178
|
-
|
|
177
|
+
value={component.properties.background}
|
|
178
|
+
options={[{ id: crypto.randomUUID(), value: 0, class: '' }]}
|
|
179
|
+
onChange={(value) => updateProperty('background', value, component, onPropertyChange)}
|
|
179
180
|
/>
|
|
180
181
|
</div>
|
|
181
182
|
</div>
|
|
@@ -37,6 +37,9 @@ const translations = {
|
|
|
37
37
|
'constructor.props.type.contain': 'Полный',
|
|
38
38
|
'constructor.props.type.square': 'Квадрат',
|
|
39
39
|
'constructor.props.type.circle': 'Круг',
|
|
40
|
+
'constructor.props.type.horizontal': 'Горизонтально',
|
|
41
|
+
'constructor.props.type.vertical': 'Вертикально',
|
|
42
|
+
'constructor.props.type.checkbox': 'Галочка',
|
|
40
43
|
/* Общие для редактора свойств */
|
|
41
44
|
'constructor.props.id': 'Идентификатор',
|
|
42
45
|
'constructor.props.label': 'Текст надписи',
|
|
@@ -95,6 +98,7 @@ const translations = {
|
|
|
95
98
|
'constructor.props.widthMode': 'Ширина кнопок',
|
|
96
99
|
'constructor.props.graphdata.title': 'Начальные данные ',
|
|
97
100
|
'constructor.props.options.title': 'Опции компонента',
|
|
101
|
+
'constructor.props.bits.title': 'Биты',
|
|
98
102
|
'constructor.props.tabs.title': 'Вкладки меню',
|
|
99
103
|
'constructor.props.valuetype': 'Тип значения',
|
|
100
104
|
'constructor.props.action': 'Действие при переключении',
|
|
@@ -114,6 +118,7 @@ const translations = {
|
|
|
114
118
|
'constructor.props.size.width': 'Ширина сетки',
|
|
115
119
|
'constructor.props.icon.text.position': 'Положение иконки',
|
|
116
120
|
'constructor.props.equal': 'Равные',
|
|
121
|
+
'constructor.props.bitmode': 'Битовый режим',
|
|
117
122
|
'constructor.props.table.columns': 'Колонки таблицы',
|
|
118
123
|
'constructor.props.table.columns.key': 'Ключ',
|
|
119
124
|
'constructor.props.table.columns.label': 'Название колонки',
|
package/dist/options.d.ts
CHANGED
|
@@ -95,6 +95,11 @@ export declare const optionsStore: import("svelte/store").Readable<{
|
|
|
95
95
|
value: string;
|
|
96
96
|
name: string;
|
|
97
97
|
}[];
|
|
98
|
+
SWITCH_OPTIONS: {
|
|
99
|
+
id: string;
|
|
100
|
+
value: string;
|
|
101
|
+
name: string;
|
|
102
|
+
}[];
|
|
98
103
|
INFO_SIDE_OPTIONS: {
|
|
99
104
|
id: string;
|
|
100
105
|
value: string;
|
package/dist/options.js
CHANGED
|
@@ -104,6 +104,11 @@ export const optionsStore = derived(t, ($t) => {
|
|
|
104
104
|
{ id: id(), value: 'cover', name: $t('constructor.props.type.cover') },
|
|
105
105
|
{ id: id(), value: 'contain', name: $t('constructor.props.type.contain') },
|
|
106
106
|
],
|
|
107
|
+
SWITCH_OPTIONS: [
|
|
108
|
+
{ id: id(), value: 'horizontal', name: $t('constructor.props.type.horizontal') },
|
|
109
|
+
{ id: id(), value: 'vertical', name: $t('constructor.props.type.vertical') },
|
|
110
|
+
{ id: id(), value: 'checkbox', name: $t('constructor.props.type.checkbox') },
|
|
111
|
+
],
|
|
107
112
|
INFO_SIDE_OPTIONS: [
|
|
108
113
|
{ id: id(), value: 'top', name: $t('constructor.props.info.top') },
|
|
109
114
|
{ id: id(), value: 'bottom', name: $t('constructor.props.info.bottom') },
|
package/dist/types.d.ts
CHANGED
|
@@ -106,6 +106,7 @@ export interface ISelectProps<T = unknown> {
|
|
|
106
106
|
type?: 'select' | 'buttons' | 'input';
|
|
107
107
|
value?: ISelectOption<T> | null;
|
|
108
108
|
options?: ISelectOption<T>[];
|
|
109
|
+
bitMode?: boolean;
|
|
109
110
|
eventHandler?: IUIComponentHandler;
|
|
110
111
|
onUpdate?: (value: ISelectOption<T>) => void;
|
|
111
112
|
}
|
|
@@ -127,6 +128,8 @@ export interface ISwitchProps {
|
|
|
127
128
|
captionLeft?: string;
|
|
128
129
|
captionRight?: string;
|
|
129
130
|
};
|
|
131
|
+
options?: ISelectOption<number>[];
|
|
132
|
+
bitMode?: boolean;
|
|
130
133
|
type?: 'horizontal' | 'vertical' | 'checkbox';
|
|
131
134
|
value?: number;
|
|
132
135
|
eventHandler?: IUIComponentHandler;
|
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.22",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"@sveltejs/vite-plugin-svelte": "^6.2.1",
|
|
49
49
|
"@types/node": "^24.10.1",
|
|
50
50
|
"publint": "^0.3.15",
|
|
51
|
-
"svelte": "^5.43.
|
|
51
|
+
"svelte": "^5.43.8",
|
|
52
52
|
"svelte-preprocess": "^6.0.3",
|
|
53
53
|
"vite": "^7.2.2",
|
|
54
54
|
"vite-plugin-compression": "^0.5.1"
|