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
@@ -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 { IInputProps, UIComponent, ISelectOption } from '../types'
4
+ import type { IInputProps, UIComponent, ISelectOption, 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<IInputProps> }
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
 
@@ -33,7 +33,7 @@
33
33
  )
34
34
 
35
35
  /* Обновление свойства */
36
- const updateProperty = (path: string, value: string | object | boolean | number | RegExp, name?: string) => {
36
+ const updateProperty = (path: string, value: string | object | boolean | number | RegExp) => {
37
37
  const newProperties = JSON.parse(JSON.stringify(component.properties))
38
38
  if (path === 'regExp') {
39
39
  try {
@@ -68,7 +68,7 @@
68
68
  }
69
69
 
70
70
  obj[parts[parts.length - 1]] = value
71
- onPropertyChange(newProperties, name)
71
+ onPropertyChange({ properties: newProperties })
72
72
  }
73
73
 
74
74
  const handleOptionColorChange = (color: string) => {
@@ -96,8 +96,8 @@
96
96
  options={VARIABLE_OPTIONS}
97
97
  value={VARIABLE_OPTIONS.find((opt) => opt.value === component.properties.id)}
98
98
  onUpdate={(value) => {
99
- updateProperty('id', value.value as string, value.name?.split('—')[1].trim())
100
- updateProperty('eventHandler.Variables', value.value as string)
99
+ updateProperty('id', value.value as string)
100
+ onPropertyChange({ name: value.name?.split('—')[1].trim(), eventHandler: { Variables: value.value as string } })
101
101
  }}
102
102
  />
103
103
  <UI.Select
@@ -105,7 +105,7 @@
105
105
  type="buttons"
106
106
  options={$optionsStore.ACCESS_OPTION}
107
107
  value={$optionsStore.ACCESS_OPTION.find((o) => o.value === component.access)}
108
- onUpdate={(option) => onPropertyChange(null, null, option.value)}
108
+ onUpdate={(option) => onPropertyChange({ access: option.value })}
109
109
  />
110
110
  <UI.Select
111
111
  label={{ name: $t('constructor.props.type') }}
@@ -128,10 +128,7 @@
128
128
  maxlength={150}
129
129
  help={{ info: $t('constructor.props.regexp.info') }}
130
130
  componentClass={isValidRegExp === false ? '!border-2 !border-red-400' : ''}
131
- onUpdate={(value) => {
132
- console.log(value)
133
- updateProperty('help.regExp', value as string)
134
- }}
131
+ onUpdate={(value) => updateProperty('help.regExp', value as string)}
135
132
  />
136
133
  {:else if component.properties.type === 'number' && !component.properties.readonly && !component.properties.disabled}
137
134
  <UI.Input
@@ -173,10 +170,7 @@
173
170
  label={{ name: $t('constructor.props.readonly') }}
174
171
  value={component.properties.readonly}
175
172
  options={[{ id: crypto.randomUUID(), value: 0, class: '' }]}
176
- onChange={(value) => {
177
- updateProperty('readonly', value)
178
- console.log(component.properties)
179
- }}
173
+ onChange={(value) => updateProperty('readonly', value)}
180
174
  />
181
175
  <UI.Switch
182
176
  label={{ name: $t('constructor.props.copy') }}
@@ -258,7 +252,7 @@
258
252
  type="buttons"
259
253
  options={$optionsStore.ACCESS_OPTION}
260
254
  value={$optionsStore.ACCESS_OPTION.find((o) => o.value === component.access)}
261
- onUpdate={(option) => onPropertyChange(null, null, option.value)}
255
+ onUpdate={(option) => onPropertyChange({ access: option.value })}
262
256
  />
263
257
  <UI.Input
264
258
  label={{ name: $t('constructor.props.value') }}
@@ -1,9 +1,14 @@
1
- import type { IInputProps, UIComponent } from '../types';
1
+ import type { IInputProps, UIComponent, IUIComponentHandler } from '../types';
2
2
  type $$ComponentProps = {
3
3
  component: UIComponent & {
4
4
  properties: Partial<IInputProps>;
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 InputProps: import("svelte").Component<$$ComponentProps, {}, "">;
@@ -6,12 +6,13 @@
6
6
  id = crypto.randomUUID(),
7
7
  wrapperClass = '',
8
8
  label = { name: '', class: '' },
9
- value = $bindable([0, 0, 0]),
10
- limits = [
11
- { minNum: -100, maxNum: 100 },
12
- { minNum: -100, maxNum: 100 },
13
- { minNum: -100, maxNum: 100 },
9
+ value = $bindable([0, 0, 0, 0]),
10
+ axes = [
11
+ { name: 'Roll', minNum: -100, maxNum: 100 },
12
+ { name: 'Pitch', minNum: -100, maxNum: 100 },
13
+ { name: 'Yaw', minNum: -100, maxNum: 100 },
14
14
  ],
15
+ buttonIcon,
15
16
  onUpdate = () => {},
16
17
  }: IJoystickProps = $props()
17
18
 
@@ -21,8 +22,8 @@
21
22
  angle: 30.5,
22
23
  content: true,
23
24
  onClick: () => {
24
- if (value[2] + sensitivity >= limits[2].maxNum) {
25
- value[2] = limits[2].maxNum
25
+ if (value[2] + sensitivity >= axes[2].maxNum) {
26
+ value[2] = axes[2].maxNum
26
27
  onUpdate(value)
27
28
  return
28
29
  }
@@ -36,15 +37,15 @@
36
37
  angle: 58,
37
38
  content: false,
38
39
  onClick: () => {
39
- if (value[2] + sensitivity >= limits[2].maxNum) {
40
- value[2] = limits[2].maxNum
40
+ if (value[2] + sensitivity >= axes[2].maxNum) {
41
+ value[2] = axes[2].maxNum
41
42
  onUpdate(value)
42
43
  } else {
43
44
  value[2] = roundToClean(value[2] + sensitivity)
44
45
  onUpdate(value)
45
46
  }
46
- if (value[1] - sensitivity <= limits[1].minNum) {
47
- value[1] = limits[1].minNum
47
+ if (value[1] - sensitivity <= axes[1].minNum) {
48
+ value[1] = axes[1].minNum
48
49
  onUpdate(value)
49
50
  } else {
50
51
  value[1] = roundToClean(value[1] - sensitivity)
@@ -57,8 +58,8 @@
57
58
  angle: 122,
58
59
  content: true,
59
60
  onClick: () => {
60
- if (value[1] - sensitivity <= limits[1].minNum) {
61
- value[1] = limits[1].minNum
61
+ if (value[1] - sensitivity <= axes[1].minNum) {
62
+ value[1] = axes[1].minNum
62
63
  onUpdate(value)
63
64
  return
64
65
  }
@@ -71,15 +72,15 @@
71
72
  angle: 149.5,
72
73
  content: false,
73
74
  onClick: () => {
74
- if (value[2] - sensitivity <= limits[2].minNum) {
75
- value[2] = limits[2].minNum
75
+ if (value[2] - sensitivity <= axes[2].minNum) {
76
+ value[2] = axes[2].minNum
76
77
  onUpdate(value)
77
78
  } else {
78
79
  value[2] = roundToClean(value[2] - sensitivity)
79
80
  onUpdate(value)
80
81
  }
81
- if (value[1] - sensitivity <= limits[1].minNum) {
82
- value[1] = limits[1].minNum
82
+ if (value[1] - sensitivity <= axes[1].minNum) {
83
+ value[1] = axes[1].minNum
83
84
  onUpdate(value)
84
85
  } else {
85
86
  value[1] = roundToClean(value[1] - sensitivity)
@@ -92,8 +93,8 @@
92
93
  angle: 212,
93
94
  content: true,
94
95
  onClick: () => {
95
- if (value[2] - sensitivity <= limits[2].minNum) {
96
- value[2] = limits[2].minNum
96
+ if (value[2] - sensitivity <= axes[2].minNum) {
97
+ value[2] = axes[2].minNum
97
98
  onUpdate(value)
98
99
  return
99
100
  }
@@ -106,15 +107,15 @@
106
107
  angle: 239,
107
108
  content: false,
108
109
  onClick: () => {
109
- if (value[1] + sensitivity >= limits[1].maxNum) {
110
- value[1] = limits[1].maxNum
110
+ if (value[1] + sensitivity >= axes[1].maxNum) {
111
+ value[1] = axes[1].maxNum
111
112
  onUpdate(value)
112
113
  } else {
113
114
  value[1] = roundToClean(value[1] + sensitivity)
114
115
  onUpdate(value)
115
116
  }
116
- if (value[2] - sensitivity <= limits[2].minNum) {
117
- value[2] = limits[2].minNum
117
+ if (value[2] - sensitivity <= axes[2].minNum) {
118
+ value[2] = axes[2].minNum
118
119
  onUpdate(value)
119
120
  } else {
120
121
  value[2] = roundToClean(value[2] - sensitivity)
@@ -127,8 +128,8 @@
127
128
  angle: 301,
128
129
  content: true,
129
130
  onClick: () => {
130
- if (value[1] + sensitivity >= limits[1].maxNum) {
131
- value[1] = limits[1].maxNum
131
+ if (value[1] + sensitivity >= axes[1].maxNum) {
132
+ value[1] = axes[1].maxNum
132
133
  onUpdate(value)
133
134
  return
134
135
  }
@@ -141,15 +142,15 @@
141
142
  angle: 328,
142
143
  content: false,
143
144
  onClick: () => {
144
- if (value[1] + sensitivity >= limits[1].maxNum) {
145
- value[1] = limits[1].maxNum
145
+ if (value[1] + sensitivity >= axes[1].maxNum) {
146
+ value[1] = axes[1].maxNum
146
147
  onUpdate(value)
147
148
  } else {
148
149
  value[1] = roundToClean(value[1] + sensitivity)
149
150
  onUpdate(value)
150
151
  }
151
- if (value[2] + sensitivity >= limits[2].maxNum) {
152
- value[2] = limits[2].maxNum
152
+ if (value[2] + sensitivity >= axes[2].maxNum) {
153
+ value[2] = axes[2].maxNum
153
154
  onUpdate(value)
154
155
  } else {
155
156
  value[2] = roundToClean(value[2] + sensitivity)
@@ -180,7 +181,7 @@
180
181
 
181
182
  <div id={`${id}-${crypto.randomUUID().slice(0, 6)}`} class={twMerge(`bg-red relative flex w-full flex-col items-center`, wrapperClass)}>
182
183
  {#if label.name}
183
- <h5 class={twMerge(` w-full px-4 text-center`, label.class)}>{label.name}</h5>
184
+ <h5 class={twMerge(`w-full px-4 text-center`, label.class)}>{label.name}</h5>
184
185
  {/if}
185
186
 
186
187
  <div class=" flex w-1/2 items-center justify-center">
@@ -204,16 +205,12 @@
204
205
  onmouseenter={(e) => (e.currentTarget.style.backgroundColor = 'color-mix(in srgb, var(--bg-color), var(--shadow-color) 20%)')}
205
206
  onmouseleave={(e) => (e.currentTarget.style.backgroundColor = 'var(--bg-color)')}
206
207
  >
207
- {#if direction.content}
208
- <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"
209
- ><path
210
- fill="currentColor"
211
- d="M12.6 12L8.7 8.1q-.275-.275-.275-.7t.275-.7t.7-.275t.7.275l4.6 4.6q.15.15.213.325t.062.375t-.062.375t-.213.325l-4.6 4.6q-.275.275-.7.275t-.7-.275t-.275-.7t.275-.7z"
212
- /></svg
213
- >
214
- {:else}
215
-
216
- {/if}
208
+ <svg xmlns="http://www.w3.org/2000/svg" width={direction.content ? 32 : 16} height={direction.content ? 32 : 16} viewBox="0 0 24 24"
209
+ ><path
210
+ fill="currentColor"
211
+ d="M12.6 12L8.7 8.1q-.275-.275-.275-.7t.275-.7t.7-.275t.7.275l4.6 4.6q.15.15.213.325t.062.375t-.062.375t-.213.325l-4.6 4.6q-.275.275-.7.275t-.7-.275t-.275-.7t.275-.7z"
212
+ /></svg
213
+ >
217
214
  </span>
218
215
  </button>
219
216
  {/each}
@@ -230,81 +227,80 @@
230
227
  </span>
231
228
  {/each}
232
229
  </div>
233
- <!-- Кнопка домой -->
230
+ <!-- Кнопка по центру -->
234
231
  <div
235
232
  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
233
  >
237
234
  <button
238
- class="flex size-18 cursor-pointer items-center justify-center rounded-full bg-(--bg-color)"
239
- title=""
235
+ class="flex size-18 cursor-pointer items-center justify-center rounded-full"
236
+ style="background: {value[3] == 1 ? 'color-mix(in srgb, var(--bg-color), var(--shadow-color) 10%)' : 'var(--bg-color)'}"
240
237
  onclick={() => {
241
- value = [0, 0, 0]
242
- onUpdate(value)
238
+ value[3] = value[3] == 0 ? 1 : 0
243
239
  }}
244
- ><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"
245
- ><path
246
- fill="currentColor"
247
- d="M6 19h3v-5q0-.425.288-.712T10 13h4q.425 0 .713.288T15 14v5h3v-9l-6-4.5L6 10zm-2 0v-9q0-.475.213-.9t.587-.7l6-4.5q.525-.4 1.2-.4t1.2.4l6 4.5q.375.275.588.7T20 10v9q0 .825-.588 1.413T18 21h-4q-.425 0-.712-.288T13 20v-5h-2v5q0 .425-.288.713T10 21H6q-.825 0-1.412-.587T4 19m8-6.75"
248
- /></svg
249
- ></button
250
240
  >
241
+ {@html buttonIcon
242
+ ? buttonIcon
243
+ : '<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor"d="M6 19h3v-5q0-.425.288-.712T10 13h4q.425 0 .713.288T15 14v5h3v-9l-6-4.5L6 10zm-2 0v-9q0-.475.213-.9t.587-.7l6-4.5q.525-.4 1.2-.4t1.2.4l6 4.5q.375.275.588.7T20 10v9q0 .825-.588 1.413T18 21h-4q-.425 0-.712-.288T13 20v-5h-2v5q0 .425-.288.713T10 21H6q-.825 0-1.412-.587T4 19m8-6.75"/></svg>'}
244
+ </button>
251
245
  </div>
252
246
  </div>
253
247
  <!-- Боковые кнопки (ось 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
248
+ {#if axes.length == 3}
249
+ <div
250
+ class="absolute flex h-15 w-65 items-center justify-between rounded-full shadow-[0_0_15px_rgb(0_0_0_/0.25)]"
251
+ style="background: color-mix(in srgb, var(--bg-color), var(--shadow-color) 10%)"
280
252
  >
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
253
+ <button
254
+ class="h-full cursor-pointer rounded-l-full px-3.5"
255
+ title=""
256
+ onclick={() => {
257
+ if (value[0] - sensitivity <= axes[0].minNum) {
258
+ value[0] = axes[0].minNum
259
+ onUpdate(value)
260
+ return
261
+ }
262
+ value[0] = roundToClean(value[0] - sensitivity)
287
263
  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>
264
+ }}
265
+ onmouseenter={(e) => (e.currentTarget.style.backgroundColor = 'color-mix(in srgb, var(--bg-color), var(--shadow-color) 30%)')}
266
+ onmouseleave={(e) => (e.currentTarget.style.backgroundColor = 'background: color-mix(in srgb, var(--bg-color), var(--shadow-color) 10%)')}
267
+ ><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
268
+ ><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="1.5"
269
+ ><path
270
+ stroke-miterlimit="10"
271
+ 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"
272
+ /><path stroke-linejoin="round" d="m7.12 2.75l-.95 3.858a1.33 1.33 0 0 0 .97 1.609l3.869.948" /></g
273
+ ></svg
274
+ ></button
275
+ >
276
+ <button
277
+ class="h-full cursor-pointer rounded-r-full px-3.5"
278
+ title=""
279
+ onclick={() => {
280
+ if (value[0] + sensitivity >= axes[0].maxNum) {
281
+ value[0] = axes[0].maxNum
282
+ onUpdate(value)
283
+ return
284
+ }
285
+ value[0] = roundToClean(value[0] + sensitivity)
286
+ onUpdate(value)
287
+ }}
288
+ onmouseenter={(e) => (e.currentTarget.style.backgroundColor = 'color-mix(in srgb, var(--bg-color), var(--shadow-color) 30%)')}
289
+ onmouseleave={(e) => (e.currentTarget.style.backgroundColor = 'vabackground: color-mix(in srgb, var(--bg-color), var(--shadow-color) 10%)')}
290
+ ><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
291
+ ><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="1.5"
292
+ ><path
293
+ stroke-miterlimit="10"
294
+ 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"
295
+ /><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
296
+ ></svg
297
+ ></button
298
+ >
299
+ </div>
300
+ {/if}
305
301
  </div>
306
302
 
307
- <div class="right-10 flex items-center md:absolute">
303
+ <div class="flex items-center md:absolute md:left-[calc(50%+120px)]">
308
304
  <div id={`${id}-${crypto.randomUUID().slice(0, 6)}`} class="flex h-full flex-col justify-center rounded-full p-10">
309
305
  {#each sensitivityOptions as option, index}
310
306
  <button
@@ -335,15 +331,15 @@
335
331
  </div>
336
332
 
337
333
  <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>
334
+ {#each axes as axe, index}
335
+ <h5 class="w-full px-4 text-center">{axe.name}</h5>
340
336
  <input
341
337
  class={`w-20 rounded-2xl border border-(--border-color) px-4 py-1 text-center transition-all duration-300 outline-none
342
338
  hover:shadow-md
343
339
  [&::-webkit-inner-spin-button]:hidden
344
340
  [&::-webkit-outer-spin-button]:hidden`}
345
341
  style="background: color-mix(in srgb, var(--bg-color), var(--back-color) 70%);"
346
- value={value[num]}
342
+ value={value[axes.length == 3 ? index : index + 1]}
347
343
  id={`${id}-${crypto.randomUUID().slice(0, 6)}`}
348
344
  readonly
349
345
  />
@@ -351,4 +347,3 @@
351
347
  </div>
352
348
  </div>
353
349
  </div>
354
- <!-- sensitivity == 0.01 ? value[num].toFixed(2) : sensitivity == 0.1 ? value[num].toFixed(1) : value[num].toFixed(0) -->