@milaboratories/uikit 2.2.10 → 2.2.12

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@milaboratories/uikit",
3
- "version": "2.2.10",
3
+ "version": "2.2.12",
4
4
  "type": "module",
5
5
  "main": "dist/pl-uikit.umd.js",
6
6
  "module": "dist/pl-uikit.js",
@@ -33,7 +33,7 @@
33
33
  "yarpm": "^1.2.0",
34
34
  "svgo": "^3.3.2",
35
35
  "@milaboratories/helpers": "^1.6.7",
36
- "@platforma-sdk/model": "^1.10.12"
36
+ "@platforma-sdk/model": "^1.13.2"
37
37
  },
38
38
  "scripts": {
39
39
  "dev": "vite",
@@ -4,16 +4,16 @@ import { PlTooltip } from '@/components/PlTooltip';
4
4
  import { PlFileDialog } from '@/components/PlFileDialog';
5
5
  import type { ImportedFiles } from '@/types';
6
6
  import { PlMaskIcon24 } from '../PlMaskIcon24';
7
- import { computed, reactive, ref, useSlots } from 'vue';
7
+ import { computed, reactive, ref, useSlots, watch } from 'vue';
8
8
  import type { ImportFileHandle, ImportProgress } from '@platforma-sdk/model';
9
- import { getFilePathFromHandle } from '@platforma-sdk/model';
9
+ import { getFileNameFromHandle, getFilePathFromHandle } from '@platforma-sdk/model';
10
10
  import DoubleContour from '@/utils/DoubleContour.vue';
11
11
  import { useLabelNotch } from '@/utils/useLabelNotch';
12
12
  import { prettyBytes } from '@milaboratories/helpers';
13
- import { extractFileName } from './utils';
14
13
 
15
14
  const data = reactive({
16
15
  fileDialogOpen: false,
16
+ error: '',
17
17
  });
18
18
 
19
19
  const slots = useSlots();
@@ -60,10 +60,6 @@ const props = withDefaults(
60
60
  * A helper text to display below the input field when there are no errors.
61
61
  */
62
62
  helper?: string;
63
- /**
64
- * If `true`, only the file name is displayed, not the full path to it.
65
- */
66
- showFilenameOnly?: boolean;
67
63
  /**
68
64
  * Remove rounded border and change styles
69
65
  */
@@ -90,27 +86,30 @@ const props = withDefaults(
90
86
  },
91
87
  );
92
88
 
93
- const fileName = computed(() => {
94
- if (props.modelValue) {
95
- try {
96
- const filePath = getFilePathFromHandle(props.modelValue as ImportFileHandle).trim();
97
- return props.showFilenameOnly ? extractFileName(filePath) : filePath;
98
- } catch (e) {
99
- console.error(e);
100
- return props.modelValue;
101
- }
89
+ const tryValue = <T extends ImportFileHandle>(v: T | undefined, cb: (v: T) => string | undefined) => {
90
+ if (!v) {
91
+ return undefined;
102
92
  }
103
93
 
104
- return '';
105
- });
94
+ try {
95
+ return cb(v);
96
+ } catch (err) {
97
+ data.error = err instanceof Error ? err.message : String(err);
98
+ return v;
99
+ }
100
+ };
101
+
102
+ const fileName = computed(() => tryValue(props.modelValue, getFileNameFromHandle));
103
+
104
+ const filePath = computed(() => tryValue(props.modelValue, getFilePathFromHandle));
106
105
 
107
106
  const isUploading = computed(() => props.progress && !props.progress.done);
108
107
 
109
108
  const isUploaded = computed(() => props.progress && props.progress.done);
110
109
 
111
- const hasErrors = computed(() => props.error);
110
+ const computedError = computed(() => data.error ?? props.error);
112
111
 
113
- const computedError = computed(() => props.error);
112
+ const hasErrors = computed(() => !!computedError.value);
114
113
 
115
114
  const uploadStats = computed(() => {
116
115
  const { status, done } = props.progress ?? {};
@@ -150,6 +149,14 @@ const onImport = (v: ImportedFiles) => {
150
149
 
151
150
  const clear = () => emit('update:modelValue', undefined);
152
151
 
152
+ watch(
153
+ () => props.modelValue,
154
+ () => {
155
+ data.error = '';
156
+ },
157
+ { immediate: true },
158
+ );
159
+
153
160
  const rootRef = ref();
154
161
 
155
162
  if (!props.cellStyle) {
@@ -159,14 +166,22 @@ if (!props.cellStyle) {
159
166
 
160
167
  <template>
161
168
  <div :class="{ 'pl-file-input__cell-style': !!cellStyle, 'has-file': !!fileName }" class="pl-file-input__envelope">
162
- <div ref="rootRef" class="pl-file-input" tabindex="0" :class="{ dashed, error: hasErrors }" @keyup.enter="openFileDialog">
169
+ <div
170
+ ref="rootRef"
171
+ class="pl-file-input"
172
+ tabindex="0"
173
+ :class="{ dashed, error: hasErrors }"
174
+ @keyup.enter="openFileDialog"
175
+ @click.stop="openFileDialog"
176
+ >
163
177
  <div class="pl-file-input__progress" :style="progressStyle" />
164
178
  <label v-if="!cellStyle && label" ref="label">
165
179
  <i v-if="required" class="required-icon" />
166
180
  <span>{{ label }}</span>
167
- <PlTooltip v-if="slots.tooltip" class="info" position="top">
181
+ <PlTooltip v-if="slots.tooltip || filePath" class="info" position="top">
168
182
  <template #tooltip>
169
- <slot name="tooltip" />
183
+ <slot v-if="slots.tooltip" name="tooltip" />
184
+ <template v-else>{{ filePath }}</template>
170
185
  </template>
171
186
  </PlTooltip>
172
187
  </label>
@@ -174,7 +189,7 @@ if (!props.cellStyle) {
174
189
  <PlMaskIcon24 v-else-if="isUploading" name="cloud-upload" />
175
190
  <PlMaskIcon24 v-else-if="isUploaded" name="success" />
176
191
  <PlMaskIcon24 v-else name="paper-clip" />
177
- <div :data-placeholder="placeholder ?? 'Choose file'" class="pl-file-input__filename" @click.stop="openFileDialog">
192
+ <div :data-placeholder="placeholder ?? 'Choose file'" class="pl-file-input__filename">
178
193
  {{ fileName }}
179
194
  </div>
180
195
  <div v-if="uploadStats" class="pl-file-input__stats">{{ uploadStats }}</div>
@@ -184,7 +199,7 @@ if (!props.cellStyle) {
184
199
  <div v-if="hasErrors" class="pl-file-input__error">
185
200
  {{ computedError }}
186
201
  </div>
187
- <div v-else-if="helper" class="upl-file-input__helper">{{ helper }}</div>
202
+ <div v-else-if="helper" class="pl-file-input__helper">{{ helper }}</div>
188
203
  </div>
189
204
  <PlFileDialog
190
205
  v-model="data.fileDialogOpen"
@@ -14,8 +14,7 @@
14
14
  --icon-color: #000;
15
15
 
16
16
  width: 100%;
17
- // min-width: 160px;
18
- height: 40px;
17
+ height: var(--control-height, 40px);
19
18
  position: relative;
20
19
  border-radius: var(--border-radius-control);
21
20
  display: flex;
@@ -28,9 +27,8 @@
28
27
 
29
28
  &__envelope {
30
29
  font-family: var(--font-family-base);
31
- height: var(--control-height);
32
30
  display: flex;
33
- align-items: center;
31
+ flex-direction: column;
34
32
  min-width: 160px;
35
33
  }
36
34
 
@@ -10,10 +10,14 @@ import { useSlots } from 'vue';
10
10
  import './pl-block-page.scss';
11
11
 
12
12
  const slots = useSlots();
13
+
14
+ defineProps<{
15
+ noBodyGutters?: boolean;
16
+ }>();
13
17
  </script>
14
18
 
15
19
  <template>
16
- <div class="pl-layout-component pl-block-page">
20
+ <div class="pl-layout-component pl-block-page" :class="{ noBodyGutters }">
17
21
  <div v-if="slots.title" class="pl-block-page__title">
18
22
  <h1><slot name="title" /></h1>
19
23
  <div class="pl-block-page__title__append">
@@ -1,6 +1,8 @@
1
1
  @import "@/assets/mixins";
2
2
 
3
3
  .pl-block-page {
4
+ --pl-block-page-body-padding: var(--main-spacing, 24px);
5
+
4
6
  padding: var(--container-spacing);
5
7
  background-color: var(--bg-elevated-01);
6
8
  height: 100%;
@@ -8,6 +10,10 @@
8
10
  display: grid;
9
11
  grid-template-rows: auto minmax(0, 1fr);
10
12
 
13
+ &.noBodyGutters {
14
+ --pl-block-page-body-padding: 0;
15
+ }
16
+
11
17
  &__title {
12
18
  height: 80px;
13
19
  display: flex;
@@ -37,7 +43,7 @@
37
43
  display: flex;
38
44
  flex-direction: column;
39
45
  gap: var(--gap-v);
40
- padding: var(--main-spacing, 24px);
46
+ padding: var(--pl-block-page-body-padding);
41
47
  @include scrollbar(true, true);
42
48
  }
43
49
  }
@@ -11,6 +11,7 @@ import './pl-row.scss';
11
11
  defineProps<{
12
12
  wrap?: boolean;
13
13
  alignCenter?: boolean;
14
+ noGap?: boolean;
14
15
  }>();
15
16
  </script>
16
17
 
@@ -3,6 +3,10 @@
3
3
  flex-direction: row;
4
4
  gap: var(--gap-h);
5
5
 
6
+ &.noGap {
7
+ gap: 0;
8
+ }
9
+
6
10
  &.wrap {
7
11
  flex-wrap: wrap;
8
12
  }