vueless 0.0.112 → 0.0.114
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/directive.clickOutside/index.js +53 -0
- package/directive.tooltip/index.js +2 -0
- package/package.json +1 -1
- package/ui.button/index.vue +1 -1
- package/ui.container-row/composables/attrs.composable.js +7 -1
- package/ui.container-row/configs/default.config.js +32 -3
- package/ui.container-row/index.stories.js +55 -10
- package/ui.container-row/index.vue +18 -0
- package/ui.dropdown-badge/index.vue +21 -43
- package/ui.dropdown-button/index.vue +20 -35
- package/ui.dropdown-link/index.vue +23 -43
- package/ui.form-calendar/index.stories.js +1 -1
- package/ui.other-dot/configs/default.config.js +3 -1
- package/ui.other-dot/index.stories.js +16 -23
- package/ui.other-dot/index.vue +1 -1
- package/web-types.json +24 -24
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { unref } from "vue";
|
|
2
|
+
|
|
3
|
+
function clickOutside(target, handler, options) {
|
|
4
|
+
const { capture = true } = options;
|
|
5
|
+
|
|
6
|
+
let shouldListen = true;
|
|
7
|
+
|
|
8
|
+
const el = unref(target);
|
|
9
|
+
|
|
10
|
+
function onClick(event) {
|
|
11
|
+
if (!el || el === event.target || event.composedPath().includes(el)) return;
|
|
12
|
+
|
|
13
|
+
if (!shouldListen) {
|
|
14
|
+
shouldListen = true;
|
|
15
|
+
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
handler(event);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function onPointerdown(event) {
|
|
23
|
+
shouldListen = !!(el && !event.composedPath().includes(el));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
window.addEventListener("click", onClick, { passive: true, capture });
|
|
27
|
+
window.addEventListener("pointerdown", onPointerdown, { passive: true });
|
|
28
|
+
|
|
29
|
+
function removeEvents() {
|
|
30
|
+
window.removeEventListener("click", onClick, { capture, passive: true });
|
|
31
|
+
window.removeEventListener("pointerdown", onPointerdown, { passive: true });
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return removeEvents;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export default {
|
|
38
|
+
mounted(el, binding) {
|
|
39
|
+
const capture = !binding.modifiers.bubble;
|
|
40
|
+
|
|
41
|
+
if (typeof binding.value === "function") {
|
|
42
|
+
el._clickOutsideRemove = clickOutside(el, binding.value, { capture });
|
|
43
|
+
} else {
|
|
44
|
+
const [handler, options] = binding.value;
|
|
45
|
+
|
|
46
|
+
el._clickOutsideRemove = clickOutside(el, handler, Object.assign({ capture }, options));
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
unmounted(el) {
|
|
51
|
+
el._clickOutsideRemove();
|
|
52
|
+
},
|
|
53
|
+
};
|
|
@@ -21,11 +21,13 @@ export default {
|
|
|
21
21
|
mounted(el, bindings) {
|
|
22
22
|
tippy(el, merge(mergedSettings, bindings.value || {}));
|
|
23
23
|
},
|
|
24
|
+
|
|
24
25
|
updated(el, bindings) {
|
|
25
26
|
if (!el._tippy) return;
|
|
26
27
|
|
|
27
28
|
el._tippy.setProps(merge(mergedSettings, bindings.value || {}));
|
|
28
29
|
},
|
|
30
|
+
|
|
29
31
|
unmounted(el) {
|
|
30
32
|
if (!el._tippy) return;
|
|
31
33
|
|
package/package.json
CHANGED
package/ui.button/index.vue
CHANGED
|
@@ -13,7 +13,13 @@ export function useAttrs(props) {
|
|
|
13
13
|
compoundVariants: wrapper.compoundVariants,
|
|
14
14
|
});
|
|
15
15
|
|
|
16
|
-
const wrapperClasses = computed(() =>
|
|
16
|
+
const wrapperClasses = computed(() =>
|
|
17
|
+
cvaWrapper({
|
|
18
|
+
gap: props.gap,
|
|
19
|
+
align: props.align,
|
|
20
|
+
noMobile: props.noMobile,
|
|
21
|
+
}),
|
|
22
|
+
);
|
|
17
23
|
|
|
18
24
|
const wrapperAttrs = getAttrs("wrapper", { classes: wrapperClasses });
|
|
19
25
|
|
|
@@ -1,14 +1,43 @@
|
|
|
1
1
|
export default /*tw*/ {
|
|
2
2
|
wrapper: {
|
|
3
|
-
base: "flex
|
|
3
|
+
base: "flex flex-col md:flex-row w-full",
|
|
4
4
|
variants: {
|
|
5
|
+
gap: {
|
|
6
|
+
none: "space-y-0 md:space-x-0",
|
|
7
|
+
"2xs": "space-y-1 md:space-x-1",
|
|
8
|
+
xs: "space-y-2 md:space-x-2",
|
|
9
|
+
sm: "space-y-3 md:space-x-3",
|
|
10
|
+
md: "space-y-4 md:space-x-4",
|
|
11
|
+
lg: "space-y-5 md:space-x-5",
|
|
12
|
+
xl: "space-y-6 md:space-x-6",
|
|
13
|
+
"2xl": "space-y-8 md:space-x-8",
|
|
14
|
+
},
|
|
15
|
+
align: {
|
|
16
|
+
end: "items-end",
|
|
17
|
+
start: "items-start",
|
|
18
|
+
center: "items-center",
|
|
19
|
+
stretch: "items-stretch",
|
|
20
|
+
baseline: "items-baseline",
|
|
21
|
+
},
|
|
5
22
|
noMobile: {
|
|
6
|
-
true: "flex-row space-
|
|
7
|
-
false: "
|
|
23
|
+
true: "flex-row space-y-0",
|
|
24
|
+
false: "md:space-y-0",
|
|
8
25
|
},
|
|
9
26
|
},
|
|
27
|
+
compoundVariants: [
|
|
28
|
+
{ gap: "none", noMobile: true, class: "space-x-0" },
|
|
29
|
+
{ gap: "2xs", noMobile: true, class: "space-x-1" },
|
|
30
|
+
{ gap: "xs", noMobile: true, class: "space-x-2" },
|
|
31
|
+
{ gap: "sm", noMobile: true, class: "space-x-3" },
|
|
32
|
+
{ gap: "md", noMobile: true, class: "space-x-4" },
|
|
33
|
+
{ gap: "lg", noMobile: true, class: "space-x-5" },
|
|
34
|
+
{ gap: "xl", noMobile: true, class: "space-x-6" },
|
|
35
|
+
{ gap: "2xl", noMobile: true, class: "space-x-8" },
|
|
36
|
+
],
|
|
10
37
|
},
|
|
11
38
|
defaultVariants: {
|
|
39
|
+
gap: "md",
|
|
40
|
+
align: "start",
|
|
12
41
|
noMobile: false,
|
|
13
42
|
},
|
|
14
43
|
};
|
|
@@ -2,6 +2,8 @@ import { getArgTypes } from "../service.storybook";
|
|
|
2
2
|
|
|
3
3
|
import URow from "../ui.container-row";
|
|
4
4
|
import UInput from "../ui.form-input";
|
|
5
|
+
import UGroup from "../ui.container-group";
|
|
6
|
+
import UButton from "../ui.button";
|
|
5
7
|
|
|
6
8
|
export default {
|
|
7
9
|
id: "5020",
|
|
@@ -13,24 +15,67 @@ export default {
|
|
|
13
15
|
};
|
|
14
16
|
|
|
15
17
|
const DefaultTemplate = (args) => ({
|
|
16
|
-
components: { URow, UInput },
|
|
18
|
+
components: { URow, UInput, UButton },
|
|
17
19
|
setup() {
|
|
18
20
|
return { args };
|
|
19
21
|
},
|
|
20
22
|
template: `
|
|
21
23
|
<URow v-bind="args">
|
|
22
|
-
${
|
|
24
|
+
${
|
|
25
|
+
args.slotTemplate ||
|
|
26
|
+
`
|
|
27
|
+
<UInput label="Name" />
|
|
28
|
+
<UButton label="Submit" size="xs" block />
|
|
29
|
+
`
|
|
30
|
+
}
|
|
23
31
|
</URow>
|
|
24
32
|
`,
|
|
25
33
|
});
|
|
26
34
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
35
|
+
const GapTemplate = (args, { argTypes } = {}) => ({
|
|
36
|
+
components: { UGroup, URow, UInput },
|
|
37
|
+
setup() {
|
|
38
|
+
return {
|
|
39
|
+
args,
|
|
40
|
+
gaps: argTypes.gap.options,
|
|
41
|
+
};
|
|
42
|
+
},
|
|
43
|
+
template: `
|
|
44
|
+
<UGroup size="lg">
|
|
45
|
+
<URow v-for="(gap, index) in gaps" :key="index" v-bind="args" :gap="gap" align="center">
|
|
46
|
+
<UInput :label="gap" />
|
|
47
|
+
<UInput :label="gap" />
|
|
48
|
+
</URow>
|
|
49
|
+
</UGroup>
|
|
32
50
|
`,
|
|
33
|
-
};
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const AlignTemplate = (args, { argTypes } = {}) => ({
|
|
54
|
+
components: { UGroup, URow, UInput, UButton },
|
|
55
|
+
setup() {
|
|
56
|
+
return {
|
|
57
|
+
args,
|
|
58
|
+
aligns: argTypes.align.options,
|
|
59
|
+
};
|
|
60
|
+
},
|
|
61
|
+
template: `
|
|
62
|
+
<UGroup size="lg">
|
|
63
|
+
<URow v-for="(align, index) in aligns" :key="index" v-bind="args" :align="align">
|
|
64
|
+
<UButton :label="align" size="xs" block />
|
|
65
|
+
<UInput label="Name" />
|
|
66
|
+
</URow>
|
|
67
|
+
</UGroup>
|
|
68
|
+
`,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
export const Default = DefaultTemplate.bind({});
|
|
72
|
+
Default.args = {};
|
|
73
|
+
|
|
74
|
+
export const Gap = GapTemplate.bind({});
|
|
75
|
+
Gap.args = {};
|
|
76
|
+
|
|
77
|
+
export const Align = AlignTemplate.bind({});
|
|
78
|
+
Align.args = {};
|
|
34
79
|
|
|
35
80
|
export const noMobile = DefaultTemplate.bind({});
|
|
36
81
|
noMobile.args = {
|
|
@@ -53,8 +98,8 @@ nestedRows.args = {
|
|
|
53
98
|
`,
|
|
54
99
|
};
|
|
55
100
|
|
|
56
|
-
export const
|
|
57
|
-
|
|
101
|
+
export const textBlocksExample = DefaultTemplate.bind({});
|
|
102
|
+
textBlocksExample.args = {
|
|
58
103
|
slotTemplate: `
|
|
59
104
|
<p>
|
|
60
105
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
|
|
@@ -16,6 +16,24 @@ import { useAttrs } from "./composables/attrs.composable";
|
|
|
16
16
|
defineOptions({ name: "URow", inheritAttrs: false });
|
|
17
17
|
|
|
18
18
|
const props = defineProps({
|
|
19
|
+
/**
|
|
20
|
+
* Row spacing between nested elements.
|
|
21
|
+
* @values none, 2xs, xs, sm, md, lg, xl, 2xl
|
|
22
|
+
*/
|
|
23
|
+
gap: {
|
|
24
|
+
type: String,
|
|
25
|
+
default: UIService.get(defaultConfig, URow).default.gap,
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Row nested elements vertical align (align-items).
|
|
30
|
+
* @values start, end, center, stretch, baseline
|
|
31
|
+
*/
|
|
32
|
+
align: {
|
|
33
|
+
type: String,
|
|
34
|
+
default: UIService.get(defaultConfig, URow).default.align,
|
|
35
|
+
},
|
|
36
|
+
|
|
19
37
|
/**
|
|
20
38
|
* Disables mobile adaptivity.
|
|
21
39
|
*/
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div v-bind="wrapperAttrs">
|
|
2
|
+
<div v-click-outside="hideOptions" v-bind="wrapperAttrs">
|
|
3
3
|
<UBadge
|
|
4
4
|
:id="id"
|
|
5
|
-
ref="badgeRef"
|
|
6
5
|
:label="label"
|
|
7
6
|
:size="size"
|
|
8
7
|
:color="color"
|
|
@@ -10,8 +9,7 @@
|
|
|
10
9
|
:variant="variant"
|
|
11
10
|
:data-cy="`${dataCy}-badge`"
|
|
12
11
|
v-bind="badgeAttrs"
|
|
13
|
-
@click
|
|
14
|
-
@blur="onBlurBadge"
|
|
12
|
+
@click="onClickBadge"
|
|
15
13
|
>
|
|
16
14
|
<template #right>
|
|
17
15
|
<UIcon
|
|
@@ -26,26 +24,32 @@
|
|
|
26
24
|
</template>
|
|
27
25
|
</UBadge>
|
|
28
26
|
|
|
29
|
-
<div
|
|
27
|
+
<div
|
|
28
|
+
v-if="isShownOptions && hasSlotContent($slots['default'])"
|
|
29
|
+
v-bind="listWrapperAttrs"
|
|
30
|
+
@click="onClickList"
|
|
31
|
+
>
|
|
30
32
|
<!-- @slot Use it to add dropdown list. -->
|
|
31
33
|
<slot />
|
|
32
34
|
</div>
|
|
33
35
|
|
|
34
36
|
<UDropdownList
|
|
35
37
|
v-if="isShownOptions && !hasSlotContent($slots['default'])"
|
|
36
|
-
v-model="
|
|
38
|
+
v-model="selectedItem"
|
|
37
39
|
:size="size"
|
|
38
40
|
:options="options"
|
|
39
41
|
:value-key="valueKey"
|
|
40
42
|
:label-key="labelKey"
|
|
41
43
|
:data-cy="`${dataCy}-item`"
|
|
42
44
|
v-bind="listAttrs"
|
|
45
|
+
@mousedown.stop
|
|
46
|
+
@click.stop="onClickList"
|
|
43
47
|
/>
|
|
44
48
|
</div>
|
|
45
49
|
</template>
|
|
46
50
|
|
|
47
51
|
<script setup>
|
|
48
|
-
import { computed,
|
|
52
|
+
import { computed, provide, ref, watch } from "vue";
|
|
49
53
|
|
|
50
54
|
import UIcon from "../ui.image-icon";
|
|
51
55
|
import UBadge from "../ui.text-badge";
|
|
@@ -53,6 +57,8 @@ import UDropdownList from "../ui.dropdown-list";
|
|
|
53
57
|
|
|
54
58
|
import UIService, { getRandomId } from "../service.ui";
|
|
55
59
|
|
|
60
|
+
import vClickOutside from "../directive.clickOutside";
|
|
61
|
+
|
|
56
62
|
import defaultConfig from "./configs/default.config";
|
|
57
63
|
import { UDropdownBadge } from "./constants";
|
|
58
64
|
import { useAttrs } from "./composables/attrs.composable";
|
|
@@ -61,14 +67,6 @@ import { useAttrs } from "./composables/attrs.composable";
|
|
|
61
67
|
defineOptions({ name: "UDropdownBadge", inheritAttrs: false });
|
|
62
68
|
|
|
63
69
|
const props = defineProps({
|
|
64
|
-
/**
|
|
65
|
-
* Selected value.
|
|
66
|
-
*/
|
|
67
|
-
modelValue: {
|
|
68
|
-
type: [String, Number],
|
|
69
|
-
default: "",
|
|
70
|
-
},
|
|
71
|
-
|
|
72
70
|
/**
|
|
73
71
|
* Badge label.
|
|
74
72
|
*/
|
|
@@ -189,25 +187,16 @@ const props = defineProps({
|
|
|
189
187
|
},
|
|
190
188
|
});
|
|
191
189
|
|
|
192
|
-
|
|
190
|
+
const emit = defineEmits(["select"]);
|
|
193
191
|
|
|
194
|
-
|
|
192
|
+
provide("hideDropdownOptions", () => hideOptions);
|
|
195
193
|
|
|
196
194
|
const isShownOptions = ref(false);
|
|
197
|
-
|
|
198
|
-
const badgeRef = ref(null);
|
|
195
|
+
const selectedItem = ref("");
|
|
199
196
|
|
|
200
197
|
const { config, listWrapperAttrs, wrapperAttrs, badgeAttrs, listAttrs, iconAttrs, hasSlotContent } =
|
|
201
198
|
useAttrs(props, { isShownOptions });
|
|
202
199
|
|
|
203
|
-
const selectValue = computed({
|
|
204
|
-
get: () => props.modelValue,
|
|
205
|
-
set: (value) => {
|
|
206
|
-
isShownOptions.value = false;
|
|
207
|
-
emit("update:modelValue", value);
|
|
208
|
-
},
|
|
209
|
-
});
|
|
210
|
-
|
|
211
200
|
const iconSize = computed(() => {
|
|
212
201
|
const sizes = {
|
|
213
202
|
sm: "xs",
|
|
@@ -218,10 +207,9 @@ const iconSize = computed(() => {
|
|
|
218
207
|
return sizes[props.size];
|
|
219
208
|
});
|
|
220
209
|
|
|
221
|
-
watch(() =>
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
onUnmounted(() => window.removeEventListener("click", onClickOutside));
|
|
210
|
+
watch(selectedItem, () => {
|
|
211
|
+
emit("select", selectedItem.value);
|
|
212
|
+
});
|
|
225
213
|
|
|
226
214
|
function onClickBadge() {
|
|
227
215
|
isShownOptions.value = !isShownOptions.value;
|
|
@@ -231,17 +219,7 @@ function hideOptions() {
|
|
|
231
219
|
isShownOptions.value = false;
|
|
232
220
|
}
|
|
233
221
|
|
|
234
|
-
function
|
|
235
|
-
|
|
236
|
-
hideOptions();
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
function onBlurBadge(event) {
|
|
241
|
-
setTimeout(() => {
|
|
242
|
-
if (!event.target.isEqualNode(event.relatedTarget) && event.relatedTarget) {
|
|
243
|
-
hideOptions();
|
|
244
|
-
}
|
|
245
|
-
}, 100);
|
|
222
|
+
function onClickList() {
|
|
223
|
+
hideOptions();
|
|
246
224
|
}
|
|
247
225
|
</script>
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div v-bind="wrapperAttrs">
|
|
2
|
+
<div v-click-outside="hideOptions" v-bind="wrapperAttrs">
|
|
3
3
|
<UButton
|
|
4
4
|
:id="id"
|
|
5
|
-
ref="buttonRef"
|
|
6
5
|
:label="label"
|
|
7
6
|
:size="size"
|
|
8
7
|
:variant="variant"
|
|
@@ -13,8 +12,7 @@
|
|
|
13
12
|
:disabled="disabled"
|
|
14
13
|
:data-cy="`${dataCy}-button`"
|
|
15
14
|
v-bind="buttonAttrs"
|
|
16
|
-
@click
|
|
17
|
-
@blur="onBlurButton"
|
|
15
|
+
@click="onClickButton"
|
|
18
16
|
>
|
|
19
17
|
<template #right>
|
|
20
18
|
<UIcon
|
|
@@ -29,14 +27,18 @@
|
|
|
29
27
|
</template>
|
|
30
28
|
</UButton>
|
|
31
29
|
|
|
32
|
-
<div
|
|
30
|
+
<div
|
|
31
|
+
v-if="isShownOptions && hasSlotContent($slots['default'])"
|
|
32
|
+
v-bind="listWrapperAttrs"
|
|
33
|
+
@click="onClickList"
|
|
34
|
+
>
|
|
33
35
|
<!-- @slot Use it to add dropdown list. -->
|
|
34
36
|
<slot />
|
|
35
37
|
</div>
|
|
36
38
|
|
|
37
39
|
<UDropdownList
|
|
38
40
|
v-if="isShownOptions && !hasSlotContent($slots['default'])"
|
|
39
|
-
v-model="
|
|
41
|
+
v-model="selectedItem"
|
|
40
42
|
:size="size"
|
|
41
43
|
:options="options"
|
|
42
44
|
:value-key="valueKey"
|
|
@@ -45,13 +47,13 @@
|
|
|
45
47
|
tabindex="-1"
|
|
46
48
|
v-bind="listAttrs"
|
|
47
49
|
@mousedown.stop
|
|
48
|
-
@click.stop
|
|
50
|
+
@click.stop="onClickList"
|
|
49
51
|
/>
|
|
50
52
|
</div>
|
|
51
53
|
</template>
|
|
52
54
|
|
|
53
55
|
<script setup>
|
|
54
|
-
import { computed,
|
|
56
|
+
import { computed, provide, ref, watch } from "vue";
|
|
55
57
|
|
|
56
58
|
import UIcon from "../ui.image-icon";
|
|
57
59
|
import UButton from "../ui.button";
|
|
@@ -59,6 +61,8 @@ import UDropdownList from "../ui.dropdown-list";
|
|
|
59
61
|
|
|
60
62
|
import UIService, { getRandomId } from "../service.ui";
|
|
61
63
|
|
|
64
|
+
import vClickOutside from "../directive.clickOutside";
|
|
65
|
+
|
|
62
66
|
import defaultConfig from "./configs/default.config";
|
|
63
67
|
import { useAttrs } from "./composables/attrs.composable";
|
|
64
68
|
import { UDropdownButton, BUTTON_VARIANT } from "./constants";
|
|
@@ -218,12 +222,12 @@ const props = defineProps({
|
|
|
218
222
|
},
|
|
219
223
|
});
|
|
220
224
|
|
|
221
|
-
|
|
225
|
+
const emit = defineEmits(["select"]);
|
|
222
226
|
|
|
223
|
-
|
|
227
|
+
provide("hideDropdownOptions", () => hideOptions);
|
|
224
228
|
|
|
225
229
|
const isShownOptions = ref(false);
|
|
226
|
-
const
|
|
230
|
+
const selectedItem = ref("");
|
|
227
231
|
|
|
228
232
|
const {
|
|
229
233
|
config,
|
|
@@ -235,14 +239,6 @@ const {
|
|
|
235
239
|
hasSlotContent,
|
|
236
240
|
} = useAttrs(props, { isShownOptions });
|
|
237
241
|
|
|
238
|
-
const selectValue = computed({
|
|
239
|
-
get: () => props.modelValue,
|
|
240
|
-
set: (value) => {
|
|
241
|
-
isShownOptions.value = false;
|
|
242
|
-
emit("update:modelValue", value);
|
|
243
|
-
},
|
|
244
|
-
});
|
|
245
|
-
|
|
246
242
|
const iconColor = computed(() => {
|
|
247
243
|
return props.variant === BUTTON_VARIANT.primary ? "white" : props.color;
|
|
248
244
|
});
|
|
@@ -257,10 +253,9 @@ const iconSize = computed(() => {
|
|
|
257
253
|
return sizes[props.size];
|
|
258
254
|
});
|
|
259
255
|
|
|
260
|
-
watch(() =>
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
onUnmounted(() => window.removeEventListener("click", onClickOutside));
|
|
256
|
+
watch(selectedItem, () => {
|
|
257
|
+
emit("select", selectedItem.value);
|
|
258
|
+
});
|
|
264
259
|
|
|
265
260
|
function onClickButton() {
|
|
266
261
|
isShownOptions.value = !isShownOptions.value;
|
|
@@ -270,17 +265,7 @@ function hideOptions() {
|
|
|
270
265
|
isShownOptions.value = false;
|
|
271
266
|
}
|
|
272
267
|
|
|
273
|
-
function
|
|
274
|
-
|
|
275
|
-
hideOptions();
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
function onBlurButton(event) {
|
|
280
|
-
setTimeout(() => {
|
|
281
|
-
if (!event.target.isEqualNode(event.relatedTarget) && event.relatedTarget) {
|
|
282
|
-
hideOptions();
|
|
283
|
-
}
|
|
284
|
-
}, 100);
|
|
268
|
+
function onClickList() {
|
|
269
|
+
hideOptions();
|
|
285
270
|
}
|
|
286
271
|
</script>
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div v-bind="wrapperAttrs">
|
|
2
|
+
<div v-click-outside="hideOptions" v-bind="wrapperAttrs">
|
|
3
3
|
<div v-bind="triggerAttrs">
|
|
4
4
|
<ULink
|
|
5
5
|
:id="id"
|
|
6
|
-
ref="linkRef"
|
|
7
6
|
:label="label"
|
|
8
7
|
:size="size"
|
|
9
8
|
:color="color"
|
|
@@ -13,43 +12,50 @@
|
|
|
13
12
|
:no-ring="noRing"
|
|
14
13
|
:data-cy="`${dataCy}-link`"
|
|
15
14
|
v-bind="linkAttrs"
|
|
16
|
-
@click
|
|
17
|
-
@blur="onBlurLink"
|
|
15
|
+
@click="onClickLink"
|
|
18
16
|
>
|
|
19
17
|
<template #right>
|
|
20
18
|
<UIcon
|
|
21
19
|
v-if="!noIcon"
|
|
22
20
|
internal
|
|
21
|
+
interactive
|
|
23
22
|
:name="config.iconName"
|
|
24
23
|
:size="iconSize"
|
|
25
24
|
:color="color"
|
|
26
25
|
:data-cy="`${dataCy}-caret`"
|
|
27
26
|
v-bind="iconAttrs"
|
|
27
|
+
@click.stop="onClickLink"
|
|
28
28
|
/>
|
|
29
29
|
</template>
|
|
30
30
|
</ULink>
|
|
31
31
|
</div>
|
|
32
32
|
|
|
33
|
-
<div
|
|
33
|
+
<div
|
|
34
|
+
v-if="isShownOptions && hasSlotContent($slots['default'])"
|
|
35
|
+
v-bind="listWrapperAttrs"
|
|
36
|
+
@click="onClickList"
|
|
37
|
+
>
|
|
34
38
|
<!-- @slot Use it to add dropdown list. -->
|
|
35
39
|
<slot />
|
|
36
40
|
</div>
|
|
37
41
|
|
|
38
42
|
<UDropdownList
|
|
39
43
|
v-if="isShownOptions && !hasSlotContent($slots['default'])"
|
|
40
|
-
v-model="
|
|
44
|
+
v-model="selectedItem"
|
|
41
45
|
:size="size"
|
|
42
46
|
:options="options"
|
|
43
47
|
:value-key="valueKey"
|
|
44
48
|
:label-key="labelKey"
|
|
45
49
|
:data-cy="`${dataCy}-item`"
|
|
46
50
|
v-bind="listAttrs"
|
|
51
|
+
@mousedown.stop
|
|
52
|
+
@click.stop="onClickList"
|
|
47
53
|
/>
|
|
48
54
|
</div>
|
|
49
55
|
</template>
|
|
50
56
|
|
|
51
57
|
<script setup>
|
|
52
|
-
import { computed,
|
|
58
|
+
import { computed, provide, ref, watch } from "vue";
|
|
53
59
|
|
|
54
60
|
import UIcon from "../ui.image-icon";
|
|
55
61
|
import ULink from "../ui.button-link";
|
|
@@ -57,6 +63,8 @@ import UDropdownList from "../ui.dropdown-list";
|
|
|
57
63
|
|
|
58
64
|
import UIService, { getRandomId } from "../service.ui";
|
|
59
65
|
|
|
66
|
+
import vClickOutside from "../directive.clickOutside";
|
|
67
|
+
|
|
60
68
|
import { UDropdownLink } from "./constants";
|
|
61
69
|
import defaultConfig from "./configs/default.config";
|
|
62
70
|
import { useAttrs } from "./composables/attrs.composable";
|
|
@@ -65,14 +73,6 @@ import { useAttrs } from "./composables/attrs.composable";
|
|
|
65
73
|
defineOptions({ name: "UDropdownLink", inheritAttrs: false });
|
|
66
74
|
|
|
67
75
|
const props = defineProps({
|
|
68
|
-
/**
|
|
69
|
-
* Selected value.
|
|
70
|
-
*/
|
|
71
|
-
modelValue: {
|
|
72
|
-
type: [String, Number],
|
|
73
|
-
default: "",
|
|
74
|
-
},
|
|
75
|
-
|
|
76
76
|
/**
|
|
77
77
|
* Link label.
|
|
78
78
|
*/
|
|
@@ -207,13 +207,12 @@ const props = defineProps({
|
|
|
207
207
|
},
|
|
208
208
|
});
|
|
209
209
|
|
|
210
|
-
|
|
210
|
+
const emit = defineEmits(["select"]);
|
|
211
211
|
|
|
212
|
-
|
|
212
|
+
provide("hideDropdownOptions", () => hideOptions());
|
|
213
213
|
|
|
214
214
|
const isShownOptions = ref(false);
|
|
215
|
-
|
|
216
|
-
const linkRef = ref(null);
|
|
215
|
+
const selectedItem = ref("");
|
|
217
216
|
|
|
218
217
|
const {
|
|
219
218
|
config,
|
|
@@ -226,14 +225,6 @@ const {
|
|
|
226
225
|
hasSlotContent,
|
|
227
226
|
} = useAttrs(props, { isShownOptions });
|
|
228
227
|
|
|
229
|
-
const selectValue = computed({
|
|
230
|
-
get: () => props.modelValue,
|
|
231
|
-
set: (value) => {
|
|
232
|
-
isShownOptions.value = false;
|
|
233
|
-
emit("update:modelValue", value);
|
|
234
|
-
},
|
|
235
|
-
});
|
|
236
|
-
|
|
237
228
|
const iconSize = computed(() => {
|
|
238
229
|
const sizes = {
|
|
239
230
|
xs: "2xs",
|
|
@@ -245,10 +236,9 @@ const iconSize = computed(() => {
|
|
|
245
236
|
return sizes[props.size];
|
|
246
237
|
});
|
|
247
238
|
|
|
248
|
-
watch(() =>
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
onUnmounted(() => window.removeEventListener("click", onClickOutside));
|
|
239
|
+
watch(selectedItem, () => {
|
|
240
|
+
emit("select", selectedItem.value);
|
|
241
|
+
});
|
|
252
242
|
|
|
253
243
|
function onClickLink() {
|
|
254
244
|
isShownOptions.value = !isShownOptions.value;
|
|
@@ -258,17 +248,7 @@ function hideOptions() {
|
|
|
258
248
|
isShownOptions.value = false;
|
|
259
249
|
}
|
|
260
250
|
|
|
261
|
-
function
|
|
262
|
-
|
|
263
|
-
hideOptions();
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
function onBlurLink(event) {
|
|
268
|
-
setTimeout(() => {
|
|
269
|
-
if (!event.target.isEqualNode(event.relatedTarget) && event.relatedTarget) {
|
|
270
|
-
hideOptions();
|
|
271
|
-
}
|
|
272
|
-
}, 100);
|
|
251
|
+
function onClickList() {
|
|
252
|
+
hideOptions();
|
|
273
253
|
}
|
|
274
254
|
</script>
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
export default /*tw*/ {
|
|
2
2
|
wrapper: {
|
|
3
|
-
base: "rounded-full bg-{color}-500
|
|
3
|
+
base: "rounded-full bg-{color}-500",
|
|
4
4
|
variants: {
|
|
5
5
|
color: {
|
|
6
6
|
white: "bg-white",
|
|
7
7
|
grayscale: "bg-gray-900",
|
|
8
8
|
},
|
|
9
9
|
size: {
|
|
10
|
+
xs: "size-0.5",
|
|
10
11
|
sm: "size-1",
|
|
11
12
|
md: "size-1.5",
|
|
12
13
|
lg: "size-2",
|
|
14
|
+
xl: "size-2.5",
|
|
13
15
|
},
|
|
14
16
|
},
|
|
15
17
|
},
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import UDot from "../ui.other-dot";
|
|
2
2
|
import URow from "../ui.container-row";
|
|
3
|
+
import UGroup from "../ui.container-group";
|
|
4
|
+
import UBadge from "../ui.text-badge";
|
|
3
5
|
|
|
4
6
|
import { getArgTypes } from "../service.storybook";
|
|
5
7
|
|
|
@@ -23,7 +25,7 @@ const DefaultTemplate = (args) => ({
|
|
|
23
25
|
});
|
|
24
26
|
|
|
25
27
|
const ColorsTemplate = (args, { argTypes } = {}) => ({
|
|
26
|
-
components: {
|
|
28
|
+
components: { UGroup, URow, UDot, UBadge },
|
|
27
29
|
setup() {
|
|
28
30
|
return {
|
|
29
31
|
args,
|
|
@@ -31,19 +33,17 @@ const ColorsTemplate = (args, { argTypes } = {}) => ({
|
|
|
31
33
|
};
|
|
32
34
|
},
|
|
33
35
|
template: `
|
|
34
|
-
<
|
|
35
|
-
<
|
|
36
|
-
v-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
/>
|
|
41
|
-
</URow>
|
|
36
|
+
<UGroup>
|
|
37
|
+
<URow v-for="(color, index) in colors" :key="index" gap="none" align="center">
|
|
38
|
+
<UDot v-bind="args" :color="color"/>
|
|
39
|
+
<UBadge :label="color" :color="color" variant="thirdary" />
|
|
40
|
+
</URow>
|
|
41
|
+
</UGroup>
|
|
42
42
|
`,
|
|
43
43
|
});
|
|
44
44
|
|
|
45
45
|
const SizesTemplate = (args, { argTypes } = {}) => ({
|
|
46
|
-
components: {
|
|
46
|
+
components: { UGroup, URow, UDot, UBadge },
|
|
47
47
|
setup() {
|
|
48
48
|
return {
|
|
49
49
|
args,
|
|
@@ -51,20 +51,13 @@ const SizesTemplate = (args, { argTypes } = {}) => ({
|
|
|
51
51
|
};
|
|
52
52
|
},
|
|
53
53
|
template: `
|
|
54
|
-
<
|
|
55
|
-
<
|
|
56
|
-
v-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
/>
|
|
61
|
-
</URow>
|
|
54
|
+
<UGroup>
|
|
55
|
+
<URow v-for="(size, index) in sizes" :key="index" gap="none" align="center">
|
|
56
|
+
<UDot v-bind="args" :size="size"/>
|
|
57
|
+
<UBadge :label="size" variant="thirdary" />
|
|
58
|
+
</URow>
|
|
59
|
+
</UGroup>
|
|
62
60
|
`,
|
|
63
|
-
methods: {
|
|
64
|
-
getText(value) {
|
|
65
|
-
return `Tag ${value}`;
|
|
66
|
-
},
|
|
67
|
-
},
|
|
68
61
|
});
|
|
69
62
|
|
|
70
63
|
export const Default = DefaultTemplate.bind({});
|
package/ui.other-dot/index.vue
CHANGED
package/web-types.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"framework": "vue",
|
|
3
3
|
"name": "vueless",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.114",
|
|
5
5
|
"contributions": {
|
|
6
6
|
"html": {
|
|
7
7
|
"description-markup": "markdown",
|
|
@@ -559,7 +559,7 @@
|
|
|
559
559
|
"description": "Button size.",
|
|
560
560
|
"value": {
|
|
561
561
|
"kind": "expression",
|
|
562
|
-
"type": "'sm' | 'md' | 'lg'"
|
|
562
|
+
"type": "'xs' | 'sm' | 'md' | 'lg'"
|
|
563
563
|
},
|
|
564
564
|
"default": "md"
|
|
565
565
|
},
|
|
@@ -1962,7 +1962,7 @@
|
|
|
1962
1962
|
"description": "Dot size.",
|
|
1963
1963
|
"value": {
|
|
1964
1964
|
"kind": "expression",
|
|
1965
|
-
"type": "'sm' | 'md' | 'lg'"
|
|
1965
|
+
"type": "'xs' | 'sm' | 'md' | 'lg' | 'xl'"
|
|
1966
1966
|
},
|
|
1967
1967
|
"default": "md"
|
|
1968
1968
|
},
|
|
@@ -1994,15 +1994,6 @@
|
|
|
1994
1994
|
"name": "UDropdownBadge",
|
|
1995
1995
|
"description": "",
|
|
1996
1996
|
"attributes": [
|
|
1997
|
-
{
|
|
1998
|
-
"name": "modelValue",
|
|
1999
|
-
"description": "Selected value.",
|
|
2000
|
-
"value": {
|
|
2001
|
-
"kind": "expression",
|
|
2002
|
-
"type": "string|number"
|
|
2003
|
-
},
|
|
2004
|
-
"default": "\"\""
|
|
2005
|
-
},
|
|
2006
1997
|
{
|
|
2007
1998
|
"name": "label",
|
|
2008
1999
|
"description": "Badge label.",
|
|
@@ -2132,7 +2123,7 @@
|
|
|
2132
2123
|
],
|
|
2133
2124
|
"events": [
|
|
2134
2125
|
{
|
|
2135
|
-
"name": "
|
|
2126
|
+
"name": "select"
|
|
2136
2127
|
}
|
|
2137
2128
|
],
|
|
2138
2129
|
"slots": [
|
|
@@ -2315,7 +2306,7 @@
|
|
|
2315
2306
|
],
|
|
2316
2307
|
"events": [
|
|
2317
2308
|
{
|
|
2318
|
-
"name": "
|
|
2309
|
+
"name": "select"
|
|
2319
2310
|
}
|
|
2320
2311
|
],
|
|
2321
2312
|
"slots": [
|
|
@@ -2380,15 +2371,6 @@
|
|
|
2380
2371
|
"name": "UDropdownLink",
|
|
2381
2372
|
"description": "",
|
|
2382
2373
|
"attributes": [
|
|
2383
|
-
{
|
|
2384
|
-
"name": "modelValue",
|
|
2385
|
-
"description": "Selected value.",
|
|
2386
|
-
"value": {
|
|
2387
|
-
"kind": "expression",
|
|
2388
|
-
"type": "string|number"
|
|
2389
|
-
},
|
|
2390
|
-
"default": "\"\""
|
|
2391
|
-
},
|
|
2392
2374
|
{
|
|
2393
2375
|
"name": "label",
|
|
2394
2376
|
"description": "Link label.",
|
|
@@ -2536,7 +2518,7 @@
|
|
|
2536
2518
|
],
|
|
2537
2519
|
"events": [
|
|
2538
2520
|
{
|
|
2539
|
-
"name": "
|
|
2521
|
+
"name": "select"
|
|
2540
2522
|
}
|
|
2541
2523
|
],
|
|
2542
2524
|
"slots": [
|
|
@@ -5825,6 +5807,24 @@
|
|
|
5825
5807
|
"name": "URow",
|
|
5826
5808
|
"description": "",
|
|
5827
5809
|
"attributes": [
|
|
5810
|
+
{
|
|
5811
|
+
"name": "gap",
|
|
5812
|
+
"description": "Row spacing between nested elements.",
|
|
5813
|
+
"value": {
|
|
5814
|
+
"kind": "expression",
|
|
5815
|
+
"type": "'none' | '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'"
|
|
5816
|
+
},
|
|
5817
|
+
"default": "md"
|
|
5818
|
+
},
|
|
5819
|
+
{
|
|
5820
|
+
"name": "align",
|
|
5821
|
+
"description": "Row nested elements vertical align (align-items).",
|
|
5822
|
+
"value": {
|
|
5823
|
+
"kind": "expression",
|
|
5824
|
+
"type": "'start' | 'end' | 'center' | 'stretch' | 'baseline'"
|
|
5825
|
+
},
|
|
5826
|
+
"default": "start"
|
|
5827
|
+
},
|
|
5828
5828
|
{
|
|
5829
5829
|
"name": "noMobile",
|
|
5830
5830
|
"description": "Disables mobile adaptivity.",
|