Files
simrsx-fe/app/components/pub/base/select-tree/tree-select.vue
Khafid Prayoga c5ec8ccd32 fix(select-tree): adjust tree node indentation and alignment logic
- Add level prop to track node hierarchy
- Fix indentation calculation for leaves and nodes
- Simplify alignment logic based on node level
2025-09-16 15:14:37 +07:00

70 lines
2.0 KiB
Vue

<script setup lang="ts">
import type { TreeItem } from './type'
import { ChevronsUpDown } from 'lucide-vue-next'
import { cn } from '~/lib/utils'
import TreeView from './tree-view.vue'
const props = defineProps<{
data: TreeItem[]
onFetchChildren: (parentId: string) => Promise<void>
}>()
const modelValue = defineModel<string>()
const open = ref(false)
function handleSelect(newVal: string) {
modelValue.value = newVal
open.value = false
}
function findLabel(value: string, items: TreeItem[]): string | undefined {
for (const item of items) {
if (item.value === value) return item.label
if (item.children) {
const found = findLabel(value, item.children)
if (found) return found
}
}
}
const selectedLabel = computed(() => {
return modelValue.value ? findLabel(modelValue.value, props.data) : '--- select item'
})
</script>
<template>
<Popover v-model:open="open">
<PopoverTrigger as-child>
<Button variant="outline" role="combobox" class="w-full justify-between bg-white border-1 border-gray-400">
<span
class="font-normal text-muted-foreground" :class="cn(
'font-normal',
!modelValue && 'text-muted-foreground',
modelValue && 'text-black',
)"
>
{{ selectedLabel }}
</span>
<ChevronsUpDown class="w-4 h-4 ml-2 opacity-50 shrink-0" />
</Button>
</PopoverTrigger>
<PopoverContent class="min-w-full max-w-[350px] p-0">
<Command>
<CommandInput placeholder="Cari item..." />
<CommandEmpty>Item tidak ditemukan.</CommandEmpty>
<CommandList class="max-h-[300px] overflow-x-auto overflow-y-auto">
<CommandGroup>
<TreeView
:data="data"
:selected-value="modelValue"
:on-fetch-children="onFetchChildren"
:level="0"
@select="handleSelect"
/>
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
</template>