@caido-utils/components 0.1.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/dist/ButtonGroup/Container.d.vue.ts +34 -0
- package/dist/ButtonGroup/Container.vue +36 -0
- package/dist/ButtonGroup/Container.vue.d.ts +34 -0
- package/dist/Card/Container.d.vue.ts +12 -0
- package/dist/Card/Container.vue +21 -0
- package/dist/Card/Container.vue.d.ts +12 -0
- package/dist/ContextMenu/Container.d.vue.ts +9 -0
- package/dist/ContextMenu/Container.vue +38 -0
- package/dist/ContextMenu/Container.vue.d.ts +9 -0
- package/dist/DataTable/Container.d.vue.ts +68 -0
- package/dist/DataTable/Container.vue +295 -0
- package/dist/DataTable/Container.vue.d.ts +68 -0
- package/dist/Dialog/Container.d.vue.ts +64 -0
- package/dist/Dialog/Container.vue +89 -0
- package/dist/Dialog/Container.vue.d.ts +64 -0
- package/dist/HttpqlInput/Container.d.vue.ts +33 -0
- package/dist/HttpqlInput/Container.vue +225 -0
- package/dist/HttpqlInput/Container.vue.d.ts +33 -0
- package/dist/HttpqlInput/suggestions.d.ts +24 -0
- package/dist/HttpqlInput/suggestions.js +325 -0
- package/dist/Menu/Container.d.vue.ts +11 -0
- package/dist/Menu/Container.vue +40 -0
- package/dist/Menu/Container.vue.d.ts +11 -0
- package/dist/MenuButton/Container.d.vue.ts +43 -0
- package/dist/MenuButton/Container.vue +42 -0
- package/dist/MenuButton/Container.vue.d.ts +43 -0
- package/dist/MultiSelect/Container.d.vue.ts +54 -0
- package/dist/MultiSelect/Container.vue +57 -0
- package/dist/MultiSelect/Container.vue.d.ts +54 -0
- package/dist/RequestEditor/Container.d.vue.ts +30 -0
- package/dist/RequestEditor/Container.vue +67 -0
- package/dist/RequestEditor/Container.vue.d.ts +30 -0
- package/dist/ResponseEditor/Container.d.vue.ts +30 -0
- package/dist/ResponseEditor/Container.vue +67 -0
- package/dist/ResponseEditor/Container.vue.d.ts +30 -0
- package/dist/Table/Container.d.vue.ts +36 -0
- package/dist/Table/Container.vue +512 -0
- package/dist/Table/Container.vue.d.ts +36 -0
- package/dist/env.d.ts +5 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +12 -0
- package/package.json +32 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
type Option = {
|
|
2
|
+
label: string;
|
|
3
|
+
value: string;
|
|
4
|
+
};
|
|
5
|
+
type __VLS_Props = {
|
|
6
|
+
modelValue: string;
|
|
7
|
+
options: Option[];
|
|
8
|
+
size?: "small" | "large" | undefined;
|
|
9
|
+
};
|
|
10
|
+
declare const _default: import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
|
|
11
|
+
size: string;
|
|
12
|
+
}>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
|
|
13
|
+
size: string;
|
|
14
|
+
}>>>, {
|
|
15
|
+
size: "small" | "large";
|
|
16
|
+
}, {}>;
|
|
17
|
+
export default _default;
|
|
18
|
+
type __VLS_WithDefaults<P, D> = {
|
|
19
|
+
[K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_PrettifyLocal<P[K] & {
|
|
20
|
+
default: D[K];
|
|
21
|
+
}> : P[K];
|
|
22
|
+
};
|
|
23
|
+
type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
|
|
24
|
+
type __VLS_TypePropsToOption<T> = {
|
|
25
|
+
[K in keyof T]-?: {} extends Pick<T, K> ? {
|
|
26
|
+
type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
|
|
27
|
+
} : {
|
|
28
|
+
type: import('vue').PropType<T[K]>;
|
|
29
|
+
required: true;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
type __VLS_PrettifyLocal<T> = {
|
|
33
|
+
[K in keyof T]: T[K];
|
|
34
|
+
} & {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import SelectButton from "primevue/selectbutton";
|
|
3
|
+
|
|
4
|
+
type Option = {
|
|
5
|
+
label: string;
|
|
6
|
+
value: string;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
withDefaults(
|
|
10
|
+
defineProps<{
|
|
11
|
+
modelValue: string;
|
|
12
|
+
options: Option[];
|
|
13
|
+
size?: "small" | "large" | undefined;
|
|
14
|
+
}>(),
|
|
15
|
+
{
|
|
16
|
+
size: "small",
|
|
17
|
+
},
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
const emit = defineEmits<{
|
|
21
|
+
"update:modelValue": [value: string];
|
|
22
|
+
}>();
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<template>
|
|
26
|
+
<SelectButton
|
|
27
|
+
:modelValue="modelValue"
|
|
28
|
+
:options="options"
|
|
29
|
+
optionLabel="label"
|
|
30
|
+
optionValue="value"
|
|
31
|
+
:allowEmpty="false"
|
|
32
|
+
:size="size"
|
|
33
|
+
class="text-xs"
|
|
34
|
+
@update:modelValue="emit('update:modelValue', $event)"
|
|
35
|
+
/>
|
|
36
|
+
</template>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
type Option = {
|
|
2
|
+
label: string;
|
|
3
|
+
value: string;
|
|
4
|
+
};
|
|
5
|
+
type __VLS_Props = {
|
|
6
|
+
modelValue: string;
|
|
7
|
+
options: Option[];
|
|
8
|
+
size?: "small" | "large" | undefined;
|
|
9
|
+
};
|
|
10
|
+
declare const _default: import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
|
|
11
|
+
size: string;
|
|
12
|
+
}>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
|
|
13
|
+
size: string;
|
|
14
|
+
}>>>, {
|
|
15
|
+
size: "small" | "large";
|
|
16
|
+
}, {}>;
|
|
17
|
+
export default _default;
|
|
18
|
+
type __VLS_WithDefaults<P, D> = {
|
|
19
|
+
[K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_PrettifyLocal<P[K] & {
|
|
20
|
+
default: D[K];
|
|
21
|
+
}> : P[K];
|
|
22
|
+
};
|
|
23
|
+
type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
|
|
24
|
+
type __VLS_TypePropsToOption<T> = {
|
|
25
|
+
[K in keyof T]-?: {} extends Pick<T, K> ? {
|
|
26
|
+
type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
|
|
27
|
+
} : {
|
|
28
|
+
type: import('vue').PropType<T[K]>;
|
|
29
|
+
required: true;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
type __VLS_PrettifyLocal<T> = {
|
|
33
|
+
[K in keyof T]: T[K];
|
|
34
|
+
} & {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
declare var __VLS_7: any, __VLS_8: any;
|
|
2
|
+
type __VLS_Slots = {} & {
|
|
3
|
+
[K in NonNullable<typeof __VLS_7>]?: (props: typeof __VLS_8) => any;
|
|
4
|
+
};
|
|
5
|
+
declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
|
|
6
|
+
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
7
|
+
export default _default;
|
|
8
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
9
|
+
new (): {
|
|
10
|
+
$slots: S;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import PrimeCard from "primevue/card";
|
|
3
|
+
|
|
4
|
+
defineOptions({
|
|
5
|
+
inheritAttrs: false,
|
|
6
|
+
});
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<PrimeCard
|
|
11
|
+
v-bind="$attrs"
|
|
12
|
+
:pt="{
|
|
13
|
+
body: { class: 'h-full p-0' },
|
|
14
|
+
content: { class: 'h-full flex flex-col' },
|
|
15
|
+
}"
|
|
16
|
+
>
|
|
17
|
+
<template v-for="(_, slot) in $slots" #[slot]="scope">
|
|
18
|
+
<slot :name="slot" v-bind="scope || {}" />
|
|
19
|
+
</template>
|
|
20
|
+
</PrimeCard>
|
|
21
|
+
</template>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
declare var __VLS_7: any, __VLS_8: any;
|
|
2
|
+
type __VLS_Slots = {} & {
|
|
3
|
+
[K in NonNullable<typeof __VLS_7>]?: (props: typeof __VLS_8) => any;
|
|
4
|
+
};
|
|
5
|
+
declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
|
|
6
|
+
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
7
|
+
export default _default;
|
|
8
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
9
|
+
new (): {
|
|
10
|
+
$slots: S;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
declare function show(event: MouseEvent): void;
|
|
2
|
+
declare function hide(): void;
|
|
3
|
+
declare function toggle(event: MouseEvent): void;
|
|
4
|
+
declare const _default: import("vue").DefineComponent<{}, {
|
|
5
|
+
show: typeof show;
|
|
6
|
+
hide: typeof hide;
|
|
7
|
+
toggle: typeof toggle;
|
|
8
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
|
|
9
|
+
export default _default;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import ContextMenu from "primevue/contextmenu";
|
|
3
|
+
import type { MenuItem } from "primevue/menuitem";
|
|
4
|
+
import { ref } from "vue";
|
|
5
|
+
|
|
6
|
+
defineProps<{
|
|
7
|
+
items: MenuItem[];
|
|
8
|
+
}>();
|
|
9
|
+
|
|
10
|
+
const menuRef = ref();
|
|
11
|
+
|
|
12
|
+
function show(event: MouseEvent) {
|
|
13
|
+
menuRef.value?.show(event);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function hide() {
|
|
17
|
+
menuRef.value?.hide();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function toggle(event: MouseEvent) {
|
|
21
|
+
menuRef.value?.toggle(event);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
defineExpose({ show, hide, toggle });
|
|
25
|
+
|
|
26
|
+
const menuPt = {
|
|
27
|
+
itemContent: { class: "!bg-transparent hover:!bg-surface-700" },
|
|
28
|
+
};
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<template>
|
|
32
|
+
<ContextMenu
|
|
33
|
+
ref="menuRef"
|
|
34
|
+
:model="items"
|
|
35
|
+
class="border border-surface-600 shadow-lg text-sm"
|
|
36
|
+
:pt="menuPt"
|
|
37
|
+
/>
|
|
38
|
+
</template>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
declare function show(event: MouseEvent): void;
|
|
2
|
+
declare function hide(): void;
|
|
3
|
+
declare function toggle(event: MouseEvent): void;
|
|
4
|
+
declare const _default: import("vue").DefineComponent<{}, {
|
|
5
|
+
show: typeof show;
|
|
6
|
+
hide: typeof hide;
|
|
7
|
+
toggle: typeof toggle;
|
|
8
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
|
|
9
|
+
export default _default;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
declare const _default: __VLS_WithSlots<import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToOption<{
|
|
2
|
+
items: Record<string, unknown>[];
|
|
3
|
+
columns: {
|
|
4
|
+
field: string;
|
|
5
|
+
header: string;
|
|
6
|
+
sortable?: boolean;
|
|
7
|
+
}[];
|
|
8
|
+
rowHeight?: number;
|
|
9
|
+
selectable?: boolean | "single" | "multiple";
|
|
10
|
+
selection?: Record<string, unknown>[] | null;
|
|
11
|
+
activeRow?: Record<string, unknown> | null;
|
|
12
|
+
scrollKey?: string;
|
|
13
|
+
}>, {
|
|
14
|
+
rowHeight: number;
|
|
15
|
+
selectable: boolean;
|
|
16
|
+
selection: () => never[];
|
|
17
|
+
activeRow: null;
|
|
18
|
+
}>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<{
|
|
19
|
+
items: Record<string, unknown>[];
|
|
20
|
+
columns: {
|
|
21
|
+
field: string;
|
|
22
|
+
header: string;
|
|
23
|
+
sortable?: boolean;
|
|
24
|
+
}[];
|
|
25
|
+
rowHeight?: number;
|
|
26
|
+
selectable?: boolean | "single" | "multiple";
|
|
27
|
+
selection?: Record<string, unknown>[] | null;
|
|
28
|
+
activeRow?: Record<string, unknown> | null;
|
|
29
|
+
scrollKey?: string;
|
|
30
|
+
}>, {
|
|
31
|
+
rowHeight: number;
|
|
32
|
+
selectable: boolean;
|
|
33
|
+
selection: () => never[];
|
|
34
|
+
activeRow: null;
|
|
35
|
+
}>>>, {
|
|
36
|
+
rowHeight: number;
|
|
37
|
+
selectable: boolean | "single" | "multiple";
|
|
38
|
+
selection: Record<string, unknown>[] | null;
|
|
39
|
+
activeRow: Record<string, unknown> | null;
|
|
40
|
+
}, {}>, {
|
|
41
|
+
[x: string]: ((props: {
|
|
42
|
+
item: any;
|
|
43
|
+
value: any;
|
|
44
|
+
}) => any) | undefined;
|
|
45
|
+
}>;
|
|
46
|
+
export default _default;
|
|
47
|
+
type __VLS_WithDefaults<P, D> = {
|
|
48
|
+
[K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_PrettifyLocal<P[K] & {
|
|
49
|
+
default: D[K];
|
|
50
|
+
}> : P[K];
|
|
51
|
+
};
|
|
52
|
+
type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
|
|
53
|
+
type __VLS_TypePropsToOption<T> = {
|
|
54
|
+
[K in keyof T]-?: {} extends Pick<T, K> ? {
|
|
55
|
+
type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
|
|
56
|
+
} : {
|
|
57
|
+
type: import('vue').PropType<T[K]>;
|
|
58
|
+
required: true;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
62
|
+
new (): {
|
|
63
|
+
$slots: S;
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
type __VLS_PrettifyLocal<T> = {
|
|
67
|
+
[K in keyof T]: T[K];
|
|
68
|
+
} & {};
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
const scrollMemory = new Map<string, number>();
|
|
3
|
+
const ROW_HEIGHT = 33;
|
|
4
|
+
</script>
|
|
5
|
+
|
|
6
|
+
<script setup lang="ts">
|
|
7
|
+
import DataTable from "primevue/datatable";
|
|
8
|
+
import Column from "primevue/column";
|
|
9
|
+
import Checkbox from "primevue/checkbox";
|
|
10
|
+
import {
|
|
11
|
+
ref,
|
|
12
|
+
computed,
|
|
13
|
+
nextTick,
|
|
14
|
+
onMounted,
|
|
15
|
+
onBeforeUnmount,
|
|
16
|
+
watch,
|
|
17
|
+
useAttrs,
|
|
18
|
+
} from "vue";
|
|
19
|
+
|
|
20
|
+
type ColumnDef = {
|
|
21
|
+
field: string;
|
|
22
|
+
header: string;
|
|
23
|
+
sortable?: boolean;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const props = withDefaults(
|
|
27
|
+
defineProps<{
|
|
28
|
+
items: Record<string, unknown>[];
|
|
29
|
+
columns: ColumnDef[];
|
|
30
|
+
rowHeight?: number;
|
|
31
|
+
selectable?: boolean | "single" | "multiple";
|
|
32
|
+
selection?: Record<string, unknown>[] | null;
|
|
33
|
+
activeRow?: Record<string, unknown> | null;
|
|
34
|
+
scrollKey?: string;
|
|
35
|
+
}>(),
|
|
36
|
+
{
|
|
37
|
+
rowHeight: ROW_HEIGHT,
|
|
38
|
+
selectable: false,
|
|
39
|
+
selection: () => [],
|
|
40
|
+
activeRow: null,
|
|
41
|
+
},
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const emit = defineEmits<{
|
|
45
|
+
"update:selection": [value: Record<string, unknown>[]];
|
|
46
|
+
"update:activeRow": [value: Record<string, unknown> | null];
|
|
47
|
+
"row-select": [event: { data: Record<string, unknown> }];
|
|
48
|
+
"row-unselect": [event: { data: Record<string, unknown> }];
|
|
49
|
+
"row-click": [event: { data: Record<string, unknown> }];
|
|
50
|
+
}>();
|
|
51
|
+
|
|
52
|
+
defineOptions({
|
|
53
|
+
inheritAttrs: false,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const containerRef = ref<HTMLElement>();
|
|
57
|
+
const tableKey = ref(0);
|
|
58
|
+
let resizeObserver: ResizeObserver | undefined;
|
|
59
|
+
|
|
60
|
+
onMounted(() => {
|
|
61
|
+
if (!containerRef.value) return;
|
|
62
|
+
resizeObserver = new ResizeObserver((entries) => {
|
|
63
|
+
if (entries[0] && entries[0].contentRect.height > 0) {
|
|
64
|
+
tableKey.value++;
|
|
65
|
+
resizeObserver?.disconnect();
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
resizeObserver.observe(containerRef.value);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
function getScrollElement(): HTMLElement | undefined {
|
|
72
|
+
if (!containerRef.value) return undefined;
|
|
73
|
+
return (
|
|
74
|
+
containerRef.value.querySelector<HTMLElement>(".p-virtualscroller") ??
|
|
75
|
+
containerRef.value.querySelector<HTMLElement>(
|
|
76
|
+
"[data-pc-section='tablecontainer']",
|
|
77
|
+
) ??
|
|
78
|
+
undefined
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function onScroll(e: Event) {
|
|
83
|
+
if (!props.scrollKey) return;
|
|
84
|
+
const target = e.target as HTMLElement;
|
|
85
|
+
scrollMemory.set(props.scrollKey, target.scrollTop);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function attachScrollListener() {
|
|
89
|
+
const el = getScrollElement();
|
|
90
|
+
el?.addEventListener("scroll", onScroll, { passive: true });
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function detachScrollListener() {
|
|
94
|
+
const el = getScrollElement();
|
|
95
|
+
el?.removeEventListener("scroll", onScroll);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function restoreScrollPosition() {
|
|
99
|
+
if (!props.scrollKey) return;
|
|
100
|
+
const saved = scrollMemory.get(props.scrollKey);
|
|
101
|
+
if (saved === undefined || saved <= 0) return;
|
|
102
|
+
const el = getScrollElement();
|
|
103
|
+
if (el) {
|
|
104
|
+
el.scrollTop = saved;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
watch(tableKey, async () => {
|
|
109
|
+
await nextTick();
|
|
110
|
+
attachScrollListener();
|
|
111
|
+
restoreScrollPosition();
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
onBeforeUnmount(() => {
|
|
115
|
+
detachScrollListener();
|
|
116
|
+
resizeObserver?.disconnect();
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const isMultiple = props.selectable === "multiple";
|
|
120
|
+
|
|
121
|
+
const attrs = useAttrs();
|
|
122
|
+
const dataKeyAttr = (attrs["dataKey"] as string) ?? "id";
|
|
123
|
+
|
|
124
|
+
function getRowKey(row: Record<string, unknown>): unknown {
|
|
125
|
+
return row[dataKeyAttr];
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// --- Selection logic ---
|
|
129
|
+
|
|
130
|
+
const selectionKeys = computed(() => {
|
|
131
|
+
const keys = new Set<unknown>();
|
|
132
|
+
if (Array.isArray(props.selection)) {
|
|
133
|
+
for (const row of props.selection) {
|
|
134
|
+
keys.add(getRowKey(row));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return keys;
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
function isRowSelected(row: Record<string, unknown>): boolean {
|
|
141
|
+
return selectionKeys.value.has(getRowKey(row));
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const allSelected = computed(() => {
|
|
145
|
+
return (
|
|
146
|
+
props.items.length > 0 && selectionKeys.value.size === props.items.length
|
|
147
|
+
);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
function toggleRow(row: Record<string, unknown>) {
|
|
151
|
+
const sel = Array.isArray(props.selection) ? [...props.selection] : [];
|
|
152
|
+
const key = getRowKey(row);
|
|
153
|
+
const idx = sel.findIndex((r) => getRowKey(r) === key);
|
|
154
|
+
if (idx >= 0) {
|
|
155
|
+
sel.splice(idx, 1);
|
|
156
|
+
emit("update:selection", sel);
|
|
157
|
+
emit("row-unselect", { data: row });
|
|
158
|
+
} else {
|
|
159
|
+
sel.push(row);
|
|
160
|
+
emit("update:selection", sel);
|
|
161
|
+
emit("row-select", { data: row });
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function toggleAll() {
|
|
166
|
+
if (allSelected.value) {
|
|
167
|
+
emit("update:selection", []);
|
|
168
|
+
} else {
|
|
169
|
+
emit("update:selection", [...props.items]);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function isCheckboxClick(e: Event): boolean {
|
|
174
|
+
const target = e.target as HTMLElement;
|
|
175
|
+
return !!target.closest("[data-pc-name='checkbox']");
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function onRowClick(event: {
|
|
179
|
+
originalEvent: Event;
|
|
180
|
+
data: Record<string, unknown>;
|
|
181
|
+
}) {
|
|
182
|
+
if (!props.selectable) return;
|
|
183
|
+
if (isMultiple && isCheckboxClick(event.originalEvent)) return;
|
|
184
|
+
emit("row-click", event);
|
|
185
|
+
|
|
186
|
+
if (isMultiple && selectionKeys.value.size > 0) {
|
|
187
|
+
// Multi mode with active checkboxes: toggle row
|
|
188
|
+
toggleRow(event.data);
|
|
189
|
+
} else {
|
|
190
|
+
// Single highlight
|
|
191
|
+
emit("update:activeRow", event.data);
|
|
192
|
+
emit("row-select", event);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// --- Styling ---
|
|
197
|
+
|
|
198
|
+
const ACTIVE_CLASS = "!bg-white/25 !text-inherit hover:!bg-white/30";
|
|
199
|
+
|
|
200
|
+
function activeRowClass(data: Record<string, unknown>): string {
|
|
201
|
+
const key = getRowKey(data);
|
|
202
|
+
|
|
203
|
+
if (props.activeRow && key === getRowKey(props.activeRow)) {
|
|
204
|
+
return ACTIVE_CLASS;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (isMultiple && selectionKeys.value.has(key)) {
|
|
208
|
+
return ACTIVE_CLASS;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return "";
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const tablePt = {};
|
|
215
|
+
|
|
216
|
+
const tablePtOptions = {
|
|
217
|
+
mergeSections: true,
|
|
218
|
+
mergeProps: true,
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
const columnPt = {
|
|
222
|
+
headerCell: {
|
|
223
|
+
class:
|
|
224
|
+
"px-2.5 py-1.5 font-mono text-sm font-semibold !bg-transparent !text-inherit !border-surface-700/50 !border-t-0 !border-b-0",
|
|
225
|
+
},
|
|
226
|
+
sort: {
|
|
227
|
+
class: "!text-inherit",
|
|
228
|
+
},
|
|
229
|
+
bodyCell: {
|
|
230
|
+
class:
|
|
231
|
+
"px-2.5 py-1.5 font-mono text-[13px] font-medium overflow-hidden text-ellipsis whitespace-nowrap !border-surface-700/50",
|
|
232
|
+
},
|
|
233
|
+
};
|
|
234
|
+
</script>
|
|
235
|
+
|
|
236
|
+
<template>
|
|
237
|
+
<div ref="containerRef" class="h-full min-h-0">
|
|
238
|
+
<DataTable
|
|
239
|
+
:key="tableKey"
|
|
240
|
+
:value="items"
|
|
241
|
+
scrollable
|
|
242
|
+
scrollHeight="flex"
|
|
243
|
+
size="small"
|
|
244
|
+
stripedRows
|
|
245
|
+
:virtualScrollerOptions="{ itemSize: props.rowHeight }"
|
|
246
|
+
resizableColumns
|
|
247
|
+
columnResizeMode="fit"
|
|
248
|
+
rowHover
|
|
249
|
+
:rowClass="activeRowClass"
|
|
250
|
+
:pt="tablePt"
|
|
251
|
+
:ptOptions="tablePtOptions"
|
|
252
|
+
@row-click="onRowClick($event)"
|
|
253
|
+
v-bind="$attrs"
|
|
254
|
+
>
|
|
255
|
+
<Column v-if="isMultiple" headerStyle="width: 3rem" :pt="columnPt">
|
|
256
|
+
<template #header>
|
|
257
|
+
<Checkbox :modelValue="allSelected" binary @change="toggleAll" />
|
|
258
|
+
</template>
|
|
259
|
+
<template #body="{ data }">
|
|
260
|
+
<Checkbox
|
|
261
|
+
:modelValue="isRowSelected(data)"
|
|
262
|
+
binary
|
|
263
|
+
@change="toggleRow(data)"
|
|
264
|
+
/>
|
|
265
|
+
</template>
|
|
266
|
+
</Column>
|
|
267
|
+
<Column
|
|
268
|
+
v-for="col in columns"
|
|
269
|
+
:key="col.field"
|
|
270
|
+
:field="col.field"
|
|
271
|
+
:header="col.header"
|
|
272
|
+
:sortable="col.sortable"
|
|
273
|
+
:style="{ height: `${props.rowHeight}px` }"
|
|
274
|
+
:pt="columnPt"
|
|
275
|
+
>
|
|
276
|
+
<template v-if="col.sortable" #sorticon="{ sorted, sortOrder }">
|
|
277
|
+
<i
|
|
278
|
+
v-if="sorted"
|
|
279
|
+
:class="[
|
|
280
|
+
'fas text-[9px]',
|
|
281
|
+
sortOrder === 1 ? 'fa-chevron-up' : 'fa-chevron-down',
|
|
282
|
+
]"
|
|
283
|
+
/>
|
|
284
|
+
</template>
|
|
285
|
+
<template v-if="$slots[`cell-${col.field}`]" #body="{ data }">
|
|
286
|
+
<slot
|
|
287
|
+
:name="`cell-${col.field}`"
|
|
288
|
+
:item="data"
|
|
289
|
+
:value="data[col.field]"
|
|
290
|
+
/>
|
|
291
|
+
</template>
|
|
292
|
+
</Column>
|
|
293
|
+
</DataTable>
|
|
294
|
+
</div>
|
|
295
|
+
</template>
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
declare const _default: __VLS_WithSlots<import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToOption<{
|
|
2
|
+
items: Record<string, unknown>[];
|
|
3
|
+
columns: {
|
|
4
|
+
field: string;
|
|
5
|
+
header: string;
|
|
6
|
+
sortable?: boolean;
|
|
7
|
+
}[];
|
|
8
|
+
rowHeight?: number;
|
|
9
|
+
selectable?: boolean | "single" | "multiple";
|
|
10
|
+
selection?: Record<string, unknown>[] | null;
|
|
11
|
+
activeRow?: Record<string, unknown> | null;
|
|
12
|
+
scrollKey?: string;
|
|
13
|
+
}>, {
|
|
14
|
+
rowHeight: number;
|
|
15
|
+
selectable: boolean;
|
|
16
|
+
selection: () => never[];
|
|
17
|
+
activeRow: null;
|
|
18
|
+
}>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<{
|
|
19
|
+
items: Record<string, unknown>[];
|
|
20
|
+
columns: {
|
|
21
|
+
field: string;
|
|
22
|
+
header: string;
|
|
23
|
+
sortable?: boolean;
|
|
24
|
+
}[];
|
|
25
|
+
rowHeight?: number;
|
|
26
|
+
selectable?: boolean | "single" | "multiple";
|
|
27
|
+
selection?: Record<string, unknown>[] | null;
|
|
28
|
+
activeRow?: Record<string, unknown> | null;
|
|
29
|
+
scrollKey?: string;
|
|
30
|
+
}>, {
|
|
31
|
+
rowHeight: number;
|
|
32
|
+
selectable: boolean;
|
|
33
|
+
selection: () => never[];
|
|
34
|
+
activeRow: null;
|
|
35
|
+
}>>>, {
|
|
36
|
+
rowHeight: number;
|
|
37
|
+
selectable: boolean | "single" | "multiple";
|
|
38
|
+
selection: Record<string, unknown>[] | null;
|
|
39
|
+
activeRow: Record<string, unknown> | null;
|
|
40
|
+
}, {}>, {
|
|
41
|
+
[x: string]: ((props: {
|
|
42
|
+
item: any;
|
|
43
|
+
value: any;
|
|
44
|
+
}) => any) | undefined;
|
|
45
|
+
}>;
|
|
46
|
+
export default _default;
|
|
47
|
+
type __VLS_WithDefaults<P, D> = {
|
|
48
|
+
[K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_PrettifyLocal<P[K] & {
|
|
49
|
+
default: D[K];
|
|
50
|
+
}> : P[K];
|
|
51
|
+
};
|
|
52
|
+
type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
|
|
53
|
+
type __VLS_TypePropsToOption<T> = {
|
|
54
|
+
[K in keyof T]-?: {} extends Pick<T, K> ? {
|
|
55
|
+
type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
|
|
56
|
+
} : {
|
|
57
|
+
type: import('vue').PropType<T[K]>;
|
|
58
|
+
required: true;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
62
|
+
new (): {
|
|
63
|
+
$slots: S;
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
type __VLS_PrettifyLocal<T> = {
|
|
67
|
+
[K in keyof T]: T[K];
|
|
68
|
+
} & {};
|