poe-svelte-ui-lib 1.0.6 → 1.0.8
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.
- package/dist/Accordion/Accordion.svelte +51 -40
- package/dist/Accordion/AccordionProps.svelte +76 -0
- package/dist/Accordion/AccordionProps.svelte.d.ts +10 -0
- package/dist/Button/Button.svelte +28 -34
- package/dist/Button/ButtonProps.svelte +113 -0
- package/dist/Button/ButtonProps.svelte.d.ts +10 -0
- package/dist/ColorPicker/ColorPicker.svelte +27 -14
- package/dist/ColorPicker/ColorPickerProps.svelte +71 -0
- package/dist/ColorPicker/ColorPickerProps.svelte.d.ts +10 -0
- package/dist/{FileAttach/FileAttach.svelte → FileAttach.svelte} +3 -11
- package/dist/{FileAttach/FileAttach.svelte.d.ts → FileAttach.svelte.d.ts} +1 -1
- package/dist/Graph/Graph.svelte +3 -3
- package/dist/Graph/GraphProps.svelte +41 -0
- package/dist/Graph/GraphProps.svelte.d.ts +10 -0
- package/dist/Input/Input.svelte +42 -48
- package/dist/Input/InputProps.svelte +205 -0
- package/dist/Input/InputProps.svelte.d.ts +10 -0
- package/dist/Modal.svelte +54 -0
- package/dist/Modal.svelte.d.ts +12 -0
- package/dist/ProgressBar/ProgressBar.svelte +23 -21
- package/dist/ProgressBar/ProgressBarProps.svelte +114 -0
- package/dist/ProgressBar/ProgressBarProps.svelte.d.ts +10 -0
- package/dist/Select/Select.svelte +38 -23
- package/dist/Select/SelectProps.svelte +216 -0
- package/dist/Select/SelectProps.svelte.d.ts +10 -0
- package/dist/Slider/Slider.svelte +17 -10
- package/dist/Slider/SliderProps.svelte +113 -0
- package/dist/Slider/SliderProps.svelte.d.ts +10 -0
- package/dist/Switch/Switch.svelte +15 -10
- package/dist/Switch/SwitchProps.svelte +99 -0
- package/dist/Switch/SwitchProps.svelte.d.ts +10 -0
- package/dist/Table/Table.svelte +62 -38
- package/dist/Table/Table.svelte.d.ts +1 -1
- package/dist/Table/TableProps.svelte +233 -0
- package/dist/Table/TableProps.svelte.d.ts +10 -0
- package/dist/TextField/TextField.svelte +15 -9
- package/dist/TextField/TextFieldProps.svelte +44 -44
- package/dist/TextField/TextFieldProps.svelte.d.ts +1 -1
- package/dist/index.d.ts +12 -3
- package/dist/index.js +12 -3
- package/dist/libIcons/ButtonAdd.svelte +5 -2
- package/dist/libIcons/ButtonDelete.svelte +1 -1
- package/dist/libIcons/CrossIcon.svelte +9 -0
- package/dist/libIcons/CrossIcon.svelte.d.ts +18 -0
- package/dist/locales/translations.js +81 -6
- package/dist/options.d.ts +7 -12
- package/dist/options.js +44 -33
- package/dist/types.d.ts +50 -89
- package/dist/types.js +13 -1
- package/package.json +7 -3
- package/dist/Loader.svelte +0 -12
- package/dist/Loader.svelte.d.ts +0 -5
- package/dist/MessageModal.svelte +0 -54
- package/dist/MessageModal.svelte.d.ts +0 -10
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
<!-- $lib/ElementsUI/SwitchProps.svelte -->
|
|
2
|
+
<script lang="ts">
|
|
3
|
+
import { getContext } from 'svelte'
|
|
4
|
+
import { t } from '../locales/i18n'
|
|
5
|
+
import { type UIComponent, type ISliderProps, updateProperty } from '../types'
|
|
6
|
+
import * as UI from '..'
|
|
7
|
+
import { optionsStore } from '../options'
|
|
8
|
+
|
|
9
|
+
const { component, onPropertyChange } = $props<{
|
|
10
|
+
component: UIComponent & { properties: Partial<ISliderProps> }
|
|
11
|
+
onPropertyChange: (value: string | object) => void
|
|
12
|
+
}>()
|
|
13
|
+
|
|
14
|
+
const DeviceVariables = getContext<{ value: string; name: string }[]>('DeviceVariables')
|
|
15
|
+
let VARIABLE_OPTIONS = $derived(
|
|
16
|
+
DeviceVariables && Array.isArray(DeviceVariables)
|
|
17
|
+
? DeviceVariables.map((variable) => ({
|
|
18
|
+
id: variable.name,
|
|
19
|
+
value: variable.value,
|
|
20
|
+
name: `${variable.value} | ${variable.name}`,
|
|
21
|
+
}))
|
|
22
|
+
: [],
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
const initialAlign = $derived(
|
|
26
|
+
$optionsStore.ALIGN_OPTIONS.find((a) =>
|
|
27
|
+
(a.value as string).includes(component.properties.label?.class?.split(' ').find((cls: string) => cls.startsWith('text-'))),
|
|
28
|
+
),
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
const initialColor = $derived(
|
|
32
|
+
$optionsStore.COLOR_OPTIONS.find((c) =>
|
|
33
|
+
(c.value as string).includes(component.properties.wrapperClass?.split(' ').find((cls: string) => cls.startsWith('bg-'))),
|
|
34
|
+
),
|
|
35
|
+
)
|
|
36
|
+
</script>
|
|
37
|
+
|
|
38
|
+
{#if component && component.properties}
|
|
39
|
+
<div class="relative flex flex-row items-start justify-center">
|
|
40
|
+
<div class="flex w-1/3 flex-col items-center px-2">
|
|
41
|
+
<UI.Select
|
|
42
|
+
label={{ name: $t('constructor.props.variable') }}
|
|
43
|
+
options={VARIABLE_OPTIONS}
|
|
44
|
+
value={VARIABLE_OPTIONS.find((opt) => opt.value === component.properties.id.value)}
|
|
45
|
+
onUpdate={(value) => {
|
|
46
|
+
updateProperty('id', value.value as string, component, onPropertyChange)
|
|
47
|
+
updateProperty('eventHandler.Variables', value.value as string, component, onPropertyChange)
|
|
48
|
+
}}
|
|
49
|
+
/>
|
|
50
|
+
<UI.Select
|
|
51
|
+
label={{ name: $t('constructor.props.action') }}
|
|
52
|
+
type="buttons"
|
|
53
|
+
value={$optionsStore.SHORT_ARGUMENT_OPTION.find((h) => h.value === component.properties.eventHandler.Argument)}
|
|
54
|
+
options={$optionsStore.SHORT_ARGUMENT_OPTION}
|
|
55
|
+
onUpdate={(option) => {
|
|
56
|
+
updateProperty('eventHandler.Argument', option.value as string, component, onPropertyChange)
|
|
57
|
+
}}
|
|
58
|
+
/>
|
|
59
|
+
</div>
|
|
60
|
+
<div class="flex w-1/3 flex-col px-2">
|
|
61
|
+
<UI.Select
|
|
62
|
+
label={{ name: $t('constructor.props.type') }}
|
|
63
|
+
type="buttons"
|
|
64
|
+
value={$optionsStore.SLIDER_TYPE_OPTIONS.find((opt) => opt.value === (component.properties.type || 'single'))}
|
|
65
|
+
options={$optionsStore.SLIDER_TYPE_OPTIONS}
|
|
66
|
+
onUpdate={(type) => {
|
|
67
|
+
updateProperty('value', type.value === 'single' ? 5 : [2, 7], component, onPropertyChange)
|
|
68
|
+
updateProperty('type', type.value as string, component, onPropertyChange)
|
|
69
|
+
}}
|
|
70
|
+
/>
|
|
71
|
+
<UI.Input
|
|
72
|
+
label={{ name: $t('constructor.props.minnum') }}
|
|
73
|
+
value={component.properties.number.minNum as number}
|
|
74
|
+
type="number"
|
|
75
|
+
onUpdate={(value) => updateProperty('number.minNum', Number(value), component, onPropertyChange)}
|
|
76
|
+
/>
|
|
77
|
+
<UI.Input
|
|
78
|
+
label={{ name: $t('constructor.props.maxnum') }}
|
|
79
|
+
value={component.properties.number.maxNum as number}
|
|
80
|
+
type="number"
|
|
81
|
+
onUpdate={(value) => updateProperty('number.maxNum', Number(value), component, onPropertyChange)}
|
|
82
|
+
/>
|
|
83
|
+
<UI.Input
|
|
84
|
+
label={{ name: $t('constructor.props.step') }}
|
|
85
|
+
value={component.properties.number.step as number}
|
|
86
|
+
type="number"
|
|
87
|
+
onUpdate={(value) => updateProperty('number.step', Number(value), component, onPropertyChange)}
|
|
88
|
+
/>
|
|
89
|
+
</div>
|
|
90
|
+
<div class="flex w-1/3 flex-col px-2">
|
|
91
|
+
<UI.Input
|
|
92
|
+
label={{ name: $t('constructor.props.label') }}
|
|
93
|
+
value={component.properties.label.name}
|
|
94
|
+
onUpdate={(value) => updateProperty('label.name', value as string, component, onPropertyChange)}
|
|
95
|
+
/>
|
|
96
|
+
<UI.Select
|
|
97
|
+
label={{ name: $t('constructor.props.align') }}
|
|
98
|
+
type="buttons"
|
|
99
|
+
value={initialAlign}
|
|
100
|
+
options={$optionsStore.ALIGN_OPTIONS}
|
|
101
|
+
onUpdate={(option) => updateProperty('label.class', `${component.properties.label.class} ${option.value}`, component, onPropertyChange)}
|
|
102
|
+
/>
|
|
103
|
+
<UI.Select
|
|
104
|
+
wrapperClass="!h-14"
|
|
105
|
+
label={{ name: $t('constructor.props.colors') }}
|
|
106
|
+
type="buttons"
|
|
107
|
+
options={$optionsStore.COLOR_OPTIONS}
|
|
108
|
+
value={initialColor}
|
|
109
|
+
onUpdate={(option) => updateProperty('wrapperClass', `${component.properties.wrapperClass} ${option.value}`, component, onPropertyChange)}
|
|
110
|
+
/>
|
|
111
|
+
</div>
|
|
112
|
+
</div>
|
|
113
|
+
{/if}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type UIComponent, type ISliderProps } from '../types';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
component: UIComponent & {
|
|
4
|
+
properties: Partial<ISliderProps>;
|
|
5
|
+
};
|
|
6
|
+
onPropertyChange: (value: string | object) => void;
|
|
7
|
+
};
|
|
8
|
+
declare const SliderProps: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
9
|
+
type SliderProps = ReturnType<typeof SliderProps>;
|
|
10
|
+
export default SliderProps;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
<!-- $lib/ElementsUI/Switch.svelte -->
|
|
2
2
|
<script lang="ts">
|
|
3
|
+
import { twMerge } from 'tailwind-merge'
|
|
3
4
|
import type { ISwitchProps } from '../types'
|
|
4
5
|
|
|
5
6
|
let {
|
|
6
|
-
id =
|
|
7
|
-
wrapperClass = '',
|
|
7
|
+
id = crypto.randomUUID(),
|
|
8
8
|
disabled = false,
|
|
9
|
-
|
|
9
|
+
wrapperClass = '',
|
|
10
|
+
label = { name: '', captionLeft: '', captionRight: '' },
|
|
10
11
|
height = '2rem',
|
|
11
12
|
value = $bindable(),
|
|
12
13
|
onChange = () => {},
|
|
@@ -43,14 +44,16 @@
|
|
|
43
44
|
)
|
|
44
45
|
</script>
|
|
45
46
|
|
|
46
|
-
<div class=
|
|
47
|
+
<div class={twMerge(`bg-blue relative flex w-full flex-col items-center justify-center`, wrapperClass)}>
|
|
47
48
|
{#if label.name}
|
|
48
|
-
<h5 class={`w-full px-4 text-center
|
|
49
|
+
<h5 class={`w-full px-4 text-center`}>{label.name}</h5>
|
|
49
50
|
{/if}
|
|
50
51
|
|
|
51
52
|
<div class="relative flex w-full grow items-center justify-center !bg-transparent">
|
|
52
|
-
<button
|
|
53
|
-
|
|
53
|
+
<button
|
|
54
|
+
class="mr-2 {disabled ? 'opacity-60' : 'cursor-pointer'}"
|
|
55
|
+
style="width: {maxCaptionWidth}; text-align: end;"
|
|
56
|
+
onclick={() => handleCaptionClick(1)}>{label.captionLeft}</button
|
|
54
57
|
>
|
|
55
58
|
<label
|
|
56
59
|
class="relative flex items-center justify-between rounded-full border-1
|
|
@@ -58,7 +61,7 @@
|
|
|
58
61
|
{disabled ? 'opacity-60' : ''}"
|
|
59
62
|
>
|
|
60
63
|
<input
|
|
61
|
-
|
|
64
|
+
{id}
|
|
62
65
|
type="checkbox"
|
|
63
66
|
class="absolute left-1/2 h-full w-full -translate-x-1/2 cursor-pointer appearance-none rounded-md"
|
|
64
67
|
bind:checked
|
|
@@ -78,8 +81,10 @@
|
|
|
78
81
|
></span>
|
|
79
82
|
</span>
|
|
80
83
|
</label>
|
|
81
|
-
<button
|
|
82
|
-
|
|
84
|
+
<button
|
|
85
|
+
class="ml-2 {disabled ? 'opacity-60' : 'cursor-pointer'}"
|
|
86
|
+
style="width: {maxCaptionWidth}; text-align: start;"
|
|
87
|
+
onclick={() => handleCaptionClick(2)}>{label.captionRight}</button
|
|
83
88
|
>
|
|
84
89
|
</div>
|
|
85
90
|
</div>
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
<!-- $lib/ElementsUI/SwitchProps.svelte -->
|
|
2
|
+
<script lang="ts">
|
|
3
|
+
import { getContext } from 'svelte'
|
|
4
|
+
import { t } from '../locales/i18n'
|
|
5
|
+
import { type UIComponent, type ISwitchProps, updateProperty, type ISelectOption } from '../types'
|
|
6
|
+
import * as UI from '..'
|
|
7
|
+
import { optionsStore } from '../options'
|
|
8
|
+
import { twMerge } from 'tailwind-merge'
|
|
9
|
+
|
|
10
|
+
const { component, onPropertyChange } = $props<{
|
|
11
|
+
component: UIComponent & { properties: Partial<ISwitchProps> }
|
|
12
|
+
onPropertyChange: (value: string | object) => void
|
|
13
|
+
}>()
|
|
14
|
+
|
|
15
|
+
const DeviceVariables = getContext<{ value: string; name: string }[]>('DeviceVariables')
|
|
16
|
+
let VARIABLE_OPTIONS = $derived(
|
|
17
|
+
DeviceVariables && Array.isArray(DeviceVariables)
|
|
18
|
+
? DeviceVariables.map((variable) => ({
|
|
19
|
+
id: variable.name,
|
|
20
|
+
value: variable.value,
|
|
21
|
+
name: `${variable.value} | ${variable.name}`,
|
|
22
|
+
}))
|
|
23
|
+
: [],
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
const initialColor = $derived(
|
|
27
|
+
$optionsStore.COLOR_OPTIONS.find((c) =>
|
|
28
|
+
(c.value as string).includes(component.properties.wrapperClass?.split(' ').find((cls: string) => cls.startsWith('bg-'))),
|
|
29
|
+
),
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
const initialAlign = $derived(
|
|
33
|
+
$optionsStore.ALIGN_OPTIONS.find((a) =>
|
|
34
|
+
(a.value as string).includes(component.properties.label?.class?.split(' ').find((cls: string) => cls.startsWith('text-'))),
|
|
35
|
+
),
|
|
36
|
+
)
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
{#if component && component.properties}
|
|
40
|
+
<div class="relative flex flex-row items-start justify-center">
|
|
41
|
+
<!-- Сообщение для отправки в ws по нажатию кнопки -->
|
|
42
|
+
<div class="flex w-1/3 flex-col items-center px-2">
|
|
43
|
+
<UI.Select
|
|
44
|
+
label={{ name: $t('constructor.props.variable') }}
|
|
45
|
+
options={VARIABLE_OPTIONS}
|
|
46
|
+
value={VARIABLE_OPTIONS.find((opt) => opt.value === component.properties.id.value)}
|
|
47
|
+
onUpdate={(value) => {
|
|
48
|
+
updateProperty('id', value.value as string, component, onPropertyChange)
|
|
49
|
+
updateProperty('eventHandler.Variables', value.value as string, component, onPropertyChange)
|
|
50
|
+
}}
|
|
51
|
+
/>
|
|
52
|
+
<UI.Select
|
|
53
|
+
label={{ name: $t('constructor.props.action') }}
|
|
54
|
+
type="buttons"
|
|
55
|
+
value={$optionsStore.SHORT_ARGUMENT_OPTION.find((h) => h.value === component.properties.eventHandler.Argument)}
|
|
56
|
+
options={$optionsStore.SHORT_ARGUMENT_OPTION}
|
|
57
|
+
onUpdate={(option) => {
|
|
58
|
+
updateProperty('eventHandler.Argument', option.value as string, component, onPropertyChange)
|
|
59
|
+
}}
|
|
60
|
+
/>
|
|
61
|
+
</div>
|
|
62
|
+
<div class="flex w-1/3 flex-col px-2">
|
|
63
|
+
<UI.Input
|
|
64
|
+
label={{ name: $t('constructor.props.caption.left') }}
|
|
65
|
+
value={component.properties.label.captionLeft}
|
|
66
|
+
type="text"
|
|
67
|
+
onUpdate={(value) => updateProperty('label.captionLeft', value as string, component, onPropertyChange)}
|
|
68
|
+
/>
|
|
69
|
+
<UI.Input
|
|
70
|
+
label={{ name: $t('constructor.props.caption.right') }}
|
|
71
|
+
value={component.properties.label.captionRight}
|
|
72
|
+
type="text"
|
|
73
|
+
onUpdate={(value) => updateProperty('label.captionRight', value as string, component, onPropertyChange)}
|
|
74
|
+
/>
|
|
75
|
+
<UI.Switch
|
|
76
|
+
wrapperClass="bg-blue"
|
|
77
|
+
label={{ name: $t('constructor.props.disabled') }}
|
|
78
|
+
value={component.properties.disabled ? 2 : 1}
|
|
79
|
+
onChange={(value) => updateProperty('disabled', value === 2, component, onPropertyChange)}
|
|
80
|
+
/>
|
|
81
|
+
</div>
|
|
82
|
+
<div class="flex w-1/3 flex-col px-2">
|
|
83
|
+
<UI.Input
|
|
84
|
+
label={{ name: $t('constructor.props.label') }}
|
|
85
|
+
value={component.properties.label.name}
|
|
86
|
+
type="text"
|
|
87
|
+
onUpdate={(value) => updateProperty('label.name', value as string, component, onPropertyChange)}
|
|
88
|
+
/>
|
|
89
|
+
<UI.Select
|
|
90
|
+
wrapperClass="!h-14"
|
|
91
|
+
label={{ name: $t('constructor.props.colors') }}
|
|
92
|
+
type="buttons"
|
|
93
|
+
options={$optionsStore.COLOR_OPTIONS.filter((option) => option.value !== 'bg-max')}
|
|
94
|
+
value={initialColor}
|
|
95
|
+
onUpdate={(option) => updateProperty('wrapperClass', `${component.properties.wrapperClass} ${option.value}`, component, onPropertyChange)}
|
|
96
|
+
/>
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
{/if}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type UIComponent, type ISwitchProps } from '../types';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
component: UIComponent & {
|
|
4
|
+
properties: Partial<ISwitchProps>;
|
|
5
|
+
};
|
|
6
|
+
onPropertyChange: (value: string | object) => void;
|
|
7
|
+
};
|
|
8
|
+
declare const SwitchProps: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
9
|
+
type SwitchProps = ReturnType<typeof SwitchProps>;
|
|
10
|
+
export default SwitchProps;
|
package/dist/Table/Table.svelte
CHANGED
|
@@ -3,10 +3,13 @@
|
|
|
3
3
|
import { get } from 'svelte/store'
|
|
4
4
|
import type { ITableHeader, ITableProps } from '../types'
|
|
5
5
|
import { fly } from 'svelte/transition'
|
|
6
|
+
import { twMerge } from 'tailwind-merge'
|
|
7
|
+
import { Button, Modal } from '..'
|
|
8
|
+
import { t } from '../locales/i18n'
|
|
6
9
|
|
|
7
10
|
let {
|
|
8
|
-
id =
|
|
9
|
-
wrapperClass = '
|
|
11
|
+
id = crypto.randomUUID(),
|
|
12
|
+
wrapperClass = '',
|
|
10
13
|
label = { name: '', class: '' },
|
|
11
14
|
body = [],
|
|
12
15
|
header = [],
|
|
@@ -14,10 +17,11 @@
|
|
|
14
17
|
cursor = null,
|
|
15
18
|
loader,
|
|
16
19
|
getData = () => {},
|
|
17
|
-
modalData = $bindable({ isOpen: false, rawData: '', formattedData: '' }),
|
|
18
20
|
onClick,
|
|
19
21
|
}: ITableProps<any> = $props()
|
|
20
22
|
|
|
23
|
+
let modalData = $state({ isOpen: false, rawData: '', formattedData: '' })
|
|
24
|
+
|
|
21
25
|
/* Сортировка */
|
|
22
26
|
let sortState: {
|
|
23
27
|
key: string | null
|
|
@@ -119,40 +123,37 @@
|
|
|
119
123
|
}
|
|
120
124
|
</script>
|
|
121
125
|
|
|
122
|
-
<div
|
|
126
|
+
<div {id} class={twMerge(`bg-blue flex h-full w-full flex-col overflow-hidden`, wrapperClass)}>
|
|
123
127
|
{#if label.name}
|
|
124
|
-
<h5 class={`w-full px-4 text-center
|
|
128
|
+
<h5 class={twMerge(`w-full px-4 text-center`, label.class)}>{label.name}</h5>
|
|
125
129
|
{/if}
|
|
126
130
|
|
|
127
131
|
<div class="flex h-full flex-col overflow-hidden rounded-xl border-[var(--border-color)]">
|
|
128
132
|
<!-- Table Header -->
|
|
129
133
|
<div class="grid font-semibold" style={`grid-template-columns: ${header.map((c) => c.width || 'minmax(0, 1fr)').join(' ')};`}>
|
|
130
134
|
{#each header as column (column)}
|
|
131
|
-
<div class=
|
|
132
|
-
<
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
{/if}
|
|
142
|
-
</div>
|
|
135
|
+
<div class={twMerge(`justify-center bg-[var(--bg-color)] p-2 text-left`, column.label?.class)}>
|
|
136
|
+
<span>{column.label?.name}</span>
|
|
137
|
+
{#if column.sortable}
|
|
138
|
+
<button
|
|
139
|
+
class="inline-block cursor-pointer font-bold transition-transform duration-75 hover:scale-110 active:scale-95"
|
|
140
|
+
onclick={() => sortRows(column.key as string)}
|
|
141
|
+
>
|
|
142
|
+
↑↓
|
|
143
|
+
</button>
|
|
144
|
+
{/if}
|
|
143
145
|
</div>
|
|
144
146
|
{/each}
|
|
145
147
|
</div>
|
|
146
148
|
|
|
147
149
|
<!-- Table Body с прокруткой -->
|
|
148
|
-
<div class="flex-1 overflow-y-auto bg-[var(--
|
|
150
|
+
<div class="flex-1 overflow-y-auto bg-[var(--container-color)]/50" bind:this={container} onscroll={handleScroll}>
|
|
149
151
|
<div class="grid min-w-0" style={`grid-template-columns: ${header.map((c) => c.width || 'minmax(0, 1fr)').join(' ')};`}>
|
|
150
152
|
{#each body as row, index (row)}
|
|
151
153
|
{#each header as column (column)}
|
|
152
154
|
<div
|
|
153
155
|
class="relative flex w-full min-w-0 items-center px-2 py-1 break-words
|
|
154
156
|
{index % 2 ? '!bg-[var(--back-color)]/40' : ''}
|
|
155
|
-
{column.cellClass}
|
|
156
157
|
{column.align === 'center'
|
|
157
158
|
? 'flex justify-center text-center'
|
|
158
159
|
: column.align === 'right'
|
|
@@ -163,11 +164,9 @@
|
|
|
163
164
|
<div class="flex w-full flex-col gap-1">
|
|
164
165
|
{#each column.buttons as button (button)}
|
|
165
166
|
<button
|
|
166
|
-
class="
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
{typeof button.class === 'function' ? button.class(row) : button.class}
|
|
170
|
-
"
|
|
167
|
+
class="{twMerge(`cursor-pointer rounded-full
|
|
168
|
+
px-4 py-1 font-medium transition-shadow outline-none select-none hover:shadow-md
|
|
169
|
+
${typeof button.class === 'function' ? button.class(row) : button.class}`)} bg-[var(--bg-color)]"
|
|
171
170
|
onclick={() => buttonClick(row, button)}
|
|
172
171
|
>
|
|
173
172
|
{typeof button.name === 'function' ? button.name(row) : button.name}
|
|
@@ -175,12 +174,15 @@
|
|
|
175
174
|
{/each}
|
|
176
175
|
</div>
|
|
177
176
|
{:else if column.image}
|
|
178
|
-
<div
|
|
177
|
+
<div
|
|
178
|
+
class="flex items-center justify-center"
|
|
179
|
+
style={`width: ${column.image.width || '5rem'}; height: ${column.image.height || '5rem'};`}
|
|
180
|
+
>
|
|
179
181
|
{#if hasImage(column, row)}
|
|
180
182
|
<img
|
|
181
183
|
src={typeof column.image?.src === 'function' ? column.image.src(row) : column.image?.src || ''}
|
|
182
184
|
alt={column.image.alt ?? 'Image'}
|
|
183
|
-
class=
|
|
185
|
+
class={twMerge(`h-full w-full object-cover ${column.image.class || ''}`)}
|
|
184
186
|
loading="lazy"
|
|
185
187
|
/>
|
|
186
188
|
{:else if column.image.defaultIcon}
|
|
@@ -189,7 +191,9 @@
|
|
|
189
191
|
</div>
|
|
190
192
|
{:else}
|
|
191
193
|
<div
|
|
192
|
-
class="w-full max-w-full break-words {column.overflow?.truncated
|
|
194
|
+
class="w-full max-w-full break-words {column.overflow?.truncated
|
|
195
|
+
? 'overflow-hidden text-ellipsis whitespace-nowrap'
|
|
196
|
+
: 'whitespace-normal'}"
|
|
193
197
|
onmouseenter={column.overflow?.truncated ? (e) => showTooltip(e, row[column.key], column.overflow?.formatting) : undefined}
|
|
194
198
|
onmouseleave={column.overflow?.truncated ? hideTooltip : undefined}
|
|
195
199
|
onmousemove={column.overflow?.truncated
|
|
@@ -228,17 +232,21 @@
|
|
|
228
232
|
aria-label="Копировать текст"
|
|
229
233
|
>
|
|
230
234
|
{#if copiedCell.y === index && copiedCell.x === column.key}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
/>
|
|
238
|
-
<path d="M6 19a3 3 0 0 1-3-3v-6c0-3.771 0-5.657 1.172-6.828S7.229 2 11 2h4a3 3 0 0 1 3 3" />
|
|
239
|
-
</g>
|
|
240
|
-
</svg>
|
|
235
|
+
<div
|
|
236
|
+
class="absolute top-1/2 right-10 -translate-y-1/2 transform rounded-md bg-[var(--green-color)] px-2 py-1 text-sm shadow-lg"
|
|
237
|
+
transition:fly={{ x: 10, duration: 200 }}
|
|
238
|
+
>
|
|
239
|
+
✓
|
|
240
|
+
</div>
|
|
241
241
|
{/if}
|
|
242
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
|
|
243
|
+
<g fill="none" stroke="currentColor" stroke-width="1.5">
|
|
244
|
+
<path
|
|
245
|
+
d="M6 11c0-2.828 0-4.243.879-5.121C7.757 5 9.172 5 12 5h3c2.828 0 4.243 0 5.121.879C21 6.757 21 8.172 21 11v5c0 2.828 0 4.243-.879 5.121C19.243 22 17.828 22 15 22h-3c-2.828 0-4.243 0-5.121-.879C6 20.243 6 18.828 6 16z"
|
|
246
|
+
/>
|
|
247
|
+
<path d="M6 19a3 3 0 0 1-3-3v-6c0-3.771 0-5.657 1.172-6.828S7.229 2 11 2h4a3 3 0 0 1 3 3" />
|
|
248
|
+
</g>
|
|
249
|
+
</svg>
|
|
242
250
|
</button>
|
|
243
251
|
{/if}
|
|
244
252
|
{/if}
|
|
@@ -261,10 +269,26 @@
|
|
|
261
269
|
{/if}
|
|
262
270
|
|
|
263
271
|
<!-- Нижнее поле для сводной информации -->
|
|
264
|
-
{#if footer
|
|
272
|
+
{#if footer}
|
|
265
273
|
<div class="flex h-8 items-center justify-center bg-[var(--bg-color)]">
|
|
266
274
|
<h5>{footer}</h5>
|
|
267
275
|
</div>
|
|
268
276
|
{/if}
|
|
269
277
|
</div>
|
|
270
278
|
</div>
|
|
279
|
+
|
|
280
|
+
<Modal isOpen={modalData.isOpen} title={$t('debug.baud_rate_data')}>
|
|
281
|
+
{#snippet main()}
|
|
282
|
+
{@html modalData.formattedData}
|
|
283
|
+
{/snippet}
|
|
284
|
+
{#snippet footer()}
|
|
285
|
+
<Button
|
|
286
|
+
content={{ name: 'Copy' }}
|
|
287
|
+
wrapperClass="w-20 bg-pink"
|
|
288
|
+
onClick={() => {
|
|
289
|
+
navigator.clipboard.writeText(modalData.rawData)
|
|
290
|
+
modalData.isOpen = false
|
|
291
|
+
}}
|
|
292
|
+
/>
|
|
293
|
+
{/snippet}
|
|
294
|
+
</Modal>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { ITableProps } from '../types';
|
|
2
|
-
declare const Table: import("svelte").Component<ITableProps<any>, {}, "
|
|
2
|
+
declare const Table: import("svelte").Component<ITableProps<any>, {}, "">;
|
|
3
3
|
type Table = ReturnType<typeof Table>;
|
|
4
4
|
export default Table;
|