@milaboratories/uikit 2.2.42 → 2.2.43
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 +6 -0
- package/dist/pl-uikit.js +2457 -2422
- package/dist/pl-uikit.umd.cjs +5 -5
- package/dist/src/components/PlDropdownMulti/PlDropdownMulti.vue.d.ts +1 -1
- package/dist/src/components/PlDropdownMultiRef/PlDropdownMultiRef.vue.d.ts +57 -0
- package/dist/src/components/PlDropdownMultiRef/__tests__/PlDropdownMultiRef.spec.d.ts +1 -0
- package/dist/src/components/PlDropdownMultiRef/index.d.ts +1 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/style.css +1 -1
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/components/PlDropdownMulti/PlDropdownMulti.vue +21 -7
- package/src/components/PlDropdownMulti/pl-dropdown-multi.scss +5 -0
- package/src/components/PlDropdownMultiRef/PlDropdownMultiRef.vue +73 -0
- package/src/components/PlDropdownMultiRef/__tests__/PlDropdownMultiRef.spec.ts +70 -0
- package/src/components/PlDropdownMultiRef/index.ts +1 -0
- package/src/index.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@milaboratories/uikit",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.43",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/pl-uikit.umd.js",
|
|
6
6
|
"module": "dist/pl-uikit.js",
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
"vue-tsc": "^2.1.10",
|
|
33
33
|
"yarpm": "^1.2.0",
|
|
34
34
|
"svgo": "^3.3.2",
|
|
35
|
-
"@platforma-sdk/model": "^1.21.0",
|
|
36
35
|
"@milaboratories/helpers": "^1.6.11",
|
|
36
|
+
"@platforma-sdk/model": "^1.21.10",
|
|
37
37
|
"@milaboratories/eslint-config": "^1.0.1"
|
|
38
38
|
},
|
|
39
39
|
"scripts": {
|
|
@@ -20,6 +20,7 @@ import DropdownListItem from '@/components/DropdownListItem.vue';
|
|
|
20
20
|
import { deepEqual, deepIncludes } from '@/helpers/objects';
|
|
21
21
|
import { normalizeListOptions } from '@/helpers/utils';
|
|
22
22
|
import DropdownOverlay from '@/utils/DropdownOverlay/DropdownOverlay.vue';
|
|
23
|
+
import { PlMaskIcon24 } from '../PlMaskIcon24';
|
|
23
24
|
|
|
24
25
|
const emit = defineEmits<{
|
|
25
26
|
(e: 'update:modelValue', v: M[]): void;
|
|
@@ -42,7 +43,7 @@ const props = withDefaults(
|
|
|
42
43
|
/**
|
|
43
44
|
* List of available options for the dropdown
|
|
44
45
|
*/
|
|
45
|
-
options
|
|
46
|
+
options?: Readonly<ListOption<M>[]>;
|
|
46
47
|
/**
|
|
47
48
|
* A helper text displayed below the dropdown when there are no errors (optional).
|
|
48
49
|
*/
|
|
@@ -98,13 +99,13 @@ const placeholderRef = computed(() => {
|
|
|
98
99
|
});
|
|
99
100
|
|
|
100
101
|
const selectedOptionsRef = computed(() => {
|
|
101
|
-
return normalizeListOptions(props.options).filter((opt) => deepIncludes(selectedValuesRef.value, opt.value));
|
|
102
|
+
return normalizeListOptions(props.options ?? []).filter((opt) => deepIncludes(selectedValuesRef.value, opt.value));
|
|
102
103
|
});
|
|
103
104
|
|
|
104
105
|
const filteredOptionsRef = computed(() => {
|
|
105
106
|
const selectedValues = unref(selectedValuesRef);
|
|
106
107
|
|
|
107
|
-
const options = normalizeListOptions(props.options);
|
|
108
|
+
const options = normalizeListOptions(props.options ?? []);
|
|
108
109
|
|
|
109
110
|
return (
|
|
110
111
|
data.search
|
|
@@ -128,7 +129,19 @@ const filteredOptionsRef = computed(() => {
|
|
|
128
129
|
}));
|
|
129
130
|
});
|
|
130
131
|
|
|
131
|
-
const
|
|
132
|
+
const isLoadingOptions = computed(() => {
|
|
133
|
+
return props.options === undefined;
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
const isDisabled = computed(() => {
|
|
137
|
+
if (isLoadingOptions.value) {
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return props.disabled;
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
const tabindex = computed(() => (isDisabled.value ? undefined : '0'));
|
|
132
145
|
|
|
133
146
|
const updateActiveOption = () => {
|
|
134
147
|
data.activeOption = tap(
|
|
@@ -223,7 +236,7 @@ watchPostEffect(() => {
|
|
|
223
236
|
ref="rootRef"
|
|
224
237
|
:tabindex="tabindex"
|
|
225
238
|
class="pl-dropdown-multi"
|
|
226
|
-
:class="{ open: data.open, error, disabled }"
|
|
239
|
+
:class="{ open: data.open, error, disabled: isDisabled }"
|
|
227
240
|
@keydown="handleKeydown"
|
|
228
241
|
@focusout="onFocusOut"
|
|
229
242
|
>
|
|
@@ -234,7 +247,7 @@ watchPostEffect(() => {
|
|
|
234
247
|
v-model="data.search"
|
|
235
248
|
type="text"
|
|
236
249
|
tabindex="-1"
|
|
237
|
-
:disabled="
|
|
250
|
+
:disabled="isDisabled"
|
|
238
251
|
:placeholder="placeholderRef"
|
|
239
252
|
spellcheck="false"
|
|
240
253
|
autocomplete="chrome-off"
|
|
@@ -245,7 +258,8 @@ watchPostEffect(() => {
|
|
|
245
258
|
{{ opt.label || opt.value }}
|
|
246
259
|
</PlChip>
|
|
247
260
|
</div>
|
|
248
|
-
<
|
|
261
|
+
<PlMaskIcon24 v-if="isLoadingOptions" name="loading" />
|
|
262
|
+
<div v-if="!isLoadingOptions" class="arrow" @click.stop="toggleModel" />
|
|
249
263
|
<div class="pl-dropdown-multi__append">
|
|
250
264
|
<slot name="append" />
|
|
251
265
|
</div>
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import type { ModelRef, RefOption } from '@/types';
|
|
3
|
+
import PlDropdownMulti from '../PlDropdownMulti/PlDropdownMulti.vue';
|
|
4
|
+
import { computed } from 'vue';
|
|
5
|
+
|
|
6
|
+
defineEmits<{
|
|
7
|
+
/**
|
|
8
|
+
* Emitted when the model value is updated.
|
|
9
|
+
*/
|
|
10
|
+
(e: 'update:modelValue', value: ModelRef[] | undefined): void;
|
|
11
|
+
}>();
|
|
12
|
+
|
|
13
|
+
const props = withDefaults(
|
|
14
|
+
defineProps<{
|
|
15
|
+
/**
|
|
16
|
+
* The current selected values.
|
|
17
|
+
*/
|
|
18
|
+
modelValue: ModelRef[] | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* The label text for the dropdown field (optional)
|
|
21
|
+
*/
|
|
22
|
+
label?: string;
|
|
23
|
+
/**
|
|
24
|
+
* List of available options for the dropdown
|
|
25
|
+
*/
|
|
26
|
+
options?: Readonly<RefOption[]>;
|
|
27
|
+
/**
|
|
28
|
+
* A helper text displayed below the dropdown when there are no errors (optional).
|
|
29
|
+
*/
|
|
30
|
+
helper?: string;
|
|
31
|
+
/**
|
|
32
|
+
* Error message displayed below the dropdown (optional)
|
|
33
|
+
*/
|
|
34
|
+
error?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Placeholder text shown when no value is selected.
|
|
37
|
+
*/
|
|
38
|
+
placeholder?: string;
|
|
39
|
+
/**
|
|
40
|
+
* If `true`, the dropdown component is marked as required.
|
|
41
|
+
*/
|
|
42
|
+
required?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* If `true`, the dropdown component is disabled and cannot be interacted with.
|
|
45
|
+
*/
|
|
46
|
+
disabled?: boolean;
|
|
47
|
+
}>(),
|
|
48
|
+
{
|
|
49
|
+
modelValue: () => [],
|
|
50
|
+
label: undefined,
|
|
51
|
+
helper: undefined,
|
|
52
|
+
error: undefined,
|
|
53
|
+
placeholder: '...',
|
|
54
|
+
required: false,
|
|
55
|
+
disabled: false,
|
|
56
|
+
},
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
const options = computed(() =>
|
|
60
|
+
props.options?.map((opt) => ({
|
|
61
|
+
label: opt.label,
|
|
62
|
+
value: opt.ref,
|
|
63
|
+
})),
|
|
64
|
+
);
|
|
65
|
+
</script>
|
|
66
|
+
|
|
67
|
+
<template>
|
|
68
|
+
<PlDropdownMulti
|
|
69
|
+
v-bind="props"
|
|
70
|
+
:options="options"
|
|
71
|
+
@update:model-value="$emit('update:modelValue', $event)"
|
|
72
|
+
/>
|
|
73
|
+
</template>
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { mount } from '@vue/test-utils';
|
|
4
|
+
import PlDropdown from '../PlDropdownMultiRef.vue';
|
|
5
|
+
import { delay } from '@milaboratories/helpers';
|
|
6
|
+
|
|
7
|
+
describe('PlDropdownMultiRef', () => {
|
|
8
|
+
it('modelValue', async () => {
|
|
9
|
+
const wrapper = mount(PlDropdown, {
|
|
10
|
+
props: {
|
|
11
|
+
'modelValue': [
|
|
12
|
+
{
|
|
13
|
+
__isRef: true as const,
|
|
14
|
+
blockId: '2',
|
|
15
|
+
name: 'Block 2 Ref',
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
'onUpdate:modelValue': (e) => wrapper.setProps({ modelValue: e }),
|
|
19
|
+
'options': [
|
|
20
|
+
{
|
|
21
|
+
label: 'Block 1 label Ref',
|
|
22
|
+
ref: {
|
|
23
|
+
__isRef: true as const,
|
|
24
|
+
blockId: '1',
|
|
25
|
+
name: 'Block 1 Ref',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
label: 'Block 2 label Ref',
|
|
30
|
+
ref: {
|
|
31
|
+
__isRef: true as const,
|
|
32
|
+
blockId: '2',
|
|
33
|
+
name: 'Block 2 Ref',
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
await wrapper.find('input').trigger('focus');
|
|
41
|
+
|
|
42
|
+
const getOptions = () => [...document.body.querySelectorAll('.dropdown-list-item')] as HTMLElement[];
|
|
43
|
+
|
|
44
|
+
const options = getOptions();
|
|
45
|
+
|
|
46
|
+
console.log('options', options);
|
|
47
|
+
|
|
48
|
+
expect(options.length).toBe(2);
|
|
49
|
+
|
|
50
|
+
console.log(wrapper.props('modelValue'), 'mv');
|
|
51
|
+
options[0].click();
|
|
52
|
+
|
|
53
|
+
await delay(20);
|
|
54
|
+
|
|
55
|
+
expect(wrapper.props('modelValue')).toEqual([
|
|
56
|
+
{
|
|
57
|
+
__isRef: true,
|
|
58
|
+
blockId: '2',
|
|
59
|
+
name: 'Block 2 Ref',
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
__isRef: true,
|
|
63
|
+
blockId: '1',
|
|
64
|
+
name: 'Block 1 Ref',
|
|
65
|
+
},
|
|
66
|
+
]);
|
|
67
|
+
|
|
68
|
+
expect(getOptions().length).toBe(2); // options are not closed after click
|
|
69
|
+
});
|
|
70
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as PlDropdownMultiRef } from './PlDropdownMultiRef.vue';
|
package/src/index.ts
CHANGED
|
@@ -38,6 +38,7 @@ export * from './components/PlTooltip';
|
|
|
38
38
|
export * from './components/PlProgressBar';
|
|
39
39
|
export * from './components/PlNumberField';
|
|
40
40
|
export * from './components/PlDropdownMulti';
|
|
41
|
+
export * from './components/PlDropdownMultiRef';
|
|
41
42
|
export * from './components/PlCheckbox';
|
|
42
43
|
export * from './components/PlCheckboxGroup';
|
|
43
44
|
export * from './components/PlChip';
|