poe-svelte-ui-lib 1.0.1 → 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 -191
  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
package/LICENSE CHANGED
@@ -1,3 +1,3 @@
1
- Looks like there's already a license file for this project.
2
- [?25l? Do you want to replace it? ┬╗ (y/N)тИЪ Do you want to replace it? ... no
3
- [?25hExiting...
1
+ Looks like there's already a license file for this project.
2
+ [?25l? Do you want to replace it? ┬╗ (y/N)тИЪ Do you want to replace it? ... no
3
+ [?25hExiting...
@@ -1,53 +1,53 @@
1
- <script lang="ts">
2
- import { slide } from 'svelte/transition'
3
- import type { IAccordionProps } from '../types'
4
-
5
- const props: IAccordionProps = $props()
6
- let isOpen = $state(props.isOpen)
7
-
8
- const toggle = () => (isOpen = !isOpen)
9
- </script>
10
-
11
- <div
12
- id={props.id?.value}
13
- class="border-[var(--border-color)] p-0 transition-shadow duration-250 {props.type === 'sub'
14
- ? 'border-none'
15
- : 'rounded-xl border bg-[var(--conteiner-color)] hover:shadow-md'}
16
- {props.componentClass}"
17
- transition:slide={{ duration: 250 }}
18
- >
19
- <button
20
- class="flex w-full cursor-pointer items-center justify-between transition-shadow duration-250 sm:p-4 sm:px-6
21
- {props.type === 'sub' ? 'border-b border-[var(--border-color)]' : ''}"
22
- onclick={toggle}
23
- >
24
- <span class="toggle m-0 cursor-pointer text-lg font-semibold {props.label?.class}">
25
- {props.label?.name}
26
- </span>
27
- <svg
28
- xmlns="http://www.w3.org/2000/svg"
29
- class="arrow h-[1.1rem] w-[1.1rem] transition-transform duration-250"
30
- style="transform: rotate({isOpen ? 180 : 0}deg)"
31
- viewBox="0 0 24 24"
32
- >
33
- <path
34
- fill="none"
35
- stroke="currentColor"
36
- stroke-linecap="round"
37
- stroke-linejoin="round"
38
- stroke-width="1.5"
39
- d="M18 12.5s-4.419 6-6 6s-6-6-6-6m12-7s-4.419 6-6 6s-6-6-6-6"
40
- color="currentColor"
41
- />
42
- </svg>
43
- </button>
44
-
45
- {#if isOpen}
46
- <div
47
- class="flex w-full flex-wrap items-start justify-around p-4 sm:p-3 {props.type === 'sub' ? '' : 'border-t border-[var(--border-color)]'}"
48
- transition:slide={{ duration: 250 }}
49
- >
50
- {@render props.children?.()}
51
- </div>
52
- {/if}
53
- </div>
1
+ <script lang="ts">
2
+ import { slide } from 'svelte/transition'
3
+ import type { IAccordionProps } from '../types'
4
+
5
+ const props: IAccordionProps = $props()
6
+ let isOpen = $state(props.isOpen)
7
+
8
+ const toggle = () => (isOpen = !isOpen)
9
+ </script>
10
+
11
+ <div
12
+ id={props.id?.value}
13
+ class="border-[var(--border-color)] p-0 transition-shadow duration-250 {props.type === 'sub'
14
+ ? 'border-none'
15
+ : 'rounded-xl border bg-[var(--conteiner-color)] hover:shadow-md'}
16
+ {props.componentClass}"
17
+ transition:slide={{ duration: 250 }}
18
+ >
19
+ <button
20
+ class="flex w-full cursor-pointer items-center justify-between transition-shadow duration-250 sm:p-4 sm:px-6
21
+ {props.type === 'sub' ? 'border-b border-[var(--border-color)]' : ''}"
22
+ onclick={toggle}
23
+ >
24
+ <span class="toggle m-0 cursor-pointer text-lg font-semibold {props.label?.class}">
25
+ {props.label?.name}
26
+ </span>
27
+ <svg
28
+ xmlns="http://www.w3.org/2000/svg"
29
+ class="arrow h-[1.1rem] w-[1.1rem] transition-transform duration-250"
30
+ style="transform: rotate({isOpen ? 180 : 0}deg)"
31
+ viewBox="0 0 24 24"
32
+ >
33
+ <path
34
+ fill="none"
35
+ stroke="currentColor"
36
+ stroke-linecap="round"
37
+ stroke-linejoin="round"
38
+ stroke-width="1.5"
39
+ d="M18 12.5s-4.419 6-6 6s-6-6-6-6m12-7s-4.419 6-6 6s-6-6-6-6"
40
+ color="currentColor"
41
+ />
42
+ </svg>
43
+ </button>
44
+
45
+ {#if isOpen}
46
+ <div
47
+ class="flex w-full flex-wrap items-start justify-around p-4 sm:p-3 {props.type === 'sub' ? '' : 'border-t border-[var(--border-color)]'}"
48
+ transition:slide={{ duration: 250 }}
49
+ >
50
+ {@render props.children?.()}
51
+ </div>
52
+ {/if}
53
+ </div>
@@ -1,70 +1,70 @@
1
- <!-- $lib/ElementsUI/AccordionProps.svelte -->
2
- <script lang="ts">
3
- import { t } from '../locales/i18n'
4
- import type { IAccordionProps, UIComponent } from '../types'
5
- import * as UI from '../index'
6
- import { optionsStore } from '../options'
7
-
8
- const { component, onPropertyChange } = $props<{
9
- component: UIComponent & { properties: Partial<IAccordionProps> }
10
- onPropertyChange: (value: string | object) => void
11
- }>()
12
-
13
- let currentType = $derived($optionsStore.ACCORDION_TYPE_OPTIONS.find((t) => t.value === component.properties.type))
14
-
15
- /* Обновление свойства */
16
- const updateProperty = (path: string, value: string | object) => {
17
- const newProperties = JSON.parse(JSON.stringify(component.properties))
18
- const parts = path.split('.')
19
- let obj = newProperties
20
-
21
- for (let i = 0; i < parts.length - 1; i++) {
22
- const part = parts[i]
23
- if (!obj[part]) obj[part] = {}
24
- obj = obj[part]
25
- }
26
-
27
- obj[parts[parts.length - 1]] = value
28
- onPropertyChange(newProperties)
29
- }
30
-
31
- const handleImageUpload = (event: Event) => {
32
- const input = event.target as HTMLInputElement
33
- if (!input.files || input.files.length === 0) return
34
-
35
- const file = input.files[0]
36
- const reader = new FileReader()
37
- reader.onload = (e) => {
38
- const base64String = e.target?.result as string
39
- updateProperty('image', base64String)
40
- }
41
- reader.readAsDataURL(file)
42
- }
43
- </script>
44
-
45
- {#if component && component.properties}
46
- <div class="flex items-center justify-center gap-8">
47
- <UI.Input
48
- label={{ name: $t('service.constructor.props.label') }}
49
- wrapperClass="!w-1/3"
50
- value={component.properties.label.name}
51
- onUpdate={(value) => updateProperty('label.name', value as string)}
52
- type="text"
53
- />
54
- <UI.Select
55
- wrapperClass="!w-1/3"
56
- label={{ name: $t('service.constructor.props.type') }}
57
- type="buttons"
58
- value={currentType}
59
- options={$optionsStore.ACCORDION_TYPE_OPTIONS}
60
- onUpdate={(item) => updateProperty('type', item.value as string)}
61
- />
62
- <UI.FileAttach
63
- type="image"
64
- label={{ name: $t('service.constructor.props.image') }}
65
- accept="image/png, image/jpeg, image/webp"
66
- onChange={handleImageUpload}
67
- />
68
- <UI.Button name={$t('service.constructor.props.removeimage')} wrapperClass="!w-auto" componentClass="px-4" onClick={() => updateProperty('image', '')} />
69
- </div>
70
- {/if}
1
+ <!-- $lib/ElementsUI/AccordionProps.svelte -->
2
+ <script lang="ts">
3
+ import { t } from '../locales/i18n'
4
+ import type { IAccordionProps, UIComponent } from '../types'
5
+ import * as UI from '../index'
6
+ import { optionsStore } from '../options'
7
+
8
+ const { component, onPropertyChange } = $props<{
9
+ component: UIComponent & { properties: Partial<IAccordionProps> }
10
+ onPropertyChange: (value: string | object) => void
11
+ }>()
12
+
13
+ let currentType = $derived($optionsStore.ACCORDION_TYPE_OPTIONS.find((t) => t.value === component.properties.type))
14
+
15
+ /* Обновление свойства */
16
+ const updateProperty = (path: string, value: string | object) => {
17
+ const newProperties = JSON.parse(JSON.stringify(component.properties))
18
+ const parts = path.split('.')
19
+ let obj = newProperties
20
+
21
+ for (let i = 0; i < parts.length - 1; i++) {
22
+ const part = parts[i]
23
+ if (!obj[part]) obj[part] = {}
24
+ obj = obj[part]
25
+ }
26
+
27
+ obj[parts[parts.length - 1]] = value
28
+ onPropertyChange(newProperties)
29
+ }
30
+
31
+ const handleImageUpload = (event: Event) => {
32
+ const input = event.target as HTMLInputElement
33
+ if (!input.files || input.files.length === 0) return
34
+
35
+ const file = input.files[0]
36
+ const reader = new FileReader()
37
+ reader.onload = (e) => {
38
+ const base64String = e.target?.result as string
39
+ updateProperty('image', base64String)
40
+ }
41
+ reader.readAsDataURL(file)
42
+ }
43
+ </script>
44
+
45
+ {#if component && component.properties}
46
+ <div class="flex items-center justify-center gap-8">
47
+ <UI.Input
48
+ label={{ name: $t('service.constructor.props.label') }}
49
+ wrapperClass="!w-1/3"
50
+ value={component.properties.label.name}
51
+ onUpdate={(value) => updateProperty('label.name', value as string)}
52
+ type="text"
53
+ />
54
+ <UI.Select
55
+ wrapperClass="!w-1/3"
56
+ label={{ name: $t('service.constructor.props.type') }}
57
+ type="buttons"
58
+ value={currentType}
59
+ options={$optionsStore.ACCORDION_TYPE_OPTIONS}
60
+ onUpdate={(item) => updateProperty('type', item.value as string)}
61
+ />
62
+ <UI.FileAttach
63
+ type="image"
64
+ label={{ name: $t('service.constructor.props.image') }}
65
+ accept="image/png, image/jpeg, image/webp"
66
+ onChange={handleImageUpload}
67
+ />
68
+ <UI.Button name={$t('service.constructor.props.removeimage')} wrapperClass="!w-auto" componentClass="px-4" onClick={() => updateProperty('image', '')} />
69
+ </div>
70
+ {/if}
@@ -1,144 +1,144 @@
1
- <!-- $lib/ElementsUI/Button.svelte -->
2
- <script lang="ts">
3
- import { onMount } from 'svelte'
4
- // import { type IButtonProps } from '../types'
5
- import { fly } from 'svelte/transition'
6
-
7
- interface IUIComponentHandler {
8
- Header?: string
9
- Argument?: string
10
- Value?: string
11
- Variables?: string[]
12
- }
13
-
14
- interface IButtonProps {
15
- id?: { value?: string; name?: string }
16
- wrapperClass?: string
17
- label?: { name?: string; class?: string }
18
- componentClass?: string
19
- name?: string
20
- icon?: {
21
- component?: ConstructorOfATypedSvelteComponent | null
22
- properties?: Record<string, unknown>
23
- }
24
- info?: string
25
- keyBind?: {
26
- key?: string
27
- ctrlKey?: boolean
28
- shiftKey?: boolean
29
- altKey?: boolean
30
- metaKey?: boolean /* Поддержка Meta (Cmd на Mac) */
31
- }
32
- disabled?: boolean
33
- eventHandler?: IUIComponentHandler
34
- onClick?: () => void
35
- }
36
-
37
- let {
38
- id = { value: crypto.randomUUID(), name: '' },
39
- wrapperClass = 'bg-blue',
40
- label = { name: '', class: '' },
41
- name = '',
42
- componentClass = '',
43
- icon = { component: null, properties: {} },
44
- info = '',
45
- disabled = false,
46
- keyBind,
47
- onClick,
48
- }: IButtonProps = $props()
49
-
50
- let showInfo = $state(false)
51
-
52
- /* Обработчик клика */
53
- const handleClick = () => {
54
- if (disabled || !onClick) return
55
- onClick()
56
- }
57
-
58
- /* Обработчик горячих клавиш */
59
- const handleKeyDown = (event: KeyboardEvent) => {
60
- if (disabled || !keyBind || !onClick) return
61
-
62
- const isKeyMatch = event.key === keyBind.key
63
- const isCtrlMatch = keyBind.ctrlKey === undefined || event.ctrlKey === keyBind.ctrlKey
64
- const isShiftMatch = keyBind.shiftKey === undefined || event.shiftKey === keyBind.shiftKey
65
- const isAltMatch = keyBind.altKey === undefined || event.altKey === keyBind.altKey
66
- const isMetaMatch = keyBind.metaKey === undefined || event.metaKey === keyBind.metaKey
67
-
68
- if (isKeyMatch && isCtrlMatch && isShiftMatch && isAltMatch && isMetaMatch) {
69
- event.preventDefault()
70
- onClick()
71
- }
72
- }
73
-
74
- /* Подписка на события клавиатуры */
75
- onMount(() => {
76
- if (keyBind) {
77
- window.addEventListener('keydown', handleKeyDown)
78
- }
79
- return () => {
80
- if (keyBind) {
81
- window.removeEventListener('keydown', handleKeyDown)
82
- }
83
- }
84
- })
85
- </script>
86
-
87
- <div class={`relative flex w-full flex-col items-center ${wrapperClass}`}>
88
- {#if label.name}
89
- <h5 class={`w-full px-4 text-center ${label.class}`}>{label.name}</h5>
90
- {/if}
91
-
92
- <div class="relative flex w-full grow items-center">
93
- <button
94
- id={id.value}
95
- class={`
96
- relative m-0 inline-block w-full items-center rounded-2xl border border-[var(--bg-color)] bg-[var(--bg-color)]
97
- px-2 py-1 font-semibold transition duration-200 select-none
98
- ${disabled ? 'cursor-not-allowed opacity-50' : 'cursor-pointer hover:shadow-md active:scale-97'}
99
- ${componentClass}
100
- `}
101
- onclick={handleClick}
102
- {disabled}
103
- aria-label={name || label.name}
104
- onmouseenter={() => {
105
- if (info) showInfo = true
106
- }}
107
- onmouseleave={() => {
108
- if (info) showInfo = false
109
- }}
110
- >
111
- <span class="flex flex-row items-center justify-center gap-2">
112
- {#if icon?.component}
113
- {@const IconComponent = icon?.component}
114
- <IconComponent {...icon?.properties} />
115
- {/if}
116
- {#if name}
117
- <div class="flex-1">
118
- {name}
119
- {#if keyBind}
120
- <div class="text-xs opacity-70">
121
- ({keyBind.ctrlKey ? 'Ctrl+' : ''}{keyBind.shiftKey ? 'Shift+' : ''}{keyBind.altKey ? 'Alt+' : ''}{keyBind.key})
122
- </div>
123
- {/if}
124
- </div>
125
- {/if}
126
- </span>
127
- </button>
128
-
129
- {#if showInfo}
130
- <div
131
- transition:fly={{ y: -15, duration: 300 }}
132
- class="absolute bottom-full left-1/2 z-50 mb-2 w-max max-w-xs rounded-md px-3 py-1 text-sm shadow-lg"
133
- style="background: color-mix(in srgb, var(--yellow-color) 30%, var(--back-color)); transform: translateX(-50%);"
134
- >
135
- {info}
136
- <!-- Треугольная стрелка -->
137
- <div
138
- class="absolute top-full left-1/2 h-2 w-2 -translate-x-1/2 -translate-y-1/2 rotate-45 transform"
139
- style="background: color-mix(in srgb, var(--yellow-color) 30%, var(--back-color));"
140
- ></div>
141
- </div>
142
- {/if}
143
- </div>
144
- </div>
1
+ <!-- $lib/ElementsUI/Button.svelte -->
2
+ <script lang="ts">
3
+ import { onMount } from 'svelte'
4
+ // import { type IButtonProps } from '../types'
5
+ import { fly } from 'svelte/transition'
6
+
7
+ interface IUIComponentHandler {
8
+ Header?: string
9
+ Argument?: string
10
+ Value?: string
11
+ Variables?: string[]
12
+ }
13
+
14
+ interface IButtonProps {
15
+ id?: { value?: string; name?: string }
16
+ wrapperClass?: string
17
+ label?: { name?: string; class?: string }
18
+ componentClass?: string
19
+ name?: string
20
+ icon?: {
21
+ component?: ConstructorOfATypedSvelteComponent | null
22
+ properties?: Record<string, unknown>
23
+ }
24
+ info?: string
25
+ keyBind?: {
26
+ key?: string
27
+ ctrlKey?: boolean
28
+ shiftKey?: boolean
29
+ altKey?: boolean
30
+ metaKey?: boolean /* Поддержка Meta (Cmd на Mac) */
31
+ }
32
+ disabled?: boolean
33
+ eventHandler?: IUIComponentHandler
34
+ onClick?: () => void
35
+ }
36
+
37
+ let {
38
+ id = { value: crypto.randomUUID(), name: '' },
39
+ wrapperClass = 'bg-blue',
40
+ label = { name: '', class: '' },
41
+ name = '',
42
+ componentClass = '',
43
+ icon = { component: null, properties: {} },
44
+ info = '',
45
+ disabled = false,
46
+ keyBind,
47
+ onClick,
48
+ }: IButtonProps = $props()
49
+
50
+ let showInfo = $state(false)
51
+
52
+ /* Обработчик клика */
53
+ const handleClick = () => {
54
+ if (disabled || !onClick) return
55
+ onClick()
56
+ }
57
+
58
+ /* Обработчик горячих клавиш */
59
+ const handleKeyDown = (event: KeyboardEvent) => {
60
+ if (disabled || !keyBind || !onClick) return
61
+
62
+ const isKeyMatch = event.key === keyBind.key
63
+ const isCtrlMatch = keyBind.ctrlKey === undefined || event.ctrlKey === keyBind.ctrlKey
64
+ const isShiftMatch = keyBind.shiftKey === undefined || event.shiftKey === keyBind.shiftKey
65
+ const isAltMatch = keyBind.altKey === undefined || event.altKey === keyBind.altKey
66
+ const isMetaMatch = keyBind.metaKey === undefined || event.metaKey === keyBind.metaKey
67
+
68
+ if (isKeyMatch && isCtrlMatch && isShiftMatch && isAltMatch && isMetaMatch) {
69
+ event.preventDefault()
70
+ onClick()
71
+ }
72
+ }
73
+
74
+ /* Подписка на события клавиатуры */
75
+ onMount(() => {
76
+ if (keyBind) {
77
+ window.addEventListener('keydown', handleKeyDown)
78
+ }
79
+ return () => {
80
+ if (keyBind) {
81
+ window.removeEventListener('keydown', handleKeyDown)
82
+ }
83
+ }
84
+ })
85
+ </script>
86
+
87
+ <div class={`relative flex w-full flex-col items-center ${wrapperClass}`}>
88
+ {#if label.name}
89
+ <h5 class={`w-full px-4 text-center ${label.class}`}>{label.name}</h5>
90
+ {/if}
91
+
92
+ <div class="relative flex w-full grow items-center">
93
+ <button
94
+ id={id.value}
95
+ class={`
96
+ relative m-0 inline-block w-full items-center rounded-2xl border border-[var(--bg-color)] bg-[var(--bg-color)]
97
+ px-2 py-1 font-semibold transition duration-200 select-none
98
+ ${disabled ? 'cursor-not-allowed opacity-50' : 'cursor-pointer hover:shadow-md active:scale-97'}
99
+ ${componentClass}
100
+ `}
101
+ onclick={handleClick}
102
+ {disabled}
103
+ aria-label={name || label.name}
104
+ onmouseenter={() => {
105
+ if (info) showInfo = true
106
+ }}
107
+ onmouseleave={() => {
108
+ if (info) showInfo = false
109
+ }}
110
+ >
111
+ <span class="flex flex-row items-center justify-center gap-2">
112
+ {#if icon?.component}
113
+ {@const IconComponent = icon?.component}
114
+ <IconComponent {...icon?.properties} />
115
+ {/if}
116
+ {#if name}
117
+ <div class="flex-1">
118
+ {name}
119
+ {#if keyBind}
120
+ <div class="text-xs opacity-70">
121
+ ({keyBind.ctrlKey ? 'Ctrl+' : ''}{keyBind.shiftKey ? 'Shift+' : ''}{keyBind.altKey ? 'Alt+' : ''}{keyBind.key})
122
+ </div>
123
+ {/if}
124
+ </div>
125
+ {/if}
126
+ </span>
127
+ </button>
128
+
129
+ {#if showInfo}
130
+ <div
131
+ transition:fly={{ y: -15, duration: 300 }}
132
+ class="absolute bottom-full left-1/2 z-50 mb-2 w-max max-w-xs rounded-md px-3 py-1 text-sm shadow-lg"
133
+ style="background: color-mix(in srgb, var(--yellow-color) 30%, var(--back-color)); transform: translateX(-50%);"
134
+ >
135
+ {info}
136
+ <!-- Треугольная стрелка -->
137
+ <div
138
+ class="absolute top-full left-1/2 h-2 w-2 -translate-x-1/2 -translate-y-1/2 rotate-45 transform"
139
+ style="background: color-mix(in srgb, var(--yellow-color) 30%, var(--back-color));"
140
+ ></div>
141
+ </div>
142
+ {/if}
143
+ </div>
144
+ </div>