Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: add recursive component to handle nested category tree #82

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading