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
This commit is contained in:
Khafid Prayoga
2025-09-16 15:14:37 +07:00
parent b106b1d23e
commit c5ec8ccd32
4 changed files with 18 additions and 12 deletions
@@ -7,14 +7,13 @@ const props = defineProps<{
item: TreeItem
selectedValue?: string
onFetchChildren: (parentId: string) => Promise<void>
level?: number
}>()
const emit = defineEmits(['select'])
// Computed untuk memastikan reactivity pada children
const hasChildren = computed(() => props.item.children && props.item.children.length > 0)
// State terpisah untuk chevron animation dan loading
const isOpen = ref(false)
const isLoading = ref(false)
const isChevronRotated = ref(false)
@@ -27,14 +26,11 @@ function handleLabelClick() {
handleSelect(props.item.value)
}
// Watch untuk handle fetch data ketika collapsible dibuka
watch(isOpen, async (newValue) => {
console.log(`[TreeNode] ${props.item.label} - isOpen changed to:`, newValue)
// Update chevron rotation berdasarkan open state
isChevronRotated.value = newValue
// Jika membuka dan belum ada children, fetch data
if (newValue && props.item.hasChildren && !props.item.children && !isLoading.value) {
console.log(`[TreeNode] Fetching children for: ${props.item.label}`)
isLoading.value = true
@@ -65,9 +61,7 @@ watch(isOpen, async (newValue) => {
variant="ghost"
class="h-4 w-4 p-0 flex items-center justify-center"
>
<!-- Loading State -->
<Loader2 v-if="isLoading" class="w-4 h-4 animate-spin text-muted-foreground" />
<!-- Chevron dengan animasi terpisah -->
<ChevronRight
v-else
class="w-4 h-4 transition-transform duration-200 ease-in-out text-muted-foreground"
@@ -93,7 +87,7 @@ watch(isOpen, async (newValue) => {
</div>
<!-- Children Container -->
<CollapsibleContent class="pl-8">
<CollapsibleContent class="pl-6">
<div v-if="!hasChildren" class="text-sm text-muted-foreground p-2">
{{ isLoading ? 'Memuat...' : 'Tidak ada data' }}
</div>
@@ -102,6 +96,7 @@ watch(isOpen, async (newValue) => {
:data="item.children!"
:selected-value="selectedValue"
:on-fetch-children="onFetchChildren"
:level="(level || 0) + 1"
@select="handleSelect"
/>
</CollapsibleContent>