generated from ryanatkn/fuz_template
-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBreadcrumb.svelte
78 lines (68 loc) · 2.13 KB
/
Breadcrumb.svelte
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
<script lang="ts">
import {parse_path_pieces} from '@ryanatkn/belt/path.js';
import {base} from '$app/paths';
import {page} from '$app/stores';
import type {Snippet} from 'svelte';
import {strip_start, ensure_end} from '@ryanatkn/belt/string.js';
interface Props {
/**
* Prefixed with a slash and relative to the base path.
*/
path?: string | undefined;
/**
* Prefixed with a slash and relative to the base path.
* `null` means none and `undefined` is detected from the current url.
*/
selected_path?: string | null | undefined;
/**
* Sets a custom base path of `path` and `selected_path`.
* Defaults to `base` from `$app/paths`.
*/
base_path?: string;
separator?: Snippet;
children?: Snippet;
}
const {path, selected_path, base_path, separator, children}: Props = $props();
const final_base_path = $derived(base_path ?? base);
const final_path = $derived(path ?? strip_start($page.url.pathname, final_base_path));
const final_selected_path = $derived(
selected_path === null ? null : (selected_path ?? final_path),
);
const path_pieces = $derived(parse_path_pieces(final_path));
const root_path = $derived(ensure_end(final_base_path, '/'));
// TODO animate these
// `transition:slide={{axis: 'x'}}`
</script>
<div class="breadcrumb">
<a href={root_path} class:selected={root_path === final_base_path + final_selected_path}
>{#if children}{@render children()}{:else}•{/if}</a
>{#each path_pieces as path_piece (path_piece)}{#if path_piece.type === 'piece'}<a
href={final_base_path + path_piece.path}
class:selected={path_piece.path === final_selected_path}>{path_piece.name}</a
>{:else}<span class="separator"
>{#if separator}{@render separator()}{:else}/{/if}</span
>{/if}{/each}
</div>
<style>
.breadcrumb {
display: flex;
flex-wrap: wrap;
align-items: center;
font-size: var(--size, var(--size_md));
}
a {
position: relative;
z-index: 1;
padding: 0 calc(var(--size, var(--size_md)) * 0.5);
display: flex;
align-items: center;
}
.separator {
position: relative;
z-index: 0;
display: flex;
justify-content: center;
align-items: center;
width: 0;
}
</style>