poe-svelte-ui-lib 1.0.0 → 1.0.2

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 (36) hide show
  1. package/LICENSE +3 -3
  2. package/dist/Accordion/Accordion.svelte +53 -53
  3. package/dist/Accordion/AccordionProps.svelte +70 -70
  4. package/dist/Button/Button.svelte +144 -144
  5. package/dist/Button/ButtonProps.svelte +200 -200
  6. package/dist/ColorPicker/ColorPicker.svelte +207 -207
  7. package/dist/ColorPicker/ColorPickerProps.svelte +100 -100
  8. package/dist/FileAttach/FileAttach.svelte +103 -103
  9. package/dist/Graph/Graph.svelte +270 -270
  10. package/dist/Graph/GraphProps.svelte +56 -56
  11. package/dist/Input/Input.svelte +239 -239
  12. package/dist/Input/InputProps.svelte +221 -221
  13. package/dist/Loader.svelte +12 -12
  14. package/dist/MessageModal.svelte +54 -54
  15. package/dist/ProgressBar/ProgressBar.svelte +48 -48
  16. package/dist/ProgressBar/ProgressBarProps.svelte +145 -145
  17. package/dist/Select/Select.svelte +191 -187
  18. package/dist/Select/SelectProps.svelte +260 -260
  19. package/dist/Slider/Slider.svelte +260 -260
  20. package/dist/Slider/SliderProps.svelte +161 -161
  21. package/dist/Switch/Switch.svelte +83 -83
  22. package/dist/Switch/SwitchProps.svelte +144 -144
  23. package/dist/Table/Table.svelte +276 -276
  24. package/dist/Table/TableProps.svelte +286 -286
  25. package/dist/TextField/TextField.svelte +22 -22
  26. package/dist/TextField/TextFieldProps.svelte +92 -92
  27. package/dist/{appIcons → libIcons}/ButtonAdd.svelte +10 -10
  28. package/dist/{appIcons → libIcons}/ButtonDelete.svelte +13 -13
  29. package/dist/{appIcons → libIcons}/LoaderRotate.svelte +9 -9
  30. package/dist/locales/CircleFlagsEn.svelte +14 -14
  31. package/dist/locales/CircleFlagsRu.svelte +8 -8
  32. package/dist/locales/CircleFlagsZh.svelte +8 -8
  33. package/package.json +49 -47
  34. /package/dist/{appIcons → libIcons}/ButtonAdd.svelte.d.ts +0 -0
  35. /package/dist/{appIcons → libIcons}/ButtonDelete.svelte.d.ts +0 -0
  36. /package/dist/{appIcons → libIcons}/LoaderRotate.svelte.d.ts +0 -0
