@dpa-id-components/dpa-shared-components 22.0.0-next.2 → 22.0.0-next.4
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/UiListItem/UiListItem.vue.d.ts +2 -2
- package/dist/components/UiPopover/UiPopover.vue.d.ts +5 -1
- package/dist/components/UiToggleButton/UiToggleButton.vue.d.ts +1 -1
- package/dist/dpa-shared-components.js +67 -71
- package/dist/src/components/UiButtonGroup/UiButtonGroup.stories.ts +9 -8
- package/dist/src/components/UiCheckbox/UiCheckbox.stories.ts +14 -5
- package/dist/src/components/UiIcon/UiIcon.stories.ts +8 -4
- package/dist/src/components/UiInput/UiInput.stories.ts +15 -6
- package/dist/src/components/UiListItem/UiListItem.vue +3 -3
- package/dist/src/components/UiMediaTypeIcon/UiMediaTypeIcon.stories.ts +8 -4
- package/dist/src/components/UiMenu/UiMenu.spec.ts +1 -1
- package/dist/src/components/UiMenu/UiMenu.vue +92 -96
- package/dist/src/components/UiPopover/UiPopover.vue +23 -3
- package/dist/src/components/UiRadioButton/UiRadioButton.stories.ts +14 -5
- package/dist/src/components/UiRadioButton/UiRadioButton.vue +1 -1
- package/dist/src/components/UiSelect/UiSelect.stories.ts +12 -5
- package/dist/src/components/UiToggleButton/UiToggleButton.vue +19 -31
- package/dist/style.css +1 -1
- package/package.json +6 -6
- package/src/components/UiListItem/UiListItem.vue +3 -3
- package/src/components/UiMenu/UiMenu.vue +92 -96
- package/src/components/UiPopover/UiPopover.vue +23 -3
- package/src/components/UiRadioButton/UiRadioButton.vue +1 -1
- package/src/components/UiToggleButton/UiToggleButton.vue +19 -31
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<UiPopover
|
|
2
|
+
<UiPopover
|
|
3
|
+
:initially-open="isOpen"
|
|
4
|
+
:animate
|
|
5
|
+
:placement="floatingUiPlacement"
|
|
6
|
+
@toggle="$event ? $emit('open') : $emit('close')"
|
|
7
|
+
>
|
|
3
8
|
<template #button="{ toggle, isOpen: isPopoverOpen }">
|
|
4
9
|
<UiButton
|
|
5
10
|
class="w-full justify-between"
|
|
@@ -10,10 +15,7 @@
|
|
|
10
15
|
:disabled
|
|
11
16
|
:size="filterButtonSize"
|
|
12
17
|
data-testid="menu-button"
|
|
13
|
-
@click="
|
|
14
|
-
toggle();
|
|
15
|
-
isPopoverOpen ? $emit('close') : $emit('open');
|
|
16
|
-
"
|
|
18
|
+
@click="toggle"
|
|
17
19
|
>
|
|
18
20
|
<div class="flex items-center gap-2">
|
|
19
21
|
<UiIcon v-if="iconLeft" :name="iconLeft" size="sm" />
|
|
@@ -23,106 +25,100 @@
|
|
|
23
25
|
</UiButton>
|
|
24
26
|
</template>
|
|
25
27
|
|
|
26
|
-
<
|
|
28
|
+
<div
|
|
29
|
+
class="block w-max max-w-full divide-y overflow-hidden rounded-sm text-base/6 shadow-lg focus:outline-hidden sm:text-sm/5"
|
|
30
|
+
>
|
|
27
31
|
<div
|
|
28
|
-
|
|
32
|
+
v-if="hasSearch"
|
|
33
|
+
class="flex items-center gap-2 rounded-t-sm px-4 py-2 text-neutral-primary [&:has(>input:focus-visible)]:focus-outline [&:has(>input:focus-visible)]:-outline-offset-2"
|
|
29
34
|
>
|
|
30
|
-
<
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
:placeholder="searchPlaceholder"
|
|
46
|
-
data-testid="menu-search-input"
|
|
47
|
-
/>
|
|
48
|
-
</div>
|
|
35
|
+
<UiIcon
|
|
36
|
+
class="shrink-0 text-neutral-emphasis"
|
|
37
|
+
name="search"
|
|
38
|
+
size="sm"
|
|
39
|
+
/>
|
|
40
|
+
<input
|
|
41
|
+
ref="search-input"
|
|
42
|
+
v-model="queryModel"
|
|
43
|
+
type="text"
|
|
44
|
+
spellcheck="false"
|
|
45
|
+
class="w-full text-sm focus:outline-hidden"
|
|
46
|
+
:placeholder="searchPlaceholder"
|
|
47
|
+
data-testid="menu-search-input"
|
|
48
|
+
/>
|
|
49
|
+
</div>
|
|
49
50
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
51
|
+
<slot
|
|
52
|
+
v-bind="{
|
|
53
|
+
checkboxAppearance,
|
|
54
|
+
checkboxSize,
|
|
55
|
+
iconSize,
|
|
56
|
+
imageShape,
|
|
57
|
+
listVariant,
|
|
58
|
+
options,
|
|
59
|
+
groupedOptions,
|
|
60
|
+
}"
|
|
61
|
+
>
|
|
62
|
+
<ul
|
|
63
|
+
v-if="processedOptions.some(({ options }) => options.length > 0)"
|
|
64
|
+
class="max-h-80 overflow-y-auto"
|
|
65
|
+
data-testid="menu-option-list"
|
|
60
66
|
>
|
|
61
|
-
<
|
|
62
|
-
v-
|
|
63
|
-
|
|
64
|
-
data-testid="menu-option-list"
|
|
67
|
+
<template
|
|
68
|
+
v-for="group in processedOptions"
|
|
69
|
+
:key="`group-${group.groupLabel ?? 'default'}`"
|
|
65
70
|
>
|
|
66
|
-
<template
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
class="flex h-6 items-center bg-neutral-whisper px-4 text-xs font-semibold tracking-wider text-neutral-subtle uppercase"
|
|
74
|
-
>
|
|
75
|
-
{{ group.groupLabel }}
|
|
76
|
-
</li>
|
|
71
|
+
<template v-if="group.options.length > 0">
|
|
72
|
+
<li
|
|
73
|
+
v-if="group.groupLabel"
|
|
74
|
+
class="flex h-6 items-center bg-neutral-whisper px-4 text-xs font-semibold tracking-wider text-neutral-subtle uppercase"
|
|
75
|
+
>
|
|
76
|
+
{{ group.groupLabel }}
|
|
77
|
+
</li>
|
|
77
78
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
if (shouldCloseMenu) {
|
|
100
|
-
close();
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
"
|
|
104
|
-
>{{ option.label }}</UiListItem
|
|
105
|
-
>
|
|
106
|
-
</template>
|
|
79
|
+
<UiListItem
|
|
80
|
+
v-for="(option, index) in group.options"
|
|
81
|
+
:key="`option-${option.value}`"
|
|
82
|
+
:selected="option.selected"
|
|
83
|
+
:selectable="listVariant === 'selectable'"
|
|
84
|
+
:is-checked="option.selected"
|
|
85
|
+
:check-box-menu="listVariant === 'checkbox'"
|
|
86
|
+
:icon-size="iconSize"
|
|
87
|
+
:image-shape="imageShape"
|
|
88
|
+
:image-src="option.imageSrc"
|
|
89
|
+
:icon-name="option.iconName"
|
|
90
|
+
:checkbox-size="checkboxSize"
|
|
91
|
+
:checkbox-appearance="checkboxAppearance"
|
|
92
|
+
class="hover:bg-neutral-whisper focus:bg-neutral-faint"
|
|
93
|
+
:class="{
|
|
94
|
+
'border-t': option.hasDividerAbove,
|
|
95
|
+
}"
|
|
96
|
+
:data-testid="`menu-option-button-${index}`"
|
|
97
|
+
@list-item-click="selectOption(option)"
|
|
98
|
+
>{{ option.label }}</UiListItem
|
|
99
|
+
>
|
|
107
100
|
</template>
|
|
108
|
-
</
|
|
109
|
-
</
|
|
101
|
+
</template>
|
|
102
|
+
</ul>
|
|
103
|
+
</slot>
|
|
110
104
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
105
|
+
<div v-if="hasResetOption" class="px-4 py-2 text-neutral-primary">
|
|
106
|
+
<UiButton
|
|
107
|
+
appearance="secondary"
|
|
108
|
+
:disabled="disabledReset"
|
|
109
|
+
icon-name="reset"
|
|
110
|
+
size="xs"
|
|
111
|
+
data-testid="menu-search-reset-button"
|
|
112
|
+
@click="
|
|
113
|
+
queryModel = '';
|
|
114
|
+
$emit('reset');
|
|
115
|
+
"
|
|
116
|
+
>
|
|
117
|
+
<UiIcon name="reset" />
|
|
118
|
+
{{ resetLabel }}
|
|
119
|
+
</UiButton>
|
|
124
120
|
</div>
|
|
125
|
-
</
|
|
121
|
+
</div>
|
|
126
122
|
</UiPopover>
|
|
127
123
|
</template>
|
|
128
124
|
|
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
2
|
+
<div
|
|
3
|
+
ref="reference"
|
|
4
|
+
v-click-away="
|
|
5
|
+
() => {
|
|
6
|
+
if (isOpen) {
|
|
7
|
+
close();
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
"
|
|
11
|
+
class="w-fit"
|
|
12
|
+
@click="update"
|
|
13
|
+
>
|
|
3
14
|
<slot name="button" v-bind="{ open, close, toggle, isOpen }" />
|
|
4
15
|
|
|
5
16
|
<Transition :name="animate ? 'fade-up' : 'none'">
|
|
@@ -25,7 +36,7 @@ import {
|
|
|
25
36
|
shift,
|
|
26
37
|
useFloating,
|
|
27
38
|
} from "@floating-ui/vue";
|
|
28
|
-
import { ref, useTemplateRef } from "vue";
|
|
39
|
+
import { ref, useTemplateRef, watch } from "vue";
|
|
29
40
|
|
|
30
41
|
import { vClickAway } from "../../directives/vClickAway.ts";
|
|
31
42
|
|
|
@@ -61,9 +72,12 @@ const {
|
|
|
61
72
|
placement?: Placement;
|
|
62
73
|
}>();
|
|
63
74
|
|
|
75
|
+
const emit = defineEmits<{
|
|
76
|
+
toggle: [isOpen: boolean];
|
|
77
|
+
}>();
|
|
78
|
+
|
|
64
79
|
const reference = useTemplateRef("reference");
|
|
65
80
|
const floating = useTemplateRef("floating");
|
|
66
|
-
const isOpen = ref(initiallyOpen);
|
|
67
81
|
|
|
68
82
|
const { floatingStyles, update } = useFloating(reference, floating, {
|
|
69
83
|
placement,
|
|
@@ -71,6 +85,12 @@ const { floatingStyles, update } = useFloating(reference, floating, {
|
|
|
71
85
|
whileElementsMounted: autoUpdate,
|
|
72
86
|
});
|
|
73
87
|
|
|
88
|
+
const isOpen = ref(initiallyOpen);
|
|
89
|
+
|
|
90
|
+
watch(isOpen, (isOpen) => {
|
|
91
|
+
emit("toggle", isOpen);
|
|
92
|
+
});
|
|
93
|
+
|
|
74
94
|
function open() {
|
|
75
95
|
isOpen.value = true;
|
|
76
96
|
}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
<input
|
|
14
14
|
:id="uniqueId"
|
|
15
15
|
v-model="model"
|
|
16
|
-
class="inline-flex aspect-square appearance-none items-center justify-center rounded-full border-2 bg-neutral align-middle transition-colors after:size-2 after:rounded-full checked:after:content-['']
|
|
16
|
+
class="inline-flex aspect-square appearance-none items-center justify-center rounded-full border-2 bg-neutral align-middle transition-colors after:size-2 after:rounded-full checked:after:content-[''] enabled:cursor-pointer disabled:border-neutral-muted disabled:text-neutral-soft disabled:checked:after:bg-neutral-muted"
|
|
17
17
|
:class="{
|
|
18
18
|
'size-4': size === 'sm',
|
|
19
19
|
'size-5': size === 'md',
|
|
@@ -9,35 +9,23 @@
|
|
|
9
9
|
"
|
|
10
10
|
>
|
|
11
11
|
<slot v-if="labelPosition === 'left'" />
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}"
|
|
30
|
-
/>
|
|
31
|
-
<div
|
|
32
|
-
:class="{
|
|
33
|
-
'translate-x-full bg-secondary': modelValue,
|
|
34
|
-
'bg-neutral-muted': !modelValue,
|
|
35
|
-
'-top-0.5 size-4': size === 'sm',
|
|
36
|
-
'-top-1 size-6': size === 'lg',
|
|
37
|
-
}"
|
|
38
|
-
class="dot absolute -left-1 rounded-full shadow-sm transition-transform duration-200 ease-in-out"
|
|
39
|
-
/>
|
|
40
|
-
</div>
|
|
12
|
+
|
|
13
|
+
<input
|
|
14
|
+
:id="toggleId"
|
|
15
|
+
v-model="model"
|
|
16
|
+
class="relative appearance-none rounded-full shadow-inner transition-opacity duration-200 ease-in-out after:absolute after:-left-1 after:block after:rounded-full after:shadow-sm after:transition-transform after:duration-200 after:ease-in-out after:content-[''] enabled:cursor-pointer"
|
|
17
|
+
:class="{
|
|
18
|
+
'bg-secondary-emphasis after:translate-x-full after:bg-secondary':
|
|
19
|
+
model,
|
|
20
|
+
'bg-neutral-faint after:bg-neutral-muted': !model,
|
|
21
|
+
'h-3 w-6 after:-top-0.5 after:size-4': size === 'sm',
|
|
22
|
+
'h-4 w-10 after:-top-1 after:size-6': size === 'lg',
|
|
23
|
+
}"
|
|
24
|
+
type="checkbox"
|
|
25
|
+
role="switch"
|
|
26
|
+
data-testid="toggleButton"
|
|
27
|
+
v-bind="{ ...$attrs, class: null }"
|
|
28
|
+
/>
|
|
41
29
|
|
|
42
30
|
<slot v-if="labelPosition === 'right'" />
|
|
43
31
|
</UiLabel>
|
|
@@ -51,13 +39,13 @@ import UiLabel from "../UiLabel/UiLabel.vue";
|
|
|
51
39
|
|
|
52
40
|
defineOptions({ inheritAttrs: false });
|
|
53
41
|
|
|
54
|
-
const
|
|
42
|
+
const model = defineModel<boolean>({ default: false });
|
|
55
43
|
|
|
56
44
|
defineSlots<{
|
|
57
45
|
/**
|
|
58
46
|
* Label content.
|
|
59
47
|
*/
|
|
60
|
-
default
|
|
48
|
+
default: () => any;
|
|
61
49
|
}>();
|
|
62
50
|
|
|
63
51
|
const {
|