@nuxt/ui 2.8.1 → 2.10.0
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/README.md +1 -0
- package/dist/module.d.mts +1411 -1092
- package/dist/module.d.ts +1411 -1092
- package/dist/module.json +1 -1
- package/dist/module.mjs +55 -11
- package/dist/runtime/components/data/Table.vue +47 -32
- package/dist/runtime/components/data/Table.vue.d.ts +22 -14
- package/dist/runtime/components/elements/Accordion.vue +33 -28
- package/dist/runtime/components/elements/Accordion.vue.d.ts +25 -18
- package/dist/runtime/components/elements/Alert.vue +22 -18
- package/dist/runtime/components/elements/Alert.vue.d.ts +26 -19
- package/dist/runtime/components/elements/Avatar.vue +22 -16
- package/dist/runtime/components/elements/Avatar.vue.d.ts +28 -19
- package/dist/runtime/components/elements/AvatarGroup.d.ts +17 -8
- package/dist/runtime/components/elements/AvatarGroup.mjs +18 -13
- package/dist/runtime/components/elements/Badge.vue +21 -17
- package/dist/runtime/components/elements/Badge.vue.d.ts +28 -19
- package/dist/runtime/components/elements/Button.vue +22 -18
- package/dist/runtime/components/elements/Button.vue.d.ts +28 -19
- package/dist/runtime/components/elements/ButtonGroup.d.ts +17 -8
- package/dist/runtime/components/elements/ButtonGroup.mjs +22 -15
- package/dist/runtime/components/elements/Dropdown.vue +45 -37
- package/dist/runtime/components/elements/Dropdown.vue.d.ts +22 -17
- package/dist/runtime/components/elements/Kbd.vue +16 -12
- package/dist/runtime/components/elements/Kbd.vue.d.ts +20 -12
- package/dist/runtime/components/elements/Link.vue +18 -5
- package/dist/runtime/components/elements/Meter.vue +166 -0
- package/dist/runtime/components/elements/Meter.vue.d.ts +123 -0
- package/dist/runtime/components/elements/MeterGroup.d.ts +78 -0
- package/dist/runtime/components/elements/MeterGroup.mjs +172 -0
- package/dist/runtime/components/elements/Progress.vue +284 -0
- package/dist/runtime/components/elements/Progress.vue.d.ts +2 -0
- package/dist/runtime/components/forms/Checkbox.vue +27 -17
- package/dist/runtime/components/forms/Checkbox.vue.d.ts +33 -15
- package/dist/runtime/components/forms/Form.vue +34 -9
- package/dist/runtime/components/forms/Form.vue.d.ts +2 -1
- package/dist/runtime/components/forms/FormGroup.vue +51 -27
- package/dist/runtime/components/forms/FormGroup.vue.d.ts +23 -15
- package/dist/runtime/components/forms/Input.vue +41 -29
- package/dist/runtime/components/forms/Input.vue.d.ts +51 -24
- package/dist/runtime/components/forms/Radio.vue +32 -21
- package/dist/runtime/components/forms/Radio.vue.d.ts +36 -18
- package/dist/runtime/components/forms/RadioGroup.vue +136 -0
- package/dist/runtime/components/forms/RadioGroup.vue.d.ts +118 -0
- package/dist/runtime/components/forms/Range.vue +26 -16
- package/dist/runtime/components/forms/Range.vue.d.ts +37 -18
- package/dist/runtime/components/forms/Select.vue +34 -26
- package/dist/runtime/components/forms/Select.vue.d.ts +42 -24
- package/dist/runtime/components/forms/SelectMenu.vue +104 -89
- package/dist/runtime/components/forms/SelectMenu.vue.d.ts +53 -33
- package/dist/runtime/components/forms/Textarea.vue +43 -31
- package/dist/runtime/components/forms/Textarea.vue.d.ts +50 -23
- package/dist/runtime/components/forms/Toggle.vue +26 -15
- package/dist/runtime/components/forms/Toggle.vue.d.ts +31 -12
- package/dist/runtime/components/layout/Card.vue +15 -10
- package/dist/runtime/components/layout/Card.vue.d.ts +17 -9
- package/dist/runtime/components/layout/Container.vue +15 -10
- package/dist/runtime/components/layout/Container.vue.d.ts +17 -9
- package/dist/runtime/components/layout/Divider.vue +107 -0
- package/dist/runtime/components/layout/Divider.vue.d.ts +82 -0
- package/dist/runtime/components/layout/Skeleton.vue +15 -10
- package/dist/runtime/components/layout/Skeleton.vue.d.ts +17 -9
- package/dist/runtime/components/navigation/CommandPalette.vue +57 -38
- package/dist/runtime/components/navigation/CommandPalette.vue.d.ts +24 -23
- package/dist/runtime/components/navigation/CommandPaletteGroup.vue +1 -1
- package/dist/runtime/components/navigation/CommandPaletteGroup.vue.d.ts +3 -4
- package/dist/runtime/components/navigation/Pagination.vue +129 -64
- package/dist/runtime/components/navigation/Pagination.vue.d.ts +70 -25
- package/dist/runtime/components/navigation/Tabs.vue +17 -14
- package/dist/runtime/components/navigation/Tabs.vue.d.ts +18 -11
- package/dist/runtime/components/navigation/VerticalNavigation.vue +15 -13
- package/dist/runtime/components/navigation/VerticalNavigation.vue.d.ts +20 -16
- package/dist/runtime/components/overlays/ContextMenu.vue +21 -11
- package/dist/runtime/components/overlays/ContextMenu.vue.d.ts +20 -11
- package/dist/runtime/components/overlays/Modal.vue +16 -14
- package/dist/runtime/components/overlays/Modal.vue.d.ts +18 -11
- package/dist/runtime/components/overlays/Notification.vue +25 -15
- package/dist/runtime/components/overlays/Notification.vue.d.ts +25 -19
- package/dist/runtime/components/overlays/Notifications.vue +19 -13
- package/dist/runtime/components/overlays/Notifications.vue.d.ts +22 -14
- package/dist/runtime/components/overlays/Popover.vue +39 -22
- package/dist/runtime/components/overlays/Popover.vue.d.ts +32 -11
- package/dist/runtime/components/overlays/Slideover.vue +15 -13
- package/dist/runtime/components/overlays/Slideover.vue.d.ts +18 -11
- package/dist/runtime/components/overlays/Tooltip.vue +31 -23
- package/dist/runtime/components/overlays/Tooltip.vue.d.ts +19 -11
- package/dist/runtime/composables/useFormGroup.d.ts +12 -2
- package/dist/runtime/composables/useFormGroup.mjs +21 -4
- package/dist/runtime/composables/usePopper.d.ts +3 -3
- package/dist/runtime/composables/usePopper.mjs +47 -31
- package/dist/runtime/composables/useToast.d.ts +3 -3
- package/dist/runtime/composables/useUI.d.ts +10 -0
- package/dist/runtime/composables/useUI.mjs +24 -0
- package/dist/runtime/types/avatar.d.ts +10 -4
- package/dist/runtime/types/badge.d.ts +14 -0
- package/dist/runtime/types/button.d.ts +10 -3
- package/dist/runtime/types/command-palette.d.ts +3 -1
- package/dist/runtime/types/form.d.ts +18 -4
- package/dist/runtime/types/index.d.ts +4 -0
- package/dist/runtime/types/link.d.ts +1 -0
- package/dist/runtime/types/meter.d.ts +5 -0
- package/dist/runtime/types/notification.d.ts +5 -3
- package/dist/runtime/types/popper.d.ts +1 -0
- package/dist/runtime/types/progress.d.ts +4 -0
- package/dist/runtime/types/tabs.d.ts +1 -0
- package/dist/runtime/types/utils.d.ts +11 -0
- package/dist/runtime/ui.config.d.ts +1470 -0
- package/dist/runtime/{app.config.mjs → ui.config.mjs} +313 -97
- package/dist/runtime/utils/index.d.ts +5 -11
- package/dist/runtime/utils/index.mjs +21 -9
- package/dist/runtime/utils/lodash.d.ts +2 -0
- package/dist/runtime/utils/lodash.mjs +23 -0
- package/dist/runtime/utils/uid.d.ts +1 -0
- package/dist/runtime/utils/uid.mjs +4 -0
- package/dist/types.d.mts +1 -1
- package/dist/types.d.ts +1 -1
- package/package.json +27 -29
- package/dist/runtime/app.config.d.ts +0 -1203
- package/dist/runtime/utils/StateEmitter.d.ts +0 -17
- package/dist/runtime/utils/StateEmitter.mjs +0 -21
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
:model-value="modelValue"
|
|
5
5
|
:multiple="multiple"
|
|
6
6
|
:nullable="nullable"
|
|
7
|
-
:class="
|
|
7
|
+
:class="ui.wrapper"
|
|
8
8
|
v-bind="attrs"
|
|
9
9
|
as="div"
|
|
10
10
|
@update:model-value="onSelect"
|
|
@@ -16,17 +16,12 @@
|
|
|
16
16
|
:value="query"
|
|
17
17
|
:class="[ui.input.base, ui.input.size, ui.input.height, ui.input.padding, icon && ui.input.icon.padding]"
|
|
18
18
|
:placeholder="placeholder"
|
|
19
|
+
:aria-label="placeholder"
|
|
19
20
|
autocomplete="off"
|
|
20
21
|
@change="query = $event.target.value"
|
|
21
22
|
/>
|
|
22
23
|
|
|
23
|
-
<UButton
|
|
24
|
-
v-if="closeButton"
|
|
25
|
-
v-bind="{ ...ui.default.closeButton, ...closeButton }"
|
|
26
|
-
:class="ui.input.closeButton"
|
|
27
|
-
aria-label="Close"
|
|
28
|
-
@click="onClear"
|
|
29
|
-
/>
|
|
24
|
+
<UButton v-if="closeButton" aria-label="Close" v-bind="{ ...ui.default.closeButton, ...closeButton }" :class="ui.input.closeButton" @click="onClear" />
|
|
30
25
|
</div>
|
|
31
26
|
|
|
32
27
|
<HComboboxOptions
|
|
@@ -67,19 +62,20 @@
|
|
|
67
62
|
</template>
|
|
68
63
|
|
|
69
64
|
<script>
|
|
70
|
-
import { ref, computed, watch, onMounted, defineComponent } from "vue";
|
|
65
|
+
import { ref, computed, watch, toRef, onMounted, defineComponent } from "vue";
|
|
71
66
|
import { Combobox as HCombobox, ComboboxInput as HComboboxInput, ComboboxOptions as HComboboxOptions } from "@headlessui/vue";
|
|
72
67
|
import { useDebounceFn } from "@vueuse/core";
|
|
73
68
|
import { useFuse } from "@vueuse/integrations/useFuse";
|
|
74
|
-
import {
|
|
75
|
-
import { groupBy, map, omit } from "lodash-es";
|
|
69
|
+
import { twJoin } from "tailwind-merge";
|
|
76
70
|
import { defu } from "defu";
|
|
77
71
|
import UIcon from "../elements/Icon.vue";
|
|
78
72
|
import UButton from "../elements/Button.vue";
|
|
79
73
|
import CommandPaletteGroup from "./CommandPaletteGroup.vue";
|
|
80
|
-
import {
|
|
81
|
-
import {
|
|
74
|
+
import { useUI } from "../../composables/useUI";
|
|
75
|
+
import { mergeConfig } from "../../utils";
|
|
82
76
|
import appConfig from "#build/app.config";
|
|
77
|
+
import { commandPalette } from "#ui/ui.config";
|
|
78
|
+
const config = mergeConfig(appConfig.ui.strategy, appConfig.ui.commandPalette, commandPalette);
|
|
83
79
|
export default defineComponent({
|
|
84
80
|
components: {
|
|
85
81
|
HCombobox,
|
|
@@ -121,23 +117,23 @@ export default defineComponent({
|
|
|
121
117
|
},
|
|
122
118
|
icon: {
|
|
123
119
|
type: String,
|
|
124
|
-
default: () =>
|
|
120
|
+
default: () => config.default.icon
|
|
125
121
|
},
|
|
126
122
|
loadingIcon: {
|
|
127
123
|
type: String,
|
|
128
|
-
default: () =>
|
|
124
|
+
default: () => config.default.loadingIcon
|
|
129
125
|
},
|
|
130
126
|
selectedIcon: {
|
|
131
127
|
type: String,
|
|
132
|
-
default: () =>
|
|
128
|
+
default: () => config.default.selectedIcon
|
|
133
129
|
},
|
|
134
130
|
closeButton: {
|
|
135
131
|
type: Object,
|
|
136
|
-
default: () =>
|
|
132
|
+
default: () => config.default.closeButton
|
|
137
133
|
},
|
|
138
134
|
emptyState: {
|
|
139
135
|
type: Object,
|
|
140
|
-
default: () =>
|
|
136
|
+
default: () => config.default.emptyState
|
|
141
137
|
},
|
|
142
138
|
placeholder: {
|
|
143
139
|
type: String,
|
|
@@ -167,15 +163,18 @@ export default defineComponent({
|
|
|
167
163
|
type: Object,
|
|
168
164
|
default: () => ({})
|
|
169
165
|
},
|
|
166
|
+
class: {
|
|
167
|
+
type: [String, Object, Array],
|
|
168
|
+
default: void 0
|
|
169
|
+
},
|
|
170
170
|
ui: {
|
|
171
171
|
type: Object,
|
|
172
|
-
default:
|
|
172
|
+
default: void 0
|
|
173
173
|
}
|
|
174
174
|
},
|
|
175
175
|
emits: ["update:modelValue", "close"],
|
|
176
|
-
setup(props, { emit,
|
|
177
|
-
const
|
|
178
|
-
const ui = computed(() => defuTwMerge({}, props.ui, appConfig2.ui.commandPalette));
|
|
176
|
+
setup(props, { emit, expose }) {
|
|
177
|
+
const { ui, attrs } = useUI("commandPalette", toRef(props, "ui"), config, toRef(props, "class"));
|
|
179
178
|
const query = ref("");
|
|
180
179
|
const comboboxInput = ref();
|
|
181
180
|
const comboboxApi = ref(null);
|
|
@@ -202,27 +201,49 @@ export default defineComponent({
|
|
|
202
201
|
resultLimit: 12,
|
|
203
202
|
matchAllWhenSearchEmpty: true
|
|
204
203
|
}));
|
|
205
|
-
const commands = computed(() =>
|
|
206
|
-
|
|
207
|
-
|
|
204
|
+
const commands = computed(() => {
|
|
205
|
+
const commands2 = [];
|
|
206
|
+
for (const group of props.groups) {
|
|
207
|
+
if (!group.search) {
|
|
208
|
+
commands2.push(...group.commands.map((command) => ({ ...command, group: group.key })));
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return commands2;
|
|
212
|
+
});
|
|
208
213
|
const searchResults = ref({});
|
|
209
214
|
const { results } = useFuse(query, commands, options);
|
|
210
|
-
const groups = computed(() =>
|
|
211
|
-
|
|
212
|
-
|
|
215
|
+
const groups = computed(() => {
|
|
216
|
+
const groups2 = [];
|
|
217
|
+
const groupedCommands = {};
|
|
218
|
+
for (const command of results.value) {
|
|
219
|
+
groupedCommands[command.item.group] ||= [];
|
|
220
|
+
groupedCommands[command.item.group].push(command);
|
|
221
|
+
}
|
|
222
|
+
for (const key in groupedCommands) {
|
|
223
|
+
const group = props.groups.find((group2) => group2.key === key);
|
|
224
|
+
let commands2 = groupedCommands[key].map((result) => {
|
|
213
225
|
const { item, ...data } = result;
|
|
214
226
|
return {
|
|
215
227
|
...item,
|
|
216
228
|
...data
|
|
217
229
|
};
|
|
218
230
|
});
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
};
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
|
|
231
|
+
if (group.filter && typeof group.filter === "function") {
|
|
232
|
+
commands2 = group.filter(query.value, commands2);
|
|
233
|
+
}
|
|
234
|
+
groups2.push({ ...group, commands: commands2.slice(0, options.value.resultLimit) });
|
|
235
|
+
}
|
|
236
|
+
for (const group of props.groups) {
|
|
237
|
+
if (group.search && searchResults.value[group.key]?.length) {
|
|
238
|
+
let commands2 = searchResults.value[group.key] || [];
|
|
239
|
+
if (group.filter && typeof group.filter === "function") {
|
|
240
|
+
commands2 = group.filter(query.value, commands2);
|
|
241
|
+
}
|
|
242
|
+
groups2.push({ ...group, commands: commands2.slice(0, options.value.resultLimit) });
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return groups2;
|
|
246
|
+
});
|
|
226
247
|
const debouncedSearch = useDebounceFn(async () => {
|
|
227
248
|
const searchableGroups = props.groups.filter((group) => !!group.search);
|
|
228
249
|
if (!searchableGroups.length) {
|
|
@@ -240,7 +261,6 @@ export default defineComponent({
|
|
|
240
261
|
comboboxInput.value?.$el.dispatchEvent(new KeyboardEvent("keydown", { key: "PageUp" }));
|
|
241
262
|
}, 0);
|
|
242
263
|
});
|
|
243
|
-
const wrapperClass = computed(() => twMerge(ui.value.wrapper, attrs.class));
|
|
244
264
|
const iconName = computed(() => {
|
|
245
265
|
if ((props.loading || isLoading.value) && props.loadingIcon) {
|
|
246
266
|
return props.loadingIcon;
|
|
@@ -284,14 +304,13 @@ export default defineComponent({
|
|
|
284
304
|
results
|
|
285
305
|
});
|
|
286
306
|
return {
|
|
287
|
-
attrs: omit(attrs, ["class"]),
|
|
288
307
|
// eslint-disable-next-line vue/no-dupe-keys
|
|
289
308
|
ui,
|
|
309
|
+
attrs,
|
|
290
310
|
// eslint-disable-next-line vue/no-dupe-keys
|
|
291
311
|
groups,
|
|
292
312
|
comboboxInput,
|
|
293
313
|
query,
|
|
294
|
-
wrapperClass,
|
|
295
314
|
iconName,
|
|
296
315
|
iconClass,
|
|
297
316
|
// eslint-disable-next-line vue/no-dupe-keys
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
/// <reference types="lodash" />
|
|
2
1
|
import type { ComputedRef, PropType, ComponentPublicInstance } from 'vue';
|
|
3
2
|
import type { UseFuseOptions } from '@vueuse/integrations/useFuse';
|
|
4
|
-
import type { Group, Command } from '../../types
|
|
5
|
-
import type { Button } from '../../types/button';
|
|
3
|
+
import type { Group, Command, Button } from '../../types';
|
|
6
4
|
declare const _default: import("vue").DefineComponent<{
|
|
7
5
|
modelValue: {
|
|
8
|
-
type: (ObjectConstructor |
|
|
6
|
+
type: (ObjectConstructor | NumberConstructor | ArrayConstructor | StringConstructor)[];
|
|
9
7
|
default: null;
|
|
10
8
|
};
|
|
11
9
|
by: {
|
|
@@ -46,7 +44,7 @@ declare const _default: import("vue").DefineComponent<{
|
|
|
46
44
|
};
|
|
47
45
|
closeButton: {
|
|
48
46
|
type: PropType<Button>;
|
|
49
|
-
default: () =>
|
|
47
|
+
default: () => Button;
|
|
50
48
|
};
|
|
51
49
|
emptyState: {
|
|
52
50
|
type: PropType<{
|
|
@@ -84,24 +82,22 @@ declare const _default: import("vue").DefineComponent<{
|
|
|
84
82
|
type: PropType<UseFuseOptions<Command>>;
|
|
85
83
|
default: () => {};
|
|
86
84
|
};
|
|
87
|
-
|
|
85
|
+
class: {
|
|
88
86
|
type: PropType<any>;
|
|
89
|
-
default:
|
|
87
|
+
default: undefined;
|
|
88
|
+
};
|
|
89
|
+
ui: {
|
|
90
|
+
type: PropType<Partial<any>>;
|
|
91
|
+
default: undefined;
|
|
90
92
|
};
|
|
91
93
|
}, {
|
|
92
|
-
attrs: import("lodash").Omit<{
|
|
93
|
-
[x: string]: unknown;
|
|
94
|
-
}, "class">;
|
|
95
94
|
ui: ComputedRef<any>;
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
inactive?: string | undefined;
|
|
101
|
-
}[]>;
|
|
95
|
+
attrs: ComputedRef<Pick<{
|
|
96
|
+
[x: string]: unknown;
|
|
97
|
+
}, string>>;
|
|
98
|
+
groups: ComputedRef<Group[]>;
|
|
102
99
|
comboboxInput: import("vue").Ref<ComponentPublicInstance<HTMLInputElement> | undefined>;
|
|
103
100
|
query: import("vue").Ref<string>;
|
|
104
|
-
wrapperClass: ComputedRef<string>;
|
|
105
101
|
iconName: ComputedRef<string | undefined>;
|
|
106
102
|
iconClass: ComputedRef<string>;
|
|
107
103
|
emptyState: ComputedRef<any>;
|
|
@@ -109,7 +105,7 @@ declare const _default: import("vue").DefineComponent<{
|
|
|
109
105
|
onClear: () => void;
|
|
110
106
|
}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("close" | "update:modelValue")[], "close" | "update:modelValue", import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
|
|
111
107
|
modelValue: {
|
|
112
|
-
type: (ObjectConstructor |
|
|
108
|
+
type: (ObjectConstructor | NumberConstructor | ArrayConstructor | StringConstructor)[];
|
|
113
109
|
default: null;
|
|
114
110
|
};
|
|
115
111
|
by: {
|
|
@@ -150,7 +146,7 @@ declare const _default: import("vue").DefineComponent<{
|
|
|
150
146
|
};
|
|
151
147
|
closeButton: {
|
|
152
148
|
type: PropType<Button>;
|
|
153
|
-
default: () =>
|
|
149
|
+
default: () => Button;
|
|
154
150
|
};
|
|
155
151
|
emptyState: {
|
|
156
152
|
type: PropType<{
|
|
@@ -188,17 +184,22 @@ declare const _default: import("vue").DefineComponent<{
|
|
|
188
184
|
type: PropType<UseFuseOptions<Command>>;
|
|
189
185
|
default: () => {};
|
|
190
186
|
};
|
|
191
|
-
|
|
187
|
+
class: {
|
|
192
188
|
type: PropType<any>;
|
|
193
|
-
default:
|
|
189
|
+
default: undefined;
|
|
190
|
+
};
|
|
191
|
+
ui: {
|
|
192
|
+
type: PropType<Partial<any>>;
|
|
193
|
+
default: undefined;
|
|
194
194
|
};
|
|
195
195
|
}>> & {
|
|
196
|
-
onClose?: ((...args: any[]) => any) | undefined;
|
|
197
196
|
"onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
|
|
197
|
+
onClose?: ((...args: any[]) => any) | undefined;
|
|
198
198
|
}, {
|
|
199
199
|
icon: string;
|
|
200
200
|
closeButton: Button;
|
|
201
|
-
ui: any
|
|
201
|
+
ui: Partial<any>;
|
|
202
|
+
class: any;
|
|
202
203
|
modelValue: string | number | unknown[] | Record<string, any>;
|
|
203
204
|
by: string;
|
|
204
205
|
loading: boolean;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PropType } from 'vue';
|
|
2
|
-
import type { Group } from '../../types
|
|
2
|
+
import type { Group } from '../../types';
|
|
3
3
|
declare const _default: import("vue").DefineComponent<{
|
|
4
4
|
group: {
|
|
5
5
|
type: PropType<Group>;
|
|
@@ -23,7 +23,7 @@ declare const _default: import("vue").DefineComponent<{
|
|
|
23
23
|
};
|
|
24
24
|
ui: {
|
|
25
25
|
type: PropType<any>;
|
|
26
|
-
|
|
26
|
+
required: true;
|
|
27
27
|
};
|
|
28
28
|
}, {
|
|
29
29
|
label: import("vue").ComputedRef<any>;
|
|
@@ -54,10 +54,9 @@ declare const _default: import("vue").DefineComponent<{
|
|
|
54
54
|
};
|
|
55
55
|
ui: {
|
|
56
56
|
type: PropType<any>;
|
|
57
|
-
|
|
57
|
+
required: true;
|
|
58
58
|
};
|
|
59
59
|
}>>, {
|
|
60
|
-
ui: any;
|
|
61
60
|
query: string;
|
|
62
61
|
}, {}>;
|
|
63
62
|
export default _default;
|
|
@@ -1,13 +1,27 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div :class="
|
|
2
|
+
<div :class="ui.wrapper" v-bind="attrs">
|
|
3
|
+
<slot name="first" :on-click="onClickFirst">
|
|
4
|
+
<UButton
|
|
5
|
+
v-if="firstButton && showFirst"
|
|
6
|
+
:size="size"
|
|
7
|
+
:disabled="!canGoFirstOrPrev"
|
|
8
|
+
:class="[ui.base, ui.rounded]"
|
|
9
|
+
v-bind="{ ...ui.default.firstButton, ...firstButton }"
|
|
10
|
+
:ui="{ rounded: '' }"
|
|
11
|
+
aria-label="First"
|
|
12
|
+
@click="onClickFirst"
|
|
13
|
+
/>
|
|
14
|
+
</slot>
|
|
15
|
+
|
|
3
16
|
<slot name="prev" :on-click="onClickPrev">
|
|
4
17
|
<UButton
|
|
5
18
|
v-if="prevButton"
|
|
6
19
|
:size="size"
|
|
7
|
-
:disabled="!
|
|
20
|
+
:disabled="!canGoFirstOrPrev"
|
|
8
21
|
:class="[ui.base, ui.rounded]"
|
|
9
22
|
v-bind="{ ...ui.default.prevButton, ...prevButton }"
|
|
10
23
|
:ui="{ rounded: '' }"
|
|
24
|
+
aria-label="Prev"
|
|
11
25
|
@click="onClickPrev"
|
|
12
26
|
/>
|
|
13
27
|
</slot>
|
|
@@ -27,24 +41,39 @@
|
|
|
27
41
|
<UButton
|
|
28
42
|
v-if="nextButton"
|
|
29
43
|
:size="size"
|
|
30
|
-
:disabled="!
|
|
44
|
+
:disabled="!canGoLastOrNext"
|
|
31
45
|
:class="[ui.base, ui.rounded]"
|
|
32
46
|
v-bind="{ ...ui.default.nextButton, ...nextButton }"
|
|
33
47
|
:ui="{ rounded: '' }"
|
|
48
|
+
aria-label="Next"
|
|
34
49
|
@click="onClickNext"
|
|
35
50
|
/>
|
|
36
51
|
</slot>
|
|
52
|
+
|
|
53
|
+
<slot name="last" :on-click="onClickLast">
|
|
54
|
+
<UButton
|
|
55
|
+
v-if="lastButton && showLast"
|
|
56
|
+
:size="size"
|
|
57
|
+
:disabled="!canGoLastOrNext"
|
|
58
|
+
:class="[ui.base, ui.rounded]"
|
|
59
|
+
v-bind="{ ...ui.default.lastButton, ...lastButton }"
|
|
60
|
+
:ui="{ rounded: '' }"
|
|
61
|
+
aria-label="Last"
|
|
62
|
+
@click="onClickLast"
|
|
63
|
+
/>
|
|
64
|
+
</slot>
|
|
37
65
|
</div>
|
|
38
66
|
</template>
|
|
39
67
|
|
|
40
68
|
<script>
|
|
41
|
-
import { computed, defineComponent } from "vue";
|
|
42
|
-
import { omit } from "lodash-es";
|
|
43
|
-
import { twMerge } from "tailwind-merge";
|
|
69
|
+
import { computed, toRef, defineComponent } from "vue";
|
|
44
70
|
import UButton from "../elements/Button.vue";
|
|
45
|
-
import {
|
|
46
|
-
import {
|
|
71
|
+
import { useUI } from "../../composables/useUI";
|
|
72
|
+
import { mergeConfig } from "../../utils";
|
|
47
73
|
import appConfig from "#build/app.config";
|
|
74
|
+
import { pagination, button } from "#ui/ui.config";
|
|
75
|
+
const config = mergeConfig(appConfig.ui.strategy, appConfig.ui.pagination, pagination);
|
|
76
|
+
const buttonConfig = mergeConfig(appConfig.ui.strategy, appConfig.ui.button, button);
|
|
48
77
|
export default defineComponent({
|
|
49
78
|
components: {
|
|
50
79
|
UButton
|
|
@@ -67,45 +96,64 @@ export default defineComponent({
|
|
|
67
96
|
type: Number,
|
|
68
97
|
default: 7,
|
|
69
98
|
validate(value) {
|
|
70
|
-
return value >=
|
|
99
|
+
return value >= 5 && value < Number.MAX_VALUE;
|
|
71
100
|
}
|
|
72
101
|
},
|
|
73
102
|
size: {
|
|
74
103
|
type: String,
|
|
75
|
-
default: () =>
|
|
104
|
+
default: () => config.default.size,
|
|
76
105
|
validator(value) {
|
|
77
|
-
return Object.keys(
|
|
106
|
+
return Object.keys(buttonConfig.size).includes(value);
|
|
78
107
|
}
|
|
79
108
|
},
|
|
80
109
|
activeButton: {
|
|
81
110
|
type: Object,
|
|
82
|
-
default: () =>
|
|
111
|
+
default: () => config.default.activeButton
|
|
83
112
|
},
|
|
84
113
|
inactiveButton: {
|
|
85
114
|
type: Object,
|
|
86
|
-
default: () =>
|
|
115
|
+
default: () => config.default.inactiveButton
|
|
116
|
+
},
|
|
117
|
+
showFirst: {
|
|
118
|
+
type: Boolean,
|
|
119
|
+
default: false
|
|
120
|
+
},
|
|
121
|
+
showLast: {
|
|
122
|
+
type: Boolean,
|
|
123
|
+
default: false
|
|
124
|
+
},
|
|
125
|
+
firstButton: {
|
|
126
|
+
type: Object,
|
|
127
|
+
default: () => config.default.firstButton
|
|
128
|
+
},
|
|
129
|
+
lastButton: {
|
|
130
|
+
type: Object,
|
|
131
|
+
default: () => config.default.lastButton
|
|
87
132
|
},
|
|
88
133
|
prevButton: {
|
|
89
134
|
type: Object,
|
|
90
|
-
default: () =>
|
|
135
|
+
default: () => config.default.prevButton
|
|
91
136
|
},
|
|
92
137
|
nextButton: {
|
|
93
138
|
type: Object,
|
|
94
|
-
default: () =>
|
|
139
|
+
default: () => config.default.nextButton
|
|
95
140
|
},
|
|
96
141
|
divider: {
|
|
97
142
|
type: String,
|
|
98
143
|
default: "\u2026"
|
|
99
144
|
},
|
|
145
|
+
class: {
|
|
146
|
+
type: [String, Object, Array],
|
|
147
|
+
default: void 0
|
|
148
|
+
},
|
|
100
149
|
ui: {
|
|
101
150
|
type: Object,
|
|
102
|
-
default:
|
|
151
|
+
default: void 0
|
|
103
152
|
}
|
|
104
153
|
},
|
|
105
154
|
emits: ["update:modelValue"],
|
|
106
|
-
setup(props, {
|
|
107
|
-
const
|
|
108
|
-
const ui = computed(() => defuTwMerge({}, props.ui, appConfig2.ui.pagination));
|
|
155
|
+
setup(props, { emit }) {
|
|
156
|
+
const { ui, attrs } = useUI("pagination", toRef(props, "ui"), config, toRef(props, "class"));
|
|
109
157
|
const currentPage = computed({
|
|
110
158
|
get() {
|
|
111
159
|
return props.modelValue;
|
|
@@ -116,50 +164,66 @@ export default defineComponent({
|
|
|
116
164
|
});
|
|
117
165
|
const pages = computed(() => Array.from({ length: Math.ceil(props.total / props.pageCount) }, (_, i) => i + 1));
|
|
118
166
|
const displayedPages = computed(() => {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if (beforeWrapped)
|
|
131
|
-
items.push(props.divider);
|
|
132
|
-
if (!afterWrapped) {
|
|
133
|
-
const addedItems = current + r + 2 - max;
|
|
134
|
-
for (let i = current - r - addedItems; i <= current - r - 1; i++) {
|
|
135
|
-
items.push(i);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
for (let i = r1 > 2 ? r1 : 2; i <= Math.min(max, r2); i++) {
|
|
167
|
+
const totalPages = pages.value.length;
|
|
168
|
+
const current = currentPage.value;
|
|
169
|
+
const maxDisplayedPages = Math.max(props.max, 5);
|
|
170
|
+
const r = Math.floor((Math.min(maxDisplayedPages, totalPages) - 5) / 2);
|
|
171
|
+
const r1 = current - r;
|
|
172
|
+
const r2 = current + r;
|
|
173
|
+
const beforeWrapped = r1 - 1 > 1;
|
|
174
|
+
const afterWrapped = r2 + 1 < totalPages;
|
|
175
|
+
const items = [];
|
|
176
|
+
if (totalPages <= maxDisplayedPages) {
|
|
177
|
+
for (let i = 1; i <= totalPages; i++) {
|
|
139
178
|
items.push(i);
|
|
140
179
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
items.push(max);
|
|
151
|
-
if (items.length >= 3 && items[1] === props.divider && items[2] === 3) {
|
|
152
|
-
items[1] = 2;
|
|
180
|
+
return items;
|
|
181
|
+
}
|
|
182
|
+
items.push(1);
|
|
183
|
+
if (beforeWrapped)
|
|
184
|
+
items.push(props.divider);
|
|
185
|
+
if (!afterWrapped) {
|
|
186
|
+
const addedItems = current + r + 2 - totalPages;
|
|
187
|
+
for (let i = current - r - addedItems; i <= current - r - 1; i++) {
|
|
188
|
+
items.push(i);
|
|
153
189
|
}
|
|
154
|
-
|
|
155
|
-
|
|
190
|
+
}
|
|
191
|
+
for (let i = Math.max(2, r1); i <= Math.min(totalPages, r2); i++) {
|
|
192
|
+
items.push(i);
|
|
193
|
+
}
|
|
194
|
+
if (!beforeWrapped) {
|
|
195
|
+
const addedItems = 1 - (current - r - 2);
|
|
196
|
+
for (let i = current + r + 1; i <= current + r + addedItems; i++) {
|
|
197
|
+
items.push(i);
|
|
156
198
|
}
|
|
157
|
-
return items;
|
|
158
199
|
}
|
|
200
|
+
if (afterWrapped)
|
|
201
|
+
items.push(props.divider);
|
|
202
|
+
if (r2 < totalPages) {
|
|
203
|
+
items.push(totalPages);
|
|
204
|
+
}
|
|
205
|
+
if (items.length >= 3 && items[1] === props.divider && items[2] === 3) {
|
|
206
|
+
items[1] = 2;
|
|
207
|
+
}
|
|
208
|
+
if (items.length >= 3 && items[items.length - 2] === props.divider && items[items.length - 1] === items.length) {
|
|
209
|
+
items[items.length - 2] = items.length - 1;
|
|
210
|
+
}
|
|
211
|
+
return items;
|
|
159
212
|
});
|
|
160
|
-
const
|
|
161
|
-
const
|
|
162
|
-
|
|
213
|
+
const canGoFirstOrPrev = computed(() => currentPage.value > 1);
|
|
214
|
+
const canGoLastOrNext = computed(() => currentPage.value < pages.value.length);
|
|
215
|
+
function onClickFirst() {
|
|
216
|
+
if (!canGoFirstOrPrev.value) {
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
currentPage.value = 1;
|
|
220
|
+
}
|
|
221
|
+
function onClickLast() {
|
|
222
|
+
if (!canGoLastOrNext.value) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
currentPage.value = pages.value.length;
|
|
226
|
+
}
|
|
163
227
|
function onClickPage(page) {
|
|
164
228
|
if (typeof page === "string") {
|
|
165
229
|
return;
|
|
@@ -167,30 +231,31 @@ export default defineComponent({
|
|
|
167
231
|
currentPage.value = page;
|
|
168
232
|
}
|
|
169
233
|
function onClickPrev() {
|
|
170
|
-
if (!
|
|
234
|
+
if (!canGoFirstOrPrev.value) {
|
|
171
235
|
return;
|
|
172
236
|
}
|
|
173
237
|
currentPage.value--;
|
|
174
238
|
}
|
|
175
239
|
function onClickNext() {
|
|
176
|
-
if (!
|
|
240
|
+
if (!canGoLastOrNext.value) {
|
|
177
241
|
return;
|
|
178
242
|
}
|
|
179
243
|
currentPage.value++;
|
|
180
244
|
}
|
|
181
245
|
return {
|
|
182
|
-
attrs: omit(attrs, ["class"]),
|
|
183
246
|
// eslint-disable-next-line vue/no-dupe-keys
|
|
184
247
|
ui,
|
|
248
|
+
attrs,
|
|
185
249
|
currentPage,
|
|
186
250
|
pages,
|
|
187
251
|
displayedPages,
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
wrapperClass,
|
|
252
|
+
canGoLastOrNext,
|
|
253
|
+
canGoFirstOrPrev,
|
|
191
254
|
onClickPrev,
|
|
192
255
|
onClickNext,
|
|
193
|
-
onClickPage
|
|
256
|
+
onClickPage,
|
|
257
|
+
onClickFirst,
|
|
258
|
+
onClickLast
|
|
194
259
|
};
|
|
195
260
|
}
|
|
196
261
|
});
|