@@ -1,207 +1,207 @@
1
- <!-- $lib/ElementsUI/ColorPicker.svelte -->
2
- <script lang="ts">
3
- import { t } from '../locales/i18n'
4
- import type { IColorPickerProps } from '../types'
5
-
6
- let {
7
- id = { name: '', value: crypto.randomUUID() },
8
- wrapperClass = '',
9
- label = { name: '', class: '' },
10
- value = [0, 0, 0],
11
- onChange = () => {},
12
- }: IColorPickerProps = $props()
13
-
14
- const hsv = $state({ h: 0, s: 100, v: 100 })
15
- let huePointer = $state(0)
16
- let brightnessPointer = $state(100)
17
- let mode = $state<'hsv' | 'white'>('hsv')
18
- let whiteValue = $state(100)
19
-
20
- $effect(() => {
21
- if (value.length !== 3) return
22
-
23
- const [r, g, b] = value
24
- const isWhite = r === g && g === b
25
- mode = isWhite ? 'white' : 'hsv'
26
- if (isWhite) {
27
- whiteValue = Math.round((r / 255) * 100)
28
- return
29
- }
30
-
31
- const normalized = value.map((v) => v / 255)
32
- const max = Math.max(...normalized)
33
- const min = Math.min(...normalized)
34
- const delta = max - min
35
- let h = 0
36
- if (delta !== 0) {
37
- const [rN, gN, bN] = normalized
38
- if (max === rN) h = ((gN - bN) / delta) % 6
39
- else if (max === gN) h = (bN - rN) / delta + 2
40
- else h = (rN - gN) / delta + 4
41
- h *= 60
42
- if (h < 0) h += 360
43
- }
44
- const s = max ? (delta / max) * 100 : 0
45
- const v = max * 100
46
- hsv.h = Math.round(h)
47
- hsv.s = Math.round(s)
48
- hsv.v = Math.round(v)
49
- huePointer = (h / 360) * 100
50
- brightnessPointer = v
51
- })
52
-
53
- const hsvToRgb = (h: number, s: number, v: number): [number, number, number] => {
54
- s /= 100
55
- v /= 100
56
- const c = v * s
57
- const x = c * (1 - Math.abs(((h / 60) % 2) - 1))
58
- const m = v - c
59
- let r = 0,
60
- g = 0,
61
- b = 0
62
- if (h < 60) [r, g, b] = [c, x, 0]
63
- else if (h < 120) [r, g, b] = [x, c, 0]
64
- else if (h < 180) [r, g, b] = [0, c, x]
65
- else if (h < 240) [r, g, b] = [0, x, c]
66
- else if (h < 300) [r, g, b] = [x, 0, c]
67
- else [r, g, b] = [c, 0, x]
68
- return [Math.round((r + m) * 255), Math.round((g + m) * 255), Math.round((b + m) * 255)]
69
- }
70
-
71
- const handleDrag = (e: MouseEvent, target: 'hue' | 'brightness' | 'white') => {
72
- const slider = document.querySelector(`.${target}-slider`) as HTMLElement
73
- const rect = slider.getBoundingClientRect()
74
- let currentHSV = { ...hsv }
75
- let currentWhite = whiteValue
76
- if (target === 'hue' || target === 'brightness') {
77
- if (mode === 'white') hsv.s = 100
78
- mode = 'hsv'
79
- } else mode = 'white'
80
- const onMove = (event: MouseEvent) => {
81
- const x = Math.max(0, Math.min(event.clientX - rect.left, rect.width))
82
- const percent = (x / rect.width) * 100
83
- if (target === 'hue') {
84
- huePointer = percent
85
- currentHSV.h = (x / rect.width) * 360
86
- hsv.h = currentHSV.h
87
- } else if (target === 'brightness') {
88
- brightnessPointer = percent
89
- currentHSV.v = percent
90
- hsv.v = currentHSV.v
91
- } else if (target === 'white') {
92
- currentWhite = percent
93
- whiteValue = currentWhite
94
- }
95
- }
96
- const onUp = () => {
97
- window.removeEventListener('mousemove', onMove)
98
- window.removeEventListener('mouseup', onUp)
99
-
100
- if (mode === 'hsv') {
101
- onChange(hsvToRgb(currentHSV.h, hsv.s, currentHSV.v))
102
- } else {
103
- const val = Math.round((currentWhite / 100) * 255)
104
- onChange([val, val, val])
105
- }
106
- }
107
- onMove(e)
108
- window.addEventListener('mousemove', onMove)
109
- window.addEventListener('mouseup', onUp)
110
- }
111
-
112
- const rgb = $derived(() => (mode === 'white' ? [whiteValue, whiteValue, whiteValue].map((v) => Math.round((v / 100) * 255)) : hsvToRgb(hsv.h, hsv.s, hsv.v)))
113
- const hex = $derived(() =>
114
- rgb()
115
- .map((v) => v.toString(16).padStart(2, '0'))
116
- .join(' ')
117
- .toUpperCase(),
118
- )
119
- const previewBaseColor = $derived(() => (mode === 'white' ? [255, 255, 255].map((c) => Math.round((whiteValue / 100) * c)) : hsvToRgb(hsv.h, hsv.s, 100)))
120
-
121
- const textColor = $derived(() => {
122
- const [r, g, b] = rgb()
123
- const luminance = (r * 299 + g * 587 + b * 114) / 1000
124
- return luminance > 128 ? 'text-black' : 'text-white'
125
- })
126
- </script>
127
-
128
- <div id={id.value} class="relative flex w-full flex-col items-center {wrapperClass}">
129
- {#if label.name}
130
- <h5 class={`mb-2 w-full px-4 text-center ${label.class}`}>{label.name}</h5>
131
- {/if}
132
-
133
- <div class="flex w-full flex-row items-center gap-2">
134
- <!-- Слайдеры цвета -->
135
- <div class="flex w-full flex-col gap-2">
136
- <!-- Выбор цвета -->
137
- <div
138
- class="hue-slider relative h-7 w-full cursor-pointer overflow-hidden rounded-full border border-gray-400"
139
- role="slider"
140
- aria-valuenow={null}
141
- tabindex={null}
142
- onmousedown={(e) => handleDrag(e, 'hue')}
143
- >
144
- <div
145
- class="absolute inset-0"
146
- style={`background: linear-gradient(to right, ${Array.from({ length: 7 }, (_, i) => {
147
- const [r, g, b] = hsvToRgb(i * 60, 100, 100)
148
- return `rgb(${r},${g},${b})`
149
- }).join(', ')})`}
150
- ></div>
151
- {#if mode === 'hsv'}
152
- <div
153
- class="pointer-events-none absolute top-1/2 h-7 w-1 -translate-x-1/2 -translate-y-1/2 rounded-full border-2 border-white"
154
- style={`left: ${huePointer}%; background: rgb(${hsvToRgb(hsv.h, 100, 100).join(',')})`}
155
- ></div>
156
- {/if}
157
- </div>
158
-
159
- <!-- Яркость цвета -->
160
- <div
161
- class="brightness-slider relative h-4 w-full cursor-pointer overflow-hidden rounded-full border border-gray-400"
162
- role="slider"
163
- aria-valuenow={null}
164
- tabindex={null}
165
- onmousedown={(e) => handleDrag(e, 'brightness')}
166
- >
167
- {#if mode === 'hsv'}
168
- <div class="absolute inset-0" style={`background: linear-gradient(to right, rgb(0,0,0), rgb(${hsvToRgb(hsv.h, hsv.s, 100).join(',')}))`}></div>
169
-
170
- <div
171
- class="pointer-events-none absolute top-1/2 h-7 w-1 -translate-x-1/2 -translate-y-1/2 rounded-full border-2 border-white"
172
- style={`left: ${brightnessPointer}%; background: rgb(${hsvToRgb(hsv.h, hsv.s, hsv.v).join(',')})`}
173
- ></div>
174
- {/if}
175
- </div>
176
-
177
- <!-- Яркость белого цвета -->
178
- <p class="h-4 px-4 text-start font-bold">{$t('component.colorpicker.whitehue')}</p>
179
- <div
180
- class="white-slider relative h-4 w-full cursor-pointer overflow-hidden rounded-full border border-gray-400"
181
- role="slider"
182
- aria-valuenow={null}
183
- tabindex={null}
184
- onmousedown={(e) => handleDrag(e, 'white')}
185
- >
186
- <div class="absolute inset-0 bg-gradient-to-r from-black to-white"></div>
187
- {#if mode === 'white'}
188
- <div
189
- class="pointer-events-none absolute top-1/2 h-7 w-1 -translate-x-1/2 -translate-y-1/2 rounded-full border-2 border-white"
190
- style={`left: ${whiteValue}%; background: rgb(${[255, 255, 255].map((c) => Math.round((whiteValue / 100) * c)).join(',')})`}
191
- ></div>
192
- {/if}
193
- </div>
194
- </div>
195
-
196
- <!-- Превью цвета -->
197
- <div
198
- class={`flex h-26 w-28 flex-col justify-center gap-1 rounded-2xl border border-gray-400 px-2 font-mono text-sm select-none ${textColor()}`}
199
- style={`background: rgb(${previewBaseColor().join(',')})`}
200
- >
201
- <div class="flex flex-col items-center">
202
- <span class="w-full flex-shrink-0">{mode === 'white' ? 'White' : 'RGB'}</span>
203
- <div class="пфз-1 w-full text-center tracking-wide">{hex()}</div>
204
- </div>
205
- </div>
206
- </div>
207
- </div>
1
+ <!-- $lib/ElementsUI/ColorPicker.svelte -->
2
+ <script lang="ts">
3
+ import { t } from '../locales/i18n'
4
+ import type { IColorPickerProps } from '../types'
5
+
6
+ let {
7
+ id = { name: '', value: crypto.randomUUID() },
8
+ wrapperClass = '',
9
+ label = { name: '', class: '' },
10
+ value = [0, 0, 0],
11
+ onChange = () => {},
12
+ }: IColorPickerProps = $props()
13
+
14
+ const hsv = $state({ h: 0, s: 100, v: 100 })
15
+ let huePointer = $state(0)
16
+ let brightnessPointer = $state(100)
17
+ let mode = $state<'hsv' | 'white'>('hsv')
18
+ let whiteValue = $state(100)
19
+
20
+ $effect(() => {
21
+ if (value.length !== 3) return
22
+
23
+ const [r, g, b] = value
24
+ const isWhite = r === g && g === b
25
+ mode = isWhite ? 'white' : 'hsv'
26
+ if (isWhite) {
27
+ whiteValue = Math.round((r / 255) * 100)
28
+ return
29
+ }
30
+
31
+ const normalized = value.map((v) => v / 255)
32
+ const max = Math.max(...normalized)
33
+ const min = Math.min(...normalized)
34
+ const delta = max - min
35
+ let h = 0
36
+ if (delta !== 0) {
37
+ const [rN, gN, bN] = normalized
38
+ if (max === rN) h = ((gN - bN) / delta) % 6
39
+ else if (max === gN) h = (bN - rN) / delta + 2
40
+ else h = (rN - gN) / delta + 4
41
+ h *= 60
42
+ if (h < 0) h += 360
43
+ }
44
+ const s = max ? (delta / max) * 100 : 0
45
+ const v = max * 100
46
+ hsv.h = Math.round(h)
47
+ hsv.s = Math.round(s)
48
+ hsv.v = Math.round(v)
49
+ huePointer = (h / 360) * 100
50
+ brightnessPointer = v
51
+ })
52
+
53
+ const hsvToRgb = (h: number, s: number, v: number): [number, number, number] => {
54
+ s /= 100
55
+ v /= 100
56
+ const c = v * s
57
+ const x = c * (1 - Math.abs(((h / 60) % 2) - 1))
58
+ const m = v - c
59
+ let r = 0,
60
+ g = 0,
61
+ b = 0
62
+ if (h < 60) [r, g, b] = [c, x, 0]
63
+ else if (h < 120) [r, g, b] = [x, c, 0]
64
+ else if (h < 180) [r, g, b] = [0, c, x]
65
+ else if (h < 240) [r, g, b] = [0, x, c]
66
+ else if (h < 300) [r, g, b] = [x, 0, c]
67
+ else [r, g, b] = [c, 0, x]
68
+ return [Math.round((r + m) * 255), Math.round((g + m) * 255), Math.round((b + m) * 255)]
69
+ }
70
+
71
+ const handleDrag = (e: MouseEvent, target: 'hue' | 'brightness' | 'white') => {
72
+ const slider = document.querySelector(`.${target}-slider`) as HTMLElement
73
+ const rect = slider.getBoundingClientRect()
74
+ let currentHSV = { ...hsv }
75
+ let currentWhite = whiteValue
76
+ if (target === 'hue' || target === 'brightness') {
77
+ if (mode === 'white') hsv.s = 100
78
+ mode = 'hsv'
79
+ } else mode = 'white'
80
+ const onMove = (event: MouseEvent) => {
81
+ const x = Math.max(0, Math.min(event.clientX - rect.left, rect.width))
82
+ const percent = (x / rect.width) * 100
83
+ if (target === 'hue') {
84
+ huePointer = percent
85
+ currentHSV.h = (x / rect.width) * 360
86
+ hsv.h = currentHSV.h
87
+ } else if (target === 'brightness') {
88
+ brightnessPointer = percent
89
+ currentHSV.v = percent
90
+ hsv.v = currentHSV.v
91
+ } else if (target === 'white') {
92
+ currentWhite = percent
93
+ whiteValue = currentWhite
94
+ }
95
+ }
96
+ const onUp = () => {
97
+ window.removeEventListener('mousemove', onMove)
98
+ window.removeEventListener('mouseup', onUp)
99
+
100
+ if (mode === 'hsv') {
101
+ onChange(hsvToRgb(currentHSV.h, hsv.s, currentHSV.v))
102
+ } else {
103
+ const val = Math.round((currentWhite / 100) * 255)
104
+ onChange([val, val, val])
105
+ }
106
+ }
107
+ onMove(e)
108
+ window.addEventListener('mousemove', onMove)
109
+ window.addEventListener('mouseup', onUp)
110
+ }
111
+
112
+ const rgb = $derived(() => (mode === 'white' ? [whiteValue, whiteValue, whiteValue].map((v) => Math.round((v / 100) * 255)) : hsvToRgb(hsv.h, hsv.s, hsv.v)))
113
+ const hex = $derived(() =>
114
+ rgb()
115
+ .map((v) => v.toString(16).padStart(2, '0'))
116
+ .join(' ')
117
+ .toUpperCase(),
118
+ )
119
+ const previewBaseColor = $derived(() => (mode === 'white' ? [255, 255, 255].map((c) => Math.round((whiteValue / 100) * c)) : hsvToRgb(hsv.h, hsv.s, 100)))
120
+
121
+ const textColor = $derived(() => {
122
+ const [r, g, b] = rgb()
123
+ const luminance = (r * 299 + g * 587 + b * 114) / 1000
124
+ return luminance > 128 ? 'text-black' : 'text-white'
125
+ })
126
+ </script>
127
+
128
+ <div id={id.value} class="relative flex w-full flex-col items-center {wrapperClass}">
129
+ {#if label.name}
130
+ <h5 class={`mb-2 w-full px-4 text-center ${label.class}`}>{label.name}</h5>
131
+ {/if}
132
+
133
+ <div class="flex w-full flex-row items-center gap-2">
134
+ <!-- Слайдеры цвета -->
135
+ <div class="flex w-full flex-col gap-2">
136
+ <!-- Выбор цвета -->
137
+ <div
138
+ class="hue-slider relative h-7 w-full cursor-pointer overflow-hidden rounded-full border border-gray-400"
139
+ role="slider"
140
+ aria-valuenow={null}
141
+ tabindex={null}
142
+ onmousedown={(e) => handleDrag(e, 'hue')}
143
+ >
144
+ <div
145
+ class="absolute inset-0"
146
+ style={`background: linear-gradient(to right, ${Array.from({ length: 7 }, (_, i) => {
147
+ const [r, g, b] = hsvToRgb(i * 60, 100, 100)
148
+ return `rgb(${r},${g},${b})`
149
+ }).join(', ')})`}
150
+ ></div>
151
+ {#if mode === 'hsv'}
152
+ <div
153
+ class="pointer-events-none absolute top-1/2 h-7 w-1 -translate-x-1/2 -translate-y-1/2 rounded-full border-2 border-white"
154
+ style={`left: ${huePointer}%; background: rgb(${hsvToRgb(hsv.h, 100, 100).join(',')})`}
155
+ ></div>
156
+ {/if}
157
+ </div>
158
+
159
+ <!-- Яркость цвета -->
160
+ <div
161
+ class="brightness-slider relative h-4 w-full cursor-pointer overflow-hidden rounded-full border border-gray-400"
162
+ role="slider"
163
+ aria-valuenow={null}
164
+ tabindex={null}
165
+ onmousedown={(e) => handleDrag(e, 'brightness')}
166
+ >
167
+ {#if mode === 'hsv'}
168
+ <div class="absolute inset-0" style={`background: linear-gradient(to right, rgb(0,0,0), rgb(${hsvToRgb(hsv.h, hsv.s, 100).join(',')}))`}></div>
169
+
170
+ <div
171
+ class="pointer-events-none absolute top-1/2 h-7 w-1 -translate-x-1/2 -translate-y-1/2 rounded-full border-2 border-white"
172
+ style={`left: ${brightnessPointer}%; background: rgb(${hsvToRgb(hsv.h, hsv.s, hsv.v).join(',')})`}
173
+ ></div>
174
+ {/if}
175
+ </div>
176
+
177
+ <!-- Яркость белого цвета -->
178
+ <p class="h-4 px-4 text-start font-bold">{$t('component.colorpicker.whitehue')}</p>
179
+ <div
180
+ class="white-slider relative h-4 w-full cursor-pointer overflow-hidden rounded-full border border-gray-400"
181
+ role="slider"
182
+ aria-valuenow={null}
183
+ tabindex={null}
184
+ onmousedown={(e) => handleDrag(e, 'white')}
185
+ >
186
+ <div class="absolute inset-0 bg-gradient-to-r from-black to-white"></div>
187
+ {#if mode === 'white'}
188
+ <div
189
+ class="pointer-events-none absolute top-1/2 h-7 w-1 -translate-x-1/2 -translate-y-1/2 rounded-full border-2 border-white"
190
+ style={`left: ${whiteValue}%; background: rgb(${[255, 255, 255].map((c) => Math.round((whiteValue / 100) * c)).join(',')})`}
191
+ ></div>
192
+ {/if}
193
+ </div>
194
+ </div>
195
+
196
+ <!-- Превью цвета -->
197
+ <div
198
+ class={`flex h-26 w-28 flex-col justify-center gap-1 rounded-2xl border border-gray-400 px-2 font-mono text-sm select-none ${textColor()}`}
199
+ style={`background: rgb(${previewBaseColor().join(',')})`}
200
+ >
201
+ <div class="flex flex-col items-center">
202
+ <span class="w-full flex-shrink-0">{mode === 'white' ? 'White' : 'RGB'}</span>
203
+ <div class="пфз-1 w-full text-center tracking-wide">{hex()}</div>
204
+ </div>
205
+ </div>
206
+ </div>
207
+ </div>
@@ -1,100 +1,100 @@
1
- <!-- $lib/ElementsUI/ButtonProps.svelte -->
2
- <script lang="ts">
3
- import { t } from '../locales/i18n'
4
- import type { UIComponent, IColorPickerProps } from '../types'
5
- import * as UI from '../index'
6
- import { getContext } from 'svelte'
7
- import { optionsStore } from '../options'
8
-
9
- const { component, onPropertyChange } = $props<{
10
- component: UIComponent & { properties: Partial<IColorPickerProps> }
11
- onPropertyChange: (value: string | object) => void
12
- }>()
13
-
14
- const DeviceVariables = getContext<{ value: string; name: string }[]>('DeviceVariables')
15
- let VARIABLE_OPTIONS = $derived(
16
- DeviceVariables.map((variable: { value: string; name: string }) => ({
17
- id: variable.name,
18
- value: variable.value,
19
- name: `${variable.value} | ${variable.name}`,
20
- })),
21
- )
22
-
23
- const initialAlign = $derived(
24
- $optionsStore.ALIGN_OPTIONS.find((a) =>
25
- (a.value as string).includes(component.properties.label?.class?.split(' ').find((cls: string) => cls.startsWith('text-'))),
26
- ),
27
- )
28
-
29
- const handleLabelAlign = (align: string) => {
30
- let labelClass = component.properties.label.class || ''
31
- labelClass = labelClass
32
- .split(' ')
33
- .filter((cls: string) => !cls.startsWith('text-'))
34
- .join(' ')
35
- if (align) {
36
- labelClass += ` ${align}`
37
- }
38
- updateProperty('label.class', labelClass)
39
- }
40
-
41
- /* Обновление свойства */
42
- const updateProperty = (path: string, value: string | object | string[]) => {
43
- const newProperties = JSON.parse(JSON.stringify(component.properties))
44
- const parts = path.split('.')
45
- let obj = newProperties
46
- for (let i = 0; i < parts.length - 1; i++) {
47
- const part = parts[i]
48
- if (!obj[part]) obj[part] = {}
49
- obj = obj[part]
50
- }
51
- obj[parts[parts.length - 1]] = value
52
- onPropertyChange(newProperties)
53
- }
54
- </script>
55
-
56
- {#if component && component.properties}
57
- <div class="relative flex flex-row items-start justify-center">
58
- <!-- Сообщение для отправки в ws по нажатию кнопки -->
59
- <div class="flex w-1/3 flex-col items-center px-2">
60
- <UI.Select
61
- label={{ name: $t('service.constructor.props.variable') }}
62
- options={VARIABLE_OPTIONS}
63
- value={VARIABLE_OPTIONS.find((opt) => opt.value === component.properties.id.value)}
64
- onUpdate={(value) => {
65
- updateProperty('id.name', (value.name as string).split('|')[1].trim())
66
- updateProperty('id.value', value.value as string)
67
- updateProperty('eventHandler.Variables', value.value as string)
68
- }}
69
- />
70
- <UI.Select
71
- wrapperClass="w-full"
72
- label={{ name: $t('service.constructor.props.action') }}
73
- type="buttons"
74
- value={$optionsStore.SHORT_ARGUMENT_OPTION.find((h) => h.value === component.properties.eventHandler.Argument)}
75
- options={$optionsStore.SHORT_ARGUMENT_OPTION}
76
- onUpdate={(option) => {
77
- updateProperty('eventHandler.Argument', option.value as string)
78
- }}
79
- />
80
- </div>
81
- <div class="flex w-1/3 flex-col px-2">
82
- <UI.Input
83
- wrapperClass="w-full"
84
- label={{ name: $t('service.constructor.props.label') }}
85
- value={component.properties.label.name}
86
- type="text"
87
- componentClass="w-full"
88
- onUpdate={(value) => updateProperty('label.name', value as string)}
89
- />
90
- <UI.Select
91
- wrapperClass="w-full"
92
- label={{ name: $t('service.constructor.props.align') }}
93
- type="buttons"
94
- value={initialAlign}
95
- options={$optionsStore.ALIGN_OPTIONS}
96
- onUpdate={(option) => handleLabelAlign(option.value as string)}
97
- />
98
- </div>
99
- </div>
100
- {/if}
1
+ <!-- $lib/ElementsUI/ButtonProps.svelte -->
2
+ <script lang="ts">
3
+ import { t } from '../locales/i18n'
4
+ import type { UIComponent, IColorPickerProps } from '../types'
5
+ import * as UI from '../index'
6
+ import { getContext } from 'svelte'
7
+ import { optionsStore } from '../options'
8
+
9
+ const { component, onPropertyChange } = $props<{
10
+ component: UIComponent & { properties: Partial<IColorPickerProps> }
11
+ onPropertyChange: (value: string | object) => void
12
+ }>()
13
+
14
+ const DeviceVariables = getContext<{ value: string; name: string }[]>('DeviceVariables')
15
+ let VARIABLE_OPTIONS = $derived(
16
+ DeviceVariables.map((variable: { value: string; name: string }) => ({
17
+ id: variable.name,
18
+ value: variable.value,
19
+ name: `${variable.value} | ${variable.name}`,
20
+ })),
21
+ )
22
+
23
+ const initialAlign = $derived(
24
+ $optionsStore.ALIGN_OPTIONS.find((a) =>
25
+ (a.value as string).includes(component.properties.label?.class?.split(' ').find((cls: string) => cls.startsWith('text-'))),
26
+ ),
27
+ )
28
+
29
+ const handleLabelAlign = (align: string) => {
30
+ let labelClass = component.properties.label.class || ''
31
+ labelClass = labelClass
32
+ .split(' ')
33
+ .filter((cls: string) => !cls.startsWith('text-'))
34
+ .join(' ')
35
+ if (align) {
36
+ labelClass += ` ${align}`
37
+ }
38
+ updateProperty('label.class', labelClass)
39
+ }
40
+
41
+ /* Обновление свойства */
42
+ const updateProperty = (path: string, value: string | object | string[]) => {
43
+ const newProperties = JSON.parse(JSON.stringify(component.properties))
44
+ const parts = path.split('.')
45
+ let obj = newProperties
46
+ for (let i = 0; i < parts.length - 1; i++) {
47
+ const part = parts[i]
48
+ if (!obj[part]) obj[part] = {}
49
+ obj = obj[part]
50
+ }
51
+ obj[parts[parts.length - 1]] = value
52
+ onPropertyChange(newProperties)
53
+ }
54
+ </script>
55
+
56
+ {#if component && component.properties}
57
+ <div class="relative flex flex-row items-start justify-center">
58
+ <!-- Сообщение для отправки в ws по нажатию кнопки -->
59
+ <div class="flex w-1/3 flex-col items-center px-2">
60
+ <UI.Select
61
+ label={{ name: $t('service.constructor.props.variable') }}
62
+ options={VARIABLE_OPTIONS}
63
+ value={VARIABLE_OPTIONS.find((opt) => opt.value === component.properties.id.value)}
64
+ onUpdate={(value) => {
65
+ updateProperty('id.name', (value.name as string).split('|')[1].trim())
66
+ updateProperty('id.value', value.value as string)
67
+ updateProperty('eventHandler.Variables', value.value as string)
68
+ }}
69
+ />
70
+ <UI.Select
71
+ wrapperClass="w-full"
72
+ label={{ name: $t('service.constructor.props.action') }}
73
+ type="buttons"
74
+ value={$optionsStore.SHORT_ARGUMENT_OPTION.find((h) => h.value === component.properties.eventHandler.Argument)}
75
+ options={$optionsStore.SHORT_ARGUMENT_OPTION}
76
+ onUpdate={(option) => {
77
+ updateProperty('eventHandler.Argument', option.value as string)
78
+ }}
79
+ />
80
+ </div>
81
+ <div class="flex w-1/3 flex-col px-2">
82
+ <UI.Input
83
+ wrapperClass="w-full"
84
+ label={{ name: $t('service.constructor.props.label') }}
85
+ value={component.properties.label.name}
86
+ type="text"
87
+ componentClass="w-full"
88
+ onUpdate={(value) => updateProperty('label.name', value as string)}
89
+ />
90
+ <UI.Select
91
+ wrapperClass="w-full"
92
+ label={{ name: $t('service.constructor.props.align') }}
93
+ type="buttons"
94
+ value={initialAlign}
95
+ options={$optionsStore.ALIGN_OPTIONS}
96
+ onUpdate={(option) => handleLabelAlign(option.value as string)}
97
+ />
98
+ </div>
99
+ </div>
100
+ {/if}