-
-
Notifications
You must be signed in to change notification settings - Fork 18
/
ScrollViewComponent.svelte
114 lines (107 loc) · 2.43 KB
/
ScrollViewComponent.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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<script lang="ts">
import { writable, type Writable } from "svelte/store";
import { type ScrollViewFile, type ScrollViewState } from "types";
import { renderSpecialTag, trimTrailingSlash } from "./util";
import ScrollViewMarkdown from "ScrollViewMarkdownComponent.svelte";
import { onDestroy } from "svelte";
import type TagFolderPlugin from "main";
interface Props {
store?: Writable<ScrollViewState>;
openfile: (path: string, specialKey: boolean) => void;
plugin: TagFolderPlugin;
}
let {
store = writable<ScrollViewState>({
files: [],
title: "",
tagPath: "",
}),
openfile,
plugin,
}: Props = $props();
const _state: ScrollViewState = $derived($store);
let files = $derived(_state.files);
const tagPath = $derived(
_state.tagPath
.split(", ")
.map(
(e) =>
"#" +
trimTrailingSlash(e)
.split("/")
.map((e) => renderSpecialTag(e.trim()))
.join("/"),
)
.join(", "),
);
function handleOpenFile(e: MouseEvent, file: ScrollViewFile) {
openfile(file.path, false);
e.preventDefault();
}
// Observe appearing and notify the component that you should render the content.
let scrollEl = $state<HTMLElement>();
let observer = $state<IntersectionObserver>();
const onAppearing = new CustomEvent("appearing", {
detail: {},
});
$effect(() => {
const options = {
root: scrollEl,
rootMargin: "10px",
threshold: 0,
};
observer = new IntersectionObserver(
(entries: IntersectionObserverEntry[]) => {
for (const entry of entries) {
if (entry.isIntersecting) {
entry.target.dispatchEvent(onAppearing);
}
}
},
options,
);
});
onDestroy(() => {
observer?.disconnect();
});
</script>
<div class="x">
<div class="header">
Files with {tagPath}
</div>
<hr />
{#each files as file}
<!-- svelte-ignore a11y_click_events_have_key_events -->
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div
class="file"
onclick={(evt) => handleOpenFile(evt, file)}
bind:this={scrollEl}
>
<div class="header">
<span>{file.title}</span>
<span class="path">({file.path})</span>
</div>
<ScrollViewMarkdown {file} {observer} {plugin} />
<hr />
</div>
{/each}
</div>
<style>
.header {
background-color: var(--background-secondary-alt);
position: sticky;
top: 0;
color: var(--text-normal);
margin-bottom: 8px;
}
.file {
cursor: pointer;
}
.path {
font-size: 75%;
}
hr {
margin: 8px auto;
}
</style>