@xleddyl/443-components-vue 0.10.2 → 0.12.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/CATALOG.md +195 -180
- package/README.md +107 -23
- package/dist/components/data/Tag.vue +2 -0
- package/dist/components/data/Tag.vue.d.ts +2 -0
- package/dist/components/data/TagList.vue +239 -0
- package/dist/components/data/TagList.vue.d.ts +53 -0
- package/dist/components/data/index.d.ts +1 -0
- package/dist/components/data/index.mjs +1 -0
- package/dist/components/data/types.d.ts +15 -0
- package/dist/components/forms/Combobox.vue +33 -4
- package/dist/components/forms/Combobox.vue.d.ts +3 -1
- package/dist/components/forms/NumberInput.vue.d.ts +1 -1
- package/dist/components/forms/PinInput.vue.d.ts +2 -2
- package/dist/components/forms/types.d.ts +2 -0
- package/dist/components/layout/AppShell.vue +14 -2
- package/dist/components/layout/AppShell.vue.d.ts +3 -1
- package/dist/components/layout/Sidebar.vue +8 -3
- package/dist/components/layout/Sidebar.vue.d.ts +6 -1
- package/dist/components/layout/Stepper.vue +148 -0
- package/dist/components/layout/Stepper.vue.d.ts +420 -0
- package/dist/components/layout/index.d.ts +1 -0
- package/dist/components/layout/index.mjs +1 -0
- package/dist/components/layout/types.d.ts +13 -0
- package/dist/components/overlays/Toaster.vue +10 -0
- package/dist/components/overlays/Toaster.vue.d.ts +1 -1
- package/dist/components/templates/DashboardLayout.vue +13 -1
- package/dist/components/templates/DashboardLayout.vue.d.ts +7 -2
- package/dist/components/templates/SettingsModal.vue +95 -4
- package/dist/components/templates/SettingsModal.vue.d.ts +6 -1
- package/dist/components/templates/types.d.ts +4 -1
- package/dist/composables/data.d.ts +1 -0
- package/dist/composables/data.mjs +1 -0
- package/dist/composables/layout.d.ts +1 -0
- package/dist/composables/layout.mjs +1 -0
- package/dist/composables/useRouteState.d.ts +13 -0
- package/dist/composables/useRouteState.mjs +37 -0
- package/dist/composables/useSortable.d.ts +38 -0
- package/dist/composables/useSortable.mjs +215 -0
- package/dist/grid/DataGrid.vue +7 -1
- package/dist/grid/DataGrid.vue.d.ts +8 -1
- package/dist/grid/GridToolbar.vue +57 -2
- package/dist/grid/GridToolbar.vue.d.ts +13 -2
- package/dist/grid/cells/BadgeCell.vue +90 -18
- package/dist/grid/cells/BadgeCell.vue.d.ts +14 -14
- package/dist/grid/data-grid.css +57 -0
- package/dist/grid/spreadsheet.mjs +8 -4
- package/dist/grid/types.d.ts +3 -0
- package/dist/icons/builtin.d.ts +2 -0
- package/dist/icons/builtin.mjs +2 -0
- package/dist/internal/data/sortable.d.ts +5 -0
- package/dist/internal/data/sortable.mjs +23 -0
- package/dist/internal/layout/query.d.ts +6 -0
- package/dist/internal/layout/query.mjs +64 -0
- package/dist/internal/layout/route.d.ts +9 -2
- package/dist/internal/overlays/avoid.d.ts +26 -0
- package/dist/internal/overlays/avoid.mjs +134 -0
- package/dist/locale/de.mjs +24 -0
- package/dist/locale/en.mjs +24 -0
- package/dist/locale/it.mjs +24 -0
- package/dist/locale/types.d.ts +24 -0
- package/dist/nuxt/module.mjs +14 -0
- package/dist/nuxt/runtime/layouts/dashboard.vue +9 -1
- package/dist/styles/data/tag-list.css +93 -0
- package/dist/styles/data.css +1 -0
- package/dist/styles/forced-colors.css +10 -0
- package/dist/styles/layout/app-shell.css +25 -6
- package/dist/styles/layout/sidebar.css +11 -2
- package/dist/styles/layout/stepper.css +244 -0
- package/dist/styles/layout.css +1 -0
- package/dist/styles/overlays/toast.css +17 -12
- package/dist/styles/templates/settings-modal.css +5 -1
- package/package.json +1 -1
|
@@ -12,6 +12,46 @@
|
|
|
12
12
|
:aria-label="text.search"
|
|
13
13
|
/>
|
|
14
14
|
</div>
|
|
15
|
+
<span v-if="$slots.filters" class="k-data-grid-filters">
|
|
16
|
+
<Button
|
|
17
|
+
variant="outline"
|
|
18
|
+
tone="neutral"
|
|
19
|
+
size="sm"
|
|
20
|
+
icon="funnel"
|
|
21
|
+
square
|
|
22
|
+
:aria-label="filtersLabel"
|
|
23
|
+
aria-haspopup="dialog"
|
|
24
|
+
:aria-expanded="filtersOpen ? 'true' : 'false'"
|
|
25
|
+
:class="{ 'is-active': activeFilters > 0 }"
|
|
26
|
+
@click="filtersOpen = true"
|
|
27
|
+
/>
|
|
28
|
+
<Badge
|
|
29
|
+
v-if="activeFilters > 0"
|
|
30
|
+
class="k-data-grid-filters-count"
|
|
31
|
+
tone="accent"
|
|
32
|
+
variant="solid"
|
|
33
|
+
size="sm"
|
|
34
|
+
:label="activeFilters"
|
|
35
|
+
aria-hidden="true"
|
|
36
|
+
/>
|
|
37
|
+
</span>
|
|
38
|
+
<Modal v-if="$slots.filters" v-model:open="filtersOpen" :title="text.filters" size="sm">
|
|
39
|
+
<div class="k-data-grid-filters-body">
|
|
40
|
+
<slot name="filters" :close="closeFilters" :count="activeFilters" />
|
|
41
|
+
</div>
|
|
42
|
+
<template #footer="{ close }">
|
|
43
|
+
<Button
|
|
44
|
+
class="k-data-grid-filters-reset"
|
|
45
|
+
variant="ghost"
|
|
46
|
+
tone="neutral"
|
|
47
|
+
icon="arrow-path"
|
|
48
|
+
:label="text.resetFilters"
|
|
49
|
+
:aria-disabled="activeFilters === 0 ? 'true' : void 0"
|
|
50
|
+
@click="resetFilters"
|
|
51
|
+
/>
|
|
52
|
+
<Button :label="text.showResults" @click="close" />
|
|
53
|
+
</template>
|
|
54
|
+
</Modal>
|
|
15
55
|
<div class="k-data-grid-toolbar-actions">
|
|
16
56
|
<slot />
|
|
17
57
|
<DropdownMenu
|
|
@@ -47,8 +87,11 @@
|
|
|
47
87
|
import { computed, onBeforeUnmount, ref, watch } from "vue";
|
|
48
88
|
import Button from "../components/core/Button.vue";
|
|
49
89
|
import Input from "../components/core/Input.vue";
|
|
90
|
+
import Badge from "../components/data/Badge.vue";
|
|
50
91
|
import DropdownMenu from "../components/overlays/DropdownMenu.vue";
|
|
92
|
+
import Modal from "../components/overlays/Modal.vue";
|
|
51
93
|
import { useLocale } from "../composables/useLocale";
|
|
94
|
+
import { formatLocaleMessage } from "../locale";
|
|
52
95
|
const props = defineProps({
|
|
53
96
|
api: { type: [Object, null], required: false },
|
|
54
97
|
messages: { type: Object, required: false },
|
|
@@ -56,15 +99,21 @@ const props = defineProps({
|
|
|
56
99
|
columnMenu: { type: Boolean, required: false, default: true },
|
|
57
100
|
exportable: { type: Boolean, required: false, default: true },
|
|
58
101
|
exportFileName: { type: String, required: false, default: "export" },
|
|
59
|
-
debounce: { type: Number, required: false, default: 0 }
|
|
102
|
+
debounce: { type: Number, required: false, default: 0 },
|
|
103
|
+
filterCount: { type: Number, required: false, default: 0 }
|
|
60
104
|
});
|
|
61
|
-
const emit = defineEmits(["resetColumns"]);
|
|
105
|
+
const emit = defineEmits(["resetColumns", "filtersReset"]);
|
|
62
106
|
const query = defineModel({ type: String, ...{ default: "" } });
|
|
63
107
|
const { locale } = useLocale();
|
|
108
|
+
const filtersOpen = ref(false);
|
|
109
|
+
const activeFilters = computed(() => Math.max(0, Math.floor(props.filterCount)));
|
|
64
110
|
const text = computed(() => ({
|
|
65
111
|
...locale.value.messages.grid,
|
|
66
112
|
...props.messages
|
|
67
113
|
}));
|
|
114
|
+
const filtersLabel = computed(
|
|
115
|
+
() => formatLocaleMessage(locale.value.code, text.value.filtersActive, { count: activeFilters.value })
|
|
116
|
+
);
|
|
68
117
|
const draft = ref(query.value);
|
|
69
118
|
const columns = ref([]);
|
|
70
119
|
const visibleCount = computed(() => columns.value.filter((column) => column.visible).length);
|
|
@@ -130,6 +179,12 @@ function resetColumns() {
|
|
|
130
179
|
props.api?.resetColumnState();
|
|
131
180
|
emit("resetColumns");
|
|
132
181
|
}
|
|
182
|
+
function resetFilters() {
|
|
183
|
+
if (activeFilters.value > 0) emit("filtersReset");
|
|
184
|
+
}
|
|
185
|
+
function closeFilters() {
|
|
186
|
+
filtersOpen.value = false;
|
|
187
|
+
}
|
|
133
188
|
function exportCsv() {
|
|
134
189
|
props.api?.exportDataAsCsv({ fileName: props.exportFileName });
|
|
135
190
|
}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import type { GridMessages } from './types';
|
|
2
|
-
declare
|
|
2
|
+
declare function closeFilters(): void;
|
|
3
|
+
declare var __VLS_28: {
|
|
4
|
+
close: typeof closeFilters;
|
|
5
|
+
count: number;
|
|
6
|
+
}, __VLS_45: {};
|
|
3
7
|
type __VLS_Slots = {} & {
|
|
4
|
-
|
|
8
|
+
filters?: (props: typeof __VLS_28) => any;
|
|
9
|
+
} & {
|
|
10
|
+
default?: (props: typeof __VLS_45) => any;
|
|
5
11
|
};
|
|
6
12
|
declare const __VLS_base: import("vue").DefineComponent<{
|
|
7
13
|
api?: import("ag-grid-community").GridApi | null;
|
|
@@ -11,6 +17,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
|
|
|
11
17
|
exportable?: boolean;
|
|
12
18
|
exportFileName?: string;
|
|
13
19
|
debounce?: number;
|
|
20
|
+
filterCount?: number;
|
|
14
21
|
modelValue?: string;
|
|
15
22
|
key?: PropertyKey | undefined;
|
|
16
23
|
prefix?: string | undefined | undefined;
|
|
@@ -207,6 +214,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
|
|
|
207
214
|
}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
208
215
|
resetColumns: () => any;
|
|
209
216
|
"update:modelValue": (value: string) => any;
|
|
217
|
+
filtersReset: () => any;
|
|
210
218
|
}, string, import("vue").PublicProps, Readonly<{
|
|
211
219
|
api?: import("ag-grid-community").GridApi | null;
|
|
212
220
|
messages?: Partial<GridMessages>;
|
|
@@ -215,6 +223,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
|
|
|
215
223
|
exportable?: boolean;
|
|
216
224
|
exportFileName?: string;
|
|
217
225
|
debounce?: number;
|
|
226
|
+
filterCount?: number;
|
|
218
227
|
modelValue?: string;
|
|
219
228
|
key?: PropertyKey | undefined;
|
|
220
229
|
prefix?: string | undefined | undefined;
|
|
@@ -411,12 +420,14 @@ declare const __VLS_base: import("vue").DefineComponent<{
|
|
|
411
420
|
}> & Readonly<{
|
|
412
421
|
onResetColumns?: (() => any) | undefined;
|
|
413
422
|
"onUpdate:modelValue"?: ((value: string) => any) | undefined;
|
|
423
|
+
onFiltersReset?: (() => any) | undefined;
|
|
414
424
|
}>, {
|
|
415
425
|
debounce: number;
|
|
416
426
|
searchable: boolean;
|
|
417
427
|
columnMenu: boolean;
|
|
418
428
|
exportable: boolean;
|
|
419
429
|
exportFileName: string;
|
|
430
|
+
filterCount: number;
|
|
420
431
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
421
432
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
422
433
|
declare const _default: typeof __VLS_export;
|
|
@@ -1,11 +1,60 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
<span
|
|
3
|
+
v-if="isList && entries.length"
|
|
4
|
+
class="k-data-grid-badges"
|
|
5
|
+
:class="{ 'is-wrap': params.wrap }"
|
|
6
|
+
:title="fullText"
|
|
7
|
+
>
|
|
8
|
+
<template v-for="entry in shown" :key="entry.key">
|
|
9
|
+
<Badge
|
|
10
|
+
v-if="params.variant"
|
|
11
|
+
:class="entry.badgeClass"
|
|
12
|
+
:tone="entry.tone"
|
|
13
|
+
:variant="params.variant"
|
|
14
|
+
:size
|
|
15
|
+
>{{ entry.text }}</Badge
|
|
16
|
+
>
|
|
17
|
+
<span
|
|
18
|
+
v-else
|
|
19
|
+
class="k-data-grid-badge"
|
|
20
|
+
:class="[`k-data-grid-badge-${entry.tone}`, entry.badgeClass]"
|
|
21
|
+
>{{ entry.text }}</span
|
|
22
|
+
>
|
|
23
|
+
</template>
|
|
24
|
+
<template v-if="hiddenCount > 0">
|
|
25
|
+
<Badge
|
|
26
|
+
v-if="params.variant"
|
|
27
|
+
class="k-data-grid-badge-more"
|
|
28
|
+
tone="neutral"
|
|
29
|
+
:variant="params.variant"
|
|
30
|
+
:size
|
|
31
|
+
aria-hidden="true"
|
|
32
|
+
>+{{ hiddenCount }}</Badge
|
|
33
|
+
>
|
|
34
|
+
<span
|
|
35
|
+
v-else
|
|
36
|
+
class="k-data-grid-badge k-data-grid-badge-neutral k-data-grid-badge-more"
|
|
37
|
+
aria-hidden="true"
|
|
38
|
+
>+{{ hiddenCount }}</span
|
|
39
|
+
>
|
|
40
|
+
<span class="k-visually-hidden">{{ moreText }}</span>
|
|
41
|
+
</template>
|
|
42
|
+
</span>
|
|
43
|
+
<template v-else-if="!isList && single">
|
|
44
|
+
<Badge
|
|
45
|
+
v-if="params.variant"
|
|
46
|
+
:class="single.badgeClass"
|
|
47
|
+
:tone="single.tone"
|
|
48
|
+
:variant="params.variant"
|
|
49
|
+
:size
|
|
50
|
+
>{{ single.text }}</Badge
|
|
51
|
+
>
|
|
52
|
+
<span
|
|
53
|
+
v-else
|
|
54
|
+
class="k-data-grid-badge"
|
|
55
|
+
:class="[`k-data-grid-badge-${single.tone}`, single.badgeClass]"
|
|
56
|
+
>{{ single.text }}</span
|
|
57
|
+
>
|
|
9
58
|
</template>
|
|
10
59
|
<EmptyCell v-else :context="cellContext" />
|
|
11
60
|
</template>
|
|
@@ -13,22 +62,45 @@
|
|
|
13
62
|
<script setup>
|
|
14
63
|
import { computed } from "vue";
|
|
15
64
|
import Badge from "../../components/data/Badge.vue";
|
|
65
|
+
import { formatLocaleMessage } from "../../locale";
|
|
16
66
|
import EmptyCell from "./EmptyCell.vue";
|
|
17
67
|
const props = defineProps({
|
|
18
68
|
params: { type: Object, required: true }
|
|
19
69
|
});
|
|
20
|
-
const
|
|
21
|
-
const raw = props.params.value;
|
|
22
|
-
return raw === null || raw === void 0 ? "" : String(raw);
|
|
23
|
-
});
|
|
24
|
-
const text = computed(() => key.value ? props.params.labels?.[key.value] ?? key.value : "");
|
|
25
|
-
const tone = computed(
|
|
26
|
-
() => props.params.tones?.[key.value] ?? props.params.defaultTone ?? "neutral"
|
|
27
|
-
);
|
|
70
|
+
const cellContext = computed(() => props.params.context);
|
|
28
71
|
const size = computed(() => props.params.size ?? "sm");
|
|
29
|
-
const
|
|
72
|
+
const isList = computed(() => Array.isArray(props.params.value));
|
|
73
|
+
function keyOf(raw) {
|
|
74
|
+
return raw === null || raw === void 0 ? "" : String(raw);
|
|
75
|
+
}
|
|
76
|
+
function entryFor(raw, index) {
|
|
77
|
+
const key = keyOf(raw);
|
|
78
|
+
if (!key) return null;
|
|
30
79
|
const source = props.params.badgeClass;
|
|
31
|
-
return
|
|
80
|
+
return {
|
|
81
|
+
key: `${index}-${key}`,
|
|
82
|
+
text: props.params.labels?.[key] ?? key,
|
|
83
|
+
tone: props.params.tones?.[key] ?? props.params.defaultTone ?? "neutral",
|
|
84
|
+
badgeClass: typeof source === "function" ? source(raw, props.params.data) : source
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
const single = computed(() => isList.value ? null : entryFor(props.params.value, 0));
|
|
88
|
+
const entries = computed(() => {
|
|
89
|
+
if (!isList.value) return [];
|
|
90
|
+
return props.params.value.map((raw, index) => entryFor(raw, index)).filter((entry) => entry !== null);
|
|
32
91
|
});
|
|
33
|
-
const
|
|
92
|
+
const limit = computed(() => {
|
|
93
|
+
const max = props.params.max;
|
|
94
|
+
return max === void 0 || max < 1 ? entries.value.length : Math.floor(max);
|
|
95
|
+
});
|
|
96
|
+
const shown = computed(() => entries.value.slice(0, limit.value));
|
|
97
|
+
const hiddenCount = computed(() => entries.value.length - shown.value.length);
|
|
98
|
+
const fullText = computed(() => entries.value.map((entry) => entry.text).join(", "));
|
|
99
|
+
const moreText = computed(
|
|
100
|
+
() => formatLocaleMessage(
|
|
101
|
+
cellContext.value?.locale ?? "en",
|
|
102
|
+
cellContext.value?.messages?.moreValues ?? "{count} more",
|
|
103
|
+
{ count: hiddenCount.value }
|
|
104
|
+
)
|
|
105
|
+
);
|
|
34
106
|
</script>
|
|
@@ -1,13 +1,6 @@
|
|
|
1
1
|
import type { BadgeCellParams, GridCellContext } from '../types';
|
|
2
2
|
declare const __VLS_export: import("vue").DefineComponent<{
|
|
3
3
|
params: import("ag-grid-community").ICellRendererParams<any, any, any> & BadgeCellParams<unknown>;
|
|
4
|
-
label?: string | number;
|
|
5
|
-
tone?: import("../../index.ts").Tone;
|
|
6
|
-
variant?: import("../../index.ts").BadgeVariant;
|
|
7
|
-
size?: import("../../index.ts").BadgeSize;
|
|
8
|
-
dot?: boolean;
|
|
9
|
-
pulse?: boolean;
|
|
10
|
-
icon?: import("../../index.ts").IconName;
|
|
11
4
|
innerHTML?: string | undefined | undefined;
|
|
12
5
|
class?: import("vue").ClassValue;
|
|
13
6
|
style?: import("vue").StyleValue;
|
|
@@ -200,6 +193,13 @@ declare const __VLS_export: import("vue").DefineComponent<{
|
|
|
200
193
|
ref?: import("vue").VNodeRef | undefined;
|
|
201
194
|
ref_for?: boolean | undefined | undefined;
|
|
202
195
|
ref_key?: string | undefined | undefined;
|
|
196
|
+
label?: string | number;
|
|
197
|
+
tone?: import("../../index.ts").Tone;
|
|
198
|
+
variant?: import("../../index.ts").BadgeVariant;
|
|
199
|
+
size?: import("../../index.ts").BadgeSize;
|
|
200
|
+
dot?: boolean;
|
|
201
|
+
pulse?: boolean;
|
|
202
|
+
icon?: import("../../index.ts").IconName;
|
|
203
203
|
onVnodeBeforeMount?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
|
|
204
204
|
onVnodeMounted?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
|
|
205
205
|
onVnodeBeforeUpdate?: (((vnode: import("vue").VNode, oldVNode: import("vue").VNode) => void) | ((vnode: import("vue").VNode, oldVNode: import("vue").VNode) => void)[]) | undefined;
|
|
@@ -209,13 +209,6 @@ declare const __VLS_export: import("vue").DefineComponent<{
|
|
|
209
209
|
context?: GridCellContext;
|
|
210
210
|
}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{
|
|
211
211
|
params: import("ag-grid-community").ICellRendererParams<any, any, any> & BadgeCellParams<unknown>;
|
|
212
|
-
label?: string | number;
|
|
213
|
-
tone?: import("../../index.ts").Tone;
|
|
214
|
-
variant?: import("../../index.ts").BadgeVariant;
|
|
215
|
-
size?: import("../../index.ts").BadgeSize;
|
|
216
|
-
dot?: boolean;
|
|
217
|
-
pulse?: boolean;
|
|
218
|
-
icon?: import("../../index.ts").IconName;
|
|
219
212
|
innerHTML?: string | undefined | undefined;
|
|
220
213
|
class?: import("vue").ClassValue;
|
|
221
214
|
style?: import("vue").StyleValue;
|
|
@@ -408,6 +401,13 @@ declare const __VLS_export: import("vue").DefineComponent<{
|
|
|
408
401
|
ref?: import("vue").VNodeRef | undefined;
|
|
409
402
|
ref_for?: boolean | undefined | undefined;
|
|
410
403
|
ref_key?: string | undefined | undefined;
|
|
404
|
+
label?: string | number;
|
|
405
|
+
tone?: import("../../index.ts").Tone;
|
|
406
|
+
variant?: import("../../index.ts").BadgeVariant;
|
|
407
|
+
size?: import("../../index.ts").BadgeSize;
|
|
408
|
+
dot?: boolean;
|
|
409
|
+
pulse?: boolean;
|
|
410
|
+
icon?: import("../../index.ts").IconName;
|
|
411
411
|
onVnodeBeforeMount?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
|
|
412
412
|
onVnodeMounted?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
|
|
413
413
|
onVnodeBeforeUpdate?: (((vnode: import("vue").VNode, oldVNode: import("vue").VNode) => void) | ((vnode: import("vue").VNode, oldVNode: import("vue").VNode) => void)[]) | undefined;
|
package/dist/grid/data-grid.css
CHANGED
|
@@ -20,6 +20,39 @@
|
|
|
20
20
|
max-width: 22rem;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
.k-data-grid-filters {
|
|
24
|
+
position: relative;
|
|
25
|
+
display: inline-flex;
|
|
26
|
+
flex: none;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.k-data-grid-filters > .k-btn.is-active {
|
|
30
|
+
color: var(--k-accent-text);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.k-data-grid-filters > .k-data-grid-filters-count {
|
|
34
|
+
position: absolute;
|
|
35
|
+
inset-block-start: -0.4375rem;
|
|
36
|
+
inset-inline-end: -0.4375rem;
|
|
37
|
+
min-width: 1.125rem;
|
|
38
|
+
height: 1.125rem;
|
|
39
|
+
padding-inline: 0.25rem;
|
|
40
|
+
justify-content: center;
|
|
41
|
+
font-size: 0.75rem;
|
|
42
|
+
line-height: 1;
|
|
43
|
+
pointer-events: none;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.k-data-grid-filters-body {
|
|
47
|
+
display: flex;
|
|
48
|
+
flex-direction: column;
|
|
49
|
+
gap: 0.875rem;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.k-data-grid-filters-reset {
|
|
53
|
+
margin-inline-end: auto;
|
|
54
|
+
}
|
|
55
|
+
|
|
23
56
|
.k-data-grid-toolbar-actions {
|
|
24
57
|
display: flex;
|
|
25
58
|
flex-wrap: wrap;
|
|
@@ -163,6 +196,30 @@
|
|
|
163
196
|
white-space: nowrap;
|
|
164
197
|
}
|
|
165
198
|
|
|
199
|
+
.k-data-grid-badges {
|
|
200
|
+
display: flex;
|
|
201
|
+
flex-wrap: nowrap;
|
|
202
|
+
align-items: center;
|
|
203
|
+
gap: 0.25rem;
|
|
204
|
+
min-width: 0;
|
|
205
|
+
max-width: 100%;
|
|
206
|
+
overflow: hidden;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.k-data-grid-badges.is-wrap {
|
|
210
|
+
flex-wrap: wrap;
|
|
211
|
+
padding-block: 0.25rem;
|
|
212
|
+
line-height: 1.2;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.k-data-grid-badges > * {
|
|
216
|
+
flex-shrink: 0;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.k-data-grid-badges > .k-data-grid-badge-more {
|
|
220
|
+
font-variant-numeric: tabular-nums;
|
|
221
|
+
}
|
|
222
|
+
|
|
166
223
|
.k-data-grid-badge-accent {
|
|
167
224
|
--k-badge-tone: var(--k-accent-text);
|
|
168
225
|
}
|
|
@@ -102,15 +102,19 @@ export function createGridSpreadsheet(options) {
|
|
|
102
102
|
const inside = cell.row >= rect.top && cell.row <= rect.bottom && cell.col >= rect.left && cell.col <= rect.right;
|
|
103
103
|
return inside ? cell : null;
|
|
104
104
|
}
|
|
105
|
+
function onRangeEdge(params, edge) {
|
|
106
|
+
const cell = rangeCell(params);
|
|
107
|
+
return !!cell && !!rect && edge(cell, rect);
|
|
108
|
+
}
|
|
105
109
|
const classRules = {
|
|
106
110
|
"is-range": (params) => {
|
|
107
111
|
const cell = rangeCell(params);
|
|
108
112
|
return !!cell && !sameCell(cell, active);
|
|
109
113
|
},
|
|
110
|
-
"is-range-top": (params) =>
|
|
111
|
-
"is-range-bottom": (params) =>
|
|
112
|
-
"is-range-left": (params) =>
|
|
113
|
-
"is-range-right": (params) =>
|
|
114
|
+
"is-range-top": (params) => onRangeEdge(params, (cell, area) => cell.row === area.top),
|
|
115
|
+
"is-range-bottom": (params) => onRangeEdge(params, (cell, area) => cell.row === area.bottom),
|
|
116
|
+
"is-range-left": (params) => onRangeEdge(params, (cell, area) => cell.col === area.left),
|
|
117
|
+
"is-range-right": (params) => onRangeEdge(params, (cell, area) => cell.col === area.right),
|
|
114
118
|
"is-active": (params) => !!active && sameCell(cellOf(params), active),
|
|
115
119
|
"is-fill-corner": (params) => {
|
|
116
120
|
if (!rect) return false;
|
package/dist/grid/types.d.ts
CHANGED
|
@@ -31,6 +31,7 @@ export interface GridToolbarProps {
|
|
|
31
31
|
exportable?: boolean;
|
|
32
32
|
exportFileName?: string;
|
|
33
33
|
debounce?: number;
|
|
34
|
+
filterCount?: number;
|
|
34
35
|
}
|
|
35
36
|
export interface BooleanCellParams {
|
|
36
37
|
trueLabel?: string;
|
|
@@ -49,6 +50,8 @@ export interface BadgeCellParams<T = unknown> {
|
|
|
49
50
|
variant?: BadgeVariant;
|
|
50
51
|
size?: BadgeSize;
|
|
51
52
|
badgeClass?: string | ((value: unknown, data: T | undefined) => string | undefined);
|
|
53
|
+
max?: number;
|
|
54
|
+
wrap?: boolean;
|
|
52
55
|
}
|
|
53
56
|
export type ImageCellFit = 'cover' | 'contain';
|
|
54
57
|
export interface ImageCellParams<T = unknown> {
|
package/dist/icons/builtin.d.ts
CHANGED
|
@@ -7,6 +7,8 @@ export declare const builtinIcons: {
|
|
|
7
7
|
readonly 'chevron-up': readonly ["m4.5 15.75 7.5-7.5 7.5 7.5"];
|
|
8
8
|
readonly 'chevron-left': readonly ["M15.75 19.5 8.25 12l7.5-7.5"];
|
|
9
9
|
readonly 'chevron-right': readonly ["m8.25 4.5 7.5 7.5-7.5 7.5"];
|
|
10
|
+
readonly 'sidebar-collapse': readonly ["M15.75 19.5 8.25 12l7.5-7.5"];
|
|
11
|
+
readonly 'sidebar-expand': readonly ["m8.25 4.5 7.5 7.5-7.5 7.5"];
|
|
10
12
|
readonly 'chevron-up-down': readonly ["M8.25 15 12 18.75 15.75 15m-7.5-6L12 5.25 15.75 9"];
|
|
11
13
|
readonly 'chevron-double-left': readonly ["m18.75 4.5-7.5 7.5 7.5 7.5m-6-15L5.25 12l7.5 7.5"];
|
|
12
14
|
readonly 'chevron-double-right': readonly ["m5.25 4.5 7.5 7.5-7.5 7.5m6-15 7.5 7.5-7.5 7.5"];
|
package/dist/icons/builtin.mjs
CHANGED
|
@@ -7,6 +7,8 @@ export const builtinIcons = {
|
|
|
7
7
|
"chevron-up": ["m4.5 15.75 7.5-7.5 7.5 7.5"],
|
|
8
8
|
"chevron-left": ["M15.75 19.5 8.25 12l7.5-7.5"],
|
|
9
9
|
"chevron-right": ["m8.25 4.5 7.5 7.5-7.5 7.5"],
|
|
10
|
+
"sidebar-collapse": ["M15.75 19.5 8.25 12l7.5-7.5"],
|
|
11
|
+
"sidebar-expand": ["m8.25 4.5 7.5 7.5-7.5 7.5"],
|
|
10
12
|
"chevron-up-down": ["M8.25 15 12 18.75 15.75 15m-7.5-6L12 5.25 15.75 9"],
|
|
11
13
|
"chevron-double-left": ["m18.75 4.5-7.5 7.5 7.5 7.5m-6-15L5.25 12l7.5 7.5"],
|
|
12
14
|
"chevron-double-right": ["m5.25 4.5 7.5 7.5-7.5 7.5m6-15 7.5 7.5-7.5 7.5"],
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type SortableAxis = 'horizontal' | 'vertical';
|
|
2
|
+
export declare const SORTABLE_ATTR = "data-k-sortable";
|
|
3
|
+
export declare function sortableElements(container: HTMLElement | null | undefined): HTMLElement[];
|
|
4
|
+
export declare function isRtl(element: Element | null | undefined): boolean;
|
|
5
|
+
export declare function insertionIndex(elements: HTMLElement[], x: number, y: number, axis: SortableAxis, rtl: boolean): number;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export const SORTABLE_ATTR = "data-k-sortable";
|
|
2
|
+
export function sortableElements(container) {
|
|
3
|
+
if (!container) return [];
|
|
4
|
+
return Array.from(container.querySelectorAll(`[${SORTABLE_ATTR}]`)).sort(
|
|
5
|
+
(a, b) => Number(a.getAttribute(SORTABLE_ATTR)) - Number(b.getAttribute(SORTABLE_ATTR))
|
|
6
|
+
);
|
|
7
|
+
}
|
|
8
|
+
export function isRtl(element) {
|
|
9
|
+
return element ? getComputedStyle(element).direction === "rtl" : false;
|
|
10
|
+
}
|
|
11
|
+
function isBefore(rect, x, y, axis, rtl) {
|
|
12
|
+
if (axis === "vertical") return rect.top + rect.height / 2 < y;
|
|
13
|
+
if (rect.bottom <= y) return true;
|
|
14
|
+
if (rect.top > y) return false;
|
|
15
|
+
const center = rect.left + rect.width / 2;
|
|
16
|
+
return rtl ? center > x : center < x;
|
|
17
|
+
}
|
|
18
|
+
export function insertionIndex(elements, x, y, axis, rtl) {
|
|
19
|
+
let index = 0;
|
|
20
|
+
for (const element of elements)
|
|
21
|
+
if (isBefore(element.getBoundingClientRect(), x, y, axis, rtl)) index++;
|
|
22
|
+
return index;
|
|
23
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { MaybeRefOrGetter } from 'vue';
|
|
2
|
+
import type { RouterLike } from './route';
|
|
3
|
+
export type RouteHistory = 'push' | 'replace';
|
|
4
|
+
export declare function firstQueryValue(value: unknown): string | undefined;
|
|
5
|
+
export declare function useQueryValue(router: RouterLike | undefined, key: MaybeRefOrGetter<string | undefined>): import("vue").ComputedRef<string | undefined>;
|
|
6
|
+
export declare function writeQueryValue(router: RouterLike, key: string, value: string | undefined, history: RouteHistory): Promise<boolean>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { computed, toValue } from "vue";
|
|
2
|
+
import { isClient } from "../core/env.mjs";
|
|
3
|
+
const batches = /* @__PURE__ */ new WeakMap();
|
|
4
|
+
export function firstQueryValue(value) {
|
|
5
|
+
if (Array.isArray(value)) return firstQueryValue(value[0]);
|
|
6
|
+
return typeof value === "string" ? value : void 0;
|
|
7
|
+
}
|
|
8
|
+
export function useQueryValue(router, key) {
|
|
9
|
+
return computed(() => {
|
|
10
|
+
const name = toValue(key);
|
|
11
|
+
if (!router || !name) return void 0;
|
|
12
|
+
return firstQueryValue(router.currentRoute?.value?.query?.[name]);
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
function isPreviousEntry(router, location) {
|
|
16
|
+
if (!router.back || !router.resolve) return false;
|
|
17
|
+
const back = window.history.state?.back;
|
|
18
|
+
if (typeof back !== "string") return false;
|
|
19
|
+
return router.resolve(location).fullPath === back;
|
|
20
|
+
}
|
|
21
|
+
async function flush(router, batch) {
|
|
22
|
+
batches.delete(router);
|
|
23
|
+
const route = router.currentRoute?.value;
|
|
24
|
+
const query = { ...route?.query };
|
|
25
|
+
let changed = false;
|
|
26
|
+
for (const [key, value] of batch.changes) {
|
|
27
|
+
if (value === void 0) {
|
|
28
|
+
if (!(key in query)) continue;
|
|
29
|
+
delete query[key];
|
|
30
|
+
changed = true;
|
|
31
|
+
} else if (query[key] !== value) {
|
|
32
|
+
query[key] = value;
|
|
33
|
+
changed = true;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (!changed) return true;
|
|
37
|
+
const location = { path: route?.path, query, hash: route?.hash };
|
|
38
|
+
try {
|
|
39
|
+
if (batch.history === "push" && isPreviousEntry(router, location)) {
|
|
40
|
+
router.back?.();
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
const failure = batch.history === "replace" && router.replace ? await router.replace(location) : await router.push(location);
|
|
44
|
+
return !failure;
|
|
45
|
+
} catch {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export function writeQueryValue(router, key, value, history) {
|
|
50
|
+
if (!isClient()) return Promise.resolve(true);
|
|
51
|
+
let batch = batches.get(router);
|
|
52
|
+
if (!batch) {
|
|
53
|
+
const created = {
|
|
54
|
+
changes: /* @__PURE__ */ new Map(),
|
|
55
|
+
history,
|
|
56
|
+
promise: Promise.resolve().then(() => flush(router, created))
|
|
57
|
+
};
|
|
58
|
+
batch = created;
|
|
59
|
+
batches.set(router, batch);
|
|
60
|
+
}
|
|
61
|
+
batch.changes.set(key, value === "" ? void 0 : value);
|
|
62
|
+
if (history === "push") batch.history = "push";
|
|
63
|
+
return batch.promise;
|
|
64
|
+
}
|
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
import type { MaybeRefOrGetter } from 'vue';
|
|
2
|
-
interface RouteLike {
|
|
2
|
+
export interface RouteLike {
|
|
3
3
|
path?: string;
|
|
4
|
+
fullPath?: string;
|
|
5
|
+
hash?: string;
|
|
6
|
+
query?: Record<string, unknown>;
|
|
4
7
|
}
|
|
5
8
|
export interface RouterLike {
|
|
6
9
|
push: (to: unknown) => unknown;
|
|
10
|
+
replace?: (to: unknown) => unknown;
|
|
11
|
+
back?: () => unknown;
|
|
12
|
+
resolve?: (to: unknown) => {
|
|
13
|
+
fullPath?: string;
|
|
14
|
+
};
|
|
7
15
|
beforeEach: (guard: (to: RouteLike, from: RouteLike) => boolean | void | Promise<boolean | void>) => () => void;
|
|
8
16
|
currentRoute?: {
|
|
9
17
|
value?: RouteLike;
|
|
@@ -13,4 +21,3 @@ export declare function useRouterLike(): RouterLike | undefined;
|
|
|
13
21
|
export declare function useCurrentPath(override?: MaybeRefOrGetter<string | undefined>): import("vue").ComputedRef<string | undefined>;
|
|
14
22
|
export declare function targetPath(target: unknown): string | undefined;
|
|
15
23
|
export declare function matchesPath(current: string, target: string, exact: boolean): boolean;
|
|
16
|
-
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Ref } from 'vue';
|
|
2
|
+
export interface ToasterInsets {
|
|
3
|
+
left: number;
|
|
4
|
+
right: number;
|
|
5
|
+
top: number;
|
|
6
|
+
bottom: number;
|
|
7
|
+
}
|
|
8
|
+
export interface ToasterAvoidanceOptions {
|
|
9
|
+
outlet: () => HTMLElement | null;
|
|
10
|
+
toaster: Readonly<Ref<HTMLElement | null | undefined>>;
|
|
11
|
+
position: () => string;
|
|
12
|
+
}
|
|
13
|
+
export declare function useToasterAvoidance(options: ToasterAvoidanceOptions): {
|
|
14
|
+
insets: Ref<{
|
|
15
|
+
left: number;
|
|
16
|
+
right: number;
|
|
17
|
+
top: number;
|
|
18
|
+
bottom: number;
|
|
19
|
+
}, ToasterInsets | {
|
|
20
|
+
left: number;
|
|
21
|
+
right: number;
|
|
22
|
+
top: number;
|
|
23
|
+
bottom: number;
|
|
24
|
+
}>;
|
|
25
|
+
refresh: () => void;
|
|
26
|
+
};
|