sprintify-ui 0.0.106 → 0.0.107
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/sprintify-ui.es.js +3900 -3896
- package/dist/types/src/components/{BaseAutocompleteDropdown.vue.d.ts → BaseAutocompleteDrawer.vue.d.ts} +3 -3
- package/package.json +1 -1
- package/src/components/BaseAutocomplete.vue +8 -8
- package/src/components/{BaseAutocompleteDropdown.vue → BaseAutocompleteDrawer.vue} +11 -11
- package/src/components/BaseDataIterator.vue +1 -0
- package/src/components/BaseDropdown.stories.js +6 -1
- package/src/components/BaseDropdown.vue +15 -4
- package/src/components/BaseTagAutocomplete.vue +8 -8
|
@@ -25,7 +25,7 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<{
|
|
|
25
25
|
type: PropType<"base" | "xs" | "sm">;
|
|
26
26
|
default: string;
|
|
27
27
|
};
|
|
28
|
-
|
|
28
|
+
drawerClass: {
|
|
29
29
|
type: StringConstructor;
|
|
30
30
|
default: string;
|
|
31
31
|
};
|
|
@@ -56,7 +56,7 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<{
|
|
|
56
56
|
type: PropType<"base" | "xs" | "sm">;
|
|
57
57
|
default: string;
|
|
58
58
|
};
|
|
59
|
-
|
|
59
|
+
drawerClass: {
|
|
60
60
|
type: StringConstructor;
|
|
61
61
|
default: string;
|
|
62
62
|
};
|
|
@@ -70,7 +70,7 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<{
|
|
|
70
70
|
loading: boolean;
|
|
71
71
|
loadingBottom: boolean;
|
|
72
72
|
size: "base" | "xs" | "sm";
|
|
73
|
-
|
|
73
|
+
drawerClass: string;
|
|
74
74
|
}>, {
|
|
75
75
|
empty: (_: {}) => any;
|
|
76
76
|
option: (_: {
|
package/package.json
CHANGED
|
@@ -68,14 +68,14 @@
|
|
|
68
68
|
: 'absolute top-1 z-menu min-h-[110px] w-full overflow-hidden rounded border border-slate-300 bg-white shadow-md',
|
|
69
69
|
]"
|
|
70
70
|
>
|
|
71
|
-
<
|
|
72
|
-
ref="
|
|
71
|
+
<BaseAutocompleteDrawer
|
|
72
|
+
ref="drawer"
|
|
73
73
|
:selected="normalizedModelValue"
|
|
74
74
|
:options="filteredNormalizedOptions"
|
|
75
75
|
:size="size"
|
|
76
76
|
:loading="loading"
|
|
77
77
|
:loading-bottom="loadingBottom"
|
|
78
|
-
:
|
|
78
|
+
:drawer-class="inline ? 'pt-1' : 'p-1'"
|
|
79
79
|
:keywords="keywords"
|
|
80
80
|
@select="onSelect"
|
|
81
81
|
@scroll-bottom="emit('scrollBottom')"
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
<template #footer="footerProps">
|
|
90
90
|
<slot name="footer" v-bind="{ ...footerProps, ...slotProps }" />
|
|
91
91
|
</template>
|
|
92
|
-
</
|
|
92
|
+
</BaseAutocompleteDrawer>
|
|
93
93
|
</div>
|
|
94
94
|
</div>
|
|
95
95
|
</div>
|
|
@@ -103,7 +103,7 @@ import { useHasOptions } from '@/composables/hasOptions';
|
|
|
103
103
|
import { useField } from '@/composables/field';
|
|
104
104
|
import { BaseIcon } from './index';
|
|
105
105
|
import { useClickOutside } from '@/composables/clickOutside';
|
|
106
|
-
import
|
|
106
|
+
import BaseAutocompleteDrawer from './BaseAutocompleteDrawer.vue';
|
|
107
107
|
|
|
108
108
|
const props = defineProps({
|
|
109
109
|
modelValue: {
|
|
@@ -212,8 +212,8 @@ const hasOptions = useHasOptions(
|
|
|
212
212
|
computed(() => false)
|
|
213
213
|
);
|
|
214
214
|
|
|
215
|
-
const
|
|
216
|
-
typeof
|
|
215
|
+
const drawer = ref(null) as Ref<InstanceType<
|
|
216
|
+
typeof BaseAutocompleteDrawer
|
|
217
217
|
> | null>;
|
|
218
218
|
|
|
219
219
|
let timerId = 0;
|
|
@@ -330,7 +330,7 @@ const onTextInput = (event: Event) => {
|
|
|
330
330
|
const onTextKeydown = (event: KeyboardEvent) => {
|
|
331
331
|
const key = event.key;
|
|
332
332
|
|
|
333
|
-
|
|
333
|
+
drawer.value?.onKeydown(event);
|
|
334
334
|
|
|
335
335
|
// Prevent default behavior for up/down arrows
|
|
336
336
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="relative w-full overflow-hidden">
|
|
3
3
|
<div
|
|
4
|
-
ref="
|
|
4
|
+
ref="drawer"
|
|
5
5
|
data-scroll-lock-scrollable
|
|
6
6
|
class="max-h-[214px] w-full overflow-y-auto"
|
|
7
7
|
>
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
</slot>
|
|
16
16
|
|
|
17
17
|
<!-- Option list -->
|
|
18
|
-
<ul v-else :class="
|
|
18
|
+
<ul v-else :class="drawerClass">
|
|
19
19
|
<li
|
|
20
20
|
v-for="(option, index) in options"
|
|
21
21
|
:key="option.value ? option.value : 'null'"
|
|
@@ -132,7 +132,7 @@ const props = defineProps({
|
|
|
132
132
|
type: String as PropType<'xs' | 'sm' | 'base'>,
|
|
133
133
|
default: 'base',
|
|
134
134
|
},
|
|
135
|
-
|
|
135
|
+
drawerClass: {
|
|
136
136
|
type: String,
|
|
137
137
|
default: '',
|
|
138
138
|
},
|
|
@@ -140,7 +140,7 @@ const props = defineProps({
|
|
|
140
140
|
|
|
141
141
|
const emit = defineEmits(['scrollBottom', 'select']);
|
|
142
142
|
|
|
143
|
-
const
|
|
143
|
+
const drawer = ref(null) as Ref<HTMLDivElement | null>;
|
|
144
144
|
|
|
145
145
|
let mouseIsMoving = false;
|
|
146
146
|
|
|
@@ -218,7 +218,7 @@ function onKeydown(event: KeyboardEvent) {
|
|
|
218
218
|
|
|
219
219
|
onMounted(() => {
|
|
220
220
|
useInfiniteScroll(
|
|
221
|
-
|
|
221
|
+
drawer.value,
|
|
222
222
|
() => {
|
|
223
223
|
emit('scrollBottom');
|
|
224
224
|
},
|
|
@@ -227,11 +227,11 @@ onMounted(() => {
|
|
|
227
227
|
});
|
|
228
228
|
|
|
229
229
|
function scrollToFocus() {
|
|
230
|
-
if (!
|
|
230
|
+
if (!drawer.value) {
|
|
231
231
|
return;
|
|
232
232
|
}
|
|
233
233
|
|
|
234
|
-
const option =
|
|
234
|
+
const option = drawer.value.querySelector(
|
|
235
235
|
`[data-index="${focusIndex.value}"]`
|
|
236
236
|
) as HTMLElement | null;
|
|
237
237
|
|
|
@@ -239,11 +239,11 @@ function scrollToFocus() {
|
|
|
239
239
|
return;
|
|
240
240
|
}
|
|
241
241
|
|
|
242
|
-
const dropdownHeight =
|
|
242
|
+
const dropdownHeight = drawer.value.clientHeight;
|
|
243
243
|
const offsetTop = option.offsetTop;
|
|
244
244
|
const optionHeight = option.clientHeight;
|
|
245
245
|
|
|
246
|
-
|
|
246
|
+
drawer.value.scrollTop = offsetTop - dropdownHeight / 2 + optionHeight / 2;
|
|
247
247
|
}
|
|
248
248
|
|
|
249
249
|
// Validate focus index
|
|
@@ -290,8 +290,8 @@ watch(
|
|
|
290
290
|
watch(
|
|
291
291
|
() => props.keywords,
|
|
292
292
|
() => {
|
|
293
|
-
if (
|
|
294
|
-
|
|
293
|
+
if (drawer.value) {
|
|
294
|
+
drawer.value.scrollTop = 0;
|
|
295
295
|
}
|
|
296
296
|
// Reset the focusIndex
|
|
297
297
|
updateFocusIndex(0);
|
|
@@ -33,7 +33,11 @@ export default {
|
|
|
33
33
|
const Template = (args) => ({
|
|
34
34
|
components: { BaseDropdown },
|
|
35
35
|
setup() {
|
|
36
|
-
|
|
36
|
+
const maxHeight = ref(200);
|
|
37
|
+
setInterval(() => {
|
|
38
|
+
maxHeight.value = Math.floor(Math.random() * 200) + 100;
|
|
39
|
+
}, 1000);
|
|
40
|
+
return { args, items, maxHeight };
|
|
37
41
|
},
|
|
38
42
|
template: `
|
|
39
43
|
<div style="height: 1000px; margin-top: 300px;">
|
|
@@ -46,6 +50,7 @@ const Template = (args) => ({
|
|
|
46
50
|
<div
|
|
47
51
|
class="bg-white shadow py-1 px-1 rounded"
|
|
48
52
|
style="max-height: 200px; overflow: auto;"
|
|
53
|
+
:style="{maxHeight: maxHeight + 'px'}"
|
|
49
54
|
data-scroll-lock-scrollable>
|
|
50
55
|
<button type="button" v-for="item in items" :key="item.label" class="block text-sm px-4 py-1.5">{{ item.label }}</button>
|
|
51
56
|
</div>
|
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
<div ref="dropdown" class="z-menu" :style="dropdownStyles">
|
|
8
8
|
<Transition
|
|
9
9
|
:enter-active-class="
|
|
10
|
-
animated ? 'duration-
|
|
10
|
+
animated ? 'transition duration-200 ease-out' : ''
|
|
11
11
|
"
|
|
12
|
-
enter-from-class="transform scale-
|
|
12
|
+
enter-from-class="transform scale-95 opacity-0"
|
|
13
13
|
enter-to-class="transform scale-100 opacity-100"
|
|
14
|
-
:leave-active-class="animated ? 'duration-75
|
|
14
|
+
:leave-active-class="animated ? 'transition duration-75 ease-in' : ''"
|
|
15
15
|
leave-from-class="transform scale-100 opacity-100"
|
|
16
|
-
leave-to-class="transform scale-
|
|
16
|
+
leave-to-class="transform scale-95 opacity-0"
|
|
17
17
|
>
|
|
18
18
|
<template v-if="showDropdown || keepAlive">
|
|
19
19
|
<div v-show="showDropdown" class="inline-block">
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
|
|
35
35
|
<script lang="ts" setup>
|
|
36
36
|
import { useClickOutside } from '@/composables/clickOutside';
|
|
37
|
+
import { useResizeObserver } from '@vueuse/core';
|
|
37
38
|
import { throttle } from 'lodash';
|
|
38
39
|
import { PropType, StyleValue } from 'vue';
|
|
39
40
|
import { disableScroll, enableScroll } from '../utils';
|
|
@@ -129,13 +130,23 @@ const setBoundingBoxesDebounced = throttle(() => {
|
|
|
129
130
|
setBoundingBoxes();
|
|
130
131
|
}, 10);
|
|
131
132
|
|
|
133
|
+
let buttonResizeObserver = null as any;
|
|
134
|
+
let dropdownResizeObserver = null as any;
|
|
135
|
+
|
|
132
136
|
function activate() {
|
|
137
|
+
buttonResizeObserver = useResizeObserver(button, setBoundingBoxesDebounced);
|
|
138
|
+
dropdownResizeObserver = useResizeObserver(
|
|
139
|
+
dropdown,
|
|
140
|
+
setBoundingBoxesDebounced
|
|
141
|
+
);
|
|
133
142
|
window.addEventListener('keydown', onKeydown);
|
|
134
143
|
window.addEventListener('resize', setBoundingBoxesDebounced);
|
|
135
144
|
window.addEventListener('scroll', setBoundingBoxesDebounced, true);
|
|
136
145
|
}
|
|
137
146
|
|
|
138
147
|
function deactivate() {
|
|
148
|
+
buttonResizeObserver?.stop();
|
|
149
|
+
dropdownResizeObserver?.stop();
|
|
139
150
|
window.removeEventListener('resize', setBoundingBoxesDebounced);
|
|
140
151
|
window.removeEventListener('scroll', setBoundingBoxesDebounced, true);
|
|
141
152
|
window.removeEventListener('keydown', onKeydown);
|
|
@@ -60,14 +60,14 @@
|
|
|
60
60
|
: 'absolute top-1 z-menu min-h-[110px] w-full overflow-hidden rounded border border-slate-300 bg-white shadow-md',
|
|
61
61
|
]"
|
|
62
62
|
>
|
|
63
|
-
<
|
|
64
|
-
ref="
|
|
63
|
+
<BaseAutocompleteDrawer
|
|
64
|
+
ref="drawer"
|
|
65
65
|
:selected="normalizedModelValue"
|
|
66
66
|
:options="filteredNormalizedOptions"
|
|
67
67
|
:size="size"
|
|
68
68
|
:loading="loading"
|
|
69
69
|
:loading-bottom="loadingBottom"
|
|
70
|
-
:
|
|
70
|
+
:drawer-class="inline ? 'pt-1' : 'p-1'"
|
|
71
71
|
:keywords="keywords"
|
|
72
72
|
@select="onSelect"
|
|
73
73
|
@scroll-bottom="emit('scrollBottom')"
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
<template #footer="footerProps">
|
|
82
82
|
<slot name="footer" v-bind="{ ...footerProps, ...slotProps }" />
|
|
83
83
|
</template>
|
|
84
|
-
</
|
|
84
|
+
</BaseAutocompleteDrawer>
|
|
85
85
|
</div>
|
|
86
86
|
</div>
|
|
87
87
|
</div>
|
|
@@ -95,7 +95,7 @@ import { useHasOptions } from '@/composables/hasOptions';
|
|
|
95
95
|
import { useField } from '@/composables/field';
|
|
96
96
|
import { useClickOutside } from '@/composables/clickOutside';
|
|
97
97
|
import { useNotificationsStore } from '@/stores/notifications';
|
|
98
|
-
import
|
|
98
|
+
import BaseAutocompleteDrawer from './BaseAutocompleteDrawer.vue';
|
|
99
99
|
|
|
100
100
|
const i18n = useI18n();
|
|
101
101
|
const notifications = useNotificationsStore();
|
|
@@ -190,8 +190,8 @@ const hasOptions = useHasOptions(
|
|
|
190
190
|
computed(() => true)
|
|
191
191
|
);
|
|
192
192
|
|
|
193
|
-
const
|
|
194
|
-
typeof
|
|
193
|
+
const drawer = ref(null) as Ref<InstanceType<
|
|
194
|
+
typeof BaseAutocompleteDrawer
|
|
195
195
|
> | null>;
|
|
196
196
|
|
|
197
197
|
const keywords = ref('');
|
|
@@ -259,7 +259,7 @@ const onTextInput = (event: Event) => {
|
|
|
259
259
|
const onTextKeydown = (event: KeyboardEvent) => {
|
|
260
260
|
const key = event.key;
|
|
261
261
|
|
|
262
|
-
|
|
262
|
+
drawer.value?.onKeydown(event);
|
|
263
263
|
|
|
264
264
|
// Prevent default behavior for up/down arrows
|
|
265
265
|
|