@r2digisolutions/components 0.14.20 → 0.14.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
name: string;
|
|
5
5
|
role?: string;
|
|
6
6
|
avatarUrl?: string;
|
|
7
|
+
assignees?: { id: string; name: string; avatarUrl?: string | null }[];
|
|
7
8
|
children?: OrgNode[];
|
|
8
9
|
}
|
|
9
10
|
|
|
@@ -17,6 +18,8 @@
|
|
|
17
18
|
|
|
18
19
|
let selected = $state<string | null>(null);
|
|
19
20
|
|
|
21
|
+
const CARD_W = 176;
|
|
22
|
+
|
|
20
23
|
function initials(name: string) {
|
|
21
24
|
return name
|
|
22
25
|
.split(/\s+/)
|
|
@@ -24,13 +27,22 @@
|
|
|
24
27
|
.map((p) => p[0]?.toUpperCase() ?? '')
|
|
25
28
|
.join('');
|
|
26
29
|
}
|
|
30
|
+
|
|
31
|
+
function primaryAvatar(node: OrgNode) {
|
|
32
|
+
return node.avatarUrl ?? node.assignees?.[0]?.avatarUrl ?? null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function primaryLabel(node: OrgNode) {
|
|
36
|
+
if (node.assignees?.length === 1) return node.assignees[0].name;
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
27
39
|
</script>
|
|
28
40
|
|
|
29
41
|
{#snippet nodeCard(node: OrgNode)}
|
|
30
42
|
<button
|
|
31
43
|
type="button"
|
|
32
44
|
class={[
|
|
33
|
-
'flex
|
|
45
|
+
'flex w-full flex-col items-center gap-1.5 rounded-xl border bg-surface-elevated px-3 py-2.5 text-center shadow-sm transition-all',
|
|
34
46
|
selected === node.id
|
|
35
47
|
? 'border-brand-500 ring-2 ring-brand-500/30'
|
|
36
48
|
: 'border-border hover:border-brand-400'
|
|
@@ -40,8 +52,8 @@
|
|
|
40
52
|
onselect?.(node);
|
|
41
53
|
}}
|
|
42
54
|
>
|
|
43
|
-
{#if node
|
|
44
|
-
<img src={node
|
|
55
|
+
{#if primaryAvatar(node)}
|
|
56
|
+
<img src={primaryAvatar(node)!} alt="" class="h-9 w-9 rounded-full object-cover" />
|
|
45
57
|
{:else}
|
|
46
58
|
<span
|
|
47
59
|
class="flex h-9 w-9 items-center justify-center rounded-full bg-brand-500/15 text-xs font-semibold text-brand-600 dark:text-brand-300"
|
|
@@ -49,42 +61,54 @@
|
|
|
49
61
|
{initials(node.name)}
|
|
50
62
|
</span>
|
|
51
63
|
{/if}
|
|
52
|
-
<span class="
|
|
64
|
+
<span class="line-clamp-2 text-sm leading-snug font-semibold text-primary">{node.name}</span>
|
|
65
|
+
{#if primaryLabel(node)}
|
|
66
|
+
<span class="truncate text-xs text-secondary">{primaryLabel(node)}</span>
|
|
67
|
+
{/if}
|
|
53
68
|
{#if node.role}
|
|
54
69
|
<span class="truncate text-[11px] text-muted">{node.role}</span>
|
|
55
70
|
{/if}
|
|
71
|
+
{#if node.assignees && node.assignees.length > 1}
|
|
72
|
+
<span class="text-[10px] text-muted">+{node.assignees.length - 1} más</span>
|
|
73
|
+
{/if}
|
|
56
74
|
</button>
|
|
57
75
|
{/snippet}
|
|
58
76
|
|
|
59
77
|
{#snippet tree(node: OrgNode)}
|
|
60
|
-
<div class="
|
|
61
|
-
{
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
<div class="
|
|
66
|
-
|
|
78
|
+
<div class="flex flex-col items-center">
|
|
79
|
+
<div class="shrink-0" style:width="{CARD_W}px">
|
|
80
|
+
{@render nodeCard(node)}
|
|
81
|
+
</div>
|
|
82
|
+
{#if node.children?.length}
|
|
83
|
+
<div class="h-6 w-0.5 shrink-0 bg-border-strong" aria-hidden="true"></div>
|
|
84
|
+
{#if node.children.length === 1}
|
|
85
|
+
{@render tree(node.children[0])}
|
|
86
|
+
{:else}
|
|
87
|
+
<div
|
|
88
|
+
class="relative inline-flex items-start justify-center gap-4"
|
|
89
|
+
style:--siblings={node.children.length}
|
|
90
|
+
>
|
|
67
91
|
<div
|
|
68
|
-
class="pointer-events-none absolute
|
|
92
|
+
class="pointer-events-none absolute top-0 h-0.5 bg-border-strong"
|
|
93
|
+
style:left="calc(50% / var(--siblings))"
|
|
94
|
+
style:right="calc(50% / var(--siblings))"
|
|
69
95
|
aria-hidden="true"
|
|
70
96
|
></div>
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
<div class="absolute left-1/2 top-0 h-3 w-px -translate-x-1/2 bg-border" aria-hidden="true"></div>
|
|
75
|
-
<div class="pt-3">
|
|
97
|
+
{#each node.children as child (child.id)}
|
|
98
|
+
<div class="flex shrink-0 flex-col items-center" style:min-width="{CARD_W}px">
|
|
99
|
+
<div class="h-4 w-0.5 shrink-0 bg-border-strong" aria-hidden="true"></div>
|
|
76
100
|
{@render tree(child)}
|
|
77
101
|
</div>
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
102
|
+
{/each}
|
|
103
|
+
</div>
|
|
104
|
+
{/if}
|
|
81
105
|
{/if}
|
|
82
106
|
</div>
|
|
83
107
|
{/snippet}
|
|
84
108
|
|
|
85
|
-
<div class={['overflow-x-auto py-
|
|
109
|
+
<div class={['overflow-x-auto py-4', className]} role="tree" aria-label="Organization chart">
|
|
86
110
|
{#if root}
|
|
87
|
-
<div class="
|
|
111
|
+
<div class="flex min-w-max justify-center px-4 pb-2">
|
|
88
112
|
{@render tree(root)}
|
|
89
113
|
</div>
|
|
90
114
|
{:else}
|