poe-svelte-ui-lib 1.2.28 → 1.2.30

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 (41) hide show
  1. package/dist/Accordion/AccordionProps.svelte +4 -4
  2. package/dist/Accordion/AccordionProps.svelte.d.ts +7 -2
  3. package/dist/Button/Button.svelte +0 -1
  4. package/dist/Button/ButtonProps.svelte +18 -19
  5. package/dist/Button/ButtonProps.svelte.d.ts +7 -2
  6. package/dist/ColorPicker/ColorPickerProps.svelte +7 -8
  7. package/dist/ColorPicker/ColorPickerProps.svelte.d.ts +7 -2
  8. package/dist/FileAttach/FileAttachProps.svelte +2 -2
  9. package/dist/FileAttach/FileAttachProps.svelte.d.ts +7 -2
  10. package/dist/Graph/GraphProps.svelte +27 -48
  11. package/dist/Graph/GraphProps.svelte.d.ts +7 -2
  12. package/dist/Input/Input.svelte +21 -21
  13. package/dist/Input/InputProps.svelte +8 -14
  14. package/dist/Input/InputProps.svelte.d.ts +7 -2
  15. package/dist/Joystick/Joystick.svelte +59 -56
  16. package/dist/Joystick/JoystickProps.svelte +215 -0
  17. package/dist/Joystick/JoystickProps.svelte.d.ts +15 -25
  18. package/dist/Map/Map.svelte +1 -1
  19. package/dist/Map/MapProps.svelte +17 -8
  20. package/dist/Map/MapProps.svelte.d.ts +7 -2
  21. package/dist/ProgressBar/ProgressBarProps.svelte +4 -4
  22. package/dist/ProgressBar/ProgressBarProps.svelte.d.ts +7 -2
  23. package/dist/Select/Select.svelte +0 -1
  24. package/dist/Select/SelectProps.svelte +51 -12
  25. package/dist/Select/SelectProps.svelte.d.ts +7 -2
  26. package/dist/Slider/Slider.svelte +7 -5
  27. package/dist/Slider/SliderProps.svelte +8 -7
  28. package/dist/Slider/SliderProps.svelte.d.ts +7 -2
  29. package/dist/Switch/Switch.svelte +1 -1
  30. package/dist/Switch/SwitchProps.svelte +49 -40
  31. package/dist/Switch/SwitchProps.svelte.d.ts +7 -2
  32. package/dist/Table/Table.svelte +7 -2
  33. package/dist/Table/TableProps.svelte +32 -12
  34. package/dist/Table/TableProps.svelte.d.ts +7 -2
  35. package/dist/Tabs/TabsProps.svelte +10 -11
  36. package/dist/Tabs/TabsProps.svelte.d.ts +7 -2
  37. package/dist/TextField/TextFieldProps.svelte +3 -5
  38. package/dist/TextField/TextFieldProps.svelte.d.ts +7 -2
  39. package/dist/types.d.ts +24 -8
  40. package/dist/types.js +10 -1
  41. package/package.json +2 -2
@@ -6,6 +6,7 @@
6
6
  id = crypto.randomUUID(),
7
7
  wrapperClass = '',
8
8
  label = { name: '', class: '' },
9
+ axesName = ['Roll', 'Pitch', 'Yaw'],
9
10
  value = $bindable([0, 0, 0]),
10
11
  limits = [
11
12
  { minNum: -100, maxNum: 100 },
@@ -13,6 +14,7 @@
13
14
  { minNum: -100, maxNum: 100 },
14
15
  ],
15
16
  onUpdate = () => {},
17
+ onClick = () => {},
16
18
  }: IJoystickProps = $props()
17
19
 
18
20
  const directions = [
@@ -180,7 +182,7 @@
180
182
 
181
183
  <div id={`${id}-${crypto.randomUUID().slice(0, 6)}`} class={twMerge(`bg-red relative flex w-full flex-col items-center`, wrapperClass)}>
182
184
  {#if label.name}
183
- <h5 class={twMerge(` w-full px-4 text-center`, label.class)}>{label.name}</h5>
185
+ <h5 class={twMerge(`w-full px-4 text-center`, label.class)}>{label.name}</h5>
184
186
  {/if}
185
187
 
186
188
  <div class=" flex w-1/2 items-center justify-center">
@@ -230,7 +232,7 @@
230
232
  </span>
231
233
  {/each}
232
234
  </div>
233
- <!-- Кнопка домой -->
235
+ <!-- Кнопка по центру -->
234
236
  <div
235
237
  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"
236
238
  >
@@ -238,8 +240,7 @@
238
240
  class="flex size-18 cursor-pointer items-center justify-center rounded-full bg-(--bg-color)"
239
241
  title=""
240
242
  onclick={() => {
241
- value = [0, 0, 0]
242
- onUpdate(value)
243
+ onClick(value)
243
244
  }}
244
245
  ><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"
245
246
  ><path
@@ -251,57 +252,59 @@
251
252
  </div>
252
253
  </div>
253
254
  <!-- Боковые кнопки (ось roll) -->
254
- <div
255
- class="absolute flex h-15 w-65 items-center justify-between rounded-full shadow-[0_0_15px_rgb(0_0_0_/0.25)]"
256
- style="background: color-mix(in srgb, var(--bg-color), var(--shadow-color) 10%)"
257
- >
258
- <button
259
- class="h-full cursor-pointer rounded-l-full px-3.5"
260
- title=""
261
- onclick={() => {
262
- if (value[0] - sensitivity <= limits[0].minNum) {
263
- value[0] = limits[0].minNum
264
- onUpdate(value)
265
- return
266
- }
267
- value[0] -= sensitivity
268
- onUpdate(value)
269
- }}
270
- onmouseenter={(e) => (e.currentTarget.style.backgroundColor = 'color-mix(in srgb, var(--bg-color), var(--shadow-color) 30%)')}
271
- onmouseleave={(e) => (e.currentTarget.style.backgroundColor = 'background: color-mix(in srgb, var(--bg-color), var(--shadow-color) 10%)')}
272
- ><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
273
- ><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="1.5"
274
- ><path
275
- stroke-miterlimit="10"
276
- 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"
277
- /><path stroke-linejoin="round" d="m7.12 2.75l-.95 3.858a1.33 1.33 0 0 0 .97 1.609l3.869.948" /></g
278
- ></svg
279
- ></button
255
+ {#if axesName.length == 3}
256
+ <div
257
+ class="absolute flex h-15 w-65 items-center justify-between rounded-full shadow-[0_0_15px_rgb(0_0_0_/0.25)]"
258
+ style="background: color-mix(in srgb, var(--bg-color), var(--shadow-color) 10%)"
280
259
  >
281
- <button
282
- class="h-full cursor-pointer rounded-r-full px-3.5"
283
- title=""
284
- onclick={() => {
285
- if (value[0] + sensitivity >= limits[0].maxNum) {
286
- value[0] = limits[0].maxNum
260
+ <button
261
+ class="h-full cursor-pointer rounded-l-full px-3.5"
262
+ title=""
263
+ onclick={() => {
264
+ if (value[0] - sensitivity <= limits[0].minNum) {
265
+ value[0] = limits[0].minNum
266
+ onUpdate(value)
267
+ return
268
+ }
269
+ value[0] -= sensitivity
287
270
  onUpdate(value)
288
- return
289
- }
290
- value[0] += sensitivity
291
- onUpdate(value)
292
- }}
293
- onmouseenter={(e) => (e.currentTarget.style.backgroundColor = 'color-mix(in srgb, var(--bg-color), var(--shadow-color) 30%)')}
294
- onmouseleave={(e) => (e.currentTarget.style.backgroundColor = 'vabackground: color-mix(in srgb, var(--bg-color), var(--shadow-color) 10%)')}
295
- ><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
296
- ><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="1.5"
297
- ><path
298
- stroke-miterlimit="10"
299
- 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"
300
- /><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
301
- ></svg
302
- ></button
303
- >
304
- </div>
271
+ }}
272
+ onmouseenter={(e) => (e.currentTarget.style.backgroundColor = 'color-mix(in srgb, var(--bg-color), var(--shadow-color) 30%)')}
273
+ onmouseleave={(e) => (e.currentTarget.style.backgroundColor = 'background: color-mix(in srgb, var(--bg-color), var(--shadow-color) 10%)')}
274
+ ><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
275
+ ><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="1.5"
276
+ ><path
277
+ stroke-miterlimit="10"
278
+ 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"
279
+ /><path stroke-linejoin="round" d="m7.12 2.75l-.95 3.858a1.33 1.33 0 0 0 .97 1.609l3.869.948" /></g
280
+ ></svg
281
+ ></button
282
+ >
283
+ <button
284
+ class="h-full cursor-pointer rounded-r-full px-3.5"
285
+ title=""
286
+ onclick={() => {
287
+ if (value[0] + sensitivity >= limits[0].maxNum) {
288
+ value[0] = limits[0].maxNum
289
+ onUpdate(value)
290
+ return
291
+ }
292
+ value[0] += sensitivity
293
+ onUpdate(value)
294
+ }}
295
+ onmouseenter={(e) => (e.currentTarget.style.backgroundColor = 'color-mix(in srgb, var(--bg-color), var(--shadow-color) 30%)')}
296
+ onmouseleave={(e) => (e.currentTarget.style.backgroundColor = 'vabackground: color-mix(in srgb, var(--bg-color), var(--shadow-color) 10%)')}
297
+ ><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
298
+ ><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="1.5"
299
+ ><path
300
+ stroke-miterlimit="10"
301
+ 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"
302
+ /><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
303
+ ></svg
304
+ ></button
305
+ >
306
+ </div>
307
+ {/if}
305
308
  </div>
306
309
 
307
310
  <div class="right-10 flex items-center md:absolute">
@@ -335,15 +338,15 @@
335
338
  </div>
336
339
 
337
340
  <div>
338
- {#each [0, 1, 2] as num}
339
- <h5 class={twMerge(` w-full px-4 text-center`, label.class)}>{num == 0 ? 'Roll' : num == 1 ? 'Pitch' : 'Yaw'}</h5>
341
+ {#each axesName as axe, index}
342
+ <h5 class={twMerge(` w-full px-4 text-center`, label.class)}>{axe}</h5>
340
343
  <input
341
344
  class={`w-20 rounded-2xl border border-(--border-color) px-4 py-1 text-center transition-all duration-300 outline-none
342
345
  hover:shadow-md
343
346
  [&::-webkit-inner-spin-button]:hidden
344
347
  [&::-webkit-outer-spin-button]:hidden`}
345
348
  style="background: color-mix(in srgb, var(--bg-color), var(--back-color) 70%);"
346
- value={value[num]}
349
+ value={value[index]}
347
350
  id={`${id}-${crypto.randomUUID().slice(0, 6)}`}
348
351
  readonly
349
352
  />
@@ -0,0 +1,215 @@
1
+ <script lang="ts">
2
+ import { getContext } from 'svelte'
3
+ import { t } from '../locales/i18n'
4
+ import { type UIComponent, type IGraphProps, updateProperty, type ISelectOption, type IUIComponentHandler } from '../types'
5
+ import * as UI from '..'
6
+ import Modal from '../Modal.svelte'
7
+ import { ICONS } from '../icons'
8
+ import Button from '../Button/Button.svelte'
9
+ import CrossIcon from '../libIcons/CrossIcon.svelte'
10
+ import { optionsStore } from '../options'
11
+ import { twMerge } from 'tailwind-merge'
12
+
13
+ const {
14
+ component,
15
+ onPropertyChange,
16
+ forConstructor = true,
17
+ } = $props<{
18
+ component: UIComponent & { properties: Partial<IGraphProps> }
19
+ onPropertyChange: (updates: Partial<{ properties?: string | object; name?: string; access?: string; eventHandler?: IUIComponentHandler }>) => void
20
+ forConstructor?: boolean
21
+ }>()
22
+
23
+ let showIconLib = $state(false)
24
+
25
+ let Header: ISelectOption = $derived(
26
+ $optionsStore.HEADER_OPTIONS.find((h) => h.value === component.eventHandler.Header) ?? {
27
+ id: '',
28
+ name: '',
29
+ value: '',
30
+ class: '!w-1/4',
31
+ },
32
+ )
33
+
34
+ const DeviceVariables = getContext<{ id: string; value: string; name: string }[]>('DeviceVariables')
35
+ let VARIABLE_OPTIONS = $derived(DeviceVariables && Array.isArray(DeviceVariables) ? DeviceVariables : [])
36
+
37
+ const initialAlign = $derived(
38
+ $optionsStore.TEXT_ALIGN_OPTIONS.find((a) =>
39
+ (a.value as string).includes(component.properties.label?.class?.split(' ').find((cls: string) => cls.startsWith('text-'))),
40
+ ),
41
+ )
42
+ </script>
43
+
44
+ {#if forConstructor}
45
+ <div class="relative flex flex-row items-start justify-center">
46
+ <!-- Сообщение для отправки в ws по нажатию кнопки -->
47
+ <div class="flex w-1/3 flex-col items-center px-2">
48
+ <UI.Select
49
+ label={{ name: $t('constructor.props.header') }}
50
+ type="buttons"
51
+ value={Header}
52
+ options={$optionsStore.HEADER_OPTIONS}
53
+ onUpdate={(option) => {
54
+ Header = { ...option }
55
+ onPropertyChange({ eventHandler: { Header: Header.value as string } })
56
+ }}
57
+ />
58
+ {#if Header.value === 'SET'}
59
+ <UI.Select
60
+ label={{ name: $t('constructor.props.argument') }}
61
+ type="buttons"
62
+ value={$optionsStore.FULL_ARGUMENT_OPTION.find((h) => h.value === component.eventHandler.Argument) ??
63
+ $optionsStore.FULL_ARGUMENT_OPTION.find((h) => h.value === '')}
64
+ options={$optionsStore.FULL_ARGUMENT_OPTION}
65
+ onUpdate={(option) => {
66
+ onPropertyChange({ eventHandler: { Argument: option.value as string } })
67
+ }}
68
+ />
69
+ {/if}
70
+ <UI.Input
71
+ label={{ name: Header.value !== 'SET' ? $t('constructor.props.argument') : '' }}
72
+ wrapperClass="{Header.value === 'SET' ? 'mt-1' : ''} "
73
+ value={component.eventHandler.Argument}
74
+ maxlength={32}
75
+ disabled={Header.value === 'SET' && (component.eventHandler.Argument == 'Save' || component.eventHandler.Argument == 'NoSave')}
76
+ help={{ info: $t('constructor.props.argument.info'), autocomplete: 'on', regExp: /^[a-zA-Z0-9\-_]{0,32}$/ }}
77
+ onUpdate={(value) => onPropertyChange({ eventHandler: { Argument: value as string } })}
78
+ />
79
+ {#if (component.eventHandler.Argument !== 'Save' && component.eventHandler.Argument !== 'NoSave') || Header.value === 'SET'}
80
+ <UI.Input
81
+ label={{ name: $t('constructor.props.value') }}
82
+ value={component.eventHandler.Value}
83
+ help={{ info: $t('constructor.props.value.info') }}
84
+ maxlength={500}
85
+ onUpdate={(value) => onPropertyChange({ eventHandler: { Value: value as string } })}
86
+ />
87
+ {/if}
88
+ </div>
89
+ <div class="flex w-1/3 flex-col px-2">
90
+ <UI.Select
91
+ label={{ name: $t('constructor.props.access') }}
92
+ type="buttons"
93
+ options={$optionsStore.ACCESS_OPTION}
94
+ value={$optionsStore.ACCESS_OPTION.find((o) => o.value === component.access)}
95
+ onUpdate={(option) => onPropertyChange({ access: option.value })}
96
+ />
97
+ <UI.Input
98
+ label={{ name: $t('constructor.props.label') }}
99
+ value={component.properties.label.name}
100
+ onUpdate={(value) => updateProperty('label.name', value as string, component, onPropertyChange)}
101
+ />
102
+ <UI.Select
103
+ label={{ name: $t('constructor.props.align') }}
104
+ type="buttons"
105
+ value={initialAlign}
106
+ options={$optionsStore.TEXT_ALIGN_OPTIONS}
107
+ onUpdate={(option) => updateProperty('label.class', twMerge(component.properties.label.class, option.value), component, onPropertyChange)}
108
+ />
109
+ </div>
110
+ <div class="flex w-1/3 flex-col px-2">
111
+ <div class="mt-6 flex gap-2">
112
+ <UI.Button content={{ name: $t('constructor.props.markerIcon') }} onClick={() => (showIconLib = true)} />
113
+ {#if showIconLib}
114
+ <Modal bind:isOpen={showIconLib} wrapperClass="w-130">
115
+ {#snippet main()}
116
+ <div class="grid grid-cols-3">
117
+ {#each ICONS as category}
118
+ <div class="relative m-1.5 rounded-xl border-2 border-(--border-color) p-3">
119
+ <div class="absolute -top-3.5 bg-(--back-color) px-1">{$t(`constructor.props.icon.${category[0]}`)}</div>
120
+ <div class="grid grid-cols-3 place-items-center gap-2">
121
+ {#each category[1] as icon}
122
+ <button
123
+ class="h-8 w-8 cursor-pointer [&_svg]:h-full [&_svg]:max-h-full [&_svg]:w-full [&_svg]:max-w-full"
124
+ onclick={() => {
125
+ updateProperty('markerIcon', icon as string, component, onPropertyChange)
126
+ }}
127
+ >
128
+ {@html icon}
129
+ </button>{/each}
130
+ </div>
131
+ </div>
132
+ {/each}
133
+ </div>
134
+ {/snippet}
135
+ </Modal>
136
+ {/if}
137
+ {#if component.properties.markerIcon}
138
+ <Button
139
+ wrapperClass="w-8.5 "
140
+ componentClass="p-0.5 bg-red"
141
+ content={{ icon: CrossIcon }}
142
+ onClick={() => {
143
+ updateProperty('markerIcon', '', component, onPropertyChange)
144
+ }}
145
+ />
146
+ {/if}
147
+ </div>
148
+ </div>
149
+ </div>
150
+ {:else}
151
+ <div class="relative mb-2 flex flex-row items-start justify-center">
152
+ <!-- Сообщение для отправки в ws по нажатию кнопки -->
153
+ <div class="flex w-1/3 flex-col items-center px-2">
154
+ <UI.Input
155
+ label={{ name: $t('constructor.props.id') }}
156
+ value={component.properties.id}
157
+ onUpdate={(value) => updateProperty('id', value as string, component, onPropertyChange)}
158
+ />
159
+ </div>
160
+ <div class="flex w-1/3 flex-col px-2">
161
+ <UI.Input
162
+ label={{ name: $t('constructor.props.label') }}
163
+ value={component.properties.label.name}
164
+ onUpdate={(value) => updateProperty('label.name', value as string, component, onPropertyChange)}
165
+ />
166
+ <UI.Select
167
+ label={{ name: $t('constructor.props.align') }}
168
+ type="buttons"
169
+ value={initialAlign}
170
+ options={$optionsStore.TEXT_ALIGN_OPTIONS}
171
+ onUpdate={(option) => updateProperty('label.class', twMerge(component.properties.label.class, option.value), component, onPropertyChange)}
172
+ />
173
+ </div>
174
+
175
+ <div class="flex w-1/3 flex-col px-2">
176
+ <div class="mt-6 flex gap-2">
177
+ <UI.Button content={{ name: $t('constructor.props.markerIcon') }} onClick={() => (showIconLib = true)} />
178
+ {#if showIconLib}
179
+ <Modal bind:isOpen={showIconLib} wrapperClass="w-130">
180
+ {#snippet main()}
181
+ <div class="grid grid-cols-3">
182
+ {#each ICONS as category}
183
+ <div class="relative m-1.5 rounded-xl border-2 border-(--border-color) p-3">
184
+ <div class="absolute -top-3.5 bg-(--back-color) px-1">{$t(`constructor.props.icon.${category[0]}`)}</div>
185
+ <div class="grid grid-cols-3 place-items-center gap-2">
186
+ {#each category[1] as icon}
187
+ <button
188
+ class="h-8 w-8 cursor-pointer [&_svg]:h-full [&_svg]:max-h-full [&_svg]:w-full [&_svg]:max-w-full"
189
+ onclick={() => {
190
+ updateProperty('markerIcon', icon as string, component, onPropertyChange)
191
+ }}
192
+ >
193
+ {@html icon}
194
+ </button>{/each}
195
+ </div>
196
+ </div>
197
+ {/each}
198
+ </div>
199
+ {/snippet}
200
+ </Modal>
201
+ {/if}
202
+ {#if component.properties.markerIcon}
203
+ <Button
204
+ wrapperClass="w-8.5 "
205
+ componentClass="p-0.5 bg-red"
206
+ content={{ icon: CrossIcon }}
207
+ onClick={() => {
208
+ updateProperty('markerIcon', '', component, onPropertyChange)
209
+ }}
210
+ />
211
+ {/if}
212
+ </div>
213
+ </div>
214
+ </div>
215
+ {/if}
@@ -1,26 +1,16 @@
1
- export default JoystickProps;
2
- type JoystickProps = SvelteComponent<{
3
- [x: string]: never;
4
- }, {
5
- [evt: string]: CustomEvent<any>;
6
- }, {}> & {
7
- $$bindings?: string | undefined;
8
- };
9
- declare const JoystickProps: $$__sveltets_2_IsomorphicComponent<{
10
- [x: string]: never;
11
- }, {
12
- [evt: string]: CustomEvent<any>;
13
- }, {}, {}, string>;
14
- interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
15
- new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
16
- $$bindings?: Bindings;
17
- } & Exports;
18
- (internal: unknown, props: {
19
- $$events?: Events;
20
- $$slots?: Slots;
21
- }): Exports & {
22
- $set?: any;
23
- $on?: any;
1
+ import { type UIComponent, type IGraphProps, type IUIComponentHandler } from '../types';
2
+ type $$ComponentProps = {
3
+ component: UIComponent & {
4
+ properties: Partial<IGraphProps>;
24
5
  };
25
- z_$$bindings?: Bindings;
26
- }
6
+ onPropertyChange: (updates: Partial<{
7
+ properties?: string | object;
8
+ name?: string;
9
+ access?: string;
10
+ eventHandler?: IUIComponentHandler;
11
+ }>) => void;
12
+ forConstructor?: boolean;
13
+ };
14
+ declare const JoystickProps: import("svelte").Component<$$ComponentProps, {}, "">;
15
+ type JoystickProps = ReturnType<typeof JoystickProps>;
16
+ export default JoystickProps;
@@ -173,7 +173,7 @@
173
173
  </button>
174
174
  {#if isCopied}
175
175
  <div
176
- class="absolute top-1/2 right-0 -translate-y-1/2 transform rounded-md bg-(--green-color) px-2 py-1 text-sm shadow-lg"
176
+ class="absolute top-1/2 right-0 -translate-y-1/2 transform rounded-md bg-(--green-color) px-1.5 py-1 text-sm shadow-lg"
177
177
  transition:fade={{ duration: 200 }}
178
178
  >
179
179
 
@@ -1,12 +1,14 @@
1
1
  <script lang="ts">
2
2
  import { getContext } from 'svelte'
3
3
  import { t } from '../locales/i18n'
4
- import { type UIComponent, type IGraphProps, updateProperty } from '../types'
4
+ import { type UIComponent, type IGraphProps, updateProperty, type IUIComponentHandler } from '../types'
5
5
  import * as UI from '..'
6
6
  import Modal from '../Modal.svelte'
7
7
  import { ICONS } from '../icons'
8
8
  import Button from '../Button/Button.svelte'
9
9
  import CrossIcon from '../libIcons/CrossIcon.svelte'
10
+ import { optionsStore } from '../options'
11
+ import { twMerge } from 'tailwind-merge'
10
12
 
11
13
  const {
12
14
  component,
@@ -14,7 +16,7 @@
14
16
  forConstructor = true,
15
17
  } = $props<{
16
18
  component: UIComponent & { properties: Partial<IGraphProps> }
17
- onPropertyChange: (value?: string | object, name?: string, access?: string) => void
19
+ onPropertyChange: (updates: Partial<{ properties?: string | object; name?: string; access?: string; eventHandler?: IUIComponentHandler }>) => void
18
20
  forConstructor?: boolean
19
21
  }>()
20
22
 
@@ -22,6 +24,12 @@
22
24
 
23
25
  const DeviceVariables = getContext<{ id: string; value: string; name: string }[]>('DeviceVariables')
24
26
  let VARIABLE_OPTIONS = $derived(DeviceVariables && Array.isArray(DeviceVariables) ? DeviceVariables : [])
27
+
28
+ const initialAlign = $derived(
29
+ $optionsStore.TEXT_ALIGN_OPTIONS.find((a) =>
30
+ (a.value as string).includes(component.properties.label?.class?.split(' ').find((cls: string) => cls.startsWith('text-'))),
31
+ ),
32
+ )
25
33
  </script>
26
34
 
27
35
  {#if forConstructor}
@@ -34,8 +42,7 @@
34
42
  value={VARIABLE_OPTIONS.find((opt) => opt.value === component.properties.id)}
35
43
  onUpdate={(value) => {
36
44
  updateProperty('id', value.value as string, component, onPropertyChange)
37
- updateProperty('eventHandler.Variables', value.value as string, component, onPropertyChange)
38
- onPropertyChange(null, value.name?.split('—')[1].trim(), null)
45
+ onPropertyChange({ name: value.name?.split('—')[1].trim(), eventHandler: { Variables: value.value as string } })
39
46
  }}
40
47
  />
41
48
  </div>
@@ -45,10 +52,12 @@
45
52
  value={component.properties.label.name}
46
53
  onUpdate={(value) => updateProperty('label.name', value as string, component, onPropertyChange)}
47
54
  />
48
- <UI.Input
49
- label={{ name: $t('constructor.props.label.class') }}
50
- value={component.properties.label.class}
51
- onUpdate={(value) => updateProperty('label.class', value as string, component, onPropertyChange)}
55
+ <UI.Select
56
+ label={{ name: $t('constructor.props.align') }}
57
+ type="buttons"
58
+ value={initialAlign}
59
+ options={$optionsStore.TEXT_ALIGN_OPTIONS}
60
+ onUpdate={(option) => updateProperty('label.class', twMerge(component.properties.label.class, option.value), component, onPropertyChange)}
52
61
  />
53
62
  </div>
54
63
  <div class="flex w-1/3 flex-col px-2">
@@ -1,9 +1,14 @@
1
- import { type UIComponent, type IGraphProps } from '../types';
1
+ import { type UIComponent, type IGraphProps, type IUIComponentHandler } from '../types';
2
2
  type $$ComponentProps = {
3
3
  component: UIComponent & {
4
4
  properties: Partial<IGraphProps>;
5
5
  };
6
- onPropertyChange: (value?: string | object, name?: string, access?: string) => void;
6
+ onPropertyChange: (updates: Partial<{
7
+ properties?: string | object;
8
+ name?: string;
9
+ access?: string;
10
+ eventHandler?: IUIComponentHandler;
11
+ }>) => void;
7
12
  forConstructor?: boolean;
8
13
  };
9
14
  declare const MapProps: import("svelte").Component<$$ComponentProps, {}, "">;
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import { getContext } from 'svelte'
3
3
  import { t } from '../locales/i18n'
4
- import { type UIComponent, type IProgressBarProps, updateProperty } from '../types'
4
+ import { type UIComponent, type IProgressBarProps, updateProperty, type IUIComponentHandler } from '../types'
5
5
  import * as UI from '..'
6
6
  import { optionsStore } from '../options'
7
7
  import { twMerge } from 'tailwind-merge'
@@ -12,7 +12,7 @@
12
12
  forConstructor = true,
13
13
  } = $props<{
14
14
  component: UIComponent & { properties: Partial<IProgressBarProps> }
15
- onPropertyChange: (value?: string | object, name?: string, access?: string) => void
15
+ onPropertyChange: (updates: Partial<{ properties?: string | object; name?: string; access?: string; eventHandler?: IUIComponentHandler }>) => void
16
16
  forConstructor?: boolean
17
17
  }>()
18
18
 
@@ -40,8 +40,8 @@
40
40
  options={VARIABLE_OPTIONS}
41
41
  value={VARIABLE_OPTIONS.find((opt) => opt.value === component.properties.id)}
42
42
  onUpdate={(value) => {
43
- updateProperty('id', value.value as string, component, onPropertyChange, value.name?.split('—')[1].trim())
44
- updateProperty('eventHandler.Variables', value.value as string, component, onPropertyChange)
43
+ updateProperty('id', value.value as string, component, onPropertyChange)
44
+ onPropertyChange({ name: value.name?.split('—')[1].trim(), eventHandler: { Variables: value.value as string } })
45
45
  }}
46
46
  />
47
47
  </div>
@@ -1,9 +1,14 @@
1
- import { type UIComponent, type IProgressBarProps } from '../types';
1
+ import { type UIComponent, type IProgressBarProps, type IUIComponentHandler } from '../types';
2
2
  type $$ComponentProps = {
3
3
  component: UIComponent & {
4
4
  properties: Partial<IProgressBarProps>;
5
5
  };
6
- onPropertyChange: (value?: string | object, name?: string, access?: string) => void;
6
+ onPropertyChange: (updates: Partial<{
7
+ properties?: string | object;
8
+ name?: string;
9
+ access?: string;
10
+ eventHandler?: IUIComponentHandler;
11
+ }>) => void;
7
12
  forConstructor?: boolean;
8
13
  };
9
14
  declare const ProgressBarProps: import("svelte").Component<$$ComponentProps, {}, "">;
@@ -14,7 +14,6 @@
14
14
 
15
15
  let {
16
16
  id = crypto.randomUUID(),
17
-
18
17
  wrapperClass = '',
19
18
  disabled = false,
20
19
  label = { name: '', class: '' },