-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathNode.svelte
More file actions
71 lines (62 loc) · 2.58 KB
/
Copy pathNode.svelte
File metadata and controls
71 lines (62 loc) · 2.58 KB
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
<script lang="ts">
import { getContext } from 'svelte';
import { serialize_path } from './utils.js';
import type {
NodeArrayAttachmentContext,
NodeArrayRenderContext,
NodeProps,
SveditRenderContext
} from './types.js';
const svedit = getContext<SveditRenderContext>('svedit');
let { path, children, tag = 'div', class: css_class, style = '', ...rest }: NodeProps = $props();
let node = $derived(svedit.session.get(path));
let path_str = $derived(serialize_path(path));
const node_array_meta = getContext<NodeArrayRenderContext | undefined>('node_array_meta');
let child_index = $derived(node_array_meta ? (path.at(-1) as number) : -1);
let is_first = $derived(node_array_meta && child_index === 0);
let is_last = $derived(node_array_meta && child_index === node_array_meta.length - 1);
// Marks and annotations covering this node become classes automatically:
// `mark-<type>`/`anno-<type>`, plus `-start`/`-end` variants on the run's
// first/last covered node. This allows styling ranges (including
// annotations, which never render wrapper components) with pure CSS. For
// richer rendering, node components still receive the `mark` and
// `annotations` props.
let range_classes = $derived.by(() => {
if (child_index < 0 || !node_array_meta?.annotations_for) return '';
const classes: string[] = [];
const add_classes = (range: NodeArrayAttachmentContext | null | undefined, prefix: string) => {
const range_type = range?.node?.type;
if (!range_type) return;
classes.push(`${prefix}-${range_type}`);
if (range.is_start) classes.push(`${prefix}-${range_type}-start`);
if (range.is_end) classes.push(`${prefix}-${range_type}-end`);
};
add_classes(node_array_meta.mark_for?.(child_index), 'mark');
for (const annotation of node_array_meta.annotations_for(child_index)) {
add_classes(annotation, 'anno');
}
return classes.join(' ');
});
</script>
<svelte:element
this={tag}
id={node.id}
class="node-{node.type} {css_class}{range_classes ? ` ${range_classes}` : ''}{is_first
? ' first'
: ''}{is_last ? ' last' : ''}"
data-node-id={node.id}
data-path={path_str}
data-type="node"
style="anchor-name: --{path_str};{style}"
{...rest}
{@attach svedit.visibility_registry.track_node(path_str)}
>
{@render children()}
</svelte:element>
<style>
[data-type='node'] {
/** any other position than static will break the anchor positioning of node gaps and node gap-marker */
/* For developers who need to position their node with `position: absolute` or `position: relative`, they need to wrap their node in a div */
position: static !important;
}
</style>