@antify/ui 4.1.26 → 4.1.28
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/components/inputs/AntNumberInput.vue +1 -0
- package/dist/components/inputs/AntSelect.vue +54 -6
- package/dist/components/inputs/AntSwitch.vue +0 -1
- package/dist/components/inputs/AntTagInput.vue +1 -1
- package/dist/components/inputs/Elements/AntSelectMenu.vue +88 -60
- package/dist/components/inputs/__stories/AntSelect.stories.d.ts +1 -0
- package/dist/components/inputs/__stories/AntSelect.stories.js +259 -5
- package/dist/components/inputs/__stories/AntSelect.stories.mjs +291 -7
- package/dist/components/inputs/__types/AntSelect.types.d.ts +1 -0
- package/package.json +1 -1
|
@@ -44,9 +44,6 @@ import {
|
|
|
44
44
|
IconSize,
|
|
45
45
|
} from '../__types';
|
|
46
46
|
import AntSelectMenu from './Elements/AntSelectMenu.vue';
|
|
47
|
-
import {
|
|
48
|
-
useVModel,
|
|
49
|
-
} from '@vueuse/core';
|
|
50
47
|
|
|
51
48
|
defineOptions({
|
|
52
49
|
inheritAttrs: false,
|
|
@@ -70,6 +67,7 @@ const props = withDefaults(defineProps<{
|
|
|
70
67
|
expanded?: boolean;
|
|
71
68
|
messages?: string[];
|
|
72
69
|
inputRef?: HTMLInputElement | null;
|
|
70
|
+
maxHeight?: string;
|
|
73
71
|
}>(), {
|
|
74
72
|
state: InputState.base,
|
|
75
73
|
grouped: Grouped.none,
|
|
@@ -81,6 +79,7 @@ const props = withDefaults(defineProps<{
|
|
|
81
79
|
expanded: true,
|
|
82
80
|
messages: () => [],
|
|
83
81
|
inputRef: null,
|
|
82
|
+
maxHeight: '350px',
|
|
84
83
|
});
|
|
85
84
|
const emit = defineEmits([
|
|
86
85
|
'update:modelValue',
|
|
@@ -88,7 +87,9 @@ const emit = defineEmits([
|
|
|
88
87
|
'blur',
|
|
89
88
|
'validate',
|
|
90
89
|
]);
|
|
91
|
-
const isOpen =
|
|
90
|
+
const isOpen = defineModel<boolean>('open', {
|
|
91
|
+
default: false,
|
|
92
|
+
});
|
|
92
93
|
const _modelValue = computed({
|
|
93
94
|
get: () => props.modelValue,
|
|
94
95
|
set: (val: string | number | null) => {
|
|
@@ -96,7 +97,15 @@ const _modelValue = computed({
|
|
|
96
97
|
},
|
|
97
98
|
});
|
|
98
99
|
const hasInputState = computed(() => props.skeleton || props.readonly || props.disabled);
|
|
99
|
-
|
|
100
|
+
|
|
101
|
+
const lastValidLabel = ref<string | null>(null);
|
|
102
|
+
|
|
103
|
+
const valueLabel = computed(() => {
|
|
104
|
+
const found = props.options.find(option => option.value === _modelValue.value);
|
|
105
|
+
|
|
106
|
+
return found ? found.label : lastValidLabel.value;
|
|
107
|
+
});
|
|
108
|
+
|
|
100
109
|
const selectedOption = computed(() => props.options.find(option => option.value === _modelValue.value) || null);
|
|
101
110
|
const inputClasses = computed(() => {
|
|
102
111
|
const variants: Record<InputState, string> = {
|
|
@@ -223,12 +232,20 @@ function onBlur(e: FocusEvent) {
|
|
|
223
232
|
emit('blur', e);
|
|
224
233
|
}
|
|
225
234
|
|
|
226
|
-
function onClickOutside() {
|
|
235
|
+
function onClickOutside(e) {
|
|
227
236
|
if (!isOpen.value) {
|
|
228
237
|
return;
|
|
229
238
|
}
|
|
230
239
|
|
|
240
|
+
const menuElement = dropDownRef.value?.floating;
|
|
241
|
+
|
|
242
|
+
if (menuElement && menuElement.contains(e.target as Node)) {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
|
|
231
246
|
isOpen.value = false;
|
|
247
|
+
|
|
248
|
+
emit('validate', props.modelValue);
|
|
232
249
|
_inputRef.value?.focus();
|
|
233
250
|
}
|
|
234
251
|
|
|
@@ -250,6 +267,27 @@ function onClickRemoveButton() {
|
|
|
250
267
|
_inputRef.value?.focus();
|
|
251
268
|
_modelValue.value = null;
|
|
252
269
|
}
|
|
270
|
+
|
|
271
|
+
function onElementSelect(value: string | number | null) {
|
|
272
|
+
_modelValue.value = value;
|
|
273
|
+
|
|
274
|
+
emit('validate', value);
|
|
275
|
+
|
|
276
|
+
_inputRef.value?.focus();
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
watch([
|
|
280
|
+
() => props.options,
|
|
281
|
+
() => _modelValue.value,
|
|
282
|
+
], () => {
|
|
283
|
+
const found = props.options.find(option => option.value === _modelValue.value);
|
|
284
|
+
|
|
285
|
+
if (found) {
|
|
286
|
+
lastValidLabel.value = found.label;
|
|
287
|
+
}
|
|
288
|
+
}, {
|
|
289
|
+
immediate: true,
|
|
290
|
+
});
|
|
253
291
|
</script>
|
|
254
292
|
|
|
255
293
|
<template>
|
|
@@ -290,7 +328,13 @@ function onClickRemoveButton() {
|
|
|
290
328
|
:size="size"
|
|
291
329
|
:state="state"
|
|
292
330
|
:close-on-enter="true"
|
|
331
|
+
:max-height="maxHeight"
|
|
332
|
+
@select-element="onElementSelect"
|
|
293
333
|
>
|
|
334
|
+
<template #contentBefore>
|
|
335
|
+
<slot name="selectMenuContentBefore" />
|
|
336
|
+
</template>
|
|
337
|
+
|
|
294
338
|
<template #contentLeft="props">
|
|
295
339
|
<slot
|
|
296
340
|
name="contentLeft"
|
|
@@ -305,6 +349,10 @@ function onClickRemoveButton() {
|
|
|
305
349
|
/>
|
|
306
350
|
</template>
|
|
307
351
|
|
|
352
|
+
<template #empty>
|
|
353
|
+
<slot name="empty" />
|
|
354
|
+
</template>
|
|
355
|
+
|
|
308
356
|
<AntSkeleton
|
|
309
357
|
:visible="skeleton"
|
|
310
358
|
rounded
|
|
@@ -187,7 +187,6 @@ function onBlur(e: FocusEvent) {
|
|
|
187
187
|
<div
|
|
188
188
|
v-if="hasSlotContent($slots['default'])"
|
|
189
189
|
class="relative flex items-center"
|
|
190
|
-
:class="props.size === Size.lg || props.size === Size.md ||props.size === Size.sm ? 'h-5' : 'h-4'"
|
|
191
190
|
>
|
|
192
191
|
<span :class="valueClasses">
|
|
193
192
|
<slot />
|
|
@@ -62,7 +62,7 @@ const props = withDefaults(defineProps<{
|
|
|
62
62
|
openOnFocus?: boolean;
|
|
63
63
|
autoCloseAfterSelection?: boolean;
|
|
64
64
|
createCallback?: (item: string) => Promise<SelectOption>;
|
|
65
|
-
inputRef
|
|
65
|
+
inputRef?: HTMLInputElement | null;
|
|
66
66
|
}>(), {
|
|
67
67
|
size: AntTagInputSize.md,
|
|
68
68
|
state: InputState.base,
|
|
@@ -22,7 +22,7 @@ import type {
|
|
|
22
22
|
Validator,
|
|
23
23
|
} from '@antify/validate';
|
|
24
24
|
import {
|
|
25
|
-
|
|
25
|
+
autoUpdate, flip, offset, useFloating,
|
|
26
26
|
} from '@floating-ui/vue';
|
|
27
27
|
|
|
28
28
|
const emit = defineEmits([
|
|
@@ -43,12 +43,14 @@ const props = withDefaults(defineProps<{
|
|
|
43
43
|
closeOnEnter?: boolean;
|
|
44
44
|
autoSelectFirstOnOpen?: boolean;
|
|
45
45
|
closeOnSelectItem?: boolean;
|
|
46
|
+
maxHeight?: string;
|
|
46
47
|
}>(), {
|
|
47
48
|
state: InputState.base,
|
|
48
49
|
focusOnOpen: true,
|
|
49
50
|
closeOnEnter: false,
|
|
50
51
|
autoSelectFirstOnOpen: true,
|
|
51
52
|
closeOnSelectItem: true,
|
|
53
|
+
maxHeight: '350px',
|
|
52
54
|
});
|
|
53
55
|
const reference = ref<HTMLElement | null | undefined>(props.inputRef);
|
|
54
56
|
const elementSize = useElementSize(reference);
|
|
@@ -80,32 +82,16 @@ const _modelValue = useVModel(props, 'modelValue', emit);
|
|
|
80
82
|
const isOpen = useVModel(props, 'open', emit);
|
|
81
83
|
const focusedDropDownItem = useVModel(props, 'focused', emit);
|
|
82
84
|
const dropdownClasses = computed(() => {
|
|
83
|
-
const variants: Record<InputState, string> = {
|
|
84
|
-
[InputState.base]: 'bg-base-300 border-base-300',
|
|
85
|
-
[InputState.success]: 'bg-success-500 border-success-500',
|
|
86
|
-
[InputState.info]: 'bg-info-500 border-info-500',
|
|
87
|
-
[InputState.warning]: 'bg-warning-500 border-warning-500',
|
|
88
|
-
[InputState.danger]: 'bg-danger-500 border-danger-500',
|
|
89
|
-
};
|
|
90
|
-
|
|
91
85
|
return {
|
|
92
86
|
'w-fit border outline-none -mt-px overflow-y-auto shadow-md z-[90] max-h-[250px]': true,
|
|
93
87
|
'rounded-md': true,
|
|
94
|
-
|
|
88
|
+
'bg-base-300 border-base-300': true,
|
|
95
89
|
};
|
|
96
90
|
});
|
|
97
91
|
const dropDownItemClasses = computed(() => {
|
|
98
|
-
const variants: Record<InputState, string> = {
|
|
99
|
-
[InputState.base]: 'bg-white text-for-white-bg-font',
|
|
100
|
-
[InputState.success]: 'bg-success-100 border-success-100-font',
|
|
101
|
-
[InputState.info]: 'bg-info-100 border-info-100-font',
|
|
102
|
-
[InputState.warning]: 'bg-warning-100 border-warning-100-font',
|
|
103
|
-
[InputState.danger]: 'bg-danger-100 border-danger-100-font',
|
|
104
|
-
};
|
|
105
|
-
|
|
106
92
|
return {
|
|
107
93
|
'flex items-center select-none text-ellipsis overflow-hidden whitespace-nowrap min-h-fit': true,
|
|
108
|
-
|
|
94
|
+
'bg-white text-for-white-bg-font': true,
|
|
109
95
|
// Size
|
|
110
96
|
'p-1 text-xs gap-1': props.size === Size.xs2,
|
|
111
97
|
'p-1.5 text-xs gap1.5': props.size === Size.xs,
|
|
@@ -241,17 +227,8 @@ function getActiveDropDownItemClasses(option: SelectOption) {
|
|
|
241
227
|
return {};
|
|
242
228
|
}
|
|
243
229
|
|
|
244
|
-
const variants: Record<InputState, string> = {
|
|
245
|
-
[InputState.base]: '!bg-base-100',
|
|
246
|
-
[InputState.success]: 'bg-success-200',
|
|
247
|
-
[InputState.info]: 'bg-info-200',
|
|
248
|
-
[InputState.warning]: 'bg-warning-200',
|
|
249
|
-
[InputState.danger]: 'bg-danger-200',
|
|
250
|
-
};
|
|
251
|
-
|
|
252
230
|
return option.value === focusedDropDownItem.value ? {
|
|
253
|
-
'bg-
|
|
254
|
-
[variants[props.state]]: true,
|
|
231
|
+
'!bg-base-100': true,
|
|
255
232
|
} : {};
|
|
256
233
|
}
|
|
257
234
|
|
|
@@ -272,9 +249,31 @@ function onClickDropDownItem(e: MouseEvent, option: SelectOption) {
|
|
|
272
249
|
_modelValue.value = option.value || null;
|
|
273
250
|
}
|
|
274
251
|
|
|
252
|
+
function getOptionClasses(option: SelectOption, index: number) {
|
|
253
|
+
const prevOption = props.options[index - 1];
|
|
254
|
+
|
|
255
|
+
return {
|
|
256
|
+
...dropDownItemClasses.value,
|
|
257
|
+
...getActiveDropDownItemClasses(option),
|
|
258
|
+
'cursor-pointer': !option.isGroupLabel,
|
|
259
|
+
'text-base-600' : true,
|
|
260
|
+
'sticky top-[-1px] z-20 font-bold bg-white': option.isGroupLabel,
|
|
261
|
+
'border-y border-base-300': option.isGroupLabel,
|
|
262
|
+
'-mt-px': option.isGroupLabel,
|
|
263
|
+
'border-t border-base-300':
|
|
264
|
+
!option.isGroupLabel &&
|
|
265
|
+
index !== 0 &&
|
|
266
|
+
(!prevOption || !prevOption.isGroupLabel),
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
|
|
275
270
|
watch(_modelValue, (val) => {
|
|
276
271
|
focusedDropDownItem.value = Array.isArray(val) ? val[0] : val;
|
|
277
272
|
});
|
|
273
|
+
|
|
274
|
+
defineExpose({
|
|
275
|
+
floating,
|
|
276
|
+
});
|
|
278
277
|
</script>
|
|
279
278
|
|
|
280
279
|
<template>
|
|
@@ -288,44 +287,73 @@ watch(_modelValue, (val) => {
|
|
|
288
287
|
<div
|
|
289
288
|
v-if="isOpen"
|
|
290
289
|
ref="floating"
|
|
291
|
-
:class="
|
|
292
|
-
|
|
290
|
+
:class="[
|
|
291
|
+
dropdownClasses,
|
|
292
|
+
'flex flex-col overflow-hidden',
|
|
293
|
+
]"
|
|
294
|
+
:style="{
|
|
295
|
+
minWidth: `${elementSize.width.value}px`,
|
|
296
|
+
maxHeight: props.maxHeight,
|
|
297
|
+
...floatingStyles}"
|
|
293
298
|
data-e2e="select-menu"
|
|
294
299
|
:data-e2e-state="state"
|
|
295
300
|
>
|
|
296
|
-
<div
|
|
301
|
+
<div
|
|
302
|
+
v-if="$slots.contentBefore"
|
|
303
|
+
class="flex-shrink-0 z-30"
|
|
304
|
+
>
|
|
305
|
+
<slot name="contentBefore" />
|
|
306
|
+
</div>
|
|
307
|
+
|
|
308
|
+
<div class="flex-grow overflow-y-auto min-h-0">
|
|
309
|
+
<div class="flex flex-col -mt-px">
|
|
310
|
+
<div
|
|
311
|
+
v-for="(option, index) in options"
|
|
312
|
+
:key="`option-${index}`"
|
|
313
|
+
data-e2e="select-menu-item"
|
|
314
|
+
:class="getOptionClasses(option, index)"
|
|
315
|
+
@click="(e) => onClickDropDownItem(e, option)"
|
|
316
|
+
@mouseover="() => focusedDropDownItem = !option.isGroupLabel && option.value !== undefined ? option.value : null"
|
|
317
|
+
>
|
|
318
|
+
<div class="flex items-center justify-between w-full">
|
|
319
|
+
<div class="flex items-center gap-2">
|
|
320
|
+
<slot
|
|
321
|
+
name="contentLeft"
|
|
322
|
+
v-bind="option"
|
|
323
|
+
/>
|
|
324
|
+
<span>{{ option.label }}</span>
|
|
325
|
+
</div>
|
|
326
|
+
|
|
327
|
+
<div
|
|
328
|
+
v-if="option.tag"
|
|
329
|
+
>
|
|
330
|
+
<span class="px-1 py-0.5 rounded bg-base-200 text-[12px]">
|
|
331
|
+
{{ option.tag }}
|
|
332
|
+
</span>
|
|
333
|
+
</div>
|
|
334
|
+
|
|
335
|
+
<slot
|
|
336
|
+
name="contentRight"
|
|
337
|
+
v-bind="option"
|
|
338
|
+
/>
|
|
339
|
+
</div>
|
|
340
|
+
</div>
|
|
341
|
+
</div>
|
|
342
|
+
|
|
297
343
|
<div
|
|
298
|
-
v-
|
|
299
|
-
:
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
}"
|
|
306
|
-
@click="(e) => onClickDropDownItem(e, option)"
|
|
307
|
-
@mouseover="() => focusedDropDownItem = !option.isGroupLabel && option.value !== undefined ? option.value : null"
|
|
344
|
+
v-if="options.length === 0"
|
|
345
|
+
:class="[
|
|
346
|
+
dropDownItemClasses,
|
|
347
|
+
{
|
|
348
|
+
'flex items-center justify-center p-2 pt-2 bg-white font-medium italic text-center': $slots.contentBefore
|
|
349
|
+
}
|
|
350
|
+
]"
|
|
308
351
|
>
|
|
309
|
-
<slot
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
/>
|
|
313
|
-
{{ option.label }}
|
|
314
|
-
<slot
|
|
315
|
-
name="contentRight"
|
|
316
|
-
v-bind="option"
|
|
317
|
-
/>
|
|
352
|
+
<slot name="empty">
|
|
353
|
+
Keine Einträge vorhanden
|
|
354
|
+
</slot>
|
|
318
355
|
</div>
|
|
319
356
|
</div>
|
|
320
|
-
|
|
321
|
-
<div
|
|
322
|
-
v-if="options.length === 0"
|
|
323
|
-
:class="{...dropDownItemClasses}"
|
|
324
|
-
>
|
|
325
|
-
<slot name="empty">
|
|
326
|
-
Keine Einträge vorhanden
|
|
327
|
-
</slot>
|
|
328
|
-
</div>
|
|
329
357
|
</div>
|
|
330
358
|
</teleport>
|
|
331
359
|
</div>
|
|
@@ -3,16 +3,17 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.withPlaceholder = exports.withDeleted = exports.summary = exports.skeleton = exports.nullable = exports.manyOptions = exports.longOptions = exports.grouped = exports.ellipsisText = exports.disabled = exports.default = exports.WithSlots = exports.Docs = void 0;
|
|
7
|
-
var _Size = require("../../../enums/Size.enum");
|
|
6
|
+
exports.withPlaceholder = exports.withDeleted = exports.summary = exports.skeleton = exports.nullable = exports.manyOptions = exports.longOptions = exports.grouped = exports.ellipsisText = exports.disabled = exports.default = exports.WithSlots = exports.Docs = exports.AdvancedCustomDropdown = void 0;
|
|
8
7
|
var _AntSelect = _interopRequireDefault(require("../AntSelect.vue"));
|
|
9
8
|
var _AntIcon = _interopRequireDefault(require("../../AntIcon.vue"));
|
|
10
9
|
var _AntSelectMenu = _interopRequireDefault(require("../Elements/AntSelectMenu.vue"));
|
|
11
10
|
var _freeSolidSvgIcons = require("@fortawesome/free-solid-svg-icons");
|
|
12
11
|
var _vue = require("vue");
|
|
13
|
-
var _enums = require("../../../enums");
|
|
14
12
|
var _AntFormGroup = _interopRequireDefault(require("../../forms/AntFormGroup.vue"));
|
|
15
13
|
var _AntFormGroupLabel = _interopRequireDefault(require("../../forms/AntFormGroupLabel.vue"));
|
|
14
|
+
var _AntSearch = _interopRequireDefault(require("../AntSearch.vue"));
|
|
15
|
+
var _AntButton = _interopRequireDefault(require("../../AntButton.vue"));
|
|
16
|
+
var _enums = require("../../../enums");
|
|
16
17
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
17
18
|
const meta = {
|
|
18
19
|
title: "Inputs/Select",
|
|
@@ -49,10 +50,10 @@ const meta = {
|
|
|
49
50
|
control: {
|
|
50
51
|
type: "select"
|
|
51
52
|
},
|
|
52
|
-
options: Object.values(
|
|
53
|
+
options: Object.values(_enums.Size),
|
|
53
54
|
table: {
|
|
54
55
|
defaultValue: {
|
|
55
|
-
summary:
|
|
56
|
+
summary: _enums.Size.md
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
},
|
|
@@ -375,6 +376,259 @@ const ellipsisText = exports.ellipsisText = {
|
|
|
375
376
|
nullable: true
|
|
376
377
|
}
|
|
377
378
|
};
|
|
379
|
+
const AdvancedCustomDropdown = exports.AdvancedCustomDropdown = {
|
|
380
|
+
render: args => ({
|
|
381
|
+
components: {
|
|
382
|
+
AntSelect: _AntSelect.default,
|
|
383
|
+
AntSearch: _AntSearch.default,
|
|
384
|
+
AntButton: _AntButton.default,
|
|
385
|
+
AntIcon: _AntIcon.default
|
|
386
|
+
},
|
|
387
|
+
setup() {
|
|
388
|
+
const searchTerm = (0, _vue.ref)(null);
|
|
389
|
+
const isSelectOpen = (0, _vue.ref)(false);
|
|
390
|
+
const activeFilter = (0, _vue.ref)("all");
|
|
391
|
+
const modelValue = (0, _vue.ref)(args.modelValue);
|
|
392
|
+
const rawPractitioners = [{
|
|
393
|
+
name: "Item 1",
|
|
394
|
+
type: "first",
|
|
395
|
+
loc: "Group Name - First"
|
|
396
|
+
}, {
|
|
397
|
+
name: "Item 1",
|
|
398
|
+
type: "first",
|
|
399
|
+
loc: "Group Name - First"
|
|
400
|
+
}, {
|
|
401
|
+
name: "Item 1",
|
|
402
|
+
type: "first",
|
|
403
|
+
loc: "Group Name - First"
|
|
404
|
+
}, {
|
|
405
|
+
name: "Item 1",
|
|
406
|
+
type: "first",
|
|
407
|
+
loc: "Group Name - First"
|
|
408
|
+
}, {
|
|
409
|
+
name: "Item 1",
|
|
410
|
+
type: "first",
|
|
411
|
+
loc: "Group Name - First"
|
|
412
|
+
}, {
|
|
413
|
+
name: "Item 1",
|
|
414
|
+
type: "first",
|
|
415
|
+
loc: "Group Name - First"
|
|
416
|
+
}, {
|
|
417
|
+
name: "Item 1",
|
|
418
|
+
type: "first",
|
|
419
|
+
loc: "Group Name - First"
|
|
420
|
+
}, {
|
|
421
|
+
name: "Item 2",
|
|
422
|
+
type: "second",
|
|
423
|
+
loc: "Group Name - Second"
|
|
424
|
+
}, {
|
|
425
|
+
name: "Item 3",
|
|
426
|
+
type: "third",
|
|
427
|
+
loc: "Group Name - Third"
|
|
428
|
+
}, {
|
|
429
|
+
name: "Item 3",
|
|
430
|
+
type: "third",
|
|
431
|
+
loc: "Group Name - Third"
|
|
432
|
+
}, {
|
|
433
|
+
name: "Item 3",
|
|
434
|
+
type: "third",
|
|
435
|
+
loc: "Group Name - Third"
|
|
436
|
+
}, {
|
|
437
|
+
name: "Item 3",
|
|
438
|
+
type: "third",
|
|
439
|
+
loc: "Group Name - Third"
|
|
440
|
+
}, {
|
|
441
|
+
name: "Item 3",
|
|
442
|
+
type: "third",
|
|
443
|
+
loc: "Group Name - Third"
|
|
444
|
+
}, {
|
|
445
|
+
name: "Item 3",
|
|
446
|
+
type: "third",
|
|
447
|
+
loc: "Group Name - Third"
|
|
448
|
+
}, {
|
|
449
|
+
name: "Item 3",
|
|
450
|
+
type: "third",
|
|
451
|
+
loc: "Group Name - Third"
|
|
452
|
+
}, {
|
|
453
|
+
name: "Item 3",
|
|
454
|
+
type: "third",
|
|
455
|
+
loc: "Group Name - Third"
|
|
456
|
+
}, {
|
|
457
|
+
name: "Item 3",
|
|
458
|
+
type: "third",
|
|
459
|
+
loc: "Group Name - Third"
|
|
460
|
+
}, {
|
|
461
|
+
name: "Item 3",
|
|
462
|
+
type: "third",
|
|
463
|
+
loc: "Group Name - Third"
|
|
464
|
+
}, {
|
|
465
|
+
name: "Item 3",
|
|
466
|
+
type: "third",
|
|
467
|
+
loc: "Group Name - Third"
|
|
468
|
+
}, {
|
|
469
|
+
name: "Item 3",
|
|
470
|
+
type: "third",
|
|
471
|
+
loc: "Group Name - Third"
|
|
472
|
+
}, {
|
|
473
|
+
name: "Item 3",
|
|
474
|
+
type: "third",
|
|
475
|
+
loc: "Group Name - Third"
|
|
476
|
+
}, {
|
|
477
|
+
name: "Item 3",
|
|
478
|
+
type: "third",
|
|
479
|
+
loc: "Group Name - Third"
|
|
480
|
+
}, {
|
|
481
|
+
name: "Item 3",
|
|
482
|
+
type: "third",
|
|
483
|
+
loc: "Group Name - Third"
|
|
484
|
+
}, {
|
|
485
|
+
name: "Item 4",
|
|
486
|
+
type: "fourth",
|
|
487
|
+
loc: "Group Name - Fourth"
|
|
488
|
+
}, {
|
|
489
|
+
name: "Item 5",
|
|
490
|
+
type: "fifth",
|
|
491
|
+
loc: "Group Name - Fifth"
|
|
492
|
+
}, {
|
|
493
|
+
name: "Item 6",
|
|
494
|
+
type: "sixth",
|
|
495
|
+
loc: "Group Name - Sixth"
|
|
496
|
+
}, {
|
|
497
|
+
name: "Item 7",
|
|
498
|
+
type: "seventh",
|
|
499
|
+
loc: "Group Name - Seventh"
|
|
500
|
+
}];
|
|
501
|
+
const typeToTag = {
|
|
502
|
+
first: "FIRST",
|
|
503
|
+
second: "SECOND",
|
|
504
|
+
third: "THIRD",
|
|
505
|
+
fourth: "FOURTH",
|
|
506
|
+
fifth: "FIFTH",
|
|
507
|
+
sixth: "SIXTH",
|
|
508
|
+
seventh: "SEVENTH"
|
|
509
|
+
};
|
|
510
|
+
const filteredOptions = (0, _vue.computed)(() => {
|
|
511
|
+
const search = searchTerm.value;
|
|
512
|
+
const groups = {};
|
|
513
|
+
rawPractitioners.forEach((p, index) => {
|
|
514
|
+
const matchesFilter = activeFilter.value === "all" || p.type === activeFilter.value;
|
|
515
|
+
const matchesSearch = !search || p.name.toLowerCase().includes(search.toLowerCase());
|
|
516
|
+
if (matchesFilter && matchesSearch) {
|
|
517
|
+
if (!groups[p.loc]) {
|
|
518
|
+
groups[p.loc] = [];
|
|
519
|
+
}
|
|
520
|
+
groups[p.loc].push({
|
|
521
|
+
label: p.name,
|
|
522
|
+
value: `${p.name}-${p.loc}-${index}`,
|
|
523
|
+
tag: typeToTag[p.type] || "Another"
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
});
|
|
527
|
+
const result = [];
|
|
528
|
+
Object.keys(groups).sort().forEach(loc => {
|
|
529
|
+
result.push({
|
|
530
|
+
label: loc,
|
|
531
|
+
value: `group-header-${loc}`,
|
|
532
|
+
isGroupLabel: true
|
|
533
|
+
});
|
|
534
|
+
result.push(...groups[loc]);
|
|
535
|
+
});
|
|
536
|
+
return result;
|
|
537
|
+
});
|
|
538
|
+
(0, _vue.watch)(isSelectOpen, val => {
|
|
539
|
+
if (!val) {
|
|
540
|
+
searchTerm.value = null;
|
|
541
|
+
}
|
|
542
|
+
});
|
|
543
|
+
return {
|
|
544
|
+
args,
|
|
545
|
+
isSelectOpen,
|
|
546
|
+
modelValue,
|
|
547
|
+
searchTerm,
|
|
548
|
+
activeFilter,
|
|
549
|
+
filteredOptions,
|
|
550
|
+
State: _enums.State,
|
|
551
|
+
GroupedEnum: _enums.Grouped
|
|
552
|
+
};
|
|
553
|
+
},
|
|
554
|
+
template: `
|
|
555
|
+
<div>
|
|
556
|
+
<AntSelect
|
|
557
|
+
v-bind="args"
|
|
558
|
+
v-model="modelValue"
|
|
559
|
+
v-model:open="isSelectOpen"
|
|
560
|
+
:options="filteredOptions"
|
|
561
|
+
>
|
|
562
|
+
<template #selectMenuContentBefore>
|
|
563
|
+
<div class="flex p-2 border-b border-base-300 bg-white gap-2">
|
|
564
|
+
<AntSearch v-model="searchTerm" placeholder="Search..." />
|
|
565
|
+
|
|
566
|
+
<div class="flex">
|
|
567
|
+
<AntButton
|
|
568
|
+
:state="activeFilter === 'all' ? State.primary : State.base"
|
|
569
|
+
:filled="activeFilter === 'all'"
|
|
570
|
+
:grouped="GroupedEnum.left"
|
|
571
|
+
@click="activeFilter = 'all'"
|
|
572
|
+
>All</AntButton>
|
|
573
|
+
<AntButton
|
|
574
|
+
:state="activeFilter === 'first' ? State.primary : State.base"
|
|
575
|
+
:filled="activeFilter === 'first'"
|
|
576
|
+
:grouped="GroupedEnum.center"
|
|
577
|
+
@click="activeFilter = 'first'"
|
|
578
|
+
>First</AntButton>
|
|
579
|
+
<AntButton
|
|
580
|
+
:state="activeFilter === 'second' ? State.primary : State.base"
|
|
581
|
+
:filled="activeFilter === 'second'"
|
|
582
|
+
:grouped="GroupedEnum.center"
|
|
583
|
+
@click="activeFilter = 'second'"
|
|
584
|
+
>Second</AntButton>
|
|
585
|
+
<AntButton
|
|
586
|
+
:state="activeFilter === 'third' ? State.primary : State.base"
|
|
587
|
+
:filled="activeFilter === 'third'"
|
|
588
|
+
:grouped="GroupedEnum.center"
|
|
589
|
+
@click="activeFilter = 'third'"
|
|
590
|
+
>Third</AntButton>
|
|
591
|
+
<AntButton
|
|
592
|
+
:state="activeFilter === 'fourth' ? State.primary : State.base"
|
|
593
|
+
:filled="activeFilter === 'fourth'"
|
|
594
|
+
:grouped="GroupedEnum.center"
|
|
595
|
+
@click="activeFilter = 'fourth'"
|
|
596
|
+
>Fourth</AntButton>
|
|
597
|
+
<AntButton
|
|
598
|
+
:state="activeFilter === 'fifth' ? State.primary : State.base"
|
|
599
|
+
:filled="activeFilter === 'fifth'"
|
|
600
|
+
:grouped="GroupedEnum.center"
|
|
601
|
+
@click="activeFilter = 'fifth'"
|
|
602
|
+
>Fifth</AntButton>
|
|
603
|
+
<AntButton
|
|
604
|
+
:state="activeFilter === 'sixth' ? State.primary : State.base"
|
|
605
|
+
:filled="activeFilter === 'sixth'"
|
|
606
|
+
:grouped="GroupedEnum.center"
|
|
607
|
+
@click="activeFilter = 'sixth'"
|
|
608
|
+
>Sixth</AntButton>
|
|
609
|
+
<AntButton
|
|
610
|
+
:state="activeFilter === 'seventh' ? State.primary : State.base"
|
|
611
|
+
:filled="activeFilter === 'seventh'"
|
|
612
|
+
:grouped="GroupedEnum.right"
|
|
613
|
+
@click="activeFilter = 'seventh'"
|
|
614
|
+
>Seventh</AntButton>
|
|
615
|
+
</div>
|
|
616
|
+
</div>
|
|
617
|
+
</template>
|
|
618
|
+
|
|
619
|
+
<template #empty>
|
|
620
|
+
Mock message when no match is found
|
|
621
|
+
</template>
|
|
622
|
+
</AntSelect>
|
|
623
|
+
</div>
|
|
624
|
+
`
|
|
625
|
+
}),
|
|
626
|
+
args: {
|
|
627
|
+
label: "Placeholder",
|
|
628
|
+
description: "Sticky groups, Tags and Search inside base AntSelect",
|
|
629
|
+
modelValue: null
|
|
630
|
+
}
|
|
631
|
+
};
|
|
378
632
|
const summary = exports.summary = {
|
|
379
633
|
parameters: {
|
|
380
634
|
chromatic: {
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Size
|
|
3
|
-
} from "../../../enums/Size.enum.mjs";
|
|
4
1
|
import AntSelect from "../AntSelect.vue";
|
|
5
2
|
import AntIcon from "../../AntIcon.vue";
|
|
6
3
|
import AntDropdown from "../Elements/AntSelectMenu.vue";
|
|
@@ -10,13 +7,19 @@ import {
|
|
|
10
7
|
import {
|
|
11
8
|
computed,
|
|
12
9
|
onMounted,
|
|
13
|
-
ref
|
|
10
|
+
ref,
|
|
11
|
+
watch
|
|
14
12
|
} from "vue";
|
|
15
|
-
import {
|
|
16
|
-
InputState
|
|
17
|
-
} from "../../../enums/index.mjs";
|
|
18
13
|
import AntFormGroup from "../../forms/AntFormGroup.vue";
|
|
19
14
|
import AntFormGroupLabel from "../../forms/AntFormGroupLabel.vue";
|
|
15
|
+
import AntSearch from "../AntSearch.vue";
|
|
16
|
+
import AntButton from "../../AntButton.vue";
|
|
17
|
+
import {
|
|
18
|
+
State,
|
|
19
|
+
Grouped as GroupedEnum,
|
|
20
|
+
InputState,
|
|
21
|
+
Size
|
|
22
|
+
} from "../../../enums/index.mjs";
|
|
20
23
|
const meta = {
|
|
21
24
|
title: "Inputs/Select",
|
|
22
25
|
component: AntSelect,
|
|
@@ -412,6 +415,287 @@ export const ellipsisText = {
|
|
|
412
415
|
nullable: true
|
|
413
416
|
}
|
|
414
417
|
};
|
|
418
|
+
export const AdvancedCustomDropdown = {
|
|
419
|
+
render: (args) => ({
|
|
420
|
+
components: {
|
|
421
|
+
AntSelect,
|
|
422
|
+
AntSearch,
|
|
423
|
+
AntButton,
|
|
424
|
+
AntIcon
|
|
425
|
+
},
|
|
426
|
+
setup() {
|
|
427
|
+
const searchTerm = ref(null);
|
|
428
|
+
const isSelectOpen = ref(false);
|
|
429
|
+
const activeFilter = ref("all");
|
|
430
|
+
const modelValue = ref(args.modelValue);
|
|
431
|
+
const rawPractitioners = [
|
|
432
|
+
{
|
|
433
|
+
name: "Item 1",
|
|
434
|
+
type: "first",
|
|
435
|
+
loc: "Group Name - First"
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
name: "Item 1",
|
|
439
|
+
type: "first",
|
|
440
|
+
loc: "Group Name - First"
|
|
441
|
+
},
|
|
442
|
+
{
|
|
443
|
+
name: "Item 1",
|
|
444
|
+
type: "first",
|
|
445
|
+
loc: "Group Name - First"
|
|
446
|
+
},
|
|
447
|
+
{
|
|
448
|
+
name: "Item 1",
|
|
449
|
+
type: "first",
|
|
450
|
+
loc: "Group Name - First"
|
|
451
|
+
},
|
|
452
|
+
{
|
|
453
|
+
name: "Item 1",
|
|
454
|
+
type: "first",
|
|
455
|
+
loc: "Group Name - First"
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
name: "Item 1",
|
|
459
|
+
type: "first",
|
|
460
|
+
loc: "Group Name - First"
|
|
461
|
+
},
|
|
462
|
+
{
|
|
463
|
+
name: "Item 1",
|
|
464
|
+
type: "first",
|
|
465
|
+
loc: "Group Name - First"
|
|
466
|
+
},
|
|
467
|
+
{
|
|
468
|
+
name: "Item 2",
|
|
469
|
+
type: "second",
|
|
470
|
+
loc: "Group Name - Second"
|
|
471
|
+
},
|
|
472
|
+
{
|
|
473
|
+
name: "Item 3",
|
|
474
|
+
type: "third",
|
|
475
|
+
loc: "Group Name - Third"
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
name: "Item 3",
|
|
479
|
+
type: "third",
|
|
480
|
+
loc: "Group Name - Third"
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
name: "Item 3",
|
|
484
|
+
type: "third",
|
|
485
|
+
loc: "Group Name - Third"
|
|
486
|
+
},
|
|
487
|
+
{
|
|
488
|
+
name: "Item 3",
|
|
489
|
+
type: "third",
|
|
490
|
+
loc: "Group Name - Third"
|
|
491
|
+
},
|
|
492
|
+
{
|
|
493
|
+
name: "Item 3",
|
|
494
|
+
type: "third",
|
|
495
|
+
loc: "Group Name - Third"
|
|
496
|
+
},
|
|
497
|
+
{
|
|
498
|
+
name: "Item 3",
|
|
499
|
+
type: "third",
|
|
500
|
+
loc: "Group Name - Third"
|
|
501
|
+
},
|
|
502
|
+
{
|
|
503
|
+
name: "Item 3",
|
|
504
|
+
type: "third",
|
|
505
|
+
loc: "Group Name - Third"
|
|
506
|
+
},
|
|
507
|
+
{
|
|
508
|
+
name: "Item 3",
|
|
509
|
+
type: "third",
|
|
510
|
+
loc: "Group Name - Third"
|
|
511
|
+
},
|
|
512
|
+
{
|
|
513
|
+
name: "Item 3",
|
|
514
|
+
type: "third",
|
|
515
|
+
loc: "Group Name - Third"
|
|
516
|
+
},
|
|
517
|
+
{
|
|
518
|
+
name: "Item 3",
|
|
519
|
+
type: "third",
|
|
520
|
+
loc: "Group Name - Third"
|
|
521
|
+
},
|
|
522
|
+
{
|
|
523
|
+
name: "Item 3",
|
|
524
|
+
type: "third",
|
|
525
|
+
loc: "Group Name - Third"
|
|
526
|
+
},
|
|
527
|
+
{
|
|
528
|
+
name: "Item 3",
|
|
529
|
+
type: "third",
|
|
530
|
+
loc: "Group Name - Third"
|
|
531
|
+
},
|
|
532
|
+
{
|
|
533
|
+
name: "Item 3",
|
|
534
|
+
type: "third",
|
|
535
|
+
loc: "Group Name - Third"
|
|
536
|
+
},
|
|
537
|
+
{
|
|
538
|
+
name: "Item 3",
|
|
539
|
+
type: "third",
|
|
540
|
+
loc: "Group Name - Third"
|
|
541
|
+
},
|
|
542
|
+
{
|
|
543
|
+
name: "Item 3",
|
|
544
|
+
type: "third",
|
|
545
|
+
loc: "Group Name - Third"
|
|
546
|
+
},
|
|
547
|
+
{
|
|
548
|
+
name: "Item 4",
|
|
549
|
+
type: "fourth",
|
|
550
|
+
loc: "Group Name - Fourth"
|
|
551
|
+
},
|
|
552
|
+
{
|
|
553
|
+
name: "Item 5",
|
|
554
|
+
type: "fifth",
|
|
555
|
+
loc: "Group Name - Fifth"
|
|
556
|
+
},
|
|
557
|
+
{
|
|
558
|
+
name: "Item 6",
|
|
559
|
+
type: "sixth",
|
|
560
|
+
loc: "Group Name - Sixth"
|
|
561
|
+
},
|
|
562
|
+
{
|
|
563
|
+
name: "Item 7",
|
|
564
|
+
type: "seventh",
|
|
565
|
+
loc: "Group Name - Seventh"
|
|
566
|
+
}
|
|
567
|
+
];
|
|
568
|
+
const typeToTag = {
|
|
569
|
+
first: "FIRST",
|
|
570
|
+
second: "SECOND",
|
|
571
|
+
third: "THIRD",
|
|
572
|
+
fourth: "FOURTH",
|
|
573
|
+
fifth: "FIFTH",
|
|
574
|
+
sixth: "SIXTH",
|
|
575
|
+
seventh: "SEVENTH"
|
|
576
|
+
};
|
|
577
|
+
const filteredOptions = computed(() => {
|
|
578
|
+
const search = searchTerm.value;
|
|
579
|
+
const groups = {};
|
|
580
|
+
rawPractitioners.forEach((p, index) => {
|
|
581
|
+
const matchesFilter = activeFilter.value === "all" || p.type === activeFilter.value;
|
|
582
|
+
const matchesSearch = !search || p.name.toLowerCase().includes(search.toLowerCase());
|
|
583
|
+
if (matchesFilter && matchesSearch) {
|
|
584
|
+
if (!groups[p.loc]) {
|
|
585
|
+
groups[p.loc] = [];
|
|
586
|
+
}
|
|
587
|
+
groups[p.loc].push({
|
|
588
|
+
label: p.name,
|
|
589
|
+
value: `${p.name}-${p.loc}-${index}`,
|
|
590
|
+
tag: typeToTag[p.type] || "Another"
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
});
|
|
594
|
+
const result = [];
|
|
595
|
+
Object.keys(groups).sort().forEach((loc) => {
|
|
596
|
+
result.push({
|
|
597
|
+
label: loc,
|
|
598
|
+
value: `group-header-${loc}`,
|
|
599
|
+
isGroupLabel: true
|
|
600
|
+
});
|
|
601
|
+
result.push(...groups[loc]);
|
|
602
|
+
});
|
|
603
|
+
return result;
|
|
604
|
+
});
|
|
605
|
+
watch(isSelectOpen, (val) => {
|
|
606
|
+
if (!val) {
|
|
607
|
+
searchTerm.value = null;
|
|
608
|
+
}
|
|
609
|
+
});
|
|
610
|
+
return {
|
|
611
|
+
args,
|
|
612
|
+
isSelectOpen,
|
|
613
|
+
modelValue,
|
|
614
|
+
searchTerm,
|
|
615
|
+
activeFilter,
|
|
616
|
+
filteredOptions,
|
|
617
|
+
State,
|
|
618
|
+
GroupedEnum
|
|
619
|
+
};
|
|
620
|
+
},
|
|
621
|
+
template: `
|
|
622
|
+
<div>
|
|
623
|
+
<AntSelect
|
|
624
|
+
v-bind="args"
|
|
625
|
+
v-model="modelValue"
|
|
626
|
+
v-model:open="isSelectOpen"
|
|
627
|
+
:options="filteredOptions"
|
|
628
|
+
>
|
|
629
|
+
<template #selectMenuContentBefore>
|
|
630
|
+
<div class="flex p-2 border-b border-base-300 bg-white gap-2">
|
|
631
|
+
<AntSearch v-model="searchTerm" placeholder="Search..." />
|
|
632
|
+
|
|
633
|
+
<div class="flex">
|
|
634
|
+
<AntButton
|
|
635
|
+
:state="activeFilter === 'all' ? State.primary : State.base"
|
|
636
|
+
:filled="activeFilter === 'all'"
|
|
637
|
+
:grouped="GroupedEnum.left"
|
|
638
|
+
@click="activeFilter = 'all'"
|
|
639
|
+
>All</AntButton>
|
|
640
|
+
<AntButton
|
|
641
|
+
:state="activeFilter === 'first' ? State.primary : State.base"
|
|
642
|
+
:filled="activeFilter === 'first'"
|
|
643
|
+
:grouped="GroupedEnum.center"
|
|
644
|
+
@click="activeFilter = 'first'"
|
|
645
|
+
>First</AntButton>
|
|
646
|
+
<AntButton
|
|
647
|
+
:state="activeFilter === 'second' ? State.primary : State.base"
|
|
648
|
+
:filled="activeFilter === 'second'"
|
|
649
|
+
:grouped="GroupedEnum.center"
|
|
650
|
+
@click="activeFilter = 'second'"
|
|
651
|
+
>Second</AntButton>
|
|
652
|
+
<AntButton
|
|
653
|
+
:state="activeFilter === 'third' ? State.primary : State.base"
|
|
654
|
+
:filled="activeFilter === 'third'"
|
|
655
|
+
:grouped="GroupedEnum.center"
|
|
656
|
+
@click="activeFilter = 'third'"
|
|
657
|
+
>Third</AntButton>
|
|
658
|
+
<AntButton
|
|
659
|
+
:state="activeFilter === 'fourth' ? State.primary : State.base"
|
|
660
|
+
:filled="activeFilter === 'fourth'"
|
|
661
|
+
:grouped="GroupedEnum.center"
|
|
662
|
+
@click="activeFilter = 'fourth'"
|
|
663
|
+
>Fourth</AntButton>
|
|
664
|
+
<AntButton
|
|
665
|
+
:state="activeFilter === 'fifth' ? State.primary : State.base"
|
|
666
|
+
:filled="activeFilter === 'fifth'"
|
|
667
|
+
:grouped="GroupedEnum.center"
|
|
668
|
+
@click="activeFilter = 'fifth'"
|
|
669
|
+
>Fifth</AntButton>
|
|
670
|
+
<AntButton
|
|
671
|
+
:state="activeFilter === 'sixth' ? State.primary : State.base"
|
|
672
|
+
:filled="activeFilter === 'sixth'"
|
|
673
|
+
:grouped="GroupedEnum.center"
|
|
674
|
+
@click="activeFilter = 'sixth'"
|
|
675
|
+
>Sixth</AntButton>
|
|
676
|
+
<AntButton
|
|
677
|
+
:state="activeFilter === 'seventh' ? State.primary : State.base"
|
|
678
|
+
:filled="activeFilter === 'seventh'"
|
|
679
|
+
:grouped="GroupedEnum.right"
|
|
680
|
+
@click="activeFilter = 'seventh'"
|
|
681
|
+
>Seventh</AntButton>
|
|
682
|
+
</div>
|
|
683
|
+
</div>
|
|
684
|
+
</template>
|
|
685
|
+
|
|
686
|
+
<template #empty>
|
|
687
|
+
Mock message when no match is found
|
|
688
|
+
</template>
|
|
689
|
+
</AntSelect>
|
|
690
|
+
</div>
|
|
691
|
+
`
|
|
692
|
+
}),
|
|
693
|
+
args: {
|
|
694
|
+
label: "Placeholder",
|
|
695
|
+
description: "Sticky groups, Tags and Search inside base AntSelect",
|
|
696
|
+
modelValue: null
|
|
697
|
+
}
|
|
698
|
+
};
|
|
415
699
|
export const summary = {
|
|
416
700
|
parameters: {
|
|
417
701
|
chromatic: {
|