poe-svelte-ui-lib 1.2.29 → 1.2.31

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 (47) 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/FileAttach.svelte +2 -13
  9. package/dist/FileAttach/FileAttach.svelte.d.ts +2 -20
  10. package/dist/FileAttach/FileAttachProps.svelte +72 -5
  11. package/dist/FileAttach/FileAttachProps.svelte.d.ts +8 -4
  12. package/dist/Graph/GraphProps.svelte +27 -48
  13. package/dist/Graph/GraphProps.svelte.d.ts +7 -2
  14. package/dist/Input/Input.svelte +21 -21
  15. package/dist/Input/InputProps.svelte +10 -16
  16. package/dist/Input/InputProps.svelte.d.ts +7 -2
  17. package/dist/Joystick/Joystick.svelte +100 -105
  18. package/dist/Joystick/JoystickProps.svelte +347 -0
  19. package/dist/Joystick/JoystickProps.svelte.d.ts +15 -25
  20. package/dist/Map/Map.svelte +1 -1
  21. package/dist/Map/MapProps.svelte +17 -8
  22. package/dist/Map/MapProps.svelte.d.ts +7 -2
  23. package/dist/ProgressBar/ProgressBar.svelte +31 -6
  24. package/dist/ProgressBar/ProgressBarProps.svelte +4 -4
  25. package/dist/ProgressBar/ProgressBarProps.svelte.d.ts +7 -2
  26. package/dist/Select/Select.svelte +0 -1
  27. package/dist/Select/SelectProps.svelte +51 -12
  28. package/dist/Select/SelectProps.svelte.d.ts +7 -2
  29. package/dist/Slider/Slider.svelte +7 -8
  30. package/dist/Slider/SliderProps.svelte +8 -7
  31. package/dist/Slider/SliderProps.svelte.d.ts +7 -2
  32. package/dist/Switch/Switch.svelte +1 -1
  33. package/dist/Switch/SwitchProps.svelte +49 -40
  34. package/dist/Switch/SwitchProps.svelte.d.ts +7 -2
  35. package/dist/Table/Table.svelte +7 -2
  36. package/dist/Table/TableProps.svelte +32 -12
  37. package/dist/Table/TableProps.svelte.d.ts +7 -2
  38. package/dist/Tabs/TabsProps.svelte +10 -11
  39. package/dist/Tabs/TabsProps.svelte.d.ts +7 -2
  40. package/dist/TextField/TextFieldProps.svelte +3 -5
  41. package/dist/TextField/TextFieldProps.svelte.d.ts +7 -2
  42. package/dist/index.d.ts +1 -0
  43. package/dist/index.js +1 -0
  44. package/dist/locales/translations.js +3 -0
  45. package/dist/types.d.ts +46 -11
  46. package/dist/types.js +10 -1
  47. package/package.json +2 -2
@@ -0,0 +1,347 @@
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 initialAlign = $derived(
35
+ $optionsStore.TEXT_ALIGN_OPTIONS.find((a) =>
36
+ (a.value as string).includes(component.properties.label?.class?.split(' ').find((cls: string) => cls.startsWith('text-'))),
37
+ ),
38
+ )
39
+
40
+ const initialColor = $derived(
41
+ $optionsStore.COLOR_OPTIONS.find((c) =>
42
+ (c.value as string).includes(component.properties.wrapperClass?.split(' ').find((cls: string) => cls.startsWith('bg-'))),
43
+ ),
44
+ )
45
+ </script>
46
+
47
+ {#if forConstructor}
48
+ <div>
49
+ <div class="relative flex flex-row items-start justify-center">
50
+ <!-- Сообщение для отправки в ws по нажатию кнопки -->
51
+ <div class="flex w-1/3 flex-col items-center px-2">
52
+ <UI.Select
53
+ label={{ name: $t('constructor.props.header') }}
54
+ type="buttons"
55
+ value={Header}
56
+ options={$optionsStore.HEADER_OPTIONS}
57
+ onUpdate={(option) => {
58
+ Header = { ...option }
59
+ onPropertyChange({ eventHandler: { Header: Header.value as string } })
60
+ }}
61
+ />
62
+ {#if Header.value === 'SET'}
63
+ <UI.Select
64
+ label={{ name: $t('constructor.props.argument') }}
65
+ type="buttons"
66
+ value={$optionsStore.FULL_ARGUMENT_OPTION.find((h) => h.value === component.eventHandler.Argument) ??
67
+ $optionsStore.FULL_ARGUMENT_OPTION.find((h) => h.value === '')}
68
+ options={$optionsStore.FULL_ARGUMENT_OPTION}
69
+ onUpdate={(option) => {
70
+ onPropertyChange({ eventHandler: { Argument: option.value as string } })
71
+ }}
72
+ />
73
+ {/if}
74
+ <UI.Input
75
+ label={{ name: Header.value !== 'SET' ? $t('constructor.props.argument') : '' }}
76
+ wrapperClass="{Header.value === 'SET' ? 'mt-1' : ''} "
77
+ value={component.eventHandler.Argument}
78
+ maxlength={32}
79
+ disabled={Header.value === 'SET' && (component.eventHandler.Argument == 'Save' || component.eventHandler.Argument == 'NoSave')}
80
+ help={{ info: $t('constructor.props.argument.info'), autocomplete: 'on', regExp: /^[a-zA-Z0-9\-_]{0,32}$/ }}
81
+ onUpdate={(value) => onPropertyChange({ eventHandler: { Argument: value as string } })}
82
+ />
83
+ {#if (component.eventHandler.Argument !== 'Save' && component.eventHandler.Argument !== 'NoSave') || Header.value === 'SET'}
84
+ <UI.Input
85
+ label={{ name: $t('constructor.props.value') }}
86
+ value={component.eventHandler.Value}
87
+ help={{ info: $t('constructor.props.value.info') }}
88
+ maxlength={500}
89
+ onUpdate={(value) => onPropertyChange({ eventHandler: { Value: value as string } })}
90
+ />
91
+ {/if}
92
+ </div>
93
+ <div class="flex w-1/3 flex-col px-2">
94
+ <UI.Select
95
+ label={{ name: $t('constructor.props.access') }}
96
+ type="buttons"
97
+ options={$optionsStore.ACCESS_OPTION}
98
+ value={$optionsStore.ACCESS_OPTION.find((o) => o.value === component.access)}
99
+ onUpdate={(option) => onPropertyChange({ access: option.value })}
100
+ />
101
+ <UI.Input
102
+ label={{ name: $t('constructor.props.label') }}
103
+ value={component.properties.label.name}
104
+ onUpdate={(value) => updateProperty('label.name', value as string, component, onPropertyChange)}
105
+ />
106
+ <UI.Input
107
+ label={{ name: $t('constructor.props.label.class') }}
108
+ value={component.properties.label.class}
109
+ onUpdate={(value) => updateProperty('label.class', value as string, component, onPropertyChange)}
110
+ />
111
+ </div>
112
+ <div class="flex w-1/3 flex-col px-2">
113
+ <div class="mt-6 flex gap-2">
114
+ <UI.Button content={{ name: $t('constructor.props.buttonIcon') }} onClick={() => (showIconLib = true)} />
115
+ {#if showIconLib}
116
+ <Modal bind:isOpen={showIconLib} wrapperClass="w-130">
117
+ {#snippet main()}
118
+ <div class="grid grid-cols-3">
119
+ {#each ICONS as category}
120
+ <div class="relative m-1.5 rounded-xl border-2 border-(--border-color) p-3">
121
+ <div class="absolute -top-3.5 bg-(--back-color) px-1">{$t(`constructor.props.icon.${category[0]}`)}</div>
122
+ <div class="grid grid-cols-3 place-items-center gap-2">
123
+ {#each category[1] as icon}
124
+ <button
125
+ class="h-8 w-8 cursor-pointer [&_svg]:h-full [&_svg]:max-h-full [&_svg]:w-full [&_svg]:max-w-full"
126
+ onclick={() => {
127
+ updateProperty('buttonIcon', icon as string, component, onPropertyChange)
128
+ }}
129
+ >
130
+ {@html icon}
131
+ </button>{/each}
132
+ </div>
133
+ </div>
134
+ {/each}
135
+ </div>
136
+ {/snippet}
137
+ </Modal>
138
+ {/if}
139
+ {#if component.properties.buttonIcon}
140
+ <Button
141
+ wrapperClass="w-8.5 "
142
+ componentClass="p-0.5 bg-red"
143
+ content={{ icon: CrossIcon }}
144
+ onClick={() => {
145
+ updateProperty('buttonIcon', '', component, onPropertyChange)
146
+ }}
147
+ />
148
+ {/if}
149
+ </div>
150
+ <UI.Input
151
+ label={{ name: $t('constructor.props.joystick.axes') }}
152
+ value={component.properties.axes.map((axe: any) => axe.name).join(' ')}
153
+ help={{ info: $t('constructor.props.joystick.axes.info'), regExp: /^[\p{L}0-9\-_":{}]+ +[\p{L}0-9\-_":{}]+(?: +[\p{L}0-9\-_":{}]+)?$/u }}
154
+ maxlength={100}
155
+ onUpdate={(value) => {
156
+ const stringValue = value as string
157
+ const spaceCount = (stringValue.match(/\s/g) || []).length
158
+ if (spaceCount > 2) {
159
+ return
160
+ }
161
+ const parts = stringValue.trim().split(/\s+/)
162
+ updateProperty(
163
+ 'axes',
164
+ parts.map((a: any, index: number) => {
165
+ let axeIndex = parts.length == 2 && component.properties.axes.length === 3 ? index + 1 : index
166
+ return {
167
+ name: a,
168
+ minNum: component.properties.axes[axeIndex] ? component.properties.axes[axeIndex].minNum : -100,
169
+ maxNum: component.properties.axes[axeIndex] ? component.properties.axes[axeIndex].maxNum : 100,
170
+ }
171
+ }),
172
+ component,
173
+ onPropertyChange,
174
+ )
175
+ }}
176
+ />
177
+ <UI.Select
178
+ wrapperClass="!h-14"
179
+ label={{ name: $t('constructor.props.colors') }}
180
+ type="buttons"
181
+ options={$optionsStore.COLOR_OPTIONS}
182
+ value={initialColor}
183
+ onUpdate={(option) => updateProperty('wrapperClass', twMerge(component.properties.wrapperClass, option.value), component, onPropertyChange)}
184
+ />
185
+ </div>
186
+ </div>
187
+ <div class="mt-2 flex w-full justify-around gap-2">
188
+ {#each component.properties.axes as axe, index}
189
+ <div class="flex items-start gap-2">
190
+ <h5 class="mt-1">{axe.name}</h5>
191
+ <UI.Slider
192
+ type="range"
193
+ number={{ minNum: -360, maxNum: 360, step: 10 }}
194
+ value={[component.properties.axes[index].minNum, component.properties.axes[index].maxNum]}
195
+ onUpdate={(value) => {
196
+ if (Array.isArray(value)) {
197
+ const axes = component.properties.axes
198
+
199
+ updateProperty(
200
+ 'axes',
201
+ axes.map((a: any, i: number) => (i === index ? { ...a, minNum: value[0], maxNum: value[1] } : a)),
202
+ component,
203
+ onPropertyChange,
204
+ )
205
+ console.log(component.properties.axes)
206
+ }
207
+ }}
208
+ />
209
+ </div>
210
+ {/each}
211
+ </div>
212
+ </div>
213
+ {:else}
214
+ <div>
215
+ <div class="relative mb-2 flex flex-row items-start justify-center">
216
+ <!-- Сообщение для отправки в ws по нажатию кнопки -->
217
+ <div class="flex w-1/3 flex-col items-center px-2">
218
+ <UI.Input
219
+ label={{ name: $t('constructor.props.id') }}
220
+ value={component.properties.id}
221
+ onUpdate={(value) => updateProperty('id', value as string, component, onPropertyChange)}
222
+ />
223
+ <UI.Select
224
+ label={{ name: $t('constructor.props.access') }}
225
+ type="buttons"
226
+ options={$optionsStore.ACCESS_OPTION}
227
+ value={$optionsStore.ACCESS_OPTION.find((o) => o.value === component.access)}
228
+ onUpdate={(option) => onPropertyChange({ access: option.value })}
229
+ />
230
+ </div>
231
+ <div class="flex w-1/3 flex-col px-2">
232
+ <UI.Input
233
+ label={{ name: $t('constructor.props.label') }}
234
+ value={component.properties.label.name}
235
+ onUpdate={(value) => updateProperty('label.name', value as string, component, onPropertyChange)}
236
+ />
237
+ <UI.Select
238
+ label={{ name: $t('constructor.props.align') }}
239
+ type="buttons"
240
+ value={initialAlign}
241
+ options={$optionsStore.TEXT_ALIGN_OPTIONS}
242
+ onUpdate={(option) => updateProperty('label.class', twMerge(component.properties.label.class, option.value), component, onPropertyChange)}
243
+ />
244
+ </div>
245
+ <div class="flex w-1/3 flex-col px-2">
246
+ <div class="mt-6 flex gap-2">
247
+ <UI.Button content={{ name: $t('constructor.props.buttonIcon') }} onClick={() => (showIconLib = true)} />
248
+ {#if showIconLib}
249
+ <Modal bind:isOpen={showIconLib} wrapperClass="w-130">
250
+ {#snippet main()}
251
+ <div class="grid grid-cols-3">
252
+ {#each ICONS as category}
253
+ <div class="relative m-1.5 rounded-xl border-2 border-(--border-color) p-3">
254
+ <div class="absolute -top-3.5 bg-(--back-color) px-1">{$t(`constructor.props.icon.${category[0]}`)}</div>
255
+ <div class="grid grid-cols-3 place-items-center gap-2">
256
+ {#each category[1] as icon}
257
+ <button
258
+ class="h-8 w-8 cursor-pointer [&_svg]:h-full [&_svg]:max-h-full [&_svg]:w-full [&_svg]:max-w-full"
259
+ onclick={() => {
260
+ updateProperty('buttonIcon', icon as string, component, onPropertyChange)
261
+ }}
262
+ >
263
+ {@html icon}
264
+ </button>{/each}
265
+ </div>
266
+ </div>
267
+ {/each}
268
+ </div>
269
+ {/snippet}
270
+ </Modal>
271
+ {/if}
272
+ {#if component.properties.buttonIcon}
273
+ <Button
274
+ wrapperClass="w-8.5 "
275
+ componentClass="p-0.5 bg-red"
276
+ content={{ icon: CrossIcon }}
277
+ onClick={() => {
278
+ updateProperty('buttonIcon', '', component, onPropertyChange)
279
+ }}
280
+ />
281
+ {/if}
282
+ </div>
283
+ <UI.Input
284
+ label={{ name: $t('constructor.props.joystick.axes') }}
285
+ value={component.properties.axes.map((axe: any) => axe.name).join(' ')}
286
+ help={{ info: $t('constructor.props.joystick.axes.info'), regExp: /^[\p{L}0-9\-_":{}]+ +[\p{L}0-9\-_":{}]+(?: +[\p{L}0-9\-_":{}]+)?$/u }}
287
+ maxlength={100}
288
+ onUpdate={(value) => {
289
+ const stringValue = value as string
290
+ const spaceCount = (stringValue.match(/\s/g) || []).length
291
+ if (spaceCount > 2) {
292
+ return
293
+ }
294
+ const parts = stringValue.trim().split(/\s+/)
295
+ updateProperty(
296
+ 'axes',
297
+ parts.map((a: any, index: number) => {
298
+ let axeIndex = parts.length == 2 && component.properties.axes.length === 3 ? index + 1 : index
299
+ return {
300
+ name: a,
301
+ minNum: component.properties.axes[axeIndex] ? component.properties.axes[axeIndex].minNum : -100,
302
+ maxNum: component.properties.axes[axeIndex] ? component.properties.axes[axeIndex].maxNum : 100,
303
+ }
304
+ }),
305
+ component,
306
+ onPropertyChange,
307
+ )
308
+ }}
309
+ />
310
+
311
+ <UI.Select
312
+ wrapperClass="!h-14"
313
+ label={{ name: $t('constructor.props.colors') }}
314
+ type="buttons"
315
+ options={$optionsStore.COLOR_OPTIONS}
316
+ value={initialColor}
317
+ onUpdate={(option) => updateProperty('wrapperClass', twMerge(component.properties.wrapperClass, option.value), component, onPropertyChange)}
318
+ />
319
+ </div>
320
+ </div>
321
+ <div class="mt-2 flex w-full justify-around gap-2">
322
+ {#each component.properties.axes as axe, index}
323
+ <div class="flex items-start gap-2">
324
+ <h5 class="mt-1">{axe.name}</h5>
325
+ <UI.Slider
326
+ type="range"
327
+ number={{ minNum: -360, maxNum: 360, step: 10 }}
328
+ value={[component.properties.axes[index].minNum, component.properties.axes[index].maxNum]}
329
+ onUpdate={(value) => {
330
+ if (Array.isArray(value)) {
331
+ const axes = component.properties.axes
332
+
333
+ updateProperty(
334
+ 'axes',
335
+ axes.map((a: any, i: number) => (i === index ? { ...a, minNum: value[0], maxNum: value[1] } : a)),
336
+ component,
337
+ onPropertyChange,
338
+ )
339
+ console.log(component.properties.axes)
340
+ }
341
+ }}
342
+ />
343
+ </div>
344
+ {/each}
345
+ </div>
346
+ </div>
347
+ {/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, {}, "">;
@@ -8,6 +8,7 @@
8
8
  wrapperClass = '',
9
9
  label = { name: '', class: '' },
10
10
  value = $bindable(0),
11
+ type = 'vertical',
11
12
  number = {
12
13
  minNum: 0,
13
14
  maxNum: 100,
@@ -38,17 +39,41 @@
38
39
  return (((Math.min(Math.max(value, min), max) - min) / (max - min)) * 100) as number
39
40
  }
40
41
  })
42
+
43
+ const roundToClean = (num: number): number => {
44
+ if (Number.isInteger(num)) return num
45
+
46
+ const rounded1 = Number(num.toFixed(1))
47
+ if (Math.abs(rounded1 - num) < 1e-10) return rounded1
48
+
49
+ const rounded2 = Number(num.toFixed(2))
50
+ if (Math.abs(rounded2 - num) < 1e-10) return rounded2
51
+
52
+ return rounded2
53
+ }
41
54
  </script>
42
55
 
43
- <div id={`${id}-${crypto.randomUUID().slice(0, 6)}`} class={twMerge(`relative flex w-full flex-col items-center`, wrapperClass)}>
56
+ <div
57
+ id={`${id}-${crypto.randomUUID().slice(0, 6)}`}
58
+ class={twMerge(`relative flex ${type == 'vertical' ? 'h-full' : ''} w-full flex-col items-center`, wrapperClass)}
59
+ >
44
60
  {#if label.name}
45
61
  <h5 class={twMerge(` w-full px-4 text-center`, label.class)}>{label.name}</h5>
46
62
  {/if}
47
63
 
48
- <div class="flex h-7 w-full items-center gap-2 rounded-full bg-(--bg-color) px-2">
49
- <span class="m-auto font-semibold">{numericValue?.toFixed(2)}{number.units}</span>
50
- <div class="relative my-auto h-3.5 w-[85%] rounded-full bg-(--back-color)/40">
51
- <div class="absolute top-0 left-0 flex h-full rounded-full bg-(--field-color)" style="width: {progressPercent()}%;"></div>
64
+ {#if type == 'vertical'}
65
+ <div class="flex h-full w-fit min-w-16 flex-col items-center gap-2 rounded-full bg-(--bg-color) px-2">
66
+ <div class="relative my-auto h-[80%] w-[70%] rounded-full bg-(--back-color)/40">
67
+ <div class="absolute bottom-0 left-0 flex w-full rounded-full bg-(--field-color)" style="height: {progressPercent()}%;"></div>
68
+ </div>
69
+ <span class="m-auto font-semibold">{roundToClean(Number(numericValue))}{number.units}</span>
70
+ </div>
71
+ {:else}
72
+ <div class="flex h-7 w-full items-center gap-2 rounded-full bg-(--bg-color) px-2">
73
+ <span class="m-auto font-semibold">{roundToClean(Number(numericValue))}{number.units}</span>
74
+ <div class="relative my-auto h-3.5 w-[85%] rounded-full bg-(--back-color)/40">
75
+ <div class="absolute top-0 left-0 flex h-full rounded-full bg-(--field-color)" style="width: {progressPercent()}%;"></div>
76
+ </div>
52
77
  </div>
53
- </div>
78
+ {/if}
54
79
  </div>
@@ -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: '' },