@milaboratories/uikit 2.2.78 → 2.2.80
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/CHANGELOG.md +12 -0
- package/dist/pl-uikit.css +1 -0
- package/dist/pl-uikit.js +5043 -4909
- package/dist/pl-uikit.js.map +1 -1
- package/dist/src/components/PlAlert/PlAlert.vue.d.ts +1 -1
- package/dist/src/components/PlAlert/PlAlert.vue.d.ts.map +1 -1
- package/dist/src/components/PlClipboard/PlClipboard.vue.d.ts +12 -0
- package/dist/src/components/PlClipboard/PlClipboard.vue.d.ts.map +1 -0
- package/dist/src/components/PlClipboard/index.d.ts +2 -0
- package/dist/src/components/PlClipboard/index.d.ts.map +1 -0
- package/dist/src/components/PlErrorAlert/PlErrorAlert.vue.d.ts +26 -0
- package/dist/src/components/PlErrorAlert/PlErrorAlert.vue.d.ts.map +1 -0
- package/dist/src/components/PlErrorAlert/index.d.ts +2 -0
- package/dist/src/components/PlErrorAlert/index.d.ts.map +1 -0
- package/dist/src/components/PlErrorBoundary/PlErrorBoundary.vue.d.ts +92 -0
- package/dist/src/components/PlErrorBoundary/PlErrorBoundary.vue.d.ts.map +1 -0
- package/dist/src/components/PlErrorBoundary/index.d.ts +2 -0
- package/dist/src/components/PlErrorBoundary/index.d.ts.map +1 -0
- package/dist/src/components/PlFileInput/PlFileInput.vue.d.ts.map +1 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/package.json +6 -9
- package/src/assets/base.scss +3 -2
- package/src/assets/variables.scss +2 -0
- package/src/components/PlAutocomplete/PlAutocomplete.vue +1 -1
- package/src/components/PlClipboard/PlClipboard.vue +47 -0
- package/src/components/PlClipboard/index.ts +1 -0
- package/src/components/PlErrorAlert/PlErrorAlert.vue +105 -0
- package/src/components/PlErrorAlert/index.ts +1 -0
- package/src/components/PlErrorBoundary/PlErrorBoundary.vue +59 -0
- package/src/components/PlErrorBoundary/index.ts +1 -0
- package/src/components/PlFileInput/PlFileInput.vue +5 -9
- package/src/index.ts +2 -0
- package/vite.config.ts +0 -7
- package/dist/style.css +0 -1
package/package.json
CHANGED
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@milaboratories/uikit",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.80",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/pl-uikit.js",
|
|
6
6
|
"module": "dist/pl-uikit.js",
|
|
7
7
|
"types": "dist/src/index.d.ts",
|
|
8
|
-
"styles": "dist/
|
|
8
|
+
"styles": "dist/pl-uikit.css",
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
|
-
"style": "./styles/main.css",
|
|
12
11
|
"types": "./dist/src/index.d.ts",
|
|
13
12
|
"default": "./dist/pl-uikit.js"
|
|
14
13
|
},
|
|
15
|
-
"./styles":
|
|
16
|
-
|
|
17
|
-
},
|
|
18
|
-
"./*": "./*"
|
|
14
|
+
"./styles": "./dist/pl-uikit.css",
|
|
15
|
+
"./styles/mixins": "./src/assets/mixins.scss"
|
|
19
16
|
},
|
|
20
17
|
"dependencies": {
|
|
21
18
|
"vue": "^3.5.13",
|
|
@@ -29,13 +26,13 @@
|
|
|
29
26
|
"@vitejs/plugin-vue": "^5.2.3",
|
|
30
27
|
"tsc-alias": "^1.8.11",
|
|
31
28
|
"vitest": "^2.1.9",
|
|
32
|
-
"vite": "^
|
|
29
|
+
"vite": "^6.3.5",
|
|
33
30
|
"vue-tsc": "^2.1.10",
|
|
34
31
|
"yarpm": "^1.2.0",
|
|
35
32
|
"svgo": "^3.3.2",
|
|
36
33
|
"@types/d3": "^7.4.3",
|
|
37
34
|
"@milaboratories/eslint-config": "^1.0.4",
|
|
38
|
-
"@milaboratories/helpers": "^1.6.
|
|
35
|
+
"@milaboratories/helpers": "^1.6.12",
|
|
39
36
|
"@platforma-sdk/model": "^1.33.2"
|
|
40
37
|
},
|
|
41
38
|
"scripts": {
|
package/src/assets/base.scss
CHANGED
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
|
|
38
38
|
--font-size-base: 14px;
|
|
39
39
|
--font-weigh-base: 500;
|
|
40
|
+
--line-height-base: 16px;
|
|
40
41
|
|
|
41
42
|
--control-height: 40px;
|
|
42
43
|
--control-hover-color: #363452;
|
|
@@ -135,8 +136,8 @@ body,
|
|
|
135
136
|
height: 100%;
|
|
136
137
|
padding: 0;
|
|
137
138
|
margin: 0;
|
|
138
|
-
font-size:
|
|
139
|
-
line-height:
|
|
139
|
+
font-size: var(--font-size-base);
|
|
140
|
+
line-height: var(--line-height-base);
|
|
140
141
|
color: var(--main-dark-color);
|
|
141
142
|
box-sizing: border-box;
|
|
142
143
|
position: relative;
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
--bg-base-light: #f7f8fa;
|
|
40
40
|
--bg-elevated-01: #ffffff;
|
|
41
41
|
--bg-elevated-02: #e1e3eb;
|
|
42
|
+
--bg-error: #FFF5F5;
|
|
42
43
|
//filled
|
|
43
44
|
--filled-V-BG: #d0f0c0;
|
|
44
45
|
--filled-D-BG: #ffcecc;
|
|
@@ -120,6 +121,7 @@
|
|
|
120
121
|
--bg-base-light: #0d0d0f;
|
|
121
122
|
--bg-elevated-01: #1b1b1f;
|
|
122
123
|
--bg-elevated-02: #2d2d33;
|
|
124
|
+
--bg-error: #FFF5F5;
|
|
123
125
|
//filled
|
|
124
126
|
--filled-V-BG: rgba(66, 184, 66, 0.4);
|
|
125
127
|
--filled-D-BG: rgba(229, 83, 229, 0.4);
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
export default {
|
|
3
|
+
name: 'PlClipboard',
|
|
4
|
+
};
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<script lang="ts" setup>
|
|
8
|
+
import { PlMaskIcon16 } from '@/components/PlMaskIcon16';
|
|
9
|
+
import type { Size } from '@/types.ts';
|
|
10
|
+
import { computed, onUnmounted, ref } from 'vue';
|
|
11
|
+
|
|
12
|
+
const props = defineProps<{
|
|
13
|
+
size?: Size;
|
|
14
|
+
}>();
|
|
15
|
+
|
|
16
|
+
const emit = defineEmits(['copy']);
|
|
17
|
+
|
|
18
|
+
const copyEffect = ref<boolean>(false);
|
|
19
|
+
|
|
20
|
+
const iconName = computed(() => copyEffect.value ? 'clipboard-copied' : 'clipboard');
|
|
21
|
+
|
|
22
|
+
let timeoutId: undefined | number;
|
|
23
|
+
|
|
24
|
+
function onCopy() {
|
|
25
|
+
clearTimeout(timeoutId);
|
|
26
|
+
copyEffect.value = true;
|
|
27
|
+
emit('copy');
|
|
28
|
+
timeoutId = window.setTimeout(() => {
|
|
29
|
+
copyEffect.value = false;
|
|
30
|
+
}, 1000);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
onUnmounted(() => {
|
|
34
|
+
clearTimeout(timeoutId);
|
|
35
|
+
});
|
|
36
|
+
</script>
|
|
37
|
+
|
|
38
|
+
<template>
|
|
39
|
+
<PlMaskIcon16 :name="iconName" :size="props.size" :class="$style.copy" @click="onCopy" />
|
|
40
|
+
</template>
|
|
41
|
+
|
|
42
|
+
<style module>
|
|
43
|
+
.copy {
|
|
44
|
+
cursor: pointer;
|
|
45
|
+
display: block;
|
|
46
|
+
}
|
|
47
|
+
</style>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as PlClipboard } from './PlClipboard.vue';
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
export default {
|
|
3
|
+
name: 'PlErrorAlert',
|
|
4
|
+
};
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<script lang="ts" setup>
|
|
8
|
+
import { PlClipboard } from '@/components/PlClipboard';
|
|
9
|
+
import { PlMaskIcon16 } from '@/components/PlMaskIcon16';
|
|
10
|
+
|
|
11
|
+
const props = withDefaults(
|
|
12
|
+
defineProps<{
|
|
13
|
+
title?: string;
|
|
14
|
+
message?: string;
|
|
15
|
+
maxHeight?: string;
|
|
16
|
+
copyMessage?: string;
|
|
17
|
+
}>(),
|
|
18
|
+
{
|
|
19
|
+
title: undefined,
|
|
20
|
+
message: undefined,
|
|
21
|
+
maxHeight: '300px',
|
|
22
|
+
copyMessage: undefined,
|
|
23
|
+
},
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
function onCopy() {
|
|
27
|
+
const value = props.copyMessage ?? props.message;
|
|
28
|
+
if (typeof value === 'string') {
|
|
29
|
+
navigator.clipboard.writeText(value);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<template>
|
|
35
|
+
<div :style="{ maxHeight: props.maxHeight }" :class="$style.root">
|
|
36
|
+
<PlClipboard :class="$style.copy" @copy="onCopy" />
|
|
37
|
+
<slot name="title">
|
|
38
|
+
<div :class="$style.title">
|
|
39
|
+
<PlMaskIcon16 :class="$style.titleIcon" name="warning" />
|
|
40
|
+
<div :class="$style.titleText">{{ props.title }}</div>
|
|
41
|
+
</div>
|
|
42
|
+
</slot>
|
|
43
|
+
<slot name="message">
|
|
44
|
+
<div :class="$style.message">
|
|
45
|
+
{{ props.message }}
|
|
46
|
+
</div>
|
|
47
|
+
</slot>
|
|
48
|
+
</div>
|
|
49
|
+
</template>
|
|
50
|
+
|
|
51
|
+
<style module>
|
|
52
|
+
.root {
|
|
53
|
+
position: relative;
|
|
54
|
+
overflow: auto;
|
|
55
|
+
display: flex;
|
|
56
|
+
flex-direction: column;
|
|
57
|
+
gap: 12px;
|
|
58
|
+
padding: 12px;
|
|
59
|
+
background: var(--bg-error);
|
|
60
|
+
border: 1px var(--border-color-error) solid;
|
|
61
|
+
border-radius: var(--border-radius-control);
|
|
62
|
+
/* color: var(--txt-error); */
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.copy {
|
|
66
|
+
position: absolute;
|
|
67
|
+
right: 12px;
|
|
68
|
+
top: 12px;
|
|
69
|
+
opacity: 0.4;
|
|
70
|
+
transition: opacity 0.3s;
|
|
71
|
+
|
|
72
|
+
&:hover {
|
|
73
|
+
opacity: 1;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.title {
|
|
78
|
+
display: flex;
|
|
79
|
+
align-items: center;
|
|
80
|
+
gap: 10px;
|
|
81
|
+
max-width: calc(100% - 20px);
|
|
82
|
+
min-height: 24px;
|
|
83
|
+
line-height: 24px;
|
|
84
|
+
font-weight: bold;
|
|
85
|
+
overflow: hidden;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.titleIcon {
|
|
89
|
+
background-color: var(--txt-error);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.titleText {
|
|
93
|
+
width: 100%;
|
|
94
|
+
overflow: hidden;
|
|
95
|
+
text-overflow: ellipsis;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.message {
|
|
99
|
+
overflow: auto;
|
|
100
|
+
max-height: 100%;
|
|
101
|
+
white-space: pre-wrap;
|
|
102
|
+
word-break: break-word;
|
|
103
|
+
font-family: var(--font-family-monospace);
|
|
104
|
+
}
|
|
105
|
+
</style>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as PlErrorAlert } from './PlErrorAlert.vue';
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { computed, onErrorCaptured, ref, onBeforeUpdate } from 'vue';
|
|
3
|
+
import { PlErrorAlert } from '@/components/PlErrorAlert';
|
|
4
|
+
import { isErrorLike, tryDo } from '@milaboratories/helpers';
|
|
5
|
+
|
|
6
|
+
const extractMessage = (err: unknown): undefined | string => {
|
|
7
|
+
if (err == null) {
|
|
8
|
+
return undefined;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
if (isErrorLike(err)) {
|
|
12
|
+
return err.stack == null || err.stack.length === 0
|
|
13
|
+
? err.message
|
|
14
|
+
: err.stack.includes(err.message)
|
|
15
|
+
? err.stack
|
|
16
|
+
: err.message + '\n' + err.stack;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return tryDo(() => JSON.stringify(err, null, 4), () => err.toString());
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const data = ref<null | {
|
|
23
|
+
title: undefined | string;
|
|
24
|
+
error: Error;
|
|
25
|
+
}>(null);
|
|
26
|
+
|
|
27
|
+
const error = computed(() => data.value?.error);
|
|
28
|
+
const message = computed(() => extractMessage(error.value));
|
|
29
|
+
|
|
30
|
+
function reset() {
|
|
31
|
+
data.value = null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const errorAlert = ref<InstanceType<typeof PlErrorAlert> | null>(null);
|
|
35
|
+
|
|
36
|
+
onBeforeUpdate(() => {
|
|
37
|
+
// If an error is currently displayed, and the component updates (e.g., due to slot content changing),
|
|
38
|
+
// reset the error state.
|
|
39
|
+
if (data.value !== null && errorAlert.value) {
|
|
40
|
+
reset();
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
onErrorCaptured((err, instance) => {
|
|
45
|
+
data.value = {
|
|
46
|
+
title: instance?.$?.type?.name ?? undefined,
|
|
47
|
+
error: err,
|
|
48
|
+
};
|
|
49
|
+
// stop error propagation
|
|
50
|
+
return false;
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
defineExpose({ error, reset });
|
|
54
|
+
</script>
|
|
55
|
+
|
|
56
|
+
<template>
|
|
57
|
+
<slot />
|
|
58
|
+
<PlErrorAlert v-if="error" ref="errorAlert" :message="message" :title="data?.title" />
|
|
59
|
+
</template>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as PlErrorBoundary } from './PlErrorBoundary.vue';
|
|
@@ -9,7 +9,7 @@ import type { ImportFileHandle, ImportProgress } from '@platforma-sdk/model';
|
|
|
9
9
|
import { getFileNameFromHandle, getFilePathFromHandle } from '@platforma-sdk/model';
|
|
10
10
|
import DoubleContour from '@/utils/DoubleContour.vue';
|
|
11
11
|
import { useLabelNotch } from '@/utils/useLabelNotch';
|
|
12
|
-
import { prettyBytes, tryDo } from '@milaboratories/helpers';
|
|
12
|
+
import { isErrorLike, prettyBytes, tryDo } from '@milaboratories/helpers';
|
|
13
13
|
|
|
14
14
|
const data = reactive({
|
|
15
15
|
fileDialogOpen: false,
|
|
@@ -99,10 +99,6 @@ const tryValue = <T extends ImportFileHandle>(v: T | undefined, cb: (v: T) => st
|
|
|
99
99
|
}
|
|
100
100
|
};
|
|
101
101
|
|
|
102
|
-
const isErrorObject = (error: unknown): error is { message: string } => {
|
|
103
|
-
return typeof error === 'object' && error != null && 'message' in error && typeof error.message === 'string';
|
|
104
|
-
};
|
|
105
|
-
|
|
106
102
|
const fileName = computed(() => tryValue(props.modelValue, getFileNameFromHandle));
|
|
107
103
|
|
|
108
104
|
const filePath = computed(() => tryValue(props.modelValue, getFilePathFromHandle));
|
|
@@ -118,7 +114,7 @@ const computedError = computed(() => {
|
|
|
118
114
|
message = data.error;
|
|
119
115
|
} else if (typeof props.error === 'string') {
|
|
120
116
|
message = props.error;
|
|
121
|
-
} else if (
|
|
117
|
+
} else if (isErrorLike(props.error)) {
|
|
122
118
|
message = props.error.message;
|
|
123
119
|
} else if (props.error != null) {
|
|
124
120
|
const unknownString = tryDo(() => JSON.stringify(props.error, null, 4), () => String(props.error));
|
|
@@ -191,13 +187,13 @@ if (!props.cellStyle) {
|
|
|
191
187
|
<div :class="{ 'pl-file-input__cell-style': !!cellStyle, 'has-file': !!fileName }" class="pl-file-input__envelope">
|
|
192
188
|
<div
|
|
193
189
|
ref="rootRef"
|
|
190
|
+
:class="{ dashed, error: hasErrors }"
|
|
194
191
|
class="pl-file-input"
|
|
195
192
|
tabindex="0"
|
|
196
|
-
:class="{ dashed, error: hasErrors }"
|
|
197
193
|
@keyup.enter="openFileDialog"
|
|
198
194
|
@click.stop="openFileDialog"
|
|
199
195
|
>
|
|
200
|
-
<div class="pl-file-input__progress"
|
|
196
|
+
<div :style="progressStyle" class="pl-file-input__progress" />
|
|
201
197
|
<label v-if="!cellStyle && label" ref="label">
|
|
202
198
|
<i v-if="required" class="required-icon" />
|
|
203
199
|
<span>{{ label }}</span>
|
|
@@ -226,9 +222,9 @@ if (!props.cellStyle) {
|
|
|
226
222
|
</div>
|
|
227
223
|
<PlFileDialog
|
|
228
224
|
v-model="data.fileDialogOpen"
|
|
225
|
+
:close-on-outside-click="fileDialogCloseOnOutsideClick"
|
|
229
226
|
:extensions="extensions"
|
|
230
227
|
:title="fileDialogTitle"
|
|
231
|
-
:close-on-outside-click="fileDialogCloseOnOutsideClick"
|
|
232
228
|
@import:files="onImport"
|
|
233
229
|
/>
|
|
234
230
|
</template>
|
package/src/index.ts
CHANGED
|
@@ -17,6 +17,8 @@ export * from './layout/PlGrid';
|
|
|
17
17
|
/**
|
|
18
18
|
* Components
|
|
19
19
|
*/
|
|
20
|
+
export * from './components/PlErrorBoundary';
|
|
21
|
+
// export * from './components/PlErrorAlert'; // @TODO discuss if we should export it
|
|
20
22
|
export * from './components/PlAlert';
|
|
21
23
|
export * from './components/PlBtnSplit';
|
|
22
24
|
export * from './components/PlBtnPrimary';
|