Created
May 7, 2025 10:50
-
-
Save vnphanquang/41656c37462a767cf923c596afbbe3b6 to your computer and use it in GitHub Desktop.
Svelte File Tree
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script lang="ts"> | |
import type { Snippet } from 'svelte'; | |
import type { HTMLLiAttributes } from 'svelte/elements'; | |
let { | |
open = $bindable(true), | |
name, | |
iconSpecifier = 'i-[ph--file]', | |
...rest | |
}: HTMLLiAttributes & { | |
/** @bindable */ | |
open?: boolean; | |
name: string | Snippet<[]>; | |
iconSpecifier?: string; | |
} = $props(); | |
</script> | |
<li {...rest}> | |
<i class={['i', iconSpecifier]}></i> | |
<span> | |
{#if typeof name === 'string'} | |
{name} | |
{:else} | |
{@render name?.()} | |
{/if} | |
</span> | |
</li> | |
<style> | |
@layer components { | |
li { | |
align-items: center; | |
display: flex; | |
padding-inline: calc(var(--spacing) * 2); | |
padding-block: calc(var(--spacing) * 1); | |
gap: calc(var(--spacing) * 2); | |
transition-property: background-color, color; | |
transition-duration: 400ms; | |
transition-timing-function: var(--timing-ease-in); | |
&:hover { | |
transition-duration: 200ms; | |
transition-timing-function: var(--timing-ease-out); | |
background-color: var(--color-surface-variant); | |
} | |
&:active { | |
transition-duration: 150ms; | |
background-color: var(--color-on-surface); | |
color: var(--color-surface); | |
} | |
} | |
} | |
i { | |
height: 1.25em; | |
width: 1.25em; | |
} | |
</style> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script lang="ts"> | |
import type { Snippet } from 'svelte'; | |
import type { HTMLLiAttributes } from 'svelte/elements'; | |
let { | |
children, | |
open = $bindable(true), | |
name, | |
iconSpecifier = 'i-[ph--folder]', | |
...rest | |
}: HTMLLiAttributes & { | |
/** @bindable */ | |
open?: boolean; | |
name: string | Snippet<[]>; | |
iconSpecifier?: string; | |
} = $props(); | |
</script> | |
<li {...rest}> | |
<details bind:open> | |
<summary class="outline-hidden cursor-pointer marker:hidden"> | |
<i class={['i icon', iconSpecifier]}></i> | |
<span class="flex-1"> | |
{#if typeof name === 'string'} | |
{name} | |
{:else} | |
{@render name?.()} | |
{/if} | |
</span> | |
<i class="i caret i-[ph--caret-down] transition-transform"></i> | |
</summary> | |
<ul> | |
{@render children?.()} | |
</ul> | |
</details> | |
</li> | |
<style lang="postcss"> | |
@layer components { | |
ul { | |
position: relative; | |
margin-inline-start: calc(var(--spacing) * 2); | |
padding-inline-start: calc(var(--spacing) * 4); | |
&::before { | |
content: ''; | |
background-color: var(--color-outline-subtle); | |
width: 1.5px; | |
inset-inline-start: 0; | |
position: absolute; | |
top: 0.75rem; | |
bottom: 0.75rem; | |
} | |
} | |
summary { | |
align-items: center; | |
display: flex; | |
padding-inline: calc(var(--spacing) * 2); | |
padding-block: calc(var(--spacing) * 1); | |
gap: calc(var(--spacing) * 2); | |
transition-property: background-color, color; | |
transition-duration: 400ms; | |
transition-timing-function: var(--timing-ease-in); | |
&:hover { | |
transition-duration: 200ms; | |
transition-timing-function: var(--timing-ease-out); | |
background-color: var(--color-surface-variant); | |
} | |
&:active { | |
transition-duration: 150ms; | |
background-color: var(--color-on-surface); | |
color: var(--color-surface); | |
} | |
} | |
} | |
.icon { | |
height: 1.25em; | |
width: 1.25em; | |
} | |
.caret { | |
height: 1em; | |
width: 1em; | |
details[open] > summary > & { | |
rotate: 180deg; | |
} | |
} | |
</style> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script lang="ts"> | |
import type { HTMLAttributes } from "svelte/elements"; | |
let { children, ...rest }: HTMLAttributes<HTMLUListElement> = $props(); | |
</script> | |
<ul {...rest}> | |
{@render children?.()} | |
</ul> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import File from './FileTree.File.svelte'; | |
import Folder from './FileTree.Folder.svelte'; | |
import Root from './FileTree.Root.svelte'; | |
export const FileTree = { | |
Root, | |
Folder, | |
File, | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Example Usage: