sprintify-ui 0.0.106 → 0.0.108
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 +7534 -7472
- package/dist/types/src/components/BaseAutocomplete.vue.d.ts +12 -1
- package/dist/types/src/components/{BaseAutocompleteDropdown.vue.d.ts → BaseAutocompleteDrawer.vue.d.ts} +3 -3
- package/dist/types/src/components/BaseAutocompleteFetch.vue.d.ts +10 -1
- package/dist/types/src/components/BaseBelongsTo.vue.d.ts +10 -1
- package/dist/types/src/types/index.d.ts +6 -0
- package/package.json +1 -1
- package/src/components/BaseAutocomplete.stories.js +50 -0
- package/src/components/BaseAutocomplete.vue +105 -40
- package/src/components/{BaseAutocompleteDropdown.vue → BaseAutocompleteDrawer.vue} +11 -11
- package/src/components/BaseAutocompleteFetch.stories.js +53 -0
- package/src/components/BaseAutocompleteFetch.vue +15 -1
- package/src/components/BaseBelongsTo.stories.js +53 -0
- package/src/components/BaseBelongsTo.vue +6 -1
- 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
- package/src/types/index.ts +7 -0
|
@@ -163,6 +163,59 @@ export const SlotEmpty = (args) => {
|
|
|
163
163
|
};
|
|
164
164
|
};
|
|
165
165
|
|
|
166
|
+
export const WithSelect = (args) => {
|
|
167
|
+
return {
|
|
168
|
+
components: { BaseBelongsTo, ShowValue },
|
|
169
|
+
setup() {
|
|
170
|
+
const value = ref(options[0]);
|
|
171
|
+
const selected = ref(null);
|
|
172
|
+
|
|
173
|
+
const select = {
|
|
174
|
+
options: [
|
|
175
|
+
{ label: 'All', value: 'all' },
|
|
176
|
+
{ label: 'Video', value: 'video' },
|
|
177
|
+
{ label: 'Article', value: 'article' },
|
|
178
|
+
],
|
|
179
|
+
labelKey: 'label',
|
|
180
|
+
valueKey: 'value',
|
|
181
|
+
onChange: (option) => {
|
|
182
|
+
selected.value = option;
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
const url = computed(() => {
|
|
187
|
+
if (selected.value == 'all' || !selected.value) {
|
|
188
|
+
return 'https://effettandem.com/api/content/articles';
|
|
189
|
+
}
|
|
190
|
+
return (
|
|
191
|
+
'https://effettandem.com/api/content/articles' +
|
|
192
|
+
'?type=' +
|
|
193
|
+
selected.value
|
|
194
|
+
);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
return { args, value, url, selected, select };
|
|
198
|
+
},
|
|
199
|
+
template: `
|
|
200
|
+
<BaseBelongsTo
|
|
201
|
+
v-model="value"
|
|
202
|
+
v-bind="args"
|
|
203
|
+
:url="url"
|
|
204
|
+
:select="select"
|
|
205
|
+
>
|
|
206
|
+
</BaseBelongsTo>
|
|
207
|
+
|
|
208
|
+
<div class="mb-2"></div>
|
|
209
|
+
|
|
210
|
+
<p class="text-xs mb-0">Selection</p>
|
|
211
|
+
<ShowValue class="mt-0 mb-2" :value="selected" />
|
|
212
|
+
|
|
213
|
+
<p class="text-xs mb-0">Model Value</p>
|
|
214
|
+
<ShowValue class="mt-0" :value="value" />
|
|
215
|
+
`,
|
|
216
|
+
};
|
|
217
|
+
};
|
|
218
|
+
|
|
166
219
|
export const Field = createFieldStory({
|
|
167
220
|
component: BaseBelongsTo,
|
|
168
221
|
componentName: 'BaseBelongsTo',
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
:show-empty-option="showEmptyOption"
|
|
18
18
|
:empty-option-label="emptyOptionLabel"
|
|
19
19
|
:visible-focus="visibleFocus"
|
|
20
|
+
:select="select"
|
|
20
21
|
@update:model-value="onUpdate"
|
|
21
22
|
>
|
|
22
23
|
<template #option="optionProps">
|
|
@@ -36,7 +37,7 @@ import { PropType, Ref } from 'vue';
|
|
|
36
37
|
import { AxiosResponse } from 'axios';
|
|
37
38
|
import { config } from '@/index';
|
|
38
39
|
import BaseAutocompleteFetch from './BaseAutocompleteFetch.vue';
|
|
39
|
-
import { Option } from '@/types';
|
|
40
|
+
import { Option, SelectConfiguration } from '@/types';
|
|
40
41
|
|
|
41
42
|
const props = defineProps({
|
|
42
43
|
modelValue: {
|
|
@@ -113,6 +114,10 @@ const props = defineProps({
|
|
|
113
114
|
default: undefined,
|
|
114
115
|
type: String,
|
|
115
116
|
},
|
|
117
|
+
select: {
|
|
118
|
+
default: undefined,
|
|
119
|
+
type: Object as PropType<SelectConfiguration | undefined>,
|
|
120
|
+
},
|
|
116
121
|
});
|
|
117
122
|
|
|
118
123
|
const http = config.http;
|
|
@@ -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
|
|
package/src/types/index.ts
CHANGED
|
@@ -197,3 +197,10 @@ export interface NotificationsConfig {
|
|
|
197
197
|
footerLabel?: string;
|
|
198
198
|
footerTo?: RouteLocationRaw;
|
|
199
199
|
}
|
|
200
|
+
|
|
201
|
+
export interface SelectConfiguration {
|
|
202
|
+
options: Option[];
|
|
203
|
+
valueKey: string;
|
|
204
|
+
labelKey: string;
|
|
205
|
+
onChange: (value: OptionValue) => void;
|
|
206
|
+
}
|