@v1nt1248/3nclient-lib 0.1.0 → 0.1.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.
- package/README.md +5 -0
- package/dist/components/index.d.ts +6 -3
- package/dist/components/ui3n-badge-simple.vue.d.ts +13 -13
- package/dist/components/ui3n-badge.vue.d.ts +18 -16
- package/dist/components/ui3n-breadcrumb.vue.d.ts +15 -13
- package/dist/components/ui3n-breadcrumbs.vue.d.ts +17 -15
- package/dist/components/ui3n-button.vue.d.ts +23 -19
- package/dist/components/ui3n-checkbox.vue.d.ts +17 -15
- package/dist/components/ui3n-chip.vue.d.ts +18 -16
- package/dist/components/ui3n-dialog.vue.d.ts +4 -5
- package/dist/components/ui3n-drop-files.vue.d.ts +16 -14
- package/dist/components/ui3n-emoji.vue.d.ts +11 -11
- package/dist/components/ui3n-icon.vue.d.ts +12 -12
- package/dist/components/ui3n-input.vue.d.ts +12 -5
- package/dist/components/ui3n-list.vue.d.ts +12 -39
- package/dist/components/ui3n-menu.vue.d.ts +14 -12
- package/dist/components/ui3n-notification.vue.d.ts +14 -15
- package/dist/components/ui3n-progress-circular.vue.d.ts +43 -0
- package/dist/components/ui3n-progress-linear.vue.d.ts +42 -0
- package/dist/components/ui3n-step-line-bar.vue.d.ts +30 -0
- package/dist/components/ui3n-switch.vue.d.ts +15 -13
- package/dist/components/ui3n-table/composables/useTable.d.ts +26 -0
- package/dist/components/ui3n-table/types.d.ts +65 -0
- package/dist/components/ui3n-table/ui3n-table.vue.d.ts +22 -0
- package/dist/components/ui3n-table-sort-icon.vue.d.ts +2 -2
- package/dist/components/ui3n-tabs.vue.d.ts +18 -16
- package/dist/components/ui3n-text.vue.d.ts +13 -13
- package/dist/components/ui3n-virtual-scroll.vue.d.ts +6 -28
- package/dist/directives/index.d.ts +0 -1
- package/dist/directives/ui3n-click-outside.d.ts +0 -1
- package/dist/directives/ui3n-html.d.ts +0 -1
- package/dist/index.d.ts +10 -1
- package/dist/plugins/dialogs.d.ts +0 -1
- package/dist/plugins/i18n.d.ts +0 -1
- package/dist/plugins/icons.d.ts +0 -1
- package/dist/plugins/index.d.ts +0 -1
- package/dist/plugins/notifications.d.ts +0 -1
- package/dist/plugins/store-dialogs.d.ts +0 -1
- package/dist/plugins/store-notifications.d.ts +0 -1
- package/dist/plugins/store-vue-bus.d.ts +0 -1
- package/dist/plugins/vue-bus.d.ts +0 -1
- package/dist/style.css +1 -1
- package/dist/tools/sqlite-on-3nstorage/index.d.ts +0 -1
- package/dist/tools/ui.helpers.d.ts +0 -1
- package/dist/ui-3n-lib.js +6588 -6551
- package/package.json +31 -29
- package/src/components/index.ts +46 -4
- package/src/components/ui3n-button.vue +6 -0
- package/src/components/ui3n-checkbox.vue +1 -1
- package/src/components/ui3n-dialog.vue +6 -1
- package/src/components/ui3n-input.vue +61 -11
- package/src/components/ui3n-progress-circular.vue +188 -0
- package/src/components/ui3n-progress-linear.vue +119 -0
- package/src/components/ui3n-step-line-bar.vue +66 -0
- package/src/components/ui3n-table/composables/useTable.ts +206 -0
- package/src/components/ui3n-table/types.ts +80 -0
- package/src/components/ui3n-table/ui3n-table.vue +319 -0
- package/src/components/{ui3n-table.vue → ui3n-table-simple.vue} +3 -4
- package/src/components/ui3n-table-sort-icon.vue +9 -6
- package/dist/components/ui3n-table.vue.d.ts +0 -36
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@v1nt1248/3nclient-lib",
|
|
3
3
|
"license": "AGPL-3.0-or-later",
|
|
4
4
|
"author": "v1nt1248",
|
|
5
|
-
"version": "0.1.
|
|
5
|
+
"version": "0.1.2",
|
|
6
6
|
"description": "Library for 3NWeb clients",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"files": [
|
|
@@ -36,54 +36,56 @@
|
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@iconify-icons/ic": "1.2.13",
|
|
38
38
|
"@iconify/vue": "4.1.2",
|
|
39
|
-
"dayjs": "1.11.
|
|
39
|
+
"dayjs": "1.11.12",
|
|
40
40
|
"lodash": "4.17.21",
|
|
41
41
|
"mitt": "3.0.1",
|
|
42
42
|
"sanitize-html": "2.13.0",
|
|
43
|
-
"tslib": "2.6.3"
|
|
43
|
+
"tslib": "2.6.3",
|
|
44
|
+
"vuedraggable": "^4.1.0"
|
|
44
45
|
},
|
|
45
46
|
"peerDependencies": {
|
|
46
|
-
"pinia": "2.1
|
|
47
|
-
"vue": "3.4.
|
|
47
|
+
"pinia": "2.2.1",
|
|
48
|
+
"vue": "3.4.37"
|
|
48
49
|
},
|
|
49
50
|
"devDependencies": {
|
|
50
51
|
"@types/lodash": "4.17.5",
|
|
51
52
|
"@types/node": "20.14.2",
|
|
52
53
|
"@types/sanitize-html": "2.11.0",
|
|
53
|
-
"@typescript-eslint/eslint-plugin": "
|
|
54
|
-
"@typescript-eslint/parser": "
|
|
55
|
-
"@vitejs/plugin-vue": "5.
|
|
56
|
-
"@vue/compiler-core": "3.4.
|
|
54
|
+
"@typescript-eslint/eslint-plugin": "8.0.1",
|
|
55
|
+
"@typescript-eslint/parser": "8.0.1",
|
|
56
|
+
"@vitejs/plugin-vue": "5.1.2",
|
|
57
|
+
"@vue/compiler-core": "3.4.37",
|
|
57
58
|
"@vue/eslint-config-typescript": "13.0.0",
|
|
58
|
-
"@vue/runtime-core": "3.4.
|
|
59
|
+
"@vue/runtime-core": "3.4.37",
|
|
59
60
|
"@vuedx/typescript-plugin-vue": "0.7.6",
|
|
60
|
-
"eslint": "9.
|
|
61
|
+
"eslint": "9.9.0",
|
|
61
62
|
"eslint-config-prettier": "^9.1.0",
|
|
62
63
|
"eslint-plugin-import": "2.29.1",
|
|
63
64
|
"eslint-plugin-node": "11.1.0",
|
|
64
|
-
"eslint-plugin-prettier": "^5.1
|
|
65
|
-
"eslint-plugin-promise": "
|
|
66
|
-
"eslint-plugin-vue": "9.
|
|
67
|
-
"jackspeak": "
|
|
65
|
+
"eslint-plugin-prettier": "^5.2.1",
|
|
66
|
+
"eslint-plugin-promise": "7.1.0",
|
|
67
|
+
"eslint-plugin-vue": "9.27.0",
|
|
68
|
+
"jackspeak": "4.0.1",
|
|
68
69
|
"path": "0.12.7",
|
|
69
|
-
"pinia": "2.1
|
|
70
|
+
"pinia": "2.2.1",
|
|
70
71
|
"postcss-html": "1.7.0",
|
|
71
|
-
"prettier": "^3.3.
|
|
72
|
-
"sass": "1.77.
|
|
73
|
-
"stylelint": "16.
|
|
74
|
-
"stylelint-config-recommended-scss": "14.
|
|
72
|
+
"prettier": "^3.3.3",
|
|
73
|
+
"sass": "1.77.8",
|
|
74
|
+
"stylelint": "16.8.1",
|
|
75
|
+
"stylelint-config-recommended-scss": "14.1.0",
|
|
75
76
|
"stylelint-config-recommended-vue": "1.5.0",
|
|
76
|
-
"stylelint-config-standard": "36.0.
|
|
77
|
-
"stylelint-scss": "6.
|
|
78
|
-
"typescript": "5.4
|
|
79
|
-
"vite": "5.
|
|
77
|
+
"stylelint-config-standard": "36.0.1",
|
|
78
|
+
"stylelint-scss": "6.5.0",
|
|
79
|
+
"typescript": "5.5.4",
|
|
80
|
+
"vite": "5.4.0",
|
|
80
81
|
"vite-plugin-css-injected-by-js": "3.5.1",
|
|
81
|
-
"vite-plugin-dts": "
|
|
82
|
-
"
|
|
83
|
-
"
|
|
84
|
-
"vue
|
|
82
|
+
"vite-plugin-dts": "4.0.2",
|
|
83
|
+
"vite-plugin-vue-devtools": "^7.3.7",
|
|
84
|
+
"vitepress": "1.3.2",
|
|
85
|
+
"vue": "3.4.37",
|
|
86
|
+
"vue-tsc": "2.0.29"
|
|
85
87
|
},
|
|
86
|
-
"packageManager": "pnpm@9.
|
|
88
|
+
"packageManager": "pnpm@9.7.0",
|
|
87
89
|
"pnpm": {
|
|
88
90
|
"peerDependencyRules": {
|
|
89
91
|
"ignoreMissing": [
|
package/src/components/index.ts
CHANGED
|
@@ -17,10 +17,29 @@ import type { Ui3nCheckboxProps, Ui3nCheckboxEmits, Ui3nCheckboxSlots } from './
|
|
|
17
17
|
import Ui3nNotification from './ui3n-notification.vue';
|
|
18
18
|
import Ui3nTableSortIcon from './ui3n-table-sort-icon.vue';
|
|
19
19
|
import type { Ui3nTableSortIconProps } from './ui3n-table-sort-icon.vue';
|
|
20
|
-
import Ui3nTable from './ui3n-table.vue';
|
|
21
|
-
import type {
|
|
20
|
+
import Ui3nTable from './ui3n-table/ui3n-table.vue';
|
|
21
|
+
import type {
|
|
22
|
+
Ui3nTableSort,
|
|
23
|
+
Ui3nTableConfig,
|
|
24
|
+
Ui3nTableHeadProps,
|
|
25
|
+
Ui3nTableBodyProps,
|
|
26
|
+
Ui3nTableGroupActionsSlot,
|
|
27
|
+
Ui3nTableHeaderCellSlot,
|
|
28
|
+
Ui3nTableBodyRowSlotScope,
|
|
29
|
+
Ui3nTableBodyRowSlot,
|
|
30
|
+
Ui3nTableBodyRowCellSlotScope,
|
|
31
|
+
Ui3nTableBodyRowCellSlot,
|
|
32
|
+
Ui3nTableSlots,
|
|
33
|
+
Ui3nTableProps,
|
|
34
|
+
Ui3nTableEmits,
|
|
35
|
+
} from './ui3n-table/types';
|
|
22
36
|
import Ui3nDialog from './ui3n-dialog.vue';
|
|
23
|
-
import type {
|
|
37
|
+
import type {
|
|
38
|
+
Ui3nDialogComponentProps,
|
|
39
|
+
Ui3nDialogComponentEmits,
|
|
40
|
+
Ui3nDialogProps,
|
|
41
|
+
Ui3nDialogEvent,
|
|
42
|
+
} from './ui3n-dialog.vue';
|
|
24
43
|
import Ui3nMenu from './ui3n-menu.vue';
|
|
25
44
|
import type { Ui3nMenuProps, Ui3nMenuEmits, Ui3nMenuSlots } from './ui3n-menu.vue';
|
|
26
45
|
import Ui3nList from './ui3n-list.vue';
|
|
@@ -37,6 +56,12 @@ import Ui3nBreadcrumbs from './ui3n-breadcrumbs.vue';
|
|
|
37
56
|
import type { Ui3nBreadcrumbsProps } from './ui3n-breadcrumbs.vue';
|
|
38
57
|
import Ui3nSwitch from './ui3n-switch.vue';
|
|
39
58
|
import type { Ui3nSwitchProps, Ui3nSwitchEmits, Ui3nSwitchSlots } from './ui3n-switch.vue';
|
|
59
|
+
import Ui3nStepLineBar from './ui3n-step-line-bar.vue';
|
|
60
|
+
import type { Ui3nStepLineBarProps } from './ui3n-step-line-bar.vue';
|
|
61
|
+
import Ui3nProgressLinear from './ui3n-progress-linear.vue';
|
|
62
|
+
import type { Ui3nProgressLinearProps } from './ui3n-progress-linear.vue';
|
|
63
|
+
import Ui3nProgressCircular from './ui3n-progress-circular.vue';
|
|
64
|
+
import type { Ui3nProgressCircularProps } from './ui3n-progress-circular.vue';
|
|
40
65
|
|
|
41
66
|
export {
|
|
42
67
|
Ui3nIcon,
|
|
@@ -69,6 +94,17 @@ export {
|
|
|
69
94
|
Ui3nTableSortIcon,
|
|
70
95
|
Ui3nTableSortIconProps,
|
|
71
96
|
Ui3nTable,
|
|
97
|
+
Ui3nTableSort,
|
|
98
|
+
Ui3nTableConfig,
|
|
99
|
+
Ui3nTableHeadProps,
|
|
100
|
+
Ui3nTableBodyProps,
|
|
101
|
+
Ui3nTableGroupActionsSlot,
|
|
102
|
+
Ui3nTableHeaderCellSlot,
|
|
103
|
+
Ui3nTableBodyRowSlotScope,
|
|
104
|
+
Ui3nTableBodyRowSlot,
|
|
105
|
+
Ui3nTableBodyRowCellSlotScope,
|
|
106
|
+
Ui3nTableBodyRowCellSlot,
|
|
107
|
+
Ui3nTableSlots,
|
|
72
108
|
Ui3nTableProps,
|
|
73
109
|
Ui3nTableEmits,
|
|
74
110
|
Ui3nDialog,
|
|
@@ -103,4 +139,10 @@ export {
|
|
|
103
139
|
Ui3nSwitchProps,
|
|
104
140
|
Ui3nSwitchEmits,
|
|
105
141
|
Ui3nSwitchSlots,
|
|
106
|
-
|
|
142
|
+
Ui3nStepLineBar,
|
|
143
|
+
Ui3nStepLineBarProps,
|
|
144
|
+
Ui3nProgressLinear,
|
|
145
|
+
Ui3nProgressLinearProps,
|
|
146
|
+
Ui3nProgressCircular,
|
|
147
|
+
Ui3nProgressCircularProps,
|
|
148
|
+
};
|
|
@@ -5,6 +5,7 @@ import Ui3nIcon from './ui3n-icon.vue';
|
|
|
5
5
|
export interface Ui3nButtonProps {
|
|
6
6
|
type?: 'primary' | 'secondary' | 'tertiary' | 'icon' | 'custom';
|
|
7
7
|
size?: 'regular' | 'small';
|
|
8
|
+
block?: boolean;
|
|
8
9
|
textColor?: string;
|
|
9
10
|
color?: string;
|
|
10
11
|
elevation?: boolean;
|
|
@@ -71,6 +72,7 @@ onMounted(() => {
|
|
|
71
72
|
$style.button,
|
|
72
73
|
$style[size],
|
|
73
74
|
$style[type],
|
|
75
|
+
block && type !== 'icon' && $style.block,
|
|
74
76
|
icon && $style[`withIcon-${iconPosition}`],
|
|
75
77
|
elevation && $style.elevation,
|
|
76
78
|
]"
|
|
@@ -143,6 +145,10 @@ onMounted(() => {
|
|
|
143
145
|
}
|
|
144
146
|
}
|
|
145
147
|
|
|
148
|
+
.block {
|
|
149
|
+
width: 100%;
|
|
150
|
+
}
|
|
151
|
+
|
|
146
152
|
.primary {
|
|
147
153
|
background: var(--color-bg-button-primary-default);
|
|
148
154
|
color: var(--color-text-button-primary-default);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
2
|
import { computed, onMounted, watch, onBeforeMount, ref, useSlots } from 'vue';
|
|
3
3
|
|
|
4
|
-
type Ui3nCheckboxValue = boolean | string | number;
|
|
4
|
+
export type Ui3nCheckboxValue = boolean | string | number;
|
|
5
5
|
|
|
6
6
|
export interface Ui3nCheckboxProps {
|
|
7
7
|
modelValue: Ui3nCheckboxValue;
|
|
@@ -36,10 +36,15 @@ export interface Ui3nDialogComponentProps {
|
|
|
36
36
|
|
|
37
37
|
export interface Ui3nDialogComponentEmits {
|
|
38
38
|
(ev: 'open', value?: any): void;
|
|
39
|
+
|
|
39
40
|
(ev: 'before-close', value?: any): void;
|
|
41
|
+
|
|
40
42
|
(ev: 'close', value?: any): void;
|
|
43
|
+
|
|
41
44
|
(ev: 'confirm', value?: any): void;
|
|
45
|
+
|
|
42
46
|
(ev: 'cancel', value?: any): void;
|
|
47
|
+
|
|
43
48
|
(ev: 'click-overlay', value?: any): void;
|
|
44
49
|
}
|
|
45
50
|
|
|
@@ -52,7 +57,7 @@ const data = ref(null);
|
|
|
52
57
|
const isValid = ref(true);
|
|
53
58
|
const dialogElement = ref<HTMLDivElement | null>(null);
|
|
54
59
|
|
|
55
|
-
const dialogProps = computed<Ui3nDialogProps
|
|
60
|
+
const dialogProps = computed<Required<Omit<Ui3nDialogProps, 'onClose' | 'onConfirm' | 'onCancel'>>>(() => ({
|
|
56
61
|
teleport: props.dialogProps?.teleport ?? 'body',
|
|
57
62
|
title: props.dialogProps?.title ?? '',
|
|
58
63
|
width: props.dialogProps?.width ?? 380,
|
|
@@ -7,16 +7,21 @@ import Ui3nButton from './ui3n-button.vue';
|
|
|
7
7
|
export interface Ui3nInputProps {
|
|
8
8
|
modelValue: string;
|
|
9
9
|
label?: string;
|
|
10
|
+
type?: 'text' | 'password';
|
|
10
11
|
placeholder?: string;
|
|
11
12
|
clearable?: boolean;
|
|
12
13
|
autofocus?: boolean;
|
|
13
|
-
rules?: Array<(v: string) => any>;
|
|
14
|
-
disabled?: boolean;
|
|
15
14
|
icon?: string;
|
|
16
15
|
iconColor?: string;
|
|
16
|
+
rules?: Array<(v: string) => any>;
|
|
17
|
+
displayStateMode?: 'error' | 'success';
|
|
18
|
+
displayStateWithIcon?: boolean;
|
|
19
|
+
displayStateMessage?: string;
|
|
20
|
+
disabled?: boolean;
|
|
17
21
|
}
|
|
18
22
|
|
|
19
23
|
export interface Ui3nInputEmits {
|
|
24
|
+
(ev: 'init', value: HTMLInputElement): void;
|
|
20
25
|
(ev: 'input', value: string): void;
|
|
21
26
|
(ev: 'focus', value: Event): void;
|
|
22
27
|
(ev: 'blur', value: Event): void;
|
|
@@ -39,7 +44,7 @@ const cssIconColor = computed(() => {
|
|
|
39
44
|
return 'var(--color-icon-control-primary-disabled)';
|
|
40
45
|
}
|
|
41
46
|
|
|
42
|
-
return props.iconColor || 'var(--color-icon-control-primary-default)'
|
|
47
|
+
return props.iconColor || 'var(--color-icon-control-primary-default)';
|
|
43
48
|
});
|
|
44
49
|
const isValid = computed(() => {
|
|
45
50
|
if (!text.value) {
|
|
@@ -53,6 +58,8 @@ onMounted(() => {
|
|
|
53
58
|
if (props.autofocus && inputElement.value) {
|
|
54
59
|
inputElement.value.focus();
|
|
55
60
|
}
|
|
61
|
+
|
|
62
|
+
emits('init', inputElement.value!);
|
|
56
63
|
});
|
|
57
64
|
|
|
58
65
|
watch(
|
|
@@ -124,7 +131,8 @@ const validate = (text: string) => {
|
|
|
124
131
|
icon && $style.withIcon,
|
|
125
132
|
clearable && text && $style.clearable,
|
|
126
133
|
disabled && $style.disabled,
|
|
127
|
-
!!errorMessage && $style.error,
|
|
134
|
+
(!!errorMessage || (displayStateMode === 'error')) && $style.error,
|
|
135
|
+
displayStateMode === 'success' && $style.success,
|
|
128
136
|
]"
|
|
129
137
|
>
|
|
130
138
|
<label v-if="label" :class="$style.label">
|
|
@@ -133,6 +141,8 @@ const validate = (text: string) => {
|
|
|
133
141
|
|
|
134
142
|
<input
|
|
135
143
|
ref="inputElement"
|
|
144
|
+
autocomplete="off"
|
|
145
|
+
:type="type || 'text'"
|
|
136
146
|
:value="text"
|
|
137
147
|
:placeholder="placeholder"
|
|
138
148
|
:disabled="disabled"
|
|
@@ -152,7 +162,7 @@ const validate = (text: string) => {
|
|
|
152
162
|
/>
|
|
153
163
|
|
|
154
164
|
<ui3n-button
|
|
155
|
-
v-if="clearable && !!text"
|
|
165
|
+
v-if="clearable && !!text && !(displayStateMode === 'success' && displayStateWithIcon && !isFocused)"
|
|
156
166
|
type="icon"
|
|
157
167
|
size="small"
|
|
158
168
|
color="transparent"
|
|
@@ -163,8 +173,24 @@ const validate = (text: string) => {
|
|
|
163
173
|
@click="clearValue"
|
|
164
174
|
/>
|
|
165
175
|
|
|
166
|
-
<
|
|
167
|
-
|
|
176
|
+
<ui3n-icon
|
|
177
|
+
v-if="displayStateMode === 'success' && displayStateWithIcon && !isFocused"
|
|
178
|
+
icon="check-circle-outline"
|
|
179
|
+
:width="16"
|
|
180
|
+
:height="16"
|
|
181
|
+
color="var(--success-content-default)"
|
|
182
|
+
:class="$style.successIcon"
|
|
183
|
+
/>
|
|
184
|
+
|
|
185
|
+
<div
|
|
186
|
+
v-if="errorMessage || displayStateMessage"
|
|
187
|
+
:class="[
|
|
188
|
+
$style.fieldMessage,
|
|
189
|
+
errorMessage || (displayStateMode === 'error' && !!displayStateMessage) && $style.errorMessage,
|
|
190
|
+
displayStateMode === 'success' && displayStateMessage && $style.successMessage,
|
|
191
|
+
]"
|
|
192
|
+
>
|
|
193
|
+
{{ errorMessage || displayStateMessage }}
|
|
168
194
|
</div>
|
|
169
195
|
</div>
|
|
170
196
|
</template>
|
|
@@ -208,7 +234,7 @@ const validate = (text: string) => {
|
|
|
208
234
|
width: 100%;
|
|
209
235
|
font-size: var(--font-12);
|
|
210
236
|
line-height: var(--font-16);
|
|
211
|
-
font-weight:
|
|
237
|
+
font-weight: 500;
|
|
212
238
|
color: var(--color-text-control-primary-default);
|
|
213
239
|
margin-bottom: var(--spacing-xs);
|
|
214
240
|
}
|
|
@@ -262,12 +288,20 @@ const validate = (text: string) => {
|
|
|
262
288
|
z-index: 1;
|
|
263
289
|
}
|
|
264
290
|
|
|
265
|
-
.
|
|
291
|
+
.fieldMessage {
|
|
266
292
|
font-style: italic;
|
|
267
293
|
font-size: var(--font-10);
|
|
268
294
|
font-weight: 400;
|
|
269
295
|
line-height: 1.4;
|
|
270
|
-
|
|
296
|
+
margin-top: 2px;
|
|
297
|
+
|
|
298
|
+
&.errorMessage {
|
|
299
|
+
color: var(--error-content-default);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
&.successMessage {
|
|
303
|
+
color: var(--success-content-default)
|
|
304
|
+
}
|
|
271
305
|
}
|
|
272
306
|
|
|
273
307
|
.clearable {
|
|
@@ -279,11 +313,27 @@ const validate = (text: string) => {
|
|
|
279
313
|
}
|
|
280
314
|
|
|
281
315
|
.error {
|
|
316
|
+
.label {
|
|
317
|
+
color: var(--error-content-default) !important;
|
|
318
|
+
}
|
|
319
|
+
|
|
282
320
|
.field {
|
|
283
|
-
outline: 1px solid var(--content-
|
|
321
|
+
outline: 1px solid var(--error-content-default) !important;
|
|
284
322
|
}
|
|
285
323
|
}
|
|
286
324
|
|
|
325
|
+
.success {
|
|
326
|
+
.label {
|
|
327
|
+
color: var(--success-content-default) !important;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
.successIcon {
|
|
332
|
+
position: absolute;
|
|
333
|
+
right: var(--spacing-s);
|
|
334
|
+
bottom: var(--spacing-s);
|
|
335
|
+
}
|
|
336
|
+
|
|
287
337
|
.disabled {
|
|
288
338
|
pointer-events: none;
|
|
289
339
|
user-select: none;
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { computed, onBeforeMount, onBeforeUnmount, ref, useCssModule } from 'vue';
|
|
3
|
+
import { toNumber } from 'lodash';
|
|
4
|
+
|
|
5
|
+
export interface Ui3nProgressCircularProps {
|
|
6
|
+
value?: number | string;
|
|
7
|
+
size?: number | string;
|
|
8
|
+
width?: number | string;
|
|
9
|
+
withText?: boolean;
|
|
10
|
+
bgColor?: string;
|
|
11
|
+
color?: string;
|
|
12
|
+
indeterminate?: boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const thresholdSize = 64;
|
|
16
|
+
const indeterminateModeValues = [1, 5, 10, 15, 20, 30, 40, 50, 60, 70, 80, 85, 90, 95, 99];
|
|
17
|
+
|
|
18
|
+
const props = withDefaults(
|
|
19
|
+
defineProps<Ui3nProgressCircularProps>(),
|
|
20
|
+
{
|
|
21
|
+
value: 0,
|
|
22
|
+
size: 64,
|
|
23
|
+
bgColor: 'var(--color-bg-control-primary-default)',
|
|
24
|
+
color: 'var(--color-bg-control-accent-default)',
|
|
25
|
+
},
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
const $style = useCssModule();
|
|
29
|
+
|
|
30
|
+
const element = ref<HTMLDivElement>();
|
|
31
|
+
const isValueShown = computed(() => props.withText && !props.indeterminate);
|
|
32
|
+
|
|
33
|
+
const innerSize = computed(() => toNumber(props.size));
|
|
34
|
+
const cssSize = computed(() => `${innerSize.value}px`);
|
|
35
|
+
const innerWidth = computed(() => {
|
|
36
|
+
if (props.width) {
|
|
37
|
+
return toNumber(props.width);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const diff = innerSize.value - thresholdSize;
|
|
41
|
+
if (diff <= 0) {
|
|
42
|
+
return Math.round(innerSize.value / 10);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return 6 + Math.round(diff / 20);
|
|
46
|
+
});
|
|
47
|
+
const cssWidth = computed(() => `${innerWidth.value}px`);
|
|
48
|
+
const innerValue = computed(() => toNumber(props.value));
|
|
49
|
+
const fontSize = computed(() => `${Math.floor((innerSize.value - 2 * innerWidth.value) / 3.2)}px`);
|
|
50
|
+
|
|
51
|
+
const circleRadius = computed(() => Math.round(innerSize.value / 2) - Math.round(innerWidth.value / 2));
|
|
52
|
+
const circumference = computed(() => Math.round(Math.PI * 2 * circleRadius.value));
|
|
53
|
+
|
|
54
|
+
const timerId = ref();
|
|
55
|
+
const indeterminateModeValue = ref(0);
|
|
56
|
+
|
|
57
|
+
const strokeDasharray = computed(() => {
|
|
58
|
+
const value = props.indeterminate ? indeterminateModeValue.value : innerValue.value;
|
|
59
|
+
const dash = Math.round(circumference.value * value! / 100);
|
|
60
|
+
const gap = circumference.value - dash;
|
|
61
|
+
return `${dash} ${gap}`;
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
function changeValueForIndeterminateMode() {
|
|
65
|
+
const indeterminateModeValuesLength = indeterminateModeValues.length;
|
|
66
|
+
let index = 0;
|
|
67
|
+
timerId.value = setInterval(() => {
|
|
68
|
+
indeterminateModeValue.value = indeterminateModeValues[index % indeterminateModeValuesLength];
|
|
69
|
+
index += 1;
|
|
70
|
+
if ((index % indeterminateModeValuesLength) === 1) {
|
|
71
|
+
if (element.value?.classList.contains($style.inverse)) {
|
|
72
|
+
element.value?.classList.remove($style.inverse);
|
|
73
|
+
} else {
|
|
74
|
+
element.value?.classList.add($style.inverse);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}, 200);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
onBeforeMount(() => {
|
|
81
|
+
if (props.indeterminate) {
|
|
82
|
+
changeValueForIndeterminateMode();
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
onBeforeUnmount(() => {
|
|
87
|
+
clearInterval(timerId.value);
|
|
88
|
+
});
|
|
89
|
+
</script>
|
|
90
|
+
|
|
91
|
+
<template>
|
|
92
|
+
<div ref="element" :class="[$style.progress, indeterminate && $style.indeterminate]">
|
|
93
|
+
<svg :height="innerSize" :width="innerSize" :class="$style.pie" xmlns="http://www.w3.org/2000/svg">
|
|
94
|
+
<circle :class="$style.background" :r="circleRadius" cx="50%" cy="50%" />
|
|
95
|
+
<circle :class="$style.chart" :r="circleRadius" cx="50%" cy="50%" :stroke-dasharray="strokeDasharray" />
|
|
96
|
+
</svg>
|
|
97
|
+
|
|
98
|
+
<div
|
|
99
|
+
v-if="isValueShown"
|
|
100
|
+
:class="$style.text"
|
|
101
|
+
>
|
|
102
|
+
{{ innerValue }}%
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
</template>
|
|
106
|
+
|
|
107
|
+
<style lang="scss" module>
|
|
108
|
+
.progress {
|
|
109
|
+
--ui3n-progress-circular-size: v-bind(cssSize);
|
|
110
|
+
--ui3n-progress-circular-width: v-bind(cssWidth);
|
|
111
|
+
--ui3n-progress-circular-font-size: v-bind(fontSize);
|
|
112
|
+
--ui3n-progress-circular-bg: v-bind(bgColor);
|
|
113
|
+
--ui3n-progress-circular-color: v-bind(color);
|
|
114
|
+
|
|
115
|
+
position: relative;
|
|
116
|
+
min-width: var(--ui3n-progress-circular-size);
|
|
117
|
+
width: var(--ui3n-progress-circular-size);
|
|
118
|
+
min-height: var(--ui3n-progress-circular-size);
|
|
119
|
+
height: var(--ui3n-progress-circular-size);
|
|
120
|
+
border-radius: 50%;
|
|
121
|
+
|
|
122
|
+
&.inverse {
|
|
123
|
+
.background {
|
|
124
|
+
stroke: var(--ui3n-progress-circular-color) !important;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.chart {
|
|
128
|
+
stroke: var(--ui3n-progress-circular-bg) !important;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
&:not(.indeterminate) {
|
|
133
|
+
.chart {
|
|
134
|
+
transition: 0.2s ease-in-out all;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.pie {
|
|
140
|
+
min-width: var(--ui3n-progress-circular-size);
|
|
141
|
+
width: var(--ui3n-progress-circular-size);
|
|
142
|
+
min-height: var(--ui3n-progress-circular-size);
|
|
143
|
+
height: var(--ui3n-progress-circular-size);
|
|
144
|
+
border-radius: 50%;
|
|
145
|
+
transform: rotate(-90deg);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.background {
|
|
149
|
+
fill: none;
|
|
150
|
+
stroke: var(--ui3n-progress-circular-bg);
|
|
151
|
+
stroke-width: var(--ui3n-progress-circular-width);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.chart {
|
|
155
|
+
fill: none;
|
|
156
|
+
stroke: var(--ui3n-progress-circular-color);
|
|
157
|
+
stroke-width: var(--ui3n-progress-circular-width);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.text {
|
|
161
|
+
position: absolute;
|
|
162
|
+
top: 0;
|
|
163
|
+
left: 0;
|
|
164
|
+
width: 100%;
|
|
165
|
+
height: 100%;
|
|
166
|
+
display: flex;
|
|
167
|
+
justify-content: center;
|
|
168
|
+
align-items: center;
|
|
169
|
+
font-size: var(--ui3n-progress-circular-font-size);
|
|
170
|
+
font-weight: 500;
|
|
171
|
+
color: var(--ui3n-progress-circular-color);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.indeterminate {
|
|
175
|
+
.pie {
|
|
176
|
+
animation: 0.75s linear 0s infinite normal spin;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
@keyframes spin {
|
|
181
|
+
0% {
|
|
182
|
+
transform: rotate(-90deg);
|
|
183
|
+
}
|
|
184
|
+
100% {
|
|
185
|
+
transform: rotate(270deg);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
</style>
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { computed } from 'vue';
|
|
3
|
+
import { toNumber } from 'lodash';
|
|
4
|
+
|
|
5
|
+
export interface Ui3nProgressLinearProps {
|
|
6
|
+
value?: number | string;
|
|
7
|
+
height?: number | string;
|
|
8
|
+
withText?: boolean;
|
|
9
|
+
bgColor?: string;
|
|
10
|
+
color?: string;
|
|
11
|
+
indeterminate?: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const thresholdHeight = 12;
|
|
15
|
+
const thresholdValue = 5;
|
|
16
|
+
|
|
17
|
+
const props = withDefaults(
|
|
18
|
+
defineProps<Ui3nProgressLinearProps>(),
|
|
19
|
+
{
|
|
20
|
+
value: 0,
|
|
21
|
+
height: 2,
|
|
22
|
+
bgColor: 'var(--color-bg-control-primary-default)',
|
|
23
|
+
color: 'var(--color-bg-control-accent-default)',
|
|
24
|
+
},
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
const isValueShown = computed(() => props.withText && !props.indeterminate);
|
|
28
|
+
const innerHeight = computed(() => toNumber(props.height));
|
|
29
|
+
const cssHeight = computed(() => `${innerHeight.value}px`);
|
|
30
|
+
const innerValue = computed(() => toNumber(props.value));
|
|
31
|
+
const displayValue = computed(() => props.indeterminate
|
|
32
|
+
? `20%`
|
|
33
|
+
: `${Math.min(innerValue.value, 100)}%`,
|
|
34
|
+
);
|
|
35
|
+
</script>
|
|
36
|
+
|
|
37
|
+
<template>
|
|
38
|
+
<div :class="[$style.progress, indeterminate && $style.indeterminate]">
|
|
39
|
+
<div
|
|
40
|
+
v-if="isValueShown && innerHeight < thresholdHeight"
|
|
41
|
+
:class="[$style.text, $style.above]"
|
|
42
|
+
>
|
|
43
|
+
{{ displayValue }}
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
<div :class="$style.body">
|
|
47
|
+
<div :class="$style.value" :style="{ width: displayValue }">
|
|
48
|
+
<div
|
|
49
|
+
v-if="isValueShown && innerHeight >= thresholdHeight && innerValue >= thresholdValue"
|
|
50
|
+
:class="$style.text"
|
|
51
|
+
>
|
|
52
|
+
{{ displayValue }}
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
</template>
|
|
58
|
+
|
|
59
|
+
<style lang="scss" module>
|
|
60
|
+
.progress {
|
|
61
|
+
--ui3n-progress-linear-height: v-bind(cssHeight);
|
|
62
|
+
--ui3n-progress-linear-bg: v-bind(bgColor);
|
|
63
|
+
--ui3n-progress-linear-color: v-bind(color);
|
|
64
|
+
|
|
65
|
+
position: relative;
|
|
66
|
+
width: 100%;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.body {
|
|
70
|
+
position: relative;
|
|
71
|
+
width: 100%;
|
|
72
|
+
height: var(--ui3n-progress-linear-height);
|
|
73
|
+
border-radius: calc(var(--ui3n-progress-linear-height) - 2px);
|
|
74
|
+
background-color: var(--ui3n-progress-linear-bg);
|
|
75
|
+
overflow-x: hidden;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.value {
|
|
79
|
+
display: flex;
|
|
80
|
+
justify-content: center;
|
|
81
|
+
align-items: center;
|
|
82
|
+
position: absolute;
|
|
83
|
+
left: 0;
|
|
84
|
+
height: var(--ui3n-progress-linear-height);
|
|
85
|
+
border-radius: calc(var(--ui3n-progress-linear-height) - 2px);
|
|
86
|
+
background-color: var(--ui3n-progress-linear-color);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.text {
|
|
90
|
+
font-size: calc(var(--ui3n-progress-linear-height) - 2px);
|
|
91
|
+
font-weight: 500;
|
|
92
|
+
line-height: var(--ui3n-progress-linear-height);
|
|
93
|
+
color: var(--ui3n-progress-linear-bg);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.above {
|
|
97
|
+
position: relative;
|
|
98
|
+
width: 100%;
|
|
99
|
+
text-align: center;
|
|
100
|
+
font-size: var(--font-14);
|
|
101
|
+
line-height: var(--font-16);
|
|
102
|
+
color: var(--color-bg-control-accent-default);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.indeterminate {
|
|
106
|
+
.value {
|
|
107
|
+
animation: 1s linear 0s infinite normal move;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
@keyframes move {
|
|
112
|
+
from {
|
|
113
|
+
left: -22%
|
|
114
|
+
}
|
|
115
|
+
to {
|
|
116
|
+
left: 122%
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
</style>
|