2023-08-21 01:51:35 -04:00
|
|
|
<script setup lang="ts">
|
|
|
|
|
import { computed } from "vue";
|
2023-10-17 16:32:59 -04:00
|
|
|
import TooltippedLabel from "@/components/common/pv-tooltipped-label.vue";
|
2023-08-21 01:51:35 -04:00
|
|
|
|
2025-01-03 18:50:25 -05:00
|
|
|
export interface SelectItem {
|
2023-08-31 16:56:58 -04:00
|
|
|
name: string | number;
|
|
|
|
|
value: string | number;
|
|
|
|
|
disabled?: boolean;
|
2023-08-21 01:51:35 -04:00
|
|
|
}
|
|
|
|
|
|
2023-08-31 16:56:58 -04:00
|
|
|
const props = withDefaults(
|
|
|
|
|
defineProps<{
|
|
|
|
|
label?: string;
|
|
|
|
|
tooltip?: string;
|
|
|
|
|
selectCols?: number;
|
|
|
|
|
// TODO fully update v-model usage in custom components on Vue3 update
|
2025-01-03 18:50:25 -05:00
|
|
|
value: any;
|
2023-08-31 16:56:58 -04:00
|
|
|
disabled?: boolean;
|
|
|
|
|
items: string[] | number[] | SelectItem[];
|
|
|
|
|
}>(),
|
|
|
|
|
{
|
|
|
|
|
selectCols: 9,
|
|
|
|
|
disabled: false
|
|
|
|
|
}
|
|
|
|
|
);
|
2023-08-21 01:51:35 -04:00
|
|
|
|
|
|
|
|
const emit = defineEmits<{
|
2025-01-03 18:50:25 -05:00
|
|
|
(e: "input", value: string): void;
|
2023-08-21 01:51:35 -04:00
|
|
|
}>();
|
|
|
|
|
|
|
|
|
|
const localValue = computed({
|
|
|
|
|
get: () => props.value,
|
2023-08-31 16:56:58 -04:00
|
|
|
set: (v) => emit("input", v)
|
2023-08-21 01:51:35 -04:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Computed in case items changes
|
|
|
|
|
const items = computed<SelectItem[]>(() => {
|
2023-09-01 12:58:35 -07:00
|
|
|
// Trivial case for empty list; we have no data
|
|
|
|
|
if (!props.items.length) {
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-21 01:51:35 -04:00
|
|
|
// Check if the prop exists on the object to infer object type
|
2023-08-31 16:56:58 -04:00
|
|
|
if ((props.items[0] as SelectItem).name) {
|
2023-08-21 01:51:35 -04:00
|
|
|
return props.items as SelectItem[];
|
|
|
|
|
}
|
|
|
|
|
return props.items.map((v, i) => ({ name: v, value: i }));
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
|
2019-09-28 02:17:18 +03:00
|
|
|
<template>
|
2025-01-07 08:45:39 -05:00
|
|
|
<div class="d-flex">
|
|
|
|
|
<v-col :cols="12 - selectCols" class="d-flex align-center pl-0">
|
|
|
|
|
<tooltipped-label :tooltip="tooltip" :label="label" />
|
|
|
|
|
</v-col>
|
|
|
|
|
<v-col :cols="selectCols" class="d-flex align-center pr-0">
|
|
|
|
|
<v-select
|
|
|
|
|
v-model="localValue"
|
|
|
|
|
:items="items"
|
|
|
|
|
item-text="name"
|
|
|
|
|
item-value="value"
|
|
|
|
|
item-disabled="disabled"
|
|
|
|
|
dark
|
|
|
|
|
color="accent"
|
|
|
|
|
item-color="secondary"
|
|
|
|
|
:disabled="disabled"
|
|
|
|
|
hide-details="auto"
|
|
|
|
|
/>
|
|
|
|
|
</v-col>
|
2020-06-26 04:39:14 -07:00
|
|
|
</div>
|
2019-09-28 02:17:18 +03:00
|
|
|
</template>
|
2025-01-08 16:46:31 -05:00
|
|
|
<style scoped>
|
2025-01-07 08:45:39 -05:00
|
|
|
.v-select {
|
|
|
|
|
padding-top: 0px;
|
2025-01-08 16:46:31 -05:00
|
|
|
margin-top: 0px;
|
2025-01-07 08:45:39 -05:00
|
|
|
}
|
|
|
|
|
</style>
|