Skip to content

Commit

Permalink
fix: add recursive component to handle nested category tree
Browse files Browse the repository at this point in the history
Signed-off-by: Robert Goniszewski <robertgoniszewski@outlook.com>
  • Loading branch information
goniszewski committed Apr 3, 2024
1 parent a2d79f6 commit 85abb8c
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 27 deletions.
24 changes: 8 additions & 16 deletions src/lib/components/CategoryTree/CategoryTree.svelte
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
<script lang="ts">
import Icon from '$lib/components/Icon/Icon.svelte';
import type { Category } from '$lib/types/Category.type';
import CategoryTreeItem from '../CategoryTreeItem/CategoryTreeItem.svelte';
export let categories: (Category & { children?: Category[] })[] | [] = [];
// CategoryWithChildren type is a recursive type that includes the children property
type CategoryWithChildren = Category & { children?: CategoryWithChildren[] };
export let categories: CategoryWithChildren[] | [] = [];
</script>

{#each categories as category (category.id)}
<div class="flex flex-col">
<div class="flex items-center">
{#if !category.icon}
<div
class="w-4 h-4 my-auto rounded-full"
class="my-auto h-4 w-4 rounded-full"
style={`background-color: ${category?.color || '#a0a0a0'};`}
/>
{:else}
Expand All @@ -22,20 +26,8 @@
</div>

{#if category.children}
{#each category.children as categoryChild (categoryChild.id)}
<div class="flex items-center ml-4">
{#if !categoryChild.icon}
<div
class="w-4 h-4 my-auto rounded-full"
style={`background-color: ${categoryChild?.color || '#a0a0a0'};`}
/>
{:else}
<Icon name={categoryChild.icon} size={16} color={categoryChild?.color} />
{/if}
<a href={`/categories/${categoryChild.slug}`} class="link m-1 hover:text-primary"
>{categoryChild.name}</a
>
</div>
{#each category.children as child (child.id)}
<CategoryTreeItem children={category.children} {...child} />
{/each}
{/if}
</div>
Expand Down
24 changes: 24 additions & 0 deletions src/lib/components/CategoryTreeItem/CategoryTreeItem.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<script lang="ts">
import type { Category } from '$lib/types/Category.type';
import Icon from '../Icon/Icon.svelte';
export let nestedTimes = 0;
export let children = [] as Category[];
export let name = '';
export let icon = null as string | null;
export let slug = '';
export let color = '';
</script>

<div class="flex items-center" style={`margin-left: ${nestedTimes + 1}rem;`}>
{#if !icon}
<div class="my-auto h-4 w-4 rounded-full" style={`background-color: ${color || '#a0a0a0'};`} />
{:else}
<Icon name={icon} size={16} {color} />
{/if}
<a href={`/categories/${slug}`} class="link m-1 hover:text-primary">{name}</a>
</div>

{#each children as child}
<svelte:self nestedTimes={nestedTimes + 1} {...child} />
{/each}
13 changes: 13 additions & 0 deletions src/lib/utils/build-category-tree.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { Category } from '$lib/types/Category.type';

export function buildCategoryTree(
categories: Category[],
parent?: Category
): (Category & { children?: Category[] })[] {
return categories
.filter((c) => c.parent?.id === parent?.id)
.map((c) => ({
...c,
children: buildCategoryTree(categories, c)
}));
}
14 changes: 3 additions & 11 deletions src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import { checkPocketbaseConnection, user } from '$lib/pb';
import { searchedValue } from '$lib/stores/search.store';
import type { Category } from '$lib/types/Category.type';
import { buildCategoryTree } from '$lib/utils/build-category-tree';
import { ToastNode, showToast } from '$lib/utils/show-toast';
import { IconMenu, IconX } from '@tabler/icons-svelte';
import { onDestroy, onMount } from 'svelte';
Expand Down Expand Up @@ -44,17 +45,8 @@
$: {
const categories = $page.data.categories;
const categoriesTreeData = categories
.filter((c) => !c.parent)
.map((c) => ({
...c,
children: categories
.filter((c2) => c2.parent?.id === c.id)
.map((c2) => ({
...c2
}))
}));
categoriesTree.set(categoriesTreeData);
categoriesTree.set(buildCategoryTree(categories));
}
</script>

Expand Down

0 comments on commit 85abb8c

Please sign in to comment